diff options
Diffstat (limited to 'drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c')
| -rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 122 | 
1 files changed, 59 insertions, 63 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index dd451c3dd83..0875ecfe337 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -4041,20 +4041,6 @@ static bool bnx2x_get_load_status(struct bnx2x *bp, int engine)  	return val != 0;  } -/* - * Reset the load status for the current engine. - */ -static void bnx2x_clear_load_status(struct bnx2x *bp) -{ -	u32 val; -	u32 mask = (BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK : -		    BNX2X_PATH0_LOAD_CNT_MASK); -	bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); -	val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); -	REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val & (~mask)); -	bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); -} -  static void _print_next_block(int idx, const char *blk)  {  	pr_cont("%s%s", idx ? ", " : "", blk); @@ -7575,8 +7561,14 @@ int bnx2x_set_mac_one(struct bnx2x *bp, u8 *mac,  	}  	rc = bnx2x_config_vlan_mac(bp, &ramrod_param); -	if (rc < 0) + +	if (rc == -EEXIST) { +		DP(BNX2X_MSG_SP, "Failed to schedule ADD operations: %d\n", rc); +		/* do not treat adding same MAC as error */ +		rc = 0; +	} else if (rc < 0)  		BNX2X_ERR("%s MAC failed\n", (set ? "Set" : "Del")); +  	return rc;  } @@ -8441,6 +8433,8 @@ unload_error:  	/* Disable HW interrupts, NAPI */  	bnx2x_netif_stop(bp, 1); +	/* Delete all NAPI objects */ +	bnx2x_del_all_napi(bp);  	/* Release IRQs */  	bnx2x_free_irq(bp); @@ -9384,32 +9378,24 @@ static int __devinit bnx2x_prev_mark_path(struct bnx2x *bp)  	return rc;  } -static bool __devinit bnx2x_can_flr(struct bnx2x *bp) -{ -	int pos; -	u32 cap; -	struct pci_dev *dev = bp->pdev; - -	pos = pci_pcie_cap(dev); -	if (!pos) -		return false; - -	pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP, &cap); -	if (!(cap & PCI_EXP_DEVCAP_FLR)) -		return false; - -	return true; -} -  static int __devinit bnx2x_do_flr(struct bnx2x *bp)  {  	int i, pos;  	u16 status;  	struct pci_dev *dev = bp->pdev; -	/* probe the capability first */ -	if (bnx2x_can_flr(bp)) -		return -ENOTTY; + +	if (CHIP_IS_E1x(bp)) { +		BNX2X_DEV_INFO("FLR not supported in E1/E1H\n"); +		return -EINVAL; +	} + +	/* only bootcode REQ_BC_VER_4_INITIATE_FLR and onwards support flr */ +	if (bp->common.bc_ver < REQ_BC_VER_4_INITIATE_FLR) { +		BNX2X_ERR("FLR not supported by BC_VER: 0x%x\n", +			  bp->common.bc_ver); +		return -EINVAL; +	}  	pos = pci_pcie_cap(dev);  	if (!pos) @@ -9429,12 +9415,8 @@ static int __devinit bnx2x_do_flr(struct bnx2x *bp)  		"transaction is not cleared; proceeding with reset anyway\n");  clear: -	if (bp->common.bc_ver < REQ_BC_VER_4_INITIATE_FLR) { -		BNX2X_ERR("FLR not supported by BC_VER: 0x%x\n", -			  bp->common.bc_ver); -		return -EINVAL; -	} +	BNX2X_DEV_INFO("Initiating FLR\n");  	bnx2x_fw_command(bp, DRV_MSG_CODE_INITIATE_FLR, 0);  	return 0; @@ -9454,8 +9436,21 @@ static int __devinit bnx2x_prev_unload_uncommon(struct bnx2x *bp)  	 * the one required, then FLR will be sufficient to clean any residue  	 * left by previous driver  	 */ -	if (bnx2x_test_firmware_version(bp, false) && bnx2x_can_flr(bp)) -		return bnx2x_do_flr(bp); +	rc = bnx2x_test_firmware_version(bp, false); + +	if (!rc) { +		/* fw version is good */ +		BNX2X_DEV_INFO("FW version matches our own. Attempting FLR\n"); +		rc = bnx2x_do_flr(bp); +	} + +	if (!rc) { +		/* FLR was performed */ +		BNX2X_DEV_INFO("FLR successful\n"); +		return 0; +	} + +	BNX2X_DEV_INFO("Could not FLR\n");  	/* Close the MCP request, return failure*/  	rc = bnx2x_prev_mcp_done(bp); @@ -9836,12 +9831,13 @@ static void __devinit bnx2x_get_igu_cam_info(struct bnx2x *bp)  	}  #ifdef CONFIG_PCI_MSI -	/* -	 * It's expected that number of CAM entries for this functions is equal -	 * to the number evaluated based on the MSI-X table size. We want a -	 * harsh warning if these values are different! +	/* Due to new PF resource allocation by MFW T7.4 and above, it's +	 * optional that number of CAM entries will not be equal to the value +	 * advertised in PCI. +	 * Driver should use the minimal value of both as the actual status +	 * block count  	 */ -	WARN_ON(bp->igu_sb_cnt != igu_sb_cnt); +	bp->igu_sb_cnt = min_t(int, bp->igu_sb_cnt, igu_sb_cnt);  #endif  	if (igu_sb_cnt == 0) @@ -10305,13 +10301,11 @@ static void __devinit bnx2x_get_fcoe_info(struct bnx2x *bp)  				dev_info.port_hw_config[port].  				 fcoe_wwn_node_name_lower);  	} else if (!IS_MF_SD(bp)) { -		u32 cfg = MF_CFG_RD(bp, func_ext_config[func].func_cfg); -  		/*  		 * Read the WWN info only if the FCoE feature is enabled for  		 * this function.  		 */ -		if (cfg & MACP_FUNC_CFG_FLAGS_FCOE_OFFLOAD) +		if (BNX2X_MF_EXT_PROTOCOL_FCOE(bp) && !CHIP_IS_E1x(bp))  			bnx2x_get_ext_wwn_info(bp, func);  	} else if (IS_MF_FCOE_SD(bp)) @@ -11084,7 +11078,14 @@ static int bnx2x_set_uc_list(struct bnx2x *bp)  	netdev_for_each_uc_addr(ha, dev) {  		rc = bnx2x_set_mac_one(bp, bnx2x_uc_addr(ha), mac_obj, true,  				       BNX2X_UC_LIST_MAC, &ramrod_flags); -		if (rc < 0) { +		if (rc == -EEXIST) { +			DP(BNX2X_MSG_SP, +			   "Failed to schedule ADD operations: %d\n", rc); +			/* do not treat adding same MAC as error */ +			rc = 0; + +		} else if (rc < 0) { +  			BNX2X_ERR("Failed to schedule ADD operations: %d\n",  				  rc);  			return rc; @@ -11242,10 +11243,12 @@ static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)  static void poll_bnx2x(struct net_device *dev)  {  	struct bnx2x *bp = netdev_priv(dev); +	int i; -	disable_irq(bp->pdev->irq); -	bnx2x_interrupt(bp->pdev->irq, dev); -	enable_irq(bp->pdev->irq); +	for_each_eth_queue(bp, i) { +		struct bnx2x_fastpath *fp = &bp->fp[i]; +		napi_schedule(&bnx2x_fp(bp, fp->index, napi)); +	}  }  #endif @@ -11427,9 +11430,6 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev,  	if (!chip_is_e1x)  		REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ, 1); -	/* Reset the load counter */ -	bnx2x_clear_load_status(bp); -  	dev->watchdog_timeo = TX_TIMEOUT;  	dev->netdev_ops = &bnx2x_netdev_ops; @@ -11915,9 +11915,6 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,  	 */  	bnx2x_set_int_mode(bp); -	/* Add all NAPI objects */ -	bnx2x_add_all_napi(bp); -  	rc = register_netdev(dev);  	if (rc) {  		dev_err(&pdev->dev, "Cannot register net device\n"); @@ -11992,9 +11989,6 @@ static void __devexit bnx2x_remove_one(struct pci_dev *pdev)  	unregister_netdev(dev); -	/* Delete all NAPI objects */ -	bnx2x_del_all_napi(bp); -  	/* Power on: we can't let PCI layer write to us while we are in D3 */  	bnx2x_set_power_state(bp, PCI_D0); @@ -12041,6 +12035,8 @@ static int bnx2x_eeh_nic_unload(struct bnx2x *bp)  	bnx2x_tx_disable(bp);  	bnx2x_netif_stop(bp, 0); +	/* Delete all NAPI objects */ +	bnx2x_del_all_napi(bp);  	del_timer_sync(&bp->timer);  |