Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 252dd176 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'bnxt_en-Bug-fixes'



Michael Chan says:

====================
bnxt_en: Bug fixes.

These are bug fixes in error code paths, TC Flower VLAN TCI flow
checking bug fix, proper filtering of Broadcast packets if IFF_BROADCAST
is not set, and a bug fix in bnxt_get_max_rings() to return 0 ring
parameters when the return value is -ENOMEM.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 26420d9c c58387ab
Loading
Loading
Loading
Loading
+17 −7
Original line number Original line Diff line number Diff line
@@ -5712,7 +5712,9 @@ static int bnxt_init_chip(struct bnxt *bp, bool irq_re_init)
	}
	}
	vnic->uc_filter_count = 1;
	vnic->uc_filter_count = 1;


	vnic->rx_mask = CFA_L2_SET_RX_MASK_REQ_MASK_BCAST;
	vnic->rx_mask = 0;
	if (bp->dev->flags & IFF_BROADCAST)
		vnic->rx_mask |= CFA_L2_SET_RX_MASK_REQ_MASK_BCAST;


	if ((bp->dev->flags & IFF_PROMISC) && bnxt_promisc_ok(bp))
	if ((bp->dev->flags & IFF_PROMISC) && bnxt_promisc_ok(bp))
		vnic->rx_mask |= CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS;
		vnic->rx_mask |= CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS;
@@ -5917,7 +5919,7 @@ unsigned int bnxt_get_max_func_irqs(struct bnxt *bp)
	return min_t(unsigned int, hw_resc->max_irqs, hw_resc->max_cp_rings);
	return min_t(unsigned int, hw_resc->max_irqs, hw_resc->max_cp_rings);
}
}


void bnxt_set_max_func_irqs(struct bnxt *bp, unsigned int max_irqs)
static void bnxt_set_max_func_irqs(struct bnxt *bp, unsigned int max_irqs)
{
{
	bp->hw_resc.max_irqs = max_irqs;
	bp->hw_resc.max_irqs = max_irqs;
}
}
@@ -6888,7 +6890,7 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
		rc = bnxt_request_irq(bp);
		rc = bnxt_request_irq(bp);
		if (rc) {
		if (rc) {
			netdev_err(bp->dev, "bnxt_request_irq err: %x\n", rc);
			netdev_err(bp->dev, "bnxt_request_irq err: %x\n", rc);
			goto open_err;
			goto open_err_irq;
		}
		}
	}
	}


@@ -6928,6 +6930,8 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
open_err:
open_err:
	bnxt_debug_dev_exit(bp);
	bnxt_debug_dev_exit(bp);
	bnxt_disable_napi(bp);
	bnxt_disable_napi(bp);

open_err_irq:
	bnxt_del_napi(bp);
	bnxt_del_napi(bp);


open_err_free_mem:
open_err_free_mem:
@@ -7214,13 +7218,16 @@ static void bnxt_set_rx_mode(struct net_device *dev)


	mask &= ~(CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS |
	mask &= ~(CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS |
		  CFA_L2_SET_RX_MASK_REQ_MASK_MCAST |
		  CFA_L2_SET_RX_MASK_REQ_MASK_MCAST |
		  CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST);
		  CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST |
		  CFA_L2_SET_RX_MASK_REQ_MASK_BCAST);


	if ((dev->flags & IFF_PROMISC) && bnxt_promisc_ok(bp))
	if ((dev->flags & IFF_PROMISC) && bnxt_promisc_ok(bp))
		mask |= CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS;
		mask |= CFA_L2_SET_RX_MASK_REQ_MASK_PROMISCUOUS;


	uc_update = bnxt_uc_list_updated(bp);
	uc_update = bnxt_uc_list_updated(bp);


	if (dev->flags & IFF_BROADCAST)
		mask |= CFA_L2_SET_RX_MASK_REQ_MASK_BCAST;
	if (dev->flags & IFF_ALLMULTI) {
	if (dev->flags & IFF_ALLMULTI) {
		mask |= CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST;
		mask |= CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST;
		vnic->mc_list_count = 0;
		vnic->mc_list_count = 0;
@@ -8502,11 +8509,11 @@ int bnxt_get_max_rings(struct bnxt *bp, int *max_rx, int *max_tx, bool shared)
	int rx, tx, cp;
	int rx, tx, cp;


	_bnxt_get_max_rings(bp, &rx, &tx, &cp);
	_bnxt_get_max_rings(bp, &rx, &tx, &cp);
	*max_rx = rx;
	*max_tx = tx;
	if (!rx || !tx || !cp)
	if (!rx || !tx || !cp)
		return -ENOMEM;
		return -ENOMEM;


	*max_rx = rx;
	*max_tx = tx;
	return bnxt_trim_rings(bp, max_rx, max_tx, cp, shared);
	return bnxt_trim_rings(bp, max_rx, max_tx, cp, shared);
}
}


