aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorGreg Rose <gregory.v.rose@intel.com>2011-05-12 21:33:48 -0400
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-05-14 20:53:09 -0400
commita1cbb15c13971bd5d41626e9e5ced9f9de132c47 (patch)
treed00386651afb90fc4e776f923fa454383cdfa46d /drivers/net
parent46ec20ff7d6f9f011e06d58e4e87153ed8c893ed (diff)
ixgbe: Add macvlan support for VF
Add infrastructure in the PF driver to support macvlan in the VF driver. Signed-off-by: Greg Rose <gregory.v.rose@intel.com> Tested-by: Sibai Li <sibai.li@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ixgbe/ixgbe.h13
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c28
-rw-r--r--drivers/net/ixgbe/ixgbe_mbx.h1
-rw-r--r--drivers/net/ixgbe/ixgbe_sriov.c96
4 files changed, 134 insertions, 4 deletions
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index 37ff531d59c0..91c15403c6bb 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -106,6 +106,7 @@
106#define IXGBE_MAX_VF_FUNCTIONS 64 106#define IXGBE_MAX_VF_FUNCTIONS 64
107#define IXGBE_MAX_VFTA_ENTRIES 128 107#define IXGBE_MAX_VFTA_ENTRIES 128
108#define MAX_EMULATION_MAC_ADDRS 16 108#define MAX_EMULATION_MAC_ADDRS 16
109#define IXGBE_MAX_PF_MACVLANS 15
109#define VMDQ_P(p) ((p) + adapter->num_vfs) 110#define VMDQ_P(p) ((p) + adapter->num_vfs)
110 111
111struct vf_data_storage { 112struct vf_data_storage {
@@ -121,6 +122,15 @@ struct vf_data_storage {
121 u16 tx_rate; 122 u16 tx_rate;
122}; 123};
123 124
125struct vf_macvlans {
126 struct list_head l;
127 int vf;
128 int rar_entry;
129 bool free;
130 bool is_macvlan;
131 u8 vf_macvlan[ETH_ALEN];
132};
133
124/* wrapper around a pointer to a socket buffer, 134/* wrapper around a pointer to a socket buffer,
125 * so a DMA handle can be stored along with the buffer */ 135 * so a DMA handle can be stored along with the buffer */
126struct ixgbe_tx_buffer { 136struct ixgbe_tx_buffer {
@@ -471,6 +481,9 @@ struct ixgbe_adapter {
471 unsigned int num_vfs; 481 unsigned int num_vfs;
472 struct vf_data_storage *vfinfo; 482 struct vf_data_storage *vfinfo;
473 int vf_rate_link_speed; 483 int vf_rate_link_speed;
484 struct vf_macvlans vf_mvs;
485 struct vf_macvlans *mv_list;
486 bool antispoofing_enabled;
474}; 487};
475 488
476enum ixbge_state_t { 489enum ixbge_state_t {
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index a3e384bc50fe..f8196e0d2745 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -3188,7 +3188,9 @@ static void ixgbe_configure_virtualization(struct ixgbe_adapter *adapter)
3188 /* enable Tx loopback for VF/PF communication */ 3188 /* enable Tx loopback for VF/PF communication */
3189 IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN); 3189 IXGBE_WRITE_REG(hw, IXGBE_PFDTXGSWC, IXGBE_PFDTXGSWC_VT_LBEN);
3190 /* Enable MAC Anti-Spoofing */ 3190 /* Enable MAC Anti-Spoofing */
3191 hw->mac.ops.set_mac_anti_spoofing(hw, (adapter->num_vfs != 0), 3191 hw->mac.ops.set_mac_anti_spoofing(hw,
3192 (adapter->antispoofing_enabled =
3193 (adapter->num_vfs != 0)),
3192 adapter->num_vfs); 3194 adapter->num_vfs);
3193} 3195}
3194 3196
@@ -3497,7 +3499,7 @@ static int ixgbe_write_uc_addr_list(struct net_device *netdev)
3497 struct ixgbe_adapter *adapter = netdev_priv(netdev); 3499 struct ixgbe_adapter *adapter = netdev_priv(netdev);
3498 struct ixgbe_hw *hw = &adapter->hw; 3500 struct ixgbe_hw *hw = &adapter->hw;
3499 unsigned int vfn = adapter->num_vfs; 3501 unsigned int vfn = adapter->num_vfs;
3500 unsigned int rar_entries = hw->mac.num_rar_entries - (vfn + 1); 3502 unsigned int rar_entries = IXGBE_MAX_PF_MACVLANS;
3501 int count = 0; 3503 int count = 0;
3502 3504
3503 /* return ENOMEM indicating insufficient memory for addresses */ 3505 /* return ENOMEM indicating insufficient memory for addresses */
@@ -7107,6 +7109,8 @@ static void __devinit ixgbe_probe_vf(struct ixgbe_adapter *adapter,
7107#ifdef CONFIG_PCI_IOV 7109#ifdef CONFIG_PCI_IOV
7108 struct ixgbe_hw *hw = &adapter->hw; 7110 struct ixgbe_hw *hw = &adapter->hw;
7109 int err; 7111 int err;
7112 int num_vf_macvlans, i;
7113 struct vf_macvlans *mv_list;
7110 7114
7111 if (hw->mac.type == ixgbe_mac_82598EB || !max_vfs) 7115 if (hw->mac.type == ixgbe_mac_82598EB || !max_vfs)
7112 return; 7116 return;
@@ -7123,6 +7127,26 @@ static void __devinit ixgbe_probe_vf(struct ixgbe_adapter *adapter,
7123 e_err(probe, "Failed to enable PCI sriov: %d\n", err); 7127 e_err(probe, "Failed to enable PCI sriov: %d\n", err);
7124 goto err_novfs; 7128 goto err_novfs;
7125 } 7129 }
7130
7131 num_vf_macvlans = hw->mac.num_rar_entries -
7132 (IXGBE_MAX_PF_MACVLANS + 1 + adapter->num_vfs);
7133
7134 adapter->mv_list = mv_list = kcalloc(num_vf_macvlans,
7135 sizeof(struct vf_macvlans),
7136 GFP_KERNEL);
7137 if (mv_list) {
7138 /* Initialize list of VF macvlans */
7139 INIT_LIST_HEAD(&adapter->vf_mvs.l);
7140 for (i = 0; i < num_vf_macvlans; i++) {
7141 mv_list->vf = -1;
7142 mv_list->free = true;
7143 mv_list->rar_entry = hw->mac.num_rar_entries -
7144 (i + adapter->num_vfs + 1);
7145 list_add(&mv_list->l, &adapter->vf_mvs.l);
7146 mv_list++;
7147 }
7148 }
7149
7126 /* If call to enable VFs succeeded then allocate memory 7150 /* If call to enable VFs succeeded then allocate memory
7127 * for per VF control structures. 7151 * for per VF control structures.
7128 */ 7152 */
diff --git a/drivers/net/ixgbe/ixgbe_mbx.h b/drivers/net/ixgbe/ixgbe_mbx.h
index f53dc5bb28b7..b239bdac38da 100644
--- a/drivers/net/ixgbe/ixgbe_mbx.h
+++ b/drivers/net/ixgbe/ixgbe_mbx.h
@@ -67,6 +67,7 @@
67#define IXGBE_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */ 67#define IXGBE_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */
68#define IXGBE_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */ 68#define IXGBE_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */
69#define IXGBE_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE */ 69#define IXGBE_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE */
70#define IXGBE_VF_SET_MACVLAN 0x06 /* VF requests PF for unicast filter */
70 71
71/* length of permanent address message returned from PF */ 72/* length of permanent address message returned from PF */
72#define IXGBE_VF_PERMADDR_MSG_LEN 4 73#define IXGBE_VF_PERMADDR_MSG_LEN 4
diff --git a/drivers/net/ixgbe/ixgbe_sriov.c b/drivers/net/ixgbe/ixgbe_sriov.c
index 47650278d414..9f972460e780 100644
--- a/drivers/net/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ixgbe/ixgbe_sriov.c
@@ -82,6 +82,21 @@ static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,
82 return 0; 82 return 0;
83} 83}
84 84
85static void ixgbe_restore_vf_macvlans(struct ixgbe_adapter *adapter)
86{
87 struct ixgbe_hw *hw = &adapter->hw;
88 struct list_head *pos;
89 struct vf_macvlans *entry;
90
91 list_for_each(pos, &adapter->vf_mvs.l) {
92 entry = list_entry(pos, struct vf_macvlans, l);
93 if (entry->free == false)
94 hw->mac.ops.set_rar(hw, entry->rar_entry,
95 entry->vf_macvlan,
96 entry->vf, IXGBE_RAH_AV);
97 }
98}
99
85void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter) 100void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
86{ 101{
87 struct ixgbe_hw *hw = &adapter->hw; 102 struct ixgbe_hw *hw = &adapter->hw;
@@ -102,6 +117,9 @@ void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
102 IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg); 117 IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg);
103 } 118 }
104 } 119 }
120
121 /* Restore any VF macvlans */
122 ixgbe_restore_vf_macvlans(adapter);
105} 123}
106 124
107static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid, 125static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid,
@@ -200,6 +218,61 @@ static int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter,
200 return 0; 218 return 0;
201} 219}
202 220
221static int ixgbe_set_vf_macvlan(struct ixgbe_adapter *adapter,
222 int vf, int index, unsigned char *mac_addr)
223{
224 struct ixgbe_hw *hw = &adapter->hw;
225 struct list_head *pos;
226 struct vf_macvlans *entry;
227
228 if (index <= 1) {
229 list_for_each(pos, &adapter->vf_mvs.l) {
230 entry = list_entry(pos, struct vf_macvlans, l);
231 if (entry->vf == vf) {
232 entry->vf = -1;
233 entry->free = true;
234 entry->is_macvlan = false;
235 hw->mac.ops.clear_rar(hw, entry->rar_entry);
236 }
237 }
238 }
239
240 /*
241 * If index was zero then we were asked to clear the uc list
242 * for the VF. We're done.
243 */
244 if (!index)
245 return 0;
246
247 entry = NULL;
248
249 list_for_each(pos, &adapter->vf_mvs.l) {
250 entry = list_entry(pos, struct vf_macvlans, l);
251 if (entry->free)
252 break;
253 }
254
255 /*
256 * If we traversed the entire list and didn't find a free entry
257 * then we're out of space on the RAR table. Also entry may
258 * be NULL because the original memory allocation for the list
259 * failed, which is not fatal but does mean we can't support
260 * VF requests for MACVLAN because we couldn't allocate
261 * memory for the list management required.
262 */
263 if (!entry || !entry->free)
264 return -ENOSPC;
265
266 entry->free = false;
267 entry->is_macvlan = true;
268 entry->vf = vf;
269 memcpy(entry->vf_macvlan, mac_addr, ETH_ALEN);
270
271 hw->mac.ops.set_rar(hw, entry->rar_entry, mac_addr, vf, IXGBE_RAH_AV);
272
273 return 0;
274}
275
203int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask) 276int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask)
204{ 277{
205 unsigned char vf_mac_addr[6]; 278 unsigned char vf_mac_addr[6];
@@ -256,7 +329,7 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
256 s32 retval; 329 s32 retval;
257 int entries; 330 int entries;
258 u16 *hash_list; 331 u16 *hash_list;
259 int add, vid; 332 int add, vid, index;
260 u8 *new_mac; 333 u8 *new_mac;
261 334
262 retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf); 335 retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf);
@@ -345,6 +418,24 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf)
345 retval = ixgbe_set_vf_vlan(adapter, add, vid, vf); 418 retval = ixgbe_set_vf_vlan(adapter, add, vid, vf);
346 } 419 }
347 break; 420 break;
421 case IXGBE_VF_SET_MACVLAN:
422 index = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) >>
423 IXGBE_VT_MSGINFO_SHIFT;
424 /*
425 * If the VF is allowed to set MAC filters then turn off
426 * anti-spoofing to avoid false positives. An index
427 * greater than 0 will indicate the VF is setting a
428 * macvlan MAC filter.
429 */
430 if (index > 0 && adapter->antispoofing_enabled) {
431 hw->mac.ops.set_mac_anti_spoofing(hw, false,
432 adapter->num_vfs);
433 hw->mac.ops.set_vlan_anti_spoofing(hw, false, vf);
434 adapter->antispoofing_enabled = false;
435 }
436 retval = ixgbe_set_vf_macvlan(adapter, vf, index,
437 (unsigned char *)(&msgbuf[1]));
438 break;
348 default: 439 default:
349 e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]); 440 e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]);
350 retval = IXGBE_ERR_MBX; 441 retval = IXGBE_ERR_MBX;
@@ -452,7 +543,8 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos)
452 goto out; 543 goto out;
453 ixgbe_set_vmvir(adapter, vlan | (qos << VLAN_PRIO_SHIFT), vf); 544 ixgbe_set_vmvir(adapter, vlan | (qos << VLAN_PRIO_SHIFT), vf);
454 ixgbe_set_vmolr(hw, vf, false); 545 ixgbe_set_vmolr(hw, vf, false);
455 hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf); 546 if (adapter->antispoofing_enabled)
547 hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf);
456 adapter->vfinfo[vf].pf_vlan = vlan; 548 adapter->vfinfo[vf].pf_vlan = vlan;
457 adapter->vfinfo[vf].pf_qos = qos; 549 adapter->vfinfo[vf].pf_qos = qos;
458 dev_info(&adapter->pdev->dev, 550 dev_info(&adapter->pdev->dev,