aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAriel Elior <ariele@broadcom.com>2013-03-11 01:17:45 -0400
committerDavid S. Miller <davem@davemloft.net>2013-03-12 07:54:23 -0400
commit3ec9f9ca79757c54b12f87e51a6664ba1e597b17 (patch)
tree5ab793d7fa40f08845adc48c1d7e846a10093813
parent3786b9426d943ef167575be2ba20dab3d858243e (diff)
bnx2x: Add iproute2 support for vfs
This patch adds support for iproute2 callbacks allowing querying a physical function as to its child virtual functions, and setting the macs and vlans of said virtual functions. Signed-off-by: Ariel Elior <ariele@broadcom.com> Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com> Signed-off-by: Eilon Greenstein <eilong@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x.h1
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h3
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c38
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c24
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h6
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c239
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h3
-rw-r--r--drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h9
8 files changed, 277 insertions, 46 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index 8ddc78bada49..d62d037b2928 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -1214,6 +1214,7 @@ enum {
1214 BNX2X_SP_RTNL_ENABLE_SRIOV, 1214 BNX2X_SP_RTNL_ENABLE_SRIOV,
1215 BNX2X_SP_RTNL_VFPF_MCAST, 1215 BNX2X_SP_RTNL_VFPF_MCAST,
1216 BNX2X_SP_RTNL_VFPF_STORM_RX_MODE, 1216 BNX2X_SP_RTNL_VFPF_STORM_RX_MODE,
1217 BNX2X_SP_RTNL_HYPERVISOR_VLAN,
1217}; 1218};
1218 1219
1219 1220
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
index 8d158d8240a2..4620fa5666e5 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h
@@ -496,7 +496,10 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev);
496/* setup_tc callback */ 496/* setup_tc callback */
497int bnx2x_setup_tc(struct net_device *dev, u8 num_tc); 497int bnx2x_setup_tc(struct net_device *dev, u8 num_tc);
498 498
499int bnx2x_get_vf_config(struct net_device *dev, int vf,
500 struct ifla_vf_info *ivi);
499int bnx2x_set_vf_mac(struct net_device *dev, int queue, u8 *mac); 501int bnx2x_set_vf_mac(struct net_device *dev, int queue, u8 *mac);
502int bnx2x_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos);
500 503
501/* select_queue callback */ 504/* select_queue callback */
502u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb); 505u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb);
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
index 423b5a074c80..9be9b0373ca9 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
@@ -75,8 +75,6 @@
75#define FW_FILE_NAME_E1H "bnx2x/bnx2x-e1h-" FW_FILE_VERSION ".fw" 75#define FW_FILE_NAME_E1H "bnx2x/bnx2x-e1h-" FW_FILE_VERSION ".fw"
76#define FW_FILE_NAME_E2 "bnx2x/bnx2x-e2-" FW_FILE_VERSION ".fw" 76#define FW_FILE_NAME_E2 "bnx2x/bnx2x-e2-" FW_FILE_VERSION ".fw"
77 77
78#define MAC_LEADING_ZERO_CNT (ALIGN(ETH_ALEN, sizeof(u32)) - ETH_ALEN)
79
80/* Time in jiffies before concluding the transmitter is hung */ 78/* Time in jiffies before concluding the transmitter is hung */
81#define TX_TIMEOUT (5*HZ) 79#define TX_TIMEOUT (5*HZ)
82 80
@@ -3227,16 +3225,29 @@ static void bnx2x_drv_info_ether_stat(struct bnx2x *bp)
3227{ 3225{
3228 struct eth_stats_info *ether_stat = 3226 struct eth_stats_info *ether_stat =
3229 &bp->slowpath->drv_info_to_mcp.ether_stat; 3227 &bp->slowpath->drv_info_to_mcp.ether_stat;
3228 struct bnx2x_vlan_mac_obj *mac_obj =
3229 &bp->sp_objs->mac_obj;
3230 int i;
3230 3231
3231 strlcpy(ether_stat->version, DRV_MODULE_VERSION, 3232 strlcpy(ether_stat->version, DRV_MODULE_VERSION,
3232 ETH_STAT_INFO_VERSION_LEN); 3233 ETH_STAT_INFO_VERSION_LEN);
3233 3234
3234 bp->sp_objs[0].mac_obj.get_n_elements(bp, &bp->sp_objs[0].mac_obj, 3235 /* get DRV_INFO_ETH_STAT_NUM_MACS_REQUIRED macs, placing them in the
3235 DRV_INFO_ETH_STAT_NUM_MACS_REQUIRED, 3236 * mac_local field in ether_stat struct. The base address is offset by 2
3236 ether_stat->mac_local); 3237 * bytes to account for the field being 8 bytes but a mac address is
3237 3238 * only 6 bytes. Likewise, the stride for the get_n_elements function is
3239 * 2 bytes to compensate from the 6 bytes of a mac to the 8 bytes
3240 * allocated by the ether_stat struct, so the macs will land in their
3241 * proper positions.
3242 */
3243 for (i = 0; i < DRV_INFO_ETH_STAT_NUM_MACS_REQUIRED; i++)
3244 memset(ether_stat->mac_local + i, 0,
3245 sizeof(ether_stat->mac_local[0]));
3246 mac_obj->get_n_elements(bp, &bp->sp_objs[0].mac_obj,
3247 DRV_INFO_ETH_STAT_NUM_MACS_REQUIRED,
3248 ether_stat->mac_local + MAC_PAD, MAC_PAD,
3249 ETH_ALEN);
3238 ether_stat->mtu_size = bp->dev->mtu; 3250 ether_stat->mtu_size = bp->dev->mtu;
3239
3240 if (bp->dev->features & NETIF_F_RXCSUM) 3251 if (bp->dev->features & NETIF_F_RXCSUM)
3241 ether_stat->feature_flags |= FEATURE_ETH_CHKSUM_OFFLOAD_MASK; 3252 ether_stat->feature_flags |= FEATURE_ETH_CHKSUM_OFFLOAD_MASK;
3242 if (bp->dev->features & NETIF_F_TSO) 3253 if (bp->dev->features & NETIF_F_TSO)
@@ -3258,8 +3269,7 @@ static void bnx2x_drv_info_fcoe_stat(struct bnx2x *bp)
3258 if (!CNIC_LOADED(bp)) 3269 if (!CNIC_LOADED(bp))
3259 return; 3270 return;
3260 3271
3261 memcpy(fcoe_stat->mac_local + MAC_LEADING_ZERO_CNT, 3272 memcpy(fcoe_stat->mac_local + MAC_PAD, bp->fip_mac, ETH_ALEN);
3262 bp->fip_mac, ETH_ALEN);
3263 3273
3264 fcoe_stat->qos_priority = 3274 fcoe_stat->qos_priority =
3265 app->traffic_type_priority[LLFC_TRAFFIC_TYPE_FCOE]; 3275 app->traffic_type_priority[LLFC_TRAFFIC_TYPE_FCOE];
@@ -3361,8 +3371,8 @@ static void bnx2x_drv_info_iscsi_stat(struct bnx2x *bp)
3361 if (!CNIC_LOADED(bp)) 3371 if (!CNIC_LOADED(bp))
3362 return; 3372 return;
3363 3373
3364 memcpy(iscsi_stat->mac_local + MAC_LEADING_ZERO_CNT, 3374 memcpy(iscsi_stat->mac_local + MAC_PAD, bp->cnic_eth_dev.iscsi_mac,
3365 bp->cnic_eth_dev.iscsi_mac, ETH_ALEN); 3375 ETH_ALEN);
3366 3376
3367 iscsi_stat->qos_priority = 3377 iscsi_stat->qos_priority =
3368 app->traffic_type_priority[LLFC_TRAFFIC_TYPE_ISCSI]; 3378 app->traffic_type_priority[LLFC_TRAFFIC_TYPE_ISCSI];
@@ -9525,6 +9535,10 @@ sp_rtnl_not_reset:
9525 bnx2x_vfpf_storm_rx_mode(bp); 9535 bnx2x_vfpf_storm_rx_mode(bp);
9526 } 9536 }
9527 9537
9538 if (test_and_clear_bit(BNX2X_SP_RTNL_HYPERVISOR_VLAN,
9539 &bp->sp_rtnl_state))
9540 bnx2x_pf_set_vfs_vlan(bp);
9541
9528 /* work which needs rtnl lock not-taken (as it takes the lock itself and 9542 /* work which needs rtnl lock not-taken (as it takes the lock itself and
9529 * can be called from other contexts as well) 9543 * can be called from other contexts as well)
9530 */ 9544 */
@@ -11798,6 +11812,8 @@ static const struct net_device_ops bnx2x_netdev_ops = {
11798 .ndo_setup_tc = bnx2x_setup_tc, 11812 .ndo_setup_tc = bnx2x_setup_tc,
11799#ifdef CONFIG_BNX2X_SRIOV 11813#ifdef CONFIG_BNX2X_SRIOV
11800 .ndo_set_vf_mac = bnx2x_set_vf_mac, 11814 .ndo_set_vf_mac = bnx2x_set_vf_mac,
11815 .ndo_set_vf_vlan = bnx2x_set_vf_vlan,
11816 .ndo_get_vf_config = bnx2x_get_vf_config,
11801#endif 11817#endif
11802#ifdef NETDEV_FCOE_WWNN 11818#ifdef NETDEV_FCOE_WWNN
11803 .ndo_fcoe_get_wwn = bnx2x_fcoe_get_wwn, 11819 .ndo_fcoe_get_wwn = bnx2x_fcoe_get_wwn,
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
index 9f2637c295c8..6b03acd5d9ad 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c
@@ -30,8 +30,6 @@
30 30
31#define BNX2X_MAX_EMUL_MULTI 16 31#define BNX2X_MAX_EMUL_MULTI 16
32 32
33#define MAC_LEADING_ZERO_CNT (ALIGN(ETH_ALEN, sizeof(u32)) - ETH_ALEN)
34
35/**** Exe Queue interfaces ****/ 33/**** Exe Queue interfaces ****/
36 34
37/** 35/**
@@ -444,30 +442,21 @@ static bool bnx2x_put_credit_vlan_mac(struct bnx2x_vlan_mac_obj *o)
444} 442}
445 443
446static int bnx2x_get_n_elements(struct bnx2x *bp, struct bnx2x_vlan_mac_obj *o, 444static int bnx2x_get_n_elements(struct bnx2x *bp, struct bnx2x_vlan_mac_obj *o,
447 int n, u8 *buf) 445 int n, u8 *base, u8 stride, u8 size)
448{ 446{
449 struct bnx2x_vlan_mac_registry_elem *pos; 447 struct bnx2x_vlan_mac_registry_elem *pos;
450 u8 *next = buf; 448 u8 *next = base;
451 int counter = 0; 449 int counter = 0;
452 450
453 /* traverse list */ 451 /* traverse list */
454 list_for_each_entry(pos, &o->head, link) { 452 list_for_each_entry(pos, &o->head, link) {
455 if (counter < n) { 453 if (counter < n) {
456 /* place leading zeroes in buffer */ 454 memcpy(next, &pos->u, size);
457 memset(next, 0, MAC_LEADING_ZERO_CNT);
458
459 /* place mac after leading zeroes*/
460 memcpy(next + MAC_LEADING_ZERO_CNT, pos->u.mac.mac,
461 ETH_ALEN);
462
463 /* calculate address of next element and
464 * advance counter
465 */
466 counter++; 455 counter++;
467 next = buf + counter * ALIGN(ETH_ALEN, sizeof(u32)); 456 DP(BNX2X_MSG_SP, "copied element number %d to address %p element was:\n",
457 counter, next);
458 next += stride + size;
468 459
469 DP(BNX2X_MSG_SP, "copied element number %d to address %p element was %pM\n",
470 counter, next, pos->u.mac.mac);
471 } 460 }
472 } 461 }
473 return counter * ETH_ALEN; 462 return counter * ETH_ALEN;
@@ -2013,6 +2002,7 @@ void bnx2x_init_vlan_obj(struct bnx2x *bp,
2013 vlan_obj->check_move = bnx2x_check_move; 2002 vlan_obj->check_move = bnx2x_check_move;
2014 vlan_obj->ramrod_cmd = 2003 vlan_obj->ramrod_cmd =
2015 RAMROD_CMD_ID_ETH_CLASSIFICATION_RULES; 2004 RAMROD_CMD_ID_ETH_CLASSIFICATION_RULES;
2005 vlan_obj->get_n_elements = bnx2x_get_n_elements;
2016 2006
2017 /* Exe Queue */ 2007 /* Exe Queue */
2018 bnx2x_exe_queue_init(bp, 2008 bnx2x_exe_queue_init(bp,
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
index ff907609b9fc..ac57e63a08ed 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h
@@ -313,8 +313,9 @@ struct bnx2x_vlan_mac_obj {
313 * 313 *
314 * @return number of copied bytes 314 * @return number of copied bytes
315 */ 315 */
316 int (*get_n_elements)(struct bnx2x *bp, struct bnx2x_vlan_mac_obj *o, 316 int (*get_n_elements)(struct bnx2x *bp,
317 int n, u8 *buf); 317 struct bnx2x_vlan_mac_obj *o, int n, u8 *base,
318 u8 stride, u8 size);
318 319
319 /** 320 /**
320 * Checks if ADD-ramrod with the given params may be performed. 321 * Checks if ADD-ramrod with the given params may be performed.
@@ -842,6 +843,7 @@ enum bnx2x_q_type {
842#define BNX2X_MULTI_TX_COS_E3B0 3 843#define BNX2X_MULTI_TX_COS_E3B0 3
843#define BNX2X_MULTI_TX_COS 3 /* Maximum possible */ 844#define BNX2X_MULTI_TX_COS 3 /* Maximum possible */
844 845
846#define MAC_PAD (ALIGN(ETH_ALEN, sizeof(u32)) - ETH_ALEN)
845 847
846struct bnx2x_queue_init_params { 848struct bnx2x_queue_init_params {
847 struct { 849 struct {
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
index 6adfa2093581..7b234e41fea8 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c
@@ -20,7 +20,9 @@
20#include "bnx2x.h" 20#include "bnx2x.h"
21#include "bnx2x_init.h" 21#include "bnx2x_init.h"
22#include "bnx2x_cmn.h" 22#include "bnx2x_cmn.h"
23#include "bnx2x_sp.h"
23#include <linux/crc32.h> 24#include <linux/crc32.h>
25#include <linux/if_vlan.h>
24 26
25/* General service functions */ 27/* General service functions */
26static void storm_memset_vf_to_pf(struct bnx2x *bp, u16 abs_fid, 28static void storm_memset_vf_to_pf(struct bnx2x *bp, u16 abs_fid,
@@ -958,6 +960,12 @@ op_err:
958 BNX2X_ERR("QSETUP[%d:%d] error: rc %d\n", vf->abs_vfid, qid, vfop->rc); 960 BNX2X_ERR("QSETUP[%d:%d] error: rc %d\n", vf->abs_vfid, qid, vfop->rc);
959op_done: 961op_done:
960 case BNX2X_VFOP_QSETUP_DONE: 962 case BNX2X_VFOP_QSETUP_DONE:
963 vf->cfg_flags |= VF_CFG_VLAN;
964 smp_mb__before_clear_bit();
965 set_bit(BNX2X_SP_RTNL_HYPERVISOR_VLAN,
966 &bp->sp_rtnl_state);
967 smp_mb__after_clear_bit();
968 schedule_delayed_work(&bp->sp_rtnl_task, 0);
961 bnx2x_vfop_end(bp, vf, vfop); 969 bnx2x_vfop_end(bp, vf, vfop);
962 return; 970 return;
963 default: 971 default:
@@ -3029,6 +3037,88 @@ void bnx2x_enable_sriov(struct bnx2x *bp)
3029 DP(BNX2X_MSG_IOV, "sriov enabled\n"); 3037 DP(BNX2X_MSG_IOV, "sriov enabled\n");
3030} 3038}
3031 3039
3040void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp)
3041{
3042 int vfidx;
3043 struct pf_vf_bulletin_content *bulletin;
3044
3045 DP(BNX2X_MSG_IOV, "configuring vlan for VFs from sp-task\n");
3046 for_each_vf(bp, vfidx) {
3047 bulletin = BP_VF_BULLETIN(bp, vfidx);
3048 if (BP_VF(bp, vfidx)->cfg_flags & VF_CFG_VLAN)
3049 bnx2x_set_vf_vlan(bp->dev, vfidx, bulletin->vlan, 0);
3050 }
3051}
3052
3053static int bnx2x_vf_ndo_sanity(struct bnx2x *bp, int vfidx,
3054 struct bnx2x_virtf *vf)
3055{
3056 if (!IS_SRIOV(bp)) {
3057 BNX2X_ERR("vf ndo called though sriov is disabled\n");
3058 return -EINVAL;
3059 }
3060
3061 if (vfidx >= BNX2X_NR_VIRTFN(bp)) {
3062 BNX2X_ERR("vf ndo called for uninitialized VF. vfidx was %d BNX2X_NR_VIRTFN was %d\n",
3063 vfidx, BNX2X_NR_VIRTFN(bp));
3064 return -EINVAL;
3065 }
3066
3067 if (!vf) {
3068 BNX2X_ERR("vf ndo called but vf was null. vfidx was %d\n",
3069 vfidx);
3070 return -EINVAL;
3071 }
3072
3073 return 0;
3074}
3075
3076int bnx2x_get_vf_config(struct net_device *dev, int vfidx,
3077 struct ifla_vf_info *ivi)
3078{
3079 struct bnx2x *bp = netdev_priv(dev);
3080 struct bnx2x_virtf *vf = BP_VF(bp, vfidx);
3081 struct bnx2x_vlan_mac_obj *mac_obj = &bnx2x_vfq(vf, 0, mac_obj);
3082 struct bnx2x_vlan_mac_obj *vlan_obj = &bnx2x_vfq(vf, 0, vlan_obj);
3083 struct pf_vf_bulletin_content *bulletin = BP_VF_BULLETIN(bp, vfidx);
3084 int rc;
3085
3086 /* sanity */
3087 rc = bnx2x_vf_ndo_sanity(bp, vfidx, vf);
3088 if (rc)
3089 return rc;
3090
3091 ivi->vf = vfidx;
3092 ivi->qos = 0;
3093 ivi->tx_rate = 10000; /* always 10G. TBA take from link struct */
3094 ivi->spoofchk = 1; /*always enabled */
3095 if (vf->state == VF_ENABLED) {
3096 /* mac and vlan are in vlan_mac objects */
3097 mac_obj->get_n_elements(bp, mac_obj, 1, (u8 *)&ivi->mac,
3098 0, ETH_ALEN);
3099 vlan_obj->get_n_elements(bp, vlan_obj, 1, (u8 *)&ivi->vlan,
3100 0, VLAN_HLEN);
3101 } else {
3102 /* mac */
3103 if (bulletin->valid_bitmap & (1 << MAC_ADDR_VALID))
3104 /* mac configured by ndo so its in bulletin board */
3105 memcpy(&ivi->mac, bulletin->mac, ETH_ALEN);
3106 else
3107 /* funtion has not been loaded yet. Show mac as 0s */
3108 memset(&ivi->mac, 0, ETH_ALEN);
3109
3110 /* vlan */
3111 if (bulletin->valid_bitmap & (1 << VLAN_VALID))
3112 /* vlan configured by ndo so its in bulletin board */
3113 memcpy(&ivi->vlan, &bulletin->vlan, VLAN_HLEN);
3114 else
3115 /* funtion has not been loaded yet. Show vlans as 0s */
3116 memset(&ivi->vlan, 0, VLAN_HLEN);
3117 }
3118
3119 return 0;
3120}
3121
3032/* New mac for VF. Consider these cases: 3122/* New mac for VF. Consider these cases:
3033 * 1. VF hasn't been acquired yet - save the mac in local bulletin board and 3123 * 1. VF hasn't been acquired yet - save the mac in local bulletin board and
3034 * supply at acquire. 3124 * supply at acquire.
@@ -3044,23 +3134,19 @@ void bnx2x_enable_sriov(struct bnx2x *bp)
3044 * VF to configure any mac for itself except for this mac. In case of a race 3134 * VF to configure any mac for itself except for this mac. In case of a race
3045 * where the VF fails to see the new post on its bulletin board before sending a 3135 * where the VF fails to see the new post on its bulletin board before sending a
3046 * mac configuration request, the PF will simply fail the request and VF can try 3136 * mac configuration request, the PF will simply fail the request and VF can try
3047 * again after consulting its bulletin board 3137 * again after consulting its bulletin board.
3048 */ 3138 */
3049int bnx2x_set_vf_mac(struct net_device *dev, int queue, u8 *mac) 3139int bnx2x_set_vf_mac(struct net_device *dev, int vfidx, u8 *mac)
3050{ 3140{
3051 struct bnx2x *bp = netdev_priv(dev); 3141 struct bnx2x *bp = netdev_priv(dev);
3052 int rc, q_logical_state, vfidx = queue; 3142 int rc, q_logical_state;
3053 struct bnx2x_virtf *vf = BP_VF(bp, vfidx); 3143 struct bnx2x_virtf *vf = BP_VF(bp, vfidx);
3054 struct pf_vf_bulletin_content *bulletin = BP_VF_BULLETIN(bp, vfidx); 3144 struct pf_vf_bulletin_content *bulletin = BP_VF_BULLETIN(bp, vfidx);
3055 3145
3056 /* if SRIOV is disabled there is nothing to do (and somewhere, someone 3146 /* sanity */
3057 * has erred). 3147 rc = bnx2x_vf_ndo_sanity(bp, vfidx, vf);
3058 */ 3148 if (rc)
3059 if (!IS_SRIOV(bp)) { 3149 return rc;
3060 BNX2X_ERR("bnx2x_set_vf_mac called though sriov is disabled\n");
3061 return -EINVAL;
3062 }
3063
3064 if (!is_valid_ether_addr(mac)) { 3150 if (!is_valid_ether_addr(mac)) {
3065 BNX2X_ERR("mac address invalid\n"); 3151 BNX2X_ERR("mac address invalid\n");
3066 return -EINVAL; 3152 return -EINVAL;
@@ -3085,7 +3171,7 @@ int bnx2x_set_vf_mac(struct net_device *dev, int queue, u8 *mac)
3085 if (vf->state == VF_ENABLED && 3171 if (vf->state == VF_ENABLED &&
3086 q_logical_state == BNX2X_Q_LOGICAL_STATE_ACTIVE) { 3172 q_logical_state == BNX2X_Q_LOGICAL_STATE_ACTIVE) {
3087 /* configure the mac in device on this vf's queue */ 3173 /* configure the mac in device on this vf's queue */
3088 unsigned long flags = 0; 3174 unsigned long ramrod_flags = 0;
3089 struct bnx2x_vlan_mac_obj *mac_obj = &bnx2x_vfq(vf, 0, mac_obj); 3175 struct bnx2x_vlan_mac_obj *mac_obj = &bnx2x_vfq(vf, 0, mac_obj);
3090 3176
3091 /* must lock vfpf channel to protect against vf flows */ 3177 /* must lock vfpf channel to protect against vf flows */
@@ -3106,14 +3192,133 @@ int bnx2x_set_vf_mac(struct net_device *dev, int queue, u8 *mac)
3106 } 3192 }
3107 3193
3108 /* configure the new mac to device */ 3194 /* configure the new mac to device */
3109 __set_bit(RAMROD_COMP_WAIT, &flags); 3195 __set_bit(RAMROD_COMP_WAIT, &ramrod_flags);
3110 bnx2x_set_mac_one(bp, (u8 *)&bulletin->mac, mac_obj, true, 3196 bnx2x_set_mac_one(bp, (u8 *)&bulletin->mac, mac_obj, true,
3111 BNX2X_ETH_MAC, &flags); 3197 BNX2X_ETH_MAC, &ramrod_flags);
3112 3198
3113 bnx2x_unlock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_SET_MAC); 3199 bnx2x_unlock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_SET_MAC);
3114 } 3200 }
3115 3201
3116 return rc; 3202 return 0;
3203}
3204
3205int bnx2x_set_vf_vlan(struct net_device *dev, int vfidx, u16 vlan, u8 qos)
3206{
3207 struct bnx2x *bp = netdev_priv(dev);
3208 int rc, q_logical_state;
3209 struct bnx2x_virtf *vf = BP_VF(bp, vfidx);
3210 struct pf_vf_bulletin_content *bulletin = BP_VF_BULLETIN(bp, vfidx);
3211
3212 /* sanity */
3213 rc = bnx2x_vf_ndo_sanity(bp, vfidx, vf);
3214 if (rc)
3215 return rc;
3216
3217 if (vlan > 4095) {
3218 BNX2X_ERR("illegal vlan value %d\n", vlan);
3219 return -EINVAL;
3220 }
3221
3222 DP(BNX2X_MSG_IOV, "configuring VF %d with VLAN %d qos %d\n",
3223 vfidx, vlan, 0);
3224
3225 /* update PF's copy of the VF's bulletin. No point in posting the vlan
3226 * to the VF since it doesn't have anything to do with it. But it useful
3227 * to store it here in case the VF is not up yet and we can only
3228 * configure the vlan later when it does.
3229 */
3230 bulletin->valid_bitmap |= 1 << VLAN_VALID;
3231 bulletin->vlan = vlan;
3232
3233 /* is vf initialized and queue set up? */
3234 q_logical_state =
3235 bnx2x_get_q_logical_state(bp, &bnx2x_vfq(vf, 0, sp_obj));
3236 if (vf->state == VF_ENABLED &&
3237 q_logical_state == BNX2X_Q_LOGICAL_STATE_ACTIVE) {
3238 /* configure the vlan in device on this vf's queue */
3239 unsigned long ramrod_flags = 0;
3240 unsigned long vlan_mac_flags = 0;
3241 struct bnx2x_vlan_mac_obj *vlan_obj =
3242 &bnx2x_vfq(vf, 0, vlan_obj);
3243 struct bnx2x_vlan_mac_ramrod_params ramrod_param;
3244 struct bnx2x_queue_state_params q_params = {NULL};
3245 struct bnx2x_queue_update_params *update_params;
3246
3247 memset(&ramrod_param, 0, sizeof(ramrod_param));
3248
3249 /* must lock vfpf channel to protect against vf flows */
3250 bnx2x_lock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_SET_VLAN);
3251
3252 /* remove existing vlans */
3253 __set_bit(RAMROD_COMP_WAIT, &ramrod_flags);
3254 rc = vlan_obj->delete_all(bp, vlan_obj, &vlan_mac_flags,
3255 &ramrod_flags);
3256 if (rc) {
3257 BNX2X_ERR("failed to delete vlans\n");
3258 return -EINVAL;
3259 }
3260
3261 /* send queue update ramrod to configure default vlan and silent
3262 * vlan removal
3263 */
3264 __set_bit(RAMROD_COMP_WAIT, &q_params.ramrod_flags);
3265 q_params.cmd = BNX2X_Q_CMD_UPDATE;
3266 q_params.q_obj = &bnx2x_vfq(vf, 0, sp_obj);
3267 update_params = &q_params.params.update;
3268 __set_bit(BNX2X_Q_UPDATE_DEF_VLAN_EN_CHNG,
3269 &update_params->update_flags);
3270 __set_bit(BNX2X_Q_UPDATE_SILENT_VLAN_REM_CHNG,
3271 &update_params->update_flags);
3272
3273 if (vlan == 0) {
3274 /* if vlan is 0 then we want to leave the VF traffic
3275 * untagged, and leave the incoming traffic untouched
3276 * (i.e. do not remove any vlan tags).
3277 */
3278 __clear_bit(BNX2X_Q_UPDATE_DEF_VLAN_EN,
3279 &update_params->update_flags);
3280 __clear_bit(BNX2X_Q_UPDATE_SILENT_VLAN_REM,
3281 &update_params->update_flags);
3282 } else {
3283 /* configure the new vlan to device */
3284 __set_bit(RAMROD_COMP_WAIT, &ramrod_flags);
3285 ramrod_param.vlan_mac_obj = vlan_obj;
3286 ramrod_param.ramrod_flags = ramrod_flags;
3287 ramrod_param.user_req.u.vlan.vlan = vlan;
3288 ramrod_param.user_req.cmd = BNX2X_VLAN_MAC_ADD;
3289 rc = bnx2x_config_vlan_mac(bp, &ramrod_param);
3290 if (rc) {
3291 BNX2X_ERR("failed to configure vlan\n");
3292 return -EINVAL;
3293 }
3294
3295 /* configure default vlan to vf queue and set silent
3296 * vlan removal (the vf remains unaware of this vlan).
3297 */
3298 update_params = &q_params.params.update;
3299 __set_bit(BNX2X_Q_UPDATE_DEF_VLAN_EN,
3300 &update_params->update_flags);
3301 __set_bit(BNX2X_Q_UPDATE_SILENT_VLAN_REM,
3302 &update_params->update_flags);
3303 update_params->def_vlan = vlan;
3304 }
3305
3306 /* Update the Queue state */
3307 rc = bnx2x_queue_state_change(bp, &q_params);
3308 if (rc) {
3309 BNX2X_ERR("Failed to configure default VLAN\n");
3310 return rc;
3311 }
3312
3313 /* clear the flag indicating that this VF needs its vlan
3314 * (will only be set if the HV configured th Vlan before vf was
3315 * and we were called because the VF came up later
3316 */
3317 vf->cfg_flags &= ~VF_CFG_VLAN;
3318
3319 bnx2x_unlock_vf_pf_channel(bp, vf, CHANNEL_TLV_PF_SET_VLAN);
3320 }
3321 return 0;
3117} 3322}
3118 3323
3119/* crc is the first field in the bulletin board. compute the crc over the 3324/* crc is the first field in the bulletin board. compute the crc over the
@@ -3165,6 +3370,10 @@ enum sample_bulletin_result bnx2x_sample_bulletin(struct bnx2x *bp)
3165 memcpy(bp->dev->dev_addr, bulletin.mac, ETH_ALEN); 3370 memcpy(bp->dev->dev_addr, bulletin.mac, ETH_ALEN);
3166 } 3371 }
3167 3372
3373 /* the vlan in bulletin board is valid and is new */
3374 if (bulletin.valid_bitmap & 1 << VLAN_VALID)
3375 memcpy(&bulletin.vlan, &bp->old_bulletin.vlan, VLAN_HLEN);
3376
3168 /* copy new bulletin board to bp */ 3377 /* copy new bulletin board to bp */
3169 bp->old_bulletin = bulletin; 3378 bp->old_bulletin = bulletin;
3170 3379
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
index b4050173add9..33d49516fcea 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h
@@ -193,6 +193,7 @@ struct bnx2x_virtf {
193#define VF_CFG_TPA 0x0004 193#define VF_CFG_TPA 0x0004
194#define VF_CFG_INT_SIMD 0x0008 194#define VF_CFG_INT_SIMD 0x0008
195#define VF_CACHE_LINE 0x0010 195#define VF_CACHE_LINE 0x0010
196#define VF_CFG_VLAN 0x0020
196 197
197 u8 state; 198 u8 state;
198#define VF_FREE 0 /* VF ready to be acquired holds no resc */ 199#define VF_FREE 0 /* VF ready to be acquired holds no resc */
@@ -757,6 +758,7 @@ static inline int bnx2x_vf_headroom(struct bnx2x *bp)
757{ 758{
758 return bp->vfdb->sriov.nr_virtfn * BNX2X_CLIENTS_PER_VF; 759 return bp->vfdb->sriov.nr_virtfn * BNX2X_CLIENTS_PER_VF;
759} 760}
761void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp);
760 762
761#else /* CONFIG_BNX2X_SRIOV */ 763#else /* CONFIG_BNX2X_SRIOV */
762 764
@@ -804,6 +806,7 @@ static inline enum sample_bulletin_result bnx2x_sample_bulletin(struct bnx2x *bp
804 806
805static inline int bnx2x_vf_map_doorbells(struct bnx2x *bp) {return 0; } 807static inline int bnx2x_vf_map_doorbells(struct bnx2x *bp) {return 0; }
806static inline int bnx2x_vf_pci_alloc(struct bnx2x *bp) {return 0; } 808static inline int bnx2x_vf_pci_alloc(struct bnx2x *bp) {return 0; }
809static inline void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp) {}
807 810
808#endif /* CONFIG_BNX2X_SRIOV */ 811#endif /* CONFIG_BNX2X_SRIOV */
809#endif /* bnx2x_sriov.h */ 812#endif /* bnx2x_sriov.h */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h
index bfc80baec00d..41708faab575 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h
@@ -328,9 +328,15 @@ struct pf_vf_bulletin_content {
328#define MAC_ADDR_VALID 0 /* alert the vf that a new mac address 328#define MAC_ADDR_VALID 0 /* alert the vf that a new mac address
329 * is available for it 329 * is available for it
330 */ 330 */
331#define VLAN_VALID 1 /* when set, the vf should not access
332 * the vfpf channel
333 */
331 334
332 u8 mac[ETH_ALEN]; 335 u8 mac[ETH_ALEN];
333 u8 padding[2]; 336 u8 mac_padding[2];
337
338 u16 vlan;
339 u8 vlan_padding[6];
334}; 340};
335 341
336union pf_vf_bulletin { 342union pf_vf_bulletin {
@@ -353,6 +359,7 @@ enum channel_tlvs {
353 CHANNEL_TLV_LIST_END, 359 CHANNEL_TLV_LIST_END,
354 CHANNEL_TLV_FLR, 360 CHANNEL_TLV_FLR,
355 CHANNEL_TLV_PF_SET_MAC, 361 CHANNEL_TLV_PF_SET_MAC,
362 CHANNEL_TLV_PF_SET_VLAN,
356 CHANNEL_TLV_MAX 363 CHANNEL_TLV_MAX
357}; 364};
358 365