@@ -8520,8 +8527,11 @@ static int bnxt_get_dflt_rings(struct bnxt *bp, int *max_rx, int *max_tx,
		/* Not enough rings, try disabling agg rings. */
		/* Not enough rings, try disabling agg rings. */
		bp->flags &= ~BNXT_FLAG_AGG_RINGS;
		bp->flags &= ~BNXT_FLAG_AGG_RINGS;
		rc = bnxt_get_max_rings(bp, max_rx, max_tx, shared);
		rc = bnxt_get_max_rings(bp, max_rx, max_tx, shared);
		if (rc)
		if (rc) {
			/* set BNXT_FLAG_AGG_RINGS back for consistency */
			bp->flags |= BNXT_FLAG_AGG_RINGS;
			return rc;
			return rc;
		}
		bp->flags |= BNXT_FLAG_NO_AGG_RINGS;
		bp->flags |= BNXT_FLAG_NO_AGG_RINGS;
		bp->dev->hw_features &= ~(NETIF_F_LRO | NETIF_F_GRO_HW);
		bp->dev->hw_features &= ~(NETIF_F_LRO | NETIF_F_GRO_HW);
		bp->dev->features &= ~(NETIF_F_LRO | NETIF_F_GRO_HW);
		bp->dev->features &= ~(NETIF_F_LRO | NETIF_F_GRO_HW);
+0 −1
Original line number Original line Diff line number Diff line
@@ -1470,7 +1470,6 @@ void bnxt_set_max_func_stat_ctxs(struct bnxt *bp, unsigned int max);
unsigned int bnxt_get_max_func_cp_rings(struct bnxt *bp);
unsigned int bnxt_get_max_func_cp_rings(struct bnxt *bp);
void bnxt_set_max_func_cp_rings(struct bnxt *bp, unsigned int max);
void bnxt_set_max_func_cp_rings(struct bnxt *bp, unsigned int max);
unsigned int bnxt_get_max_func_irqs(struct bnxt *bp);
unsigned int bnxt_get_max_func_irqs(struct bnxt *bp);
void bnxt_set_max_func_irqs(struct bnxt *bp, unsigned int max);
int bnxt_get_avail_msix(struct bnxt *bp, int num);
int bnxt_get_avail_msix(struct bnxt *bp, int num);
int bnxt_reserve_rings(struct bnxt *bp);
int bnxt_reserve_rings(struct bnxt *bp);
void bnxt_tx_disable(struct bnxt *bp);
void bnxt_tx_disable(struct bnxt *bp);
+27 −3
Original line number Original line Diff line number Diff line
@@ -27,6 +27,15 @@
#define BNXT_FID_INVALID			0xffff
#define BNXT_FID_INVALID			0xffff
#define VLAN_TCI(vid, prio)	((vid) | ((prio) << VLAN_PRIO_SHIFT))
#define VLAN_TCI(vid, prio)	((vid) | ((prio) << VLAN_PRIO_SHIFT))


#define is_vlan_pcp_wildcarded(vlan_tci_mask)	\
	((ntohs(vlan_tci_mask) & VLAN_PRIO_MASK) == 0x0000)
#define is_vlan_pcp_exactmatch(vlan_tci_mask)	\
	((ntohs(vlan_tci_mask) & VLAN_PRIO_MASK) == VLAN_PRIO_MASK)
#define is_vlan_pcp_zero(vlan_tci)	\
	((ntohs(vlan_tci) & VLAN_PRIO_MASK) == 0x0000)
#define is_vid_exactmatch(vlan_tci_mask)	\
	((ntohs(vlan_tci_mask) & VLAN_VID_MASK) == VLAN_VID_MASK)

/* Return the dst fid of the func for flow forwarding
/* Return the dst fid of the func for flow forwarding
 * For PFs: src_fid is the fid of the PF
 * For PFs: src_fid is the fid of the PF
 * For VF-reps: src_fid the fid of the VF
 * For VF-reps: src_fid the fid of the VF
@@ -389,6 +398,21 @@ static bool is_exactmatch(void *mask, int len)
	return true;
	return true;
}
}


static bool is_vlan_tci_allowed(__be16  vlan_tci_mask,
				__be16  vlan_tci)
{
	/* VLAN priority must be either exactly zero or fully wildcarded and
	 * VLAN id must be exact match.
	 */
	if (is_vid_exactmatch(vlan_tci_mask) &&
	    ((is_vlan_pcp_exactmatch(vlan_tci_mask) &&
	      is_vlan_pcp_zero(vlan_tci)) ||
	     is_vlan_pcp_wildcarded(vlan_tci_mask)))
		return true;

	return false;
}

