Commit 256cbafb authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-hns3-fix-some-bug-for-hns3'

Hao Lan says:

====================
net: hns3: fix some bug for hns3

There are some bugfixes for the HNS3 ethernet driver. patch#1 fix miss
checking for rx packet. patch#2 fixes VF promisc mode not update
when mac table full bug, and patch#3 fixes a nterrupts not
initialization in VF FLR bug.
====================

Link: https://lore.kernel.org/r/20221222064343.61537-1-lanhao@huawei.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 7fac54b9 8ee57c7b
Loading
Loading
Loading
Loading
+4 −6
Original line number Diff line number Diff line
@@ -3855,18 +3855,16 @@ static int hns3_gro_complete(struct sk_buff *skb, u32 l234info)
	return 0;
}

static bool hns3_checksum_complete(struct hns3_enet_ring *ring,
static void hns3_checksum_complete(struct hns3_enet_ring *ring,
				   struct sk_buff *skb, u32 ptype, u16 csum)
{
	if (ptype == HNS3_INVALID_PTYPE ||
	    hns3_rx_ptype_tbl[ptype].ip_summed != CHECKSUM_COMPLETE)
		return false;
		return;

	hns3_ring_stats_update(ring, csum_complete);
	skb->ip_summed = CHECKSUM_COMPLETE;
	skb->csum = csum_unfold((__force __sum16)csum);

	return true;
}

static void hns3_rx_handle_csum(struct sk_buff *skb, u32 l234info,
@@ -3926,8 +3924,7 @@ static void hns3_rx_checksum(struct hns3_enet_ring *ring, struct sk_buff *skb,
		ptype = hnae3_get_field(ol_info, HNS3_RXD_PTYPE_M,
					HNS3_RXD_PTYPE_S);

	if (hns3_checksum_complete(ring, skb, ptype, csum))
		return;
	hns3_checksum_complete(ring, skb, ptype, csum);

	/* check if hardware has done checksum */
	if (!(bd_base_info & BIT(HNS3_RXD_L3L4P_B)))
@@ -3936,6 +3933,7 @@ static void hns3_rx_checksum(struct hns3_enet_ring *ring, struct sk_buff *skb,
	if (unlikely(l234info & (BIT(HNS3_RXD_L3E_B) | BIT(HNS3_RXD_L4E_B) |
				 BIT(HNS3_RXD_OL3E_B) |
				 BIT(HNS3_RXD_OL4E_B)))) {
		skb->ip_summed = CHECKSUM_NONE;
		hns3_ring_stats_update(ring, l3l4_csum_err);

		return;
+43 −32
Original line number Diff line number Diff line
@@ -12754,60 +12754,71 @@ static int hclge_gro_en(struct hnae3_handle *handle, bool enable)
	return ret;
}

static void hclge_sync_promisc_mode(struct hclge_dev *hdev)
static int hclge_sync_vport_promisc_mode(struct hclge_vport *vport)
{
	struct hclge_vport *vport = &hdev->vport[0];
	struct hnae3_handle *handle = &vport->nic;
	struct hclge_dev *hdev = vport->back;
	bool uc_en = false;
	bool mc_en = false;
	u8 tmp_flags;
	bool bc_en;
	int ret;
	u16 i;

	if (vport->last_promisc_flags != vport->overflow_promisc_flags) {
		set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state);
		vport->last_promisc_flags = vport->overflow_promisc_flags;
	}

	if (test_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state)) {
	if (!test_and_clear_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
				&vport->state))
		return 0;

	/* for PF */
	if (!vport->vport_id) {
		tmp_flags = handle->netdev_flags | vport->last_promisc_flags;
		ret = hclge_set_promisc_mode(handle, tmp_flags & HNAE3_UPE,
					     tmp_flags & HNAE3_MPE);
		if (!ret) {
			clear_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
				  &vport->state);
		if (!ret)
			set_bit(HCLGE_VPORT_STATE_VLAN_FLTR_CHANGE,
				&vport->state);
		}
		else
			set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
				&vport->state);
		return ret;
	}

	for (i = 1; i < hdev->num_alloc_vport; i++) {
		bool uc_en = false;
		bool mc_en = false;
		bool bc_en;

		vport = &hdev->vport[i];

		if (!test_and_clear_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
					&vport->state))
			continue;

	/* for VF */
	if (vport->vf_info.trusted) {
		uc_en = vport->vf_info.request_uc_en > 0 ||
				vport->overflow_promisc_flags &
				HNAE3_OVERFLOW_UPE;
			vport->overflow_promisc_flags & HNAE3_OVERFLOW_UPE;
		mc_en = vport->vf_info.request_mc_en > 0 ||
				vport->overflow_promisc_flags &
				HNAE3_OVERFLOW_MPE;
			vport->overflow_promisc_flags & HNAE3_OVERFLOW_MPE;
	}
	bc_en = vport->vf_info.request_bc_en > 0;

	ret = hclge_cmd_set_promisc_mode(hdev, vport->vport_id, uc_en,
					 mc_en, bc_en);
	if (ret) {
			set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
				&vport->state);
			return;
		set_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, &vport->state);
		return ret;
	}
	hclge_set_vport_vlan_fltr_change(vport);

	return 0;
}

static void hclge_sync_promisc_mode(struct hclge_dev *hdev)
{
	struct hclge_vport *vport;
	int ret;
	u16 i;

	for (i = 0; i < hdev->num_alloc_vport; i++) {
		vport = &hdev->vport[i];

		ret = hclge_sync_vport_promisc_mode(vport);
		if (ret)
			return;
	}
}

+2 −1
Original line number Diff line number Diff line
@@ -2767,7 +2767,8 @@ static int hclgevf_pci_reset(struct hclgevf_dev *hdev)
	struct pci_dev *pdev = hdev->pdev;
	int ret = 0;

	if (hdev->reset_type == HNAE3_VF_FULL_RESET &&
	if ((hdev->reset_type == HNAE3_VF_FULL_RESET ||
	     hdev->reset_type == HNAE3_FLR_RESET) &&
	    test_bit(HCLGEVF_STATE_IRQ_INITED, &hdev->state)) {
		hclgevf_misc_irq_uninit(hdev);
		hclgevf_uninit_msi(hdev);