diff options
Diffstat (limited to 'drivers/net/ethernet/broadcom/cnic.c')
| -rw-r--r-- | drivers/net/ethernet/broadcom/cnic.c | 63 | 
1 files changed, 46 insertions, 17 deletions
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c index c95e7b5e2b8..3b4fc61f24c 100644 --- a/drivers/net/ethernet/broadcom/cnic.c +++ b/drivers/net/ethernet/broadcom/cnic.c @@ -256,11 +256,16 @@ static void cnic_ulp_ctl(struct cnic_dev *dev, int ulp_type, bool reg)  	struct cnic_local *cp = dev->cnic_priv;  	struct cnic_eth_dev *ethdev = cp->ethdev;  	struct drv_ctl_info info; +	struct fcoe_capabilities *fcoe_cap = +		&info.data.register_data.fcoe_features; -	if (reg) +	if (reg) {  		info.cmd = DRV_CTL_ULP_REGISTER_CMD; -	else +		if (ulp_type == CNIC_ULP_FCOE && dev->fcoe_cap) +			memcpy(fcoe_cap, dev->fcoe_cap, sizeof(*fcoe_cap)); +	} else {  		info.cmd = DRV_CTL_ULP_UNREGISTER_CMD; +	}  	info.data.ulp_type = ulp_type;  	ethdev->drv_ctl(dev->netdev, &info); @@ -286,6 +291,9 @@ static int cnic_get_l5_cid(struct cnic_local *cp, u32 cid, u32 *l5_cid)  {  	u32 i; +	if (!cp->ctx_tbl) +		return -EINVAL; +  	for (i = 0; i < cp->max_cid_space; i++) {  		if (cp->ctx_tbl[i].cid == cid) {  			*l5_cid = i; @@ -534,7 +542,8 @@ int cnic_unregister_driver(int ulp_type)  	}  	if (atomic_read(&ulp_ops->ref_count) != 0) -		netdev_warn(dev->netdev, "Failed waiting for ref count to go to zero\n"); +		pr_warn("%s: Failed waiting for ref count to go to zero\n", +			__func__);  	return 0;  out_unlock: @@ -611,6 +620,8 @@ static int cnic_unregister_device(struct cnic_dev *dev, int ulp_type)  	if (ulp_type == CNIC_ULP_ISCSI)  		cnic_send_nlmsg(cp, ISCSI_KEVENT_IF_DOWN, NULL); +	else if (ulp_type == CNIC_ULP_FCOE) +		dev->fcoe_cap = NULL;  	synchronize_rcu(); @@ -1053,12 +1064,13 @@ static int cnic_init_uio(struct cnic_dev *dev)  	uinfo = &udev->cnic_uinfo; -	uinfo->mem[0].addr = dev->netdev->base_addr; +	uinfo->mem[0].addr = pci_resource_start(dev->pcidev, 0);  	uinfo->mem[0].internal_addr = dev->regview; -	uinfo->mem[0].size = dev->netdev->mem_end - dev->netdev->mem_start;  	uinfo->mem[0].memtype = UIO_MEM_PHYS;  	if (test_bit(CNIC_F_BNX2_CLASS, &dev->flags)) { +		uinfo->mem[0].size = MB_GET_CID_ADDR(TX_TSS_CID + +						     TX_MAX_TSS_RINGS + 1);  		uinfo->mem[1].addr = (unsigned long) cp->status_blk.gen &  					PAGE_MASK;  		if (cp->ethdev->drv_state & CNIC_DRV_STATE_USING_MSIX) @@ -1068,6 +1080,8 @@ static int cnic_init_uio(struct cnic_dev *dev)  		uinfo->name = "bnx2_cnic";  	} else if (test_bit(CNIC_F_BNX2X_CLASS, &dev->flags)) { +		uinfo->mem[0].size = pci_resource_len(dev->pcidev, 0); +  		uinfo->mem[1].addr = (unsigned long) cp->bnx2x_def_status_blk &  			PAGE_MASK;  		uinfo->mem[1].size = sizeof(*cp->bnx2x_def_status_blk); @@ -2585,7 +2599,7 @@ static void cnic_bnx2x_kwqe_err(struct cnic_dev *dev, struct kwqe *kwqe)  		return;  	} -	cqes[0] = (struct kcqe *) &kcqe; +	cqes[0] = &kcqe;  	cnic_reply_bnx2x_kcqes(dev, ulp_type, cqes, 1);  } @@ -3213,6 +3227,9 @@ static int cnic_ctl(void *data, struct cnic_ctl_info *info)  		u32 l5_cid;  		struct cnic_local *cp = dev->cnic_priv; +		if (!test_bit(CNIC_F_CNIC_UP, &dev->flags)) +			break; +  		if (cnic_get_l5_cid(cp, cid, &l5_cid) == 0) {  			struct cnic_context *ctx = &cp->ctx_tbl[l5_cid]; @@ -3943,6 +3960,15 @@ static void cnic_cm_process_kcqe(struct cnic_dev *dev, struct kcqe *kcqe)  		cnic_cm_upcall(cp, csk, opcode);  		break; +	case L5CM_RAMROD_CMD_ID_CLOSE: +		if (l4kcqe->status != 0) { +			netdev_warn(dev->netdev, "RAMROD CLOSE compl with " +				    "status 0x%x\n", l4kcqe->status); +			opcode = L4_KCQE_OPCODE_VALUE_CLOSE_COMP; +			/* Fall through */ +		} else { +			break; +		}  	case L4_KCQE_OPCODE_VALUE_RESET_RECEIVED:  	case L4_KCQE_OPCODE_VALUE_CLOSE_COMP:  	case L4_KCQE_OPCODE_VALUE_RESET_COMP: @@ -4246,8 +4272,6 @@ static int cnic_cm_shutdown(struct cnic_dev *dev)  	struct cnic_local *cp = dev->cnic_priv;  	int i; -	cp->stop_cm(dev); -  	if (!cp->csk_tbl)  		return 0; @@ -4665,9 +4689,9 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev)  	cp->kcq1.sw_prod_idx = 0;  	cp->kcq1.hw_prod_idx_ptr = -		(u16 *) &sblk->status_completion_producer_index; +		&sblk->status_completion_producer_index; -	cp->kcq1.status_idx_ptr = (u16 *) &sblk->status_idx; +	cp->kcq1.status_idx_ptr = &sblk->status_idx;  	/* Initialize the kernel complete queue context. */  	val = KRNLQ_TYPE_TYPE_KRNLQ | KRNLQ_SIZE_TYPE_SIZE | @@ -4693,9 +4717,9 @@ static int cnic_start_bnx2_hw(struct cnic_dev *dev)  		u32 sb = BNX2_L2CTX_L5_STATUSB_NUM(sb_id);  		cp->kcq1.hw_prod_idx_ptr = -			(u16 *) &msblk->status_completion_producer_index; -		cp->kcq1.status_idx_ptr = (u16 *) &msblk->status_idx; -		cp->kwq_con_idx_ptr = (u16 *) &msblk->status_cmd_consumer_index; +			&msblk->status_completion_producer_index; +		cp->kcq1.status_idx_ptr = &msblk->status_idx; +		cp->kwq_con_idx_ptr = &msblk->status_cmd_consumer_index;  		cp->int_num = sb_id << BNX2_PCICFG_INT_ACK_CMD_INT_NUM_SHIFT;  		cnic_ctx_wr(dev, kwq_cid_addr, L5_KRNLQ_HOST_QIDX, sb);  		cnic_ctx_wr(dev, kcq_cid_addr, L5_KRNLQ_HOST_QIDX, sb); @@ -4977,8 +5001,14 @@ static int cnic_start_bnx2x_hw(struct cnic_dev *dev)  	cp->port_mode = CHIP_PORT_MODE_NONE;  	if (BNX2X_CHIP_IS_E2_PLUS(cp->chip_id)) { -		u32 val = CNIC_RD(dev, MISC_REG_PORT4MODE_EN_OVWR); +		u32 val; +		pci_read_config_dword(dev->pcidev, PCICFG_ME_REGISTER, &val); +		cp->func = (u8) ((val & ME_REG_ABS_PF_NUM) >> +				 ME_REG_ABS_PF_NUM_SHIFT); +		func = CNIC_FUNC(cp); + +		val = CNIC_RD(dev, MISC_REG_PORT4MODE_EN_OVWR);  		if (!(val & 1))  			val = CNIC_RD(dev, MISC_REG_PORT4MODE_EN);  		else @@ -5283,6 +5313,7 @@ static void cnic_stop_hw(struct cnic_dev *dev)  			i++;  		}  		cnic_shutdown_rings(dev); +		cp->stop_cm(dev);  		clear_bit(CNIC_F_CNIC_UP, &dev->flags);  		RCU_INIT_POINTER(cp->ulp_ops[CNIC_ULP_L4], NULL);  		synchronize_rcu(); @@ -5512,9 +5543,7 @@ static void cnic_rcv_netevent(struct cnic_local *cp, unsigned long event,  	rcu_read_unlock();  } -/** - * netdev event handler - */ +/* netdev event handler */  static int cnic_netdev_event(struct notifier_block *this, unsigned long event,  							 void *ptr)  {  |