static bool bits_set(void *key, int len)
static bool bits_set(void *key, int len)
{
{
	const u8 *p = key;
	const u8 *p = key;
@@ -803,9 +827,9 @@ static bool bnxt_tc_can_offload(struct bnxt *bp, struct bnxt_tc_flow *flow)
	/* Currently VLAN fields cannot be partial wildcard */
	/* Currently VLAN fields cannot be partial wildcard */
	if (bits_set(&flow->l2_key.inner_vlan_tci,
	if (bits_set(&flow->l2_key.inner_vlan_tci,
		     sizeof(flow->l2_key.inner_vlan_tci)) &&
		     sizeof(flow->l2_key.inner_vlan_tci)) &&
	    !is_exactmatch(&flow->l2_mask.inner_vlan_tci,
	    !is_vlan_tci_allowed(flow->l2_mask.inner_vlan_tci,
			   sizeof(flow->l2_mask.inner_vlan_tci))) {
				 flow->l2_key.inner_vlan_tci)) {
		netdev_info(bp->dev, "Wildcard match unsupported for VLAN TCI\n");
		netdev_info(bp->dev, "Unsupported VLAN TCI\n");
		return false;
		return false;
	}
	}
	if (bits_set(&flow->l2_key.inner_vlan_tpid,
	if (bits_set(&flow->l2_key.inner_vlan_tpid,
+0 −2
Original line number Original line Diff line number Diff line
@@ -169,7 +169,6 @@ static int bnxt_req_msix_vecs(struct bnxt_en_dev *edev, int ulp_id,
		edev->ulp_tbl[ulp_id].msix_requested = avail_msix;
		edev->ulp_tbl[ulp_id].msix_requested = avail_msix;
	}
	}
	bnxt_fill_msix_vecs(bp, ent);
	bnxt_fill_msix_vecs(bp, ent);
	bnxt_set_max_func_irqs(bp, bnxt_get_max_func_irqs(bp) - avail_msix);
	bnxt_set_max_func_cp_rings(bp, max_cp_rings - avail_msix);
	bnxt_set_max_func_cp_rings(bp, max_cp_rings - avail_msix);
	edev->flags |= BNXT_EN_FLAG_MSIX_REQUESTED;
	edev->flags |= BNXT_EN_FLAG_MSIX_REQUESTED;
	return avail_msix;
	return avail_msix;
@@ -192,7 +191,6 @@ static int bnxt_free_msix_vecs(struct bnxt_en_dev *edev, int ulp_id)
	msix_requested = edev->ulp_tbl[ulp_id].msix_requested;
	msix_requested = edev->ulp_tbl[ulp_id].msix_requested;
	bnxt_set_max_func_cp_rings(bp, max_cp_rings + msix_requested);
	bnxt_set_max_func_cp_rings(bp, max_cp_rings + msix_requested);
	edev->ulp_tbl[ulp_id].msix_requested = 0;
	edev->ulp_tbl[ulp_id].msix_requested = 0;
	bnxt_set_max_func_irqs(bp, bnxt_get_max_func_irqs(bp) + msix_requested);
	edev->flags &= ~BNXT_EN_FLAG_MSIX_REQUESTED;
	edev->flags &= ~BNXT_EN_FLAG_MSIX_REQUESTED;
	if (netif_running(dev)) {
	if (netif_running(dev)) {
		bnxt_close_nic(bp, true, false);
		bnxt_close_nic(bp, true, false);