aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAriel Elior <ariele@broadcom.com>2013-01-01 00:22:29 -0500
committerDavid S. Miller <davem@davemloft.net>2013-01-02 04:45:05 -0500
commit381ac16b10ae9369ebbbd74bb52b970818f68022 (patch)
treeae14a3c059359493aaf25df0f7ec345546208ad3 /drivers/net
parent9b176b6b63ed07472c26b6833a0ac23b373e6bf8 (diff)
bnx2x: Support ndo_set_rxmode in VF driver
The VF driver uses the 'q_filter' request in the VF <-> PF channel to have the PF configure the requested rxmode to device. ndo_set_rxmode is called under bottom half lock, so sleeping until the response arrives over the VF <-> PF channel is out of the question. For this reason the VF driver returns from the ndo after scheduling a work item, which in turn processes the rx mode request and adds the classification information through the VF <-> PF channel accordingly. Signed-off-by: Ariel Elior <ariele@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x.h5
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c173
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h7
3 files changed, 179 insertions, 6 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 82c6233bcace..2fe1908e94d7 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -1191,6 +1191,8 @@ enum {
1191 BNX2X_SP_RTNL_TX_TIMEOUT, 1191 BNX2X_SP_RTNL_TX_TIMEOUT,
1192 BNX2X_SP_RTNL_AFEX_F_UPDATE, 1192 BNX2X_SP_RTNL_AFEX_F_UPDATE,
1193 BNX2X_SP_RTNL_FAN_FAILURE, 1193 BNX2X_SP_RTNL_FAN_FAILURE,
1194 BNX2X_SP_RTNL_VFPF_MCAST,
1195 BNX2X_SP_RTNL_VFPF_STORM_RX_MODE,
1194}; 1196};
1195 1197
1196 1198
@@ -2229,6 +2231,9 @@ void bnx2x_vfpf_close_vf(struct bnx2x *bp);
2229int bnx2x_vfpf_setup_q(struct bnx2x *bp, int fp_idx); 2231int bnx2x_vfpf_setup_q(struct bnx2x *bp, int fp_idx);
2230int bnx2x_vfpf_teardown_queue(struct bnx2x *bp, int qidx); 2232int bnx2x_vfpf_teardown_queue(struct bnx2x *bp, int qidx);
2231int bnx2x_vfpf_set_mac(struct bnx2x *bp); 2233int bnx2x_vfpf_set_mac(struct bnx2x *bp);
2234int bnx2x_vfpf_set_mcast(struct net_device *dev);
2235int bnx2x_vfpf_storm_rx_mode(struct bnx2x *bp);
2236
2232int bnx2x_nic_load_analyze_req(struct bnx2x *bp, u32 load_code); 2237int bnx2x_nic_load_analyze_req(struct bnx2x *bp, u32 load_code);
2233/* Congestion management fairness mode */ 2238/* Congestion management fairness mode */
2234#define CMNG_FNS_NONE 0 2239#define CMNG_FNS_NONE 0
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 2bf7dcca397d..d27820542c3e 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -9403,6 +9403,19 @@ sp_rtnl_not_reset:
9403 bnx2x_close(bp->dev); 9403 bnx2x_close(bp->dev);
9404 } 9404 }
9405 9405
9406 if (test_and_clear_bit(BNX2X_SP_RTNL_VFPF_MCAST, &bp->sp_rtnl_state)) {
9407 DP(BNX2X_MSG_SP,
9408 "sending set mcast vf pf channel message from rtnl sp-task\n");
9409 bnx2x_vfpf_set_mcast(bp->dev);
9410 }
9411
9412 if (test_and_clear_bit(BNX2X_SP_RTNL_VFPF_STORM_RX_MODE,
9413 &bp->sp_rtnl_state)) {
9414 DP(BNX2X_MSG_SP,
9415 "sending set storm rx mode vf pf channel message from rtnl sp-task\n");
9416 bnx2x_vfpf_storm_rx_mode(bp);
9417 }
9418
9406sp_rtnl_exit: 9419sp_rtnl_exit:
9407 rtnl_unlock(); 9420 rtnl_unlock();
9408} 9421}
@@ -11479,12 +11492,25 @@ void bnx2x_set_rx_mode(struct net_device *dev)
11479 CHIP_IS_E1(bp))) 11492 CHIP_IS_E1(bp)))
11480 rx_mode = BNX2X_RX_MODE_ALLMULTI; 11493 rx_mode = BNX2X_RX_MODE_ALLMULTI;
11481 else { 11494 else {
11482 /* some multicasts */ 11495 if (IS_PF(bp)) {
11483 if (bnx2x_set_mc_list(bp) < 0) 11496 /* some multicasts */
11484 rx_mode = BNX2X_RX_MODE_ALLMULTI; 11497 if (bnx2x_set_mc_list(bp) < 0)
11498 rx_mode = BNX2X_RX_MODE_ALLMULTI;
11485 11499
11486 if (bnx2x_set_uc_list(bp) < 0) 11500 if (bnx2x_set_uc_list(bp) < 0)
11487 rx_mode = BNX2X_RX_MODE_PROMISC; 11501 rx_mode = BNX2X_RX_MODE_PROMISC;
11502 } else {
11503 /* configuring mcast to a vf involves sleeping (when we
11504 * wait for the pf's response). Since this function is
11505 * called from non sleepable context we must schedule
11506 * a work item for this purpose
11507 */
11508 smp_mb__before_clear_bit();
11509 set_bit(BNX2X_SP_RTNL_VFPF_MCAST,
11510 &bp->sp_rtnl_state);
11511 smp_mb__after_clear_bit();
11512 schedule_delayed_work(&bp->sp_rtnl_task, 0);
11513 }
11488 } 11514 }
11489 11515
11490 bp->rx_mode = rx_mode; 11516 bp->rx_mode = rx_mode;
@@ -11498,7 +11524,20 @@ void bnx2x_set_rx_mode(struct net_device *dev)
11498 return; 11524 return;
11499 } 11525 }
11500 11526
11501 bnx2x_set_storm_rx_mode(bp); 11527 if (IS_PF(bp)) {
11528 bnx2x_set_storm_rx_mode(bp);
11529 } else {
11530 /* configuring rx mode to storms in a vf involves sleeping (when
11531 * we wait for the pf's response). Since this function is
11532 * called from non sleepable context we must schedule
11533 * a work item for this purpose
11534 */
11535 smp_mb__before_clear_bit();
11536 set_bit(BNX2X_SP_RTNL_VFPF_STORM_RX_MODE,
11537 &bp->sp_rtnl_state);
11538 smp_mb__after_clear_bit();
11539 schedule_delayed_work(&bp->sp_rtnl_task, 0);
11540 }
11502} 11541}
11503 11542
11504/* called with rtnl_lock */ 11543/* called with rtnl_lock */
@@ -13676,3 +13715,125 @@ int bnx2x_vfpf_set_mac(struct bnx2x *bp)
13676 13715
13677 return 0; 13716 return 0;
13678} 13717}
13718
13719int bnx2x_vfpf_set_mcast(struct net_device *dev)
13720{
13721 struct bnx2x *bp = netdev_priv(dev);
13722 struct vfpf_set_q_filters_tlv *req = &bp->vf2pf_mbox->req.set_q_filters;
13723 struct pfvf_general_resp_tlv *resp = &bp->vf2pf_mbox->resp.general_resp;
13724 int rc, i = 0;
13725 struct netdev_hw_addr *ha;
13726
13727 if (bp->state != BNX2X_STATE_OPEN) {
13728 DP(NETIF_MSG_IFUP, "state is %x, returning\n", bp->state);
13729 return -EINVAL;
13730 }
13731
13732 /* clear mailbox and prep first tlv */
13733 bnx2x_vfpf_prep(bp, &req->first_tlv, CHANNEL_TLV_SET_Q_FILTERS,
13734 sizeof(*req));
13735
13736 /* Get Rx mode requested */
13737 DP(NETIF_MSG_IFUP, "dev->flags = %x\n", dev->flags);
13738
13739 netdev_for_each_mc_addr(ha, dev) {
13740 DP(NETIF_MSG_IFUP, "Adding mcast MAC: %pM\n",
13741 bnx2x_mc_addr(ha));
13742 memcpy(req->multicast[i], bnx2x_mc_addr(ha), ETH_ALEN);
13743 i++;
13744 }
13745
13746 /* We support four PFVF_MAX_MULTICAST_PER_VF mcast
13747 * addresses tops
13748 */
13749 if (i >= PFVF_MAX_MULTICAST_PER_VF) {
13750 DP(NETIF_MSG_IFUP,
13751 "VF supports not more than %d multicast MAC addresses\n",
13752 PFVF_MAX_MULTICAST_PER_VF);
13753 return -EINVAL;
13754 }
13755
13756 req->n_multicast = i;
13757 req->flags |= VFPF_SET_Q_FILTERS_MULTICAST_CHANGED;
13758 req->vf_qid = 0;
13759
13760 /* add list termination tlv */
13761 bnx2x_add_tlv(bp, req, req->first_tlv.tl.length, CHANNEL_TLV_LIST_END,
13762 sizeof(struct channel_list_end_tlv));
13763
13764 /* output tlvs list */
13765 bnx2x_dp_tlv_list(bp, req);
13766
13767 rc = bnx2x_send_msg2pf(bp, &resp->hdr.status, bp->vf2pf_mbox_mapping);
13768 if (rc) {
13769 BNX2X_ERR("Sending a message failed: %d\n", rc);
13770 return rc;
13771 }
13772
13773 if (resp->hdr.status != PFVF_STATUS_SUCCESS) {
13774 BNX2X_ERR("Set Rx mode/multicast failed: %d\n",
13775 resp->hdr.status);
13776 return -EINVAL;
13777 }
13778
13779 return 0;
13780}
13781
13782int bnx2x_vfpf_storm_rx_mode(struct bnx2x *bp)
13783{
13784 int mode = bp->rx_mode;
13785 struct vfpf_set_q_filters_tlv *req = &bp->vf2pf_mbox->req.set_q_filters;
13786 struct pfvf_general_resp_tlv *resp = &bp->vf2pf_mbox->resp.general_resp;
13787 int rc;
13788
13789 /* clear mailbox and prep first tlv */
13790 bnx2x_vfpf_prep(bp, &req->first_tlv, CHANNEL_TLV_SET_Q_FILTERS,
13791 sizeof(*req));
13792
13793 DP(NETIF_MSG_IFUP, "Rx mode is %d\n", mode);
13794
13795 switch (mode) {
13796 case BNX2X_RX_MODE_NONE: /* no Rx */
13797 req->rx_mask = VFPF_RX_MASK_ACCEPT_NONE;
13798 break;
13799 case BNX2X_RX_MODE_NORMAL:
13800 req->rx_mask = VFPF_RX_MASK_ACCEPT_MATCHED_MULTICAST;
13801 req->rx_mask |= VFPF_RX_MASK_ACCEPT_MATCHED_UNICAST;
13802 req->rx_mask |= VFPF_RX_MASK_ACCEPT_BROADCAST;
13803 break;
13804 case BNX2X_RX_MODE_ALLMULTI:
13805 req->rx_mask = VFPF_RX_MASK_ACCEPT_ALL_MULTICAST;
13806 req->rx_mask |= VFPF_RX_MASK_ACCEPT_MATCHED_UNICAST;
13807 req->rx_mask |= VFPF_RX_MASK_ACCEPT_BROADCAST;
13808 break;
13809 case BNX2X_RX_MODE_PROMISC:
13810 req->rx_mask = VFPF_RX_MASK_ACCEPT_ALL_UNICAST;
13811 req->rx_mask |= VFPF_RX_MASK_ACCEPT_ALL_MULTICAST;
13812 req->rx_mask |= VFPF_RX_MASK_ACCEPT_BROADCAST;
13813 break;
13814 default:
13815 BNX2X_ERR("BAD rx mode (%d)\n", mode);
13816 return -EINVAL;
13817 }
13818
13819 req->flags |= VFPF_SET_Q_FILTERS_RX_MASK_CHANGED;
13820 req->vf_qid = 0;
13821
13822 /* add list termination tlv */
13823 bnx2x_add_tlv(bp, req, req->first_tlv.tl.length, CHANNEL_TLV_LIST_END,
13824 sizeof(struct channel_list_end_tlv));
13825
13826 /* output tlvs list */
13827 bnx2x_dp_tlv_list(bp, req);
13828
13829 rc = bnx2x_send_msg2pf(bp, &resp->hdr.status, bp->vf2pf_mbox_mapping);
13830 if (rc)
13831 BNX2X_ERR("Sending a message failed: %d\n", rc);
13832
13833 if (resp->hdr.status != PFVF_STATUS_SUCCESS) {
13834 BNX2X_ERR("Set Rx mode failed: %d\n", resp->hdr.status);
13835 return -EINVAL;
13836 }
13837
13838 return rc;
13839}
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h
index ed4a61815175..bf11e084c215 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h
@@ -54,6 +54,13 @@ struct hw_sb_info {
54#define VFPF_QUEUE_DROP_TTL0 (1 << 2) 54#define VFPF_QUEUE_DROP_TTL0 (1 << 2)
55#define VFPF_QUEUE_DROP_UDP_CS_ERR (1 << 3) 55#define VFPF_QUEUE_DROP_UDP_CS_ERR (1 << 3)
56 56
57#define VFPF_RX_MASK_ACCEPT_NONE 0x00000000
58#define VFPF_RX_MASK_ACCEPT_MATCHED_UNICAST 0x00000001
59#define VFPF_RX_MASK_ACCEPT_MATCHED_MULTICAST 0x00000002
60#define VFPF_RX_MASK_ACCEPT_ALL_UNICAST 0x00000004
61#define VFPF_RX_MASK_ACCEPT_ALL_MULTICAST 0x00000008
62#define VFPF_RX_MASK_ACCEPT_BROADCAST 0x00000010
63
57enum { 64enum {
58 PFVF_STATUS_WAITING = 0, 65 PFVF_STATUS_WAITING = 0,
59 PFVF_STATUS_SUCCESS, 66 PFVF_STATUS_SUCCESS,