diff options
Diffstat (limited to 'drivers/net/ethernet/broadcom')
| -rw-r--r-- | drivers/net/ethernet/broadcom/bcm63xx_enet.c | 3 | ||||
| -rw-r--r-- | drivers/net/ethernet/broadcom/bgmac.c | 11 | ||||
| -rw-r--r-- | drivers/net/ethernet/broadcom/bnx2.c | 65 | ||||
| -rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt.c | 30 | ||||
| -rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c | 4 | 
6 files changed, 81 insertions, 34 deletions
| diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c index ae364c74baf3..537090952c45 100644 --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c @@ -1126,7 +1126,8 @@ out_freeirq:  	free_irq(dev->irq, dev);  out_phy_disconnect: -	phy_disconnect(phydev); +	if (priv->has_phy) +		phy_disconnect(phydev);  	return ret;  } diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 856379cbb402..49f4cafe5438 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -307,6 +307,10 @@ static void bgmac_dma_rx_enable(struct bgmac *bgmac,  	u32 ctl;  	ctl = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_RX_CTL); + +	/* preserve ONLY bits 16-17 from current hardware value */ +	ctl &= BGMAC_DMA_RX_ADDREXT_MASK; +  	if (bgmac->feature_flags & BGMAC_FEAT_RX_MASK_SETUP) {  		ctl &= ~BGMAC_DMA_RX_BL_MASK;  		ctl |= BGMAC_DMA_RX_BL_128 << BGMAC_DMA_RX_BL_SHIFT; @@ -317,7 +321,6 @@ static void bgmac_dma_rx_enable(struct bgmac *bgmac,  		ctl &= ~BGMAC_DMA_RX_PT_MASK;  		ctl |= BGMAC_DMA_RX_PT_1 << BGMAC_DMA_RX_PT_SHIFT;  	} -	ctl &= BGMAC_DMA_RX_ADDREXT_MASK;  	ctl |= BGMAC_DMA_RX_ENABLE;  	ctl |= BGMAC_DMA_RX_PARITY_DISABLE;  	ctl |= BGMAC_DMA_RX_OVERFLOW_CONT; @@ -1046,9 +1049,9 @@ static void bgmac_enable(struct bgmac *bgmac)  	mode = (bgmac_read(bgmac, BGMAC_DEV_STATUS) & BGMAC_DS_MM_MASK) >>  		BGMAC_DS_MM_SHIFT; -	if (!(bgmac->feature_flags & BGMAC_FEAT_CLKCTLST) || mode != 0) +	if (bgmac->feature_flags & BGMAC_FEAT_CLKCTLST || mode != 0)  		bgmac_set(bgmac, BCMA_CLKCTLST, BCMA_CLKCTLST_FORCEHT); -	if (bgmac->feature_flags & BGMAC_FEAT_CLKCTLST && mode == 2) +	if (!(bgmac->feature_flags & BGMAC_FEAT_CLKCTLST) && mode == 2)  		bgmac_cco_ctl_maskset(bgmac, 1, ~0,  				      BGMAC_CHIPCTL_1_RXC_DLL_BYPASS); @@ -1449,7 +1452,7 @@ static int bgmac_phy_connect(struct bgmac *bgmac)  	phy_dev = phy_connect(bgmac->net_dev, bus_id, &bgmac_adjust_link,  			      PHY_INTERFACE_MODE_MII);  	if (IS_ERR(phy_dev)) { -		dev_err(bgmac->dev, "PHY connecton failed\n"); +		dev_err(bgmac->dev, "PHY connection failed\n");  		return PTR_ERR(phy_dev);  	} diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index 27f11a5d5fe2..1f7034d739b0 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -49,6 +49,7 @@  #include <linux/firmware.h>  #include <linux/log2.h>  #include <linux/aer.h> +#include <linux/crash_dump.h>  #if IS_ENABLED(CONFIG_CNIC)  #define BCM_CNIC 1 @@ -271,22 +272,25 @@ static inline u32 bnx2_tx_avail(struct bnx2 *bp, struct bnx2_tx_ring_info *txr)  static u32  bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset)  { +	unsigned long flags;  	u32 val; -	spin_lock_bh(&bp->indirect_lock); +	spin_lock_irqsave(&bp->indirect_lock, flags);  	BNX2_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset);  	val = BNX2_RD(bp, BNX2_PCICFG_REG_WINDOW); -	spin_unlock_bh(&bp->indirect_lock); +	spin_unlock_irqrestore(&bp->indirect_lock, flags);  	return val;  }  static void  bnx2_reg_wr_ind(struct bnx2 *bp, u32 offset, u32 val)  { -	spin_lock_bh(&bp->indirect_lock); +	unsigned long flags; + +	spin_lock_irqsave(&bp->indirect_lock, flags);  	BNX2_WR(bp, BNX2_PCICFG_REG_WINDOW_ADDRESS, offset);  	BNX2_WR(bp, BNX2_PCICFG_REG_WINDOW, val); -	spin_unlock_bh(&bp->indirect_lock); +	spin_unlock_irqrestore(&bp->indirect_lock, flags);  }  static void @@ -304,8 +308,10 @@ bnx2_shmem_rd(struct bnx2 *bp, u32 offset)  static void  bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val)  { +	unsigned long flags; +  	offset += cid_addr; -	spin_lock_bh(&bp->indirect_lock); +	spin_lock_irqsave(&bp->indirect_lock, flags);  	if (BNX2_CHIP(bp) == BNX2_CHIP_5709) {  		int i; @@ -322,7 +328,7 @@ bnx2_ctx_wr(struct bnx2 *bp, u32 cid_addr, u32 offset, u32 val)  		BNX2_WR(bp, BNX2_CTX_DATA_ADR, offset);  		BNX2_WR(bp, BNX2_CTX_DATA, val);  	} -	spin_unlock_bh(&bp->indirect_lock); +	spin_unlock_irqrestore(&bp->indirect_lock, flags);  }  #ifdef BCM_CNIC @@ -4759,15 +4765,16 @@ bnx2_setup_msix_tbl(struct bnx2 *bp)  	BNX2_WR(bp, BNX2_PCI_GRC_WINDOW3_ADDR, BNX2_MSIX_PBA_ADDR);  } -static int -bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) +static void +bnx2_wait_dma_complete(struct bnx2 *bp)  {  	u32 val; -	int i, rc = 0; -	u8 old_port; +	int i; -	/* Wait for the current PCI transaction to complete before -	 * issuing a reset. */ +	/* +	 * Wait for the current PCI transaction to complete before +	 * issuing a reset. +	 */  	if ((BNX2_CHIP(bp) == BNX2_CHIP_5706) ||  	    (BNX2_CHIP(bp) == BNX2_CHIP_5708)) {  		BNX2_WR(bp, BNX2_MISC_ENABLE_CLR_BITS, @@ -4791,6 +4798,21 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)  		}  	} +	return; +} + + +static int +bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) +{ +	u32 val; +	int i, rc = 0; +	u8 old_port; + +	/* Wait for the current PCI transaction to complete before +	 * issuing a reset. */ +	bnx2_wait_dma_complete(bp); +  	/* Wait for the firmware to tell us it is ok to issue a reset. */  	bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code, 1, 1); @@ -6356,6 +6378,10 @@ bnx2_open(struct net_device *dev)  	struct bnx2 *bp = netdev_priv(dev);  	int rc; +	rc = bnx2_request_firmware(bp); +	if (rc < 0) +		goto out; +  	netif_carrier_off(dev);  	bnx2_disable_int(bp); @@ -6424,6 +6450,7 @@ open_err:  	bnx2_free_irq(bp);  	bnx2_free_mem(bp);  	bnx2_del_napi(bp); +	bnx2_release_firmware(bp);  	goto out;  } @@ -8570,12 +8597,15 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)  	pci_set_drvdata(pdev, dev); -	rc = bnx2_request_firmware(bp); -	if (rc < 0) -		goto error; - +	/* +	 * In-flight DMA from 1st kernel could continue going in kdump kernel. +	 * New io-page table has been created before bnx2 does reset at open stage. +	 * We have to wait for the in-flight DMA to complete to avoid it look up +	 * into the newly created io-page table. +	 */ +	if (is_kdump_kernel()) +		bnx2_wait_dma_complete(bp); -	bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);  	memcpy(dev->dev_addr, bp->mac_addr, ETH_ALEN);  	dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | @@ -8608,7 +8638,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)  	return 0;  error: -	bnx2_release_firmware(bp);  	pci_iounmap(pdev, bp->regview);  	pci_release_regions(pdev);  	pci_disable_device(pdev); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 20fe6a8c35c1..0cee4c0283f9 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -15241,7 +15241,7 @@ static void bnx2x_init_cyclecounter(struct bnx2x *bp)  	memset(&bp->cyclecounter, 0, sizeof(bp->cyclecounter));  	bp->cyclecounter.read = bnx2x_cyclecounter_read;  	bp->cyclecounter.mask = CYCLECOUNTER_MASK(64); -	bp->cyclecounter.shift = 1; +	bp->cyclecounter.shift = 0;  	bp->cyclecounter.mult = 1;  } diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index a9f9f3738022..ee1a803aa11a 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -1811,6 +1811,9 @@ static int bnxt_busy_poll(struct napi_struct *napi)  	if (atomic_read(&bp->intr_sem) != 0)  		return LL_FLUSH_FAILED; +	if (!bp->link_info.link_up) +		return LL_FLUSH_FAILED; +  	if (!bnxt_lock_poll(bnapi))  		return LL_FLUSH_BUSY; @@ -3210,11 +3213,17 @@ static int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, __be16 port,  		goto err_out;  	} -	if (tunnel_type & TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_VXLAN) +	switch (tunnel_type) { +	case TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_VXLAN:  		bp->vxlan_fw_dst_port_id = resp->tunnel_dst_port_id; - -	else if (tunnel_type & TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_GENEVE) +		break; +	case TUNNEL_DST_PORT_ALLOC_REQ_TUNNEL_TYPE_GENEVE:  		bp->nge_fw_dst_port_id = resp->tunnel_dst_port_id; +		break; +	default: +		break; +	} +  err_out:  	mutex_unlock(&bp->hwrm_cmd_lock);  	return rc; @@ -4934,6 +4943,10 @@ static void bnxt_del_napi(struct bnxt *bp)  		napi_hash_del(&bnapi->napi);  		netif_napi_del(&bnapi->napi);  	} +	/* We called napi_hash_del() before netif_napi_del(), we need +	 * to respect an RCU grace period before freeing napi structures. +	 */ +	synchronize_net();  }  static void bnxt_init_napi(struct bnxt *bp) @@ -6309,6 +6322,7 @@ static int bnxt_setup_tc(struct net_device *dev, u32 handle, __be16 proto,  			 struct tc_to_netdev *ntc)  {  	struct bnxt *bp = netdev_priv(dev); +	bool sh = false;  	u8 tc;  	if (ntc->type != TC_SETUP_MQPRIO) @@ -6325,12 +6339,11 @@ static int bnxt_setup_tc(struct net_device *dev, u32 handle, __be16 proto,  	if (netdev_get_num_tc(dev) == tc)  		return 0; +	if (bp->flags & BNXT_FLAG_SHARED_RINGS) +		sh = true; +  	if (tc) {  		int max_rx_rings, max_tx_rings, rc; -		bool sh = false; - -		if (bp->flags & BNXT_FLAG_SHARED_RINGS) -			sh = true;  		rc = bnxt_get_max_rings(bp, &max_rx_rings, &max_tx_rings, sh);  		if (rc || bp->tx_nr_rings_per_tc * tc > max_tx_rings) @@ -6348,7 +6361,8 @@ static int bnxt_setup_tc(struct net_device *dev, u32 handle, __be16 proto,  		bp->tx_nr_rings = bp->tx_nr_rings_per_tc;  		netdev_reset_tc(dev);  	} -	bp->cp_nr_rings = max_t(int, bp->tx_nr_rings, bp->rx_nr_rings); +	bp->cp_nr_rings = sh ? max_t(int, bp->tx_nr_rings, bp->rx_nr_rings) : +			       bp->tx_nr_rings + bp->rx_nr_rings;  	bp->num_stat_ctxs = bp->cp_nr_rings;  	if (netif_running(bp->dev)) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c index ec6cd18842c3..60e2af8678bd 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c @@ -774,8 +774,8 @@ static int bnxt_vf_set_link(struct bnxt *bp, struct bnxt_vf_info *vf)  		if (vf->flags & BNXT_VF_LINK_UP) {  			/* if physical link is down, force link up on VF */ -			if (phy_qcfg_resp.link == -			    PORT_PHY_QCFG_RESP_LINK_NO_LINK) { +			if (phy_qcfg_resp.link != +			    PORT_PHY_QCFG_RESP_LINK_LINK) {  				phy_qcfg_resp.link =  					PORT_PHY_QCFG_RESP_LINK_LINK;  				phy_qcfg_resp.link_speed = cpu_to_le16( |