diff options
author | Michael Chan <mchan@broadcom.com> | 2009-10-10 09:46:56 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-10-12 02:30:14 -0400 |
commit | 993ac7b5183f82edc9696cd17faae03523e00e09 (patch) | |
tree | b57561971c47a3529d646389dc58b9ec890543d4 /drivers/net/bnx2x_main.c | |
parent | 37b091bacba7bd329eced9a56998b6247da414c4 (diff) |
bnx2x: Add main CNIC interface functions.
Add the main CNIC registration, callback, MAC addr. setup functions.
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: Shmulik Ravid - Rabinovitz <shmulikr@broadcom.com>
Acked-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2x_main.c')
-rw-r--r-- | drivers/net/bnx2x_main.c | 388 |
1 files changed, 388 insertions, 0 deletions
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index f7b71100e95c..b4e9c6ebac54 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c | |||
@@ -969,6 +969,9 @@ static void bnx2x_tx_int(struct bnx2x_fastpath *fp) | |||
969 | } | 969 | } |
970 | } | 970 | } |
971 | 971 | ||
972 | #ifdef BCM_CNIC | ||
973 | static void bnx2x_cnic_cfc_comp(struct bnx2x *bp, int cid); | ||
974 | #endif | ||
972 | 975 | ||
973 | static void bnx2x_sp_event(struct bnx2x_fastpath *fp, | 976 | static void bnx2x_sp_event(struct bnx2x_fastpath *fp, |
974 | union eth_rx_cqe *rr_cqe) | 977 | union eth_rx_cqe *rr_cqe) |
@@ -1025,6 +1028,12 @@ static void bnx2x_sp_event(struct bnx2x_fastpath *fp, | |||
1025 | bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_CLOSED; | 1028 | bnx2x_fp(bp, cid, state) = BNX2X_FP_STATE_CLOSED; |
1026 | break; | 1029 | break; |
1027 | 1030 | ||
1031 | #ifdef BCM_CNIC | ||
1032 | case (RAMROD_CMD_ID_ETH_CFC_DEL | BNX2X_STATE_OPEN): | ||
1033 | DP(NETIF_MSG_IFDOWN, "got delete ramrod for CID %d\n", cid); | ||
1034 | bnx2x_cnic_cfc_comp(bp, cid); | ||
1035 | break; | ||
1036 | #endif | ||
1028 | 1037 | ||
1029 | case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN): | 1038 | case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_OPEN): |
1030 | case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_DIAG): | 1039 | case (RAMROD_CMD_ID_ETH_SET_MAC | BNX2X_STATE_DIAG): |
@@ -1810,6 +1819,20 @@ static irqreturn_t bnx2x_interrupt(int irq, void *dev_instance) | |||
1810 | } | 1819 | } |
1811 | } | 1820 | } |
1812 | 1821 | ||
1822 | #ifdef BCM_CNIC | ||
1823 | mask = 0x2 << CNIC_SB_ID(bp); | ||
1824 | if (status & (mask | 0x1)) { | ||
1825 | struct cnic_ops *c_ops = NULL; | ||
1826 | |||
1827 | rcu_read_lock(); | ||
1828 | c_ops = rcu_dereference(bp->cnic_ops); | ||
1829 | if (c_ops) | ||
1830 | c_ops->cnic_handler(bp->cnic_data, NULL); | ||
1831 | rcu_read_unlock(); | ||
1832 | |||
1833 | status &= ~mask; | ||
1834 | } | ||
1835 | #endif | ||
1813 | 1836 | ||
1814 | if (unlikely(status & 0x1)) { | 1837 | if (unlikely(status & 0x1)) { |
1815 | queue_delayed_work(bnx2x_wq, &bp->sp_task, 0); | 1838 | queue_delayed_work(bnx2x_wq, &bp->sp_task, 0); |
@@ -3247,6 +3270,17 @@ static irqreturn_t bnx2x_msix_sp_int(int irq, void *dev_instance) | |||
3247 | return IRQ_HANDLED; | 3270 | return IRQ_HANDLED; |
3248 | #endif | 3271 | #endif |
3249 | 3272 | ||
3273 | #ifdef BCM_CNIC | ||
3274 | { | ||
3275 | struct cnic_ops *c_ops; | ||
3276 | |||
3277 | rcu_read_lock(); | ||
3278 | c_ops = rcu_dereference(bp->cnic_ops); | ||
3279 | if (c_ops) | ||
3280 | c_ops->cnic_handler(bp->cnic_data, NULL); | ||
3281 | rcu_read_unlock(); | ||
3282 | } | ||
3283 | #endif | ||
3250 | queue_delayed_work(bnx2x_wq, &bp->sp_task, 0); | 3284 | queue_delayed_work(bnx2x_wq, &bp->sp_task, 0); |
3251 | 3285 | ||
3252 | return IRQ_HANDLED; | 3286 | return IRQ_HANDLED; |
@@ -7291,6 +7325,44 @@ static void bnx2x_set_eth_mac_addr_e1(struct bnx2x *bp, int set) | |||
7291 | bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1); | 7325 | bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1); |
7292 | } | 7326 | } |
7293 | 7327 | ||
7328 | #ifdef BCM_CNIC | ||
7329 | /** | ||
7330 | * Set iSCSI MAC(s) at the next enties in the CAM after the ETH | ||
7331 | * MAC(s). This function will wait until the ramdord completion | ||
7332 | * returns. | ||
7333 | * | ||
7334 | * @param bp driver handle | ||
7335 | * @param set set or clear the CAM entry | ||
7336 | * | ||
7337 | * @return 0 if cussess, -ENODEV if ramrod doesn't return. | ||
7338 | */ | ||
7339 | static int bnx2x_set_iscsi_eth_mac_addr(struct bnx2x *bp, int set) | ||
7340 | { | ||
7341 | u32 cl_bit_vec = (1 << BCM_ISCSI_ETH_CL_ID); | ||
7342 | |||
7343 | bp->set_mac_pending++; | ||
7344 | smp_wmb(); | ||
7345 | |||
7346 | /* Send a SET_MAC ramrod */ | ||
7347 | if (CHIP_IS_E1(bp)) | ||
7348 | bnx2x_set_mac_addr_e1_gen(bp, set, bp->iscsi_mac, | ||
7349 | cl_bit_vec, (BP_PORT(bp) ? 32 : 0) + 2, | ||
7350 | 1); | ||
7351 | else | ||
7352 | /* CAM allocation for E1H | ||
7353 | * unicasts: by func number | ||
7354 | * multicast: 20+FUNC*20, 20 each | ||
7355 | */ | ||
7356 | bnx2x_set_mac_addr_e1h_gen(bp, set, bp->iscsi_mac, | ||
7357 | cl_bit_vec, E1H_FUNC_MAX + BP_FUNC(bp)); | ||
7358 | |||
7359 | /* Wait for a completion when setting */ | ||
7360 | bnx2x_wait_ramrod(bp, 0, 0, &bp->set_mac_pending, set ? 0 : 1); | ||
7361 | |||
7362 | return 0; | ||
7363 | } | ||
7364 | #endif | ||
7365 | |||
7294 | static int bnx2x_setup_leading(struct bnx2x *bp) | 7366 | static int bnx2x_setup_leading(struct bnx2x *bp) |
7295 | { | 7367 | { |
7296 | int rc; | 7368 | int rc; |
@@ -7416,6 +7488,10 @@ static int bnx2x_set_int_mode(struct bnx2x *bp) | |||
7416 | return rc; | 7488 | return rc; |
7417 | } | 7489 | } |
7418 | 7490 | ||
7491 | #ifdef BCM_CNIC | ||
7492 | static int bnx2x_cnic_notify(struct bnx2x *bp, int cmd); | ||
7493 | static void bnx2x_setup_cnic_irq_info(struct bnx2x *bp); | ||
7494 | #endif | ||
7419 | 7495 | ||
7420 | /* must be called with rtnl_lock */ | 7496 | /* must be called with rtnl_lock */ |
7421 | static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | 7497 | static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) |
@@ -7576,6 +7652,15 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
7576 | bnx2x_set_eth_mac_addr_e1(bp, 1); | 7652 | bnx2x_set_eth_mac_addr_e1(bp, 1); |
7577 | else | 7653 | else |
7578 | bnx2x_set_eth_mac_addr_e1h(bp, 1); | 7654 | bnx2x_set_eth_mac_addr_e1h(bp, 1); |
7655 | #ifdef BCM_CNIC | ||
7656 | /* Set iSCSI L2 MAC */ | ||
7657 | mutex_lock(&bp->cnic_mutex); | ||
7658 | if (bp->cnic_eth_dev.drv_state & CNIC_DRV_STATE_REGD) { | ||
7659 | bnx2x_set_iscsi_eth_mac_addr(bp, 1); | ||
7660 | bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET; | ||
7661 | } | ||
7662 | mutex_unlock(&bp->cnic_mutex); | ||
7663 | #endif | ||
7579 | } | 7664 | } |
7580 | 7665 | ||
7581 | if (bp->port.pmf) | 7666 | if (bp->port.pmf) |
@@ -7616,6 +7701,11 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) | |||
7616 | /* start the timer */ | 7701 | /* start the timer */ |
7617 | mod_timer(&bp->timer, jiffies + bp->current_interval); | 7702 | mod_timer(&bp->timer, jiffies + bp->current_interval); |
7618 | 7703 | ||
7704 | #ifdef BCM_CNIC | ||
7705 | bnx2x_setup_cnic_irq_info(bp); | ||
7706 | if (bp->state == BNX2X_STATE_OPEN) | ||
7707 | bnx2x_cnic_notify(bp, CNIC_CTL_START_CMD); | ||
7708 | #endif | ||
7619 | 7709 | ||
7620 | return 0; | 7710 | return 0; |
7621 | 7711 | ||
@@ -7810,6 +7900,9 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) | |||
7810 | u32 reset_code = 0; | 7900 | u32 reset_code = 0; |
7811 | int i, cnt, rc; | 7901 | int i, cnt, rc; |
7812 | 7902 | ||
7903 | #ifdef BCM_CNIC | ||
7904 | bnx2x_cnic_notify(bp, CNIC_CTL_STOP_CMD); | ||
7905 | #endif | ||
7813 | bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT; | 7906 | bp->state = BNX2X_STATE_CLOSING_WAIT4_HALT; |
7814 | 7907 | ||
7815 | /* Set "drop all" */ | 7908 | /* Set "drop all" */ |
@@ -7886,6 +7979,15 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) | |||
7886 | 7979 | ||
7887 | REG_WR(bp, MISC_REG_E1HMF_MODE, 0); | 7980 | REG_WR(bp, MISC_REG_E1HMF_MODE, 0); |
7888 | } | 7981 | } |
7982 | #ifdef BCM_CNIC | ||
7983 | /* Clear iSCSI L2 MAC */ | ||
7984 | mutex_lock(&bp->cnic_mutex); | ||
7985 | if (bp->cnic_flags & BNX2X_CNIC_FLAG_MAC_SET) { | ||
7986 | bnx2x_set_iscsi_eth_mac_addr(bp, 0); | ||
7987 | bp->cnic_flags &= ~BNX2X_CNIC_FLAG_MAC_SET; | ||
7988 | } | ||
7989 | mutex_unlock(&bp->cnic_mutex); | ||
7990 | #endif | ||
7889 | 7991 | ||
7890 | if (unload_mode == UNLOAD_NORMAL) | 7992 | if (unload_mode == UNLOAD_NORMAL) |
7891 | reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; | 7993 | reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS; |
@@ -8855,6 +8957,9 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) | |||
8855 | smp_wmb(); /* Ensure that bp->intr_sem update is SMP-safe */ | 8957 | smp_wmb(); /* Ensure that bp->intr_sem update is SMP-safe */ |
8856 | 8958 | ||
8857 | mutex_init(&bp->port.phy_mutex); | 8959 | mutex_init(&bp->port.phy_mutex); |
8960 | #ifdef BCM_CNIC | ||
8961 | mutex_init(&bp->cnic_mutex); | ||
8962 | #endif | ||
8858 | 8963 | ||
8859 | INIT_DELAYED_WORK(&bp->sp_task, bnx2x_sp_task); | 8964 | INIT_DELAYED_WORK(&bp->sp_task, bnx2x_sp_task); |
8860 | INIT_WORK(&bp->reset_task, bnx2x_reset_task); | 8965 | INIT_WORK(&bp->reset_task, bnx2x_reset_task); |
@@ -12448,4 +12553,287 @@ static void __exit bnx2x_cleanup(void) | |||
12448 | module_init(bnx2x_init); | 12553 | module_init(bnx2x_init); |
12449 | module_exit(bnx2x_cleanup); | 12554 | module_exit(bnx2x_cleanup); |
12450 | 12555 | ||
12556 | #ifdef BCM_CNIC | ||
12557 | |||
12558 | /* count denotes the number of new completions we have seen */ | ||
12559 | static void bnx2x_cnic_sp_post(struct bnx2x *bp, int count) | ||
12560 | { | ||
12561 | struct eth_spe *spe; | ||
12562 | |||
12563 | #ifdef BNX2X_STOP_ON_ERROR | ||
12564 | if (unlikely(bp->panic)) | ||
12565 | return; | ||
12566 | #endif | ||
12567 | |||
12568 | spin_lock_bh(&bp->spq_lock); | ||
12569 | bp->cnic_spq_pending -= count; | ||
12570 | |||
12571 | for (; bp->cnic_spq_pending < bp->cnic_eth_dev.max_kwqe_pending; | ||
12572 | bp->cnic_spq_pending++) { | ||
12573 | |||
12574 | if (!bp->cnic_kwq_pending) | ||
12575 | break; | ||
12576 | |||
12577 | spe = bnx2x_sp_get_next(bp); | ||
12578 | *spe = *bp->cnic_kwq_cons; | ||
12579 | |||
12580 | bp->cnic_kwq_pending--; | ||
12581 | |||
12582 | DP(NETIF_MSG_TIMER, "pending on SPQ %d, on KWQ %d count %d\n", | ||
12583 | bp->cnic_spq_pending, bp->cnic_kwq_pending, count); | ||
12584 | |||
12585 | if (bp->cnic_kwq_cons == bp->cnic_kwq_last) | ||
12586 | bp->cnic_kwq_cons = bp->cnic_kwq; | ||
12587 | else | ||
12588 | bp->cnic_kwq_cons++; | ||
12589 | } | ||
12590 | bnx2x_sp_prod_update(bp); | ||
12591 | spin_unlock_bh(&bp->spq_lock); | ||
12592 | } | ||
12593 | |||
12594 | static int bnx2x_cnic_sp_queue(struct net_device *dev, | ||
12595 | struct kwqe_16 *kwqes[], u32 count) | ||
12596 | { | ||
12597 | struct bnx2x *bp = netdev_priv(dev); | ||
12598 | int i; | ||
12599 | |||
12600 | #ifdef BNX2X_STOP_ON_ERROR | ||
12601 | if (unlikely(bp->panic)) | ||
12602 | return -EIO; | ||
12603 | #endif | ||
12604 | |||
12605 | spin_lock_bh(&bp->spq_lock); | ||
12606 | |||
12607 | for (i = 0; i < count; i++) { | ||
12608 | struct eth_spe *spe = (struct eth_spe *)kwqes[i]; | ||
12609 | |||
12610 | if (bp->cnic_kwq_pending == MAX_SP_DESC_CNT) | ||
12611 | break; | ||
12612 | |||
12613 | *bp->cnic_kwq_prod = *spe; | ||
12614 | |||
12615 | bp->cnic_kwq_pending++; | ||
12616 | |||
12617 | DP(NETIF_MSG_TIMER, "L5 SPQE %x %x %x:%x pos %d\n", | ||
12618 | spe->hdr.conn_and_cmd_data, spe->hdr.type, | ||
12619 | spe->data.mac_config_addr.hi, | ||
12620 | spe->data.mac_config_addr.lo, | ||
12621 | bp->cnic_kwq_pending); | ||
12622 | |||
12623 | if (bp->cnic_kwq_prod == bp->cnic_kwq_last) | ||
12624 | bp->cnic_kwq_prod = bp->cnic_kwq; | ||
12625 | else | ||
12626 | bp->cnic_kwq_prod++; | ||
12627 | } | ||
12628 | |||
12629 | spin_unlock_bh(&bp->spq_lock); | ||
12630 | |||
12631 | if (bp->cnic_spq_pending < bp->cnic_eth_dev.max_kwqe_pending) | ||
12632 | bnx2x_cnic_sp_post(bp, 0); | ||
12633 | |||
12634 | return i; | ||
12635 | } | ||
12636 | |||
12637 | static int bnx2x_cnic_ctl_send(struct bnx2x *bp, struct cnic_ctl_info *ctl) | ||
12638 | { | ||
12639 | struct cnic_ops *c_ops; | ||
12640 | int rc = 0; | ||
12641 | |||
12642 | mutex_lock(&bp->cnic_mutex); | ||
12643 | c_ops = bp->cnic_ops; | ||
12644 | if (c_ops) | ||
12645 | rc = c_ops->cnic_ctl(bp->cnic_data, ctl); | ||
12646 | mutex_unlock(&bp->cnic_mutex); | ||
12647 | |||
12648 | return rc; | ||
12649 | } | ||
12650 | |||
12651 | static int bnx2x_cnic_ctl_send_bh(struct bnx2x *bp, struct cnic_ctl_info *ctl) | ||
12652 | { | ||
12653 | struct cnic_ops *c_ops; | ||
12654 | int rc = 0; | ||
12655 | |||
12656 | rcu_read_lock(); | ||
12657 | c_ops = rcu_dereference(bp->cnic_ops); | ||
12658 | if (c_ops) | ||
12659 | rc = c_ops->cnic_ctl(bp->cnic_data, ctl); | ||
12660 | rcu_read_unlock(); | ||
12661 | |||
12662 | return rc; | ||
12663 | } | ||
12664 | |||
12665 | /* | ||
12666 | * for commands that have no data | ||
12667 | */ | ||
12668 | static int bnx2x_cnic_notify(struct bnx2x *bp, int cmd) | ||
12669 | { | ||
12670 | struct cnic_ctl_info ctl = {0}; | ||
12671 | |||
12672 | ctl.cmd = cmd; | ||
12673 | |||
12674 | return bnx2x_cnic_ctl_send(bp, &ctl); | ||
12675 | } | ||
12676 | |||
12677 | static void bnx2x_cnic_cfc_comp(struct bnx2x *bp, int cid) | ||
12678 | { | ||
12679 | struct cnic_ctl_info ctl; | ||
12680 | |||
12681 | /* first we tell CNIC and only then we count this as a completion */ | ||
12682 | ctl.cmd = CNIC_CTL_COMPLETION_CMD; | ||
12683 | ctl.data.comp.cid = cid; | ||
12684 | |||
12685 | bnx2x_cnic_ctl_send_bh(bp, &ctl); | ||
12686 | bnx2x_cnic_sp_post(bp, 1); | ||
12687 | } | ||
12688 | |||
12689 | static int bnx2x_drv_ctl(struct net_device *dev, struct drv_ctl_info *ctl) | ||
12690 | { | ||
12691 | struct bnx2x *bp = netdev_priv(dev); | ||
12692 | int rc = 0; | ||
12693 | |||
12694 | switch (ctl->cmd) { | ||
12695 | case DRV_CTL_CTXTBL_WR_CMD: { | ||
12696 | u32 index = ctl->data.io.offset; | ||
12697 | dma_addr_t addr = ctl->data.io.dma_addr; | ||
12698 | |||
12699 | bnx2x_ilt_wr(bp, index, addr); | ||
12700 | break; | ||
12701 | } | ||
12702 | |||
12703 | case DRV_CTL_COMPLETION_CMD: { | ||
12704 | int count = ctl->data.comp.comp_count; | ||
12705 | |||
12706 | bnx2x_cnic_sp_post(bp, count); | ||
12707 | break; | ||
12708 | } | ||
12709 | |||
12710 | /* rtnl_lock is held. */ | ||
12711 | case DRV_CTL_START_L2_CMD: { | ||
12712 | u32 cli = ctl->data.ring.client_id; | ||
12713 | |||
12714 | bp->rx_mode_cl_mask |= (1 << cli); | ||
12715 | bnx2x_set_storm_rx_mode(bp); | ||
12716 | break; | ||
12717 | } | ||
12718 | |||
12719 | /* rtnl_lock is held. */ | ||
12720 | case DRV_CTL_STOP_L2_CMD: { | ||
12721 | u32 cli = ctl->data.ring.client_id; | ||
12722 | |||
12723 | bp->rx_mode_cl_mask &= ~(1 << cli); | ||
12724 | bnx2x_set_storm_rx_mode(bp); | ||
12725 | break; | ||
12726 | } | ||
12727 | |||
12728 | default: | ||
12729 | BNX2X_ERR("unknown command %x\n", ctl->cmd); | ||
12730 | rc = -EINVAL; | ||
12731 | } | ||
12732 | |||
12733 | return rc; | ||
12734 | } | ||
12735 | |||
12736 | static void bnx2x_setup_cnic_irq_info(struct bnx2x *bp) | ||
12737 | { | ||
12738 | struct cnic_eth_dev *cp = &bp->cnic_eth_dev; | ||
12739 | |||
12740 | if (bp->flags & USING_MSIX_FLAG) { | ||
12741 | cp->drv_state |= CNIC_DRV_STATE_USING_MSIX; | ||
12742 | cp->irq_arr[0].irq_flags |= CNIC_IRQ_FL_MSIX; | ||
12743 | cp->irq_arr[0].vector = bp->msix_table[1].vector; | ||
12744 | } else { | ||
12745 | cp->drv_state &= ~CNIC_DRV_STATE_USING_MSIX; | ||
12746 | cp->irq_arr[0].irq_flags &= ~CNIC_IRQ_FL_MSIX; | ||
12747 | } | ||
12748 | cp->irq_arr[0].status_blk = bp->cnic_sb; | ||
12749 | cp->irq_arr[0].status_blk_num = CNIC_SB_ID(bp); | ||
12750 | cp->irq_arr[1].status_blk = bp->def_status_blk; | ||
12751 | cp->irq_arr[1].status_blk_num = DEF_SB_ID; | ||
12752 | |||
12753 | cp->num_irq = 2; | ||
12754 | } | ||
12755 | |||
12756 | static int bnx2x_register_cnic(struct net_device *dev, struct cnic_ops *ops, | ||
12757 | void *data) | ||
12758 | { | ||
12759 | struct bnx2x *bp = netdev_priv(dev); | ||
12760 | struct cnic_eth_dev *cp = &bp->cnic_eth_dev; | ||
12761 | |||
12762 | if (ops == NULL) | ||
12763 | return -EINVAL; | ||
12764 | |||
12765 | if (atomic_read(&bp->intr_sem) != 0) | ||
12766 | return -EBUSY; | ||
12767 | |||
12768 | bp->cnic_kwq = kzalloc(PAGE_SIZE, GFP_KERNEL); | ||
12769 | if (!bp->cnic_kwq) | ||
12770 | return -ENOMEM; | ||
12771 | |||
12772 | bp->cnic_kwq_cons = bp->cnic_kwq; | ||
12773 | bp->cnic_kwq_prod = bp->cnic_kwq; | ||
12774 | bp->cnic_kwq_last = bp->cnic_kwq + MAX_SP_DESC_CNT; | ||
12775 | |||
12776 | bp->cnic_spq_pending = 0; | ||
12777 | bp->cnic_kwq_pending = 0; | ||
12778 | |||
12779 | bp->cnic_data = data; | ||
12780 | |||
12781 | cp->num_irq = 0; | ||
12782 | cp->drv_state = CNIC_DRV_STATE_REGD; | ||
12783 | |||
12784 | bnx2x_init_sb(bp, bp->cnic_sb, bp->cnic_sb_mapping, CNIC_SB_ID(bp)); | ||
12785 | |||
12786 | bnx2x_setup_cnic_irq_info(bp); | ||
12787 | bnx2x_set_iscsi_eth_mac_addr(bp, 1); | ||
12788 | bp->cnic_flags |= BNX2X_CNIC_FLAG_MAC_SET; | ||
12789 | rcu_assign_pointer(bp->cnic_ops, ops); | ||
12790 | |||
12791 | return 0; | ||
12792 | } | ||
12793 | |||
12794 | static int bnx2x_unregister_cnic(struct net_device *dev) | ||
12795 | { | ||
12796 | struct bnx2x *bp = netdev_priv(dev); | ||
12797 | struct cnic_eth_dev *cp = &bp->cnic_eth_dev; | ||
12798 | |||
12799 | mutex_lock(&bp->cnic_mutex); | ||
12800 | if (bp->cnic_flags & BNX2X_CNIC_FLAG_MAC_SET) { | ||
12801 | bp->cnic_flags &= ~BNX2X_CNIC_FLAG_MAC_SET; | ||
12802 | bnx2x_set_iscsi_eth_mac_addr(bp, 0); | ||
12803 | } | ||
12804 | cp->drv_state = 0; | ||
12805 | rcu_assign_pointer(bp->cnic_ops, NULL); | ||
12806 | mutex_unlock(&bp->cnic_mutex); | ||
12807 | synchronize_rcu(); | ||
12808 | kfree(bp->cnic_kwq); | ||
12809 | bp->cnic_kwq = NULL; | ||
12810 | |||
12811 | return 0; | ||
12812 | } | ||
12813 | |||
12814 | struct cnic_eth_dev *bnx2x_cnic_probe(struct net_device *dev) | ||
12815 | { | ||
12816 | struct bnx2x *bp = netdev_priv(dev); | ||
12817 | struct cnic_eth_dev *cp = &bp->cnic_eth_dev; | ||
12818 | |||
12819 | cp->drv_owner = THIS_MODULE; | ||
12820 | cp->chip_id = CHIP_ID(bp); | ||
12821 | cp->pdev = bp->pdev; | ||
12822 | cp->io_base = bp->regview; | ||
12823 | cp->io_base2 = bp->doorbells; | ||
12824 | cp->max_kwqe_pending = 8; | ||
12825 | cp->ctx_blk_size = CNIC_CTX_PER_ILT * sizeof(union cdu_context); | ||
12826 | cp->ctx_tbl_offset = FUNC_ILT_BASE(BP_FUNC(bp)) + 1; | ||
12827 | cp->ctx_tbl_len = CNIC_ILT_LINES; | ||
12828 | cp->starting_cid = BCM_CNIC_CID_START; | ||
12829 | cp->drv_submit_kwqes_16 = bnx2x_cnic_sp_queue; | ||
12830 | cp->drv_ctl = bnx2x_drv_ctl; | ||
12831 | cp->drv_register_cnic = bnx2x_register_cnic; | ||
12832 | cp->drv_unregister_cnic = bnx2x_unregister_cnic; | ||
12833 | |||
12834 | return cp; | ||
12835 | } | ||
12836 | EXPORT_SYMBOL(bnx2x_cnic_probe); | ||
12837 | |||
12838 | #endif /* BCM_CNIC */ | ||
12451 | 12839 | ||