aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x_main.c
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2009-10-10 09:46:56 -0400
committerDavid S. Miller <davem@davemloft.net>2009-10-12 02:30:14 -0400
commit993ac7b5183f82edc9696cd17faae03523e00e09 (patch)
treeb57561971c47a3529d646389dc58b9ec890543d4 /drivers/net/bnx2x_main.c
parent37b091bacba7bd329eced9a56998b6247da414c4 (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.c388
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
973static void bnx2x_cnic_cfc_comp(struct bnx2x *bp, int cid);
974#endif
972 975
973static void bnx2x_sp_event(struct bnx2x_fastpath *fp, 976static 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 */
7339static 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
7294static int bnx2x_setup_leading(struct bnx2x *bp) 7366static 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
7492static int bnx2x_cnic_notify(struct bnx2x *bp, int cmd);
7493static 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 */
7421static int bnx2x_nic_load(struct bnx2x *bp, int load_mode) 7497static 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)
12448module_init(bnx2x_init); 12553module_init(bnx2x_init);
12449module_exit(bnx2x_cleanup); 12554module_exit(bnx2x_cleanup);
12450 12555
12556#ifdef BCM_CNIC
12557
12558/* count denotes the number of new completions we have seen */
12559static 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
12594static 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
12637static 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
12651static 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 */
12668static 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
12677static 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
12689static 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
12736static 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
12756static 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
12794static 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
12814struct 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}
12836EXPORT_SYMBOL(bnx2x_cnic_probe);
12837
12838#endif /* BCM_CNIC */
12451 12839