diff options
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_sriov.c')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_sriov.c | 286 |
1 files changed, 255 insertions, 31 deletions
diff --git a/drivers/net/ixgbe/ixgbe_sriov.c b/drivers/net/ixgbe/ixgbe_sriov.c index 49661a138e22..ac99b0458fe2 100644 --- a/drivers/net/ixgbe/ixgbe_sriov.c +++ b/drivers/net/ixgbe/ixgbe_sriov.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | Intel 10 Gigabit PCI Express Linux driver | 3 | Intel 10 Gigabit PCI Express Linux driver |
4 | Copyright(c) 1999 - 2009 Intel Corporation. | 4 | Copyright(c) 1999 - 2011 Intel Corporation. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms and conditions of the GNU General Public License, | 7 | under the terms and conditions of the GNU General Public License, |
@@ -43,8 +43,8 @@ | |||
43 | 43 | ||
44 | #include "ixgbe_sriov.h" | 44 | #include "ixgbe_sriov.h" |
45 | 45 | ||
46 | int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter, | 46 | static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter, |
47 | int entries, u16 *hash_list, u32 vf) | 47 | int entries, u16 *hash_list, u32 vf) |
48 | { | 48 | { |
49 | struct vf_data_storage *vfinfo = &adapter->vfinfo[vf]; | 49 | struct vf_data_storage *vfinfo = &adapter->vfinfo[vf]; |
50 | struct ixgbe_hw *hw = &adapter->hw; | 50 | struct ixgbe_hw *hw = &adapter->hw; |
@@ -68,7 +68,7 @@ int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter, | |||
68 | * addresses | 68 | * addresses |
69 | */ | 69 | */ |
70 | for (i = 0; i < entries; i++) { | 70 | for (i = 0; i < entries; i++) { |
71 | vfinfo->vf_mc_hashes[i] = hash_list[i];; | 71 | vfinfo->vf_mc_hashes[i] = hash_list[i]; |
72 | } | 72 | } |
73 | 73 | ||
74 | for (i = 0; i < vfinfo->num_vf_mc_hashes; i++) { | 74 | for (i = 0; i < vfinfo->num_vf_mc_hashes; i++) { |
@@ -82,6 +82,21 @@ int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter, | |||
82 | return 0; | 82 | return 0; |
83 | } | 83 | } |
84 | 84 | ||
85 | static 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 | |||
85 | void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter) | 100 | void 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,19 +117,48 @@ 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 | ||
107 | int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid, u32 vf) | 125 | static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid, |
126 | u32 vf) | ||
108 | { | 127 | { |
109 | return adapter->hw.mac.ops.set_vfta(&adapter->hw, vid, vf, (bool)add); | 128 | return adapter->hw.mac.ops.set_vfta(&adapter->hw, vid, vf, (bool)add); |
110 | } | 129 | } |
111 | 130 | ||
131 | static void ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 *msgbuf) | ||
132 | { | ||
133 | struct ixgbe_hw *hw = &adapter->hw; | ||
134 | int new_mtu = msgbuf[1]; | ||
135 | u32 max_frs; | ||
136 | int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; | ||
137 | |||
138 | /* Only X540 supports jumbo frames in IOV mode */ | ||
139 | if (adapter->hw.mac.type != ixgbe_mac_X540) | ||
140 | return; | ||
141 | |||
142 | /* MTU < 68 is an error and causes problems on some kernels */ | ||
143 | if ((new_mtu < 68) || (max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE)) { | ||
144 | e_err(drv, "VF mtu %d out of range\n", new_mtu); | ||
145 | return; | ||
146 | } | ||
147 | |||
148 | max_frs = (IXGBE_READ_REG(hw, IXGBE_MAXFRS) & | ||
149 | IXGBE_MHADD_MFS_MASK) >> IXGBE_MHADD_MFS_SHIFT; | ||
150 | if (max_frs < new_mtu) { | ||
151 | max_frs = new_mtu << IXGBE_MHADD_MFS_SHIFT; | ||
152 | IXGBE_WRITE_REG(hw, IXGBE_MAXFRS, max_frs); | ||
153 | } | ||
112 | 154 | ||
113 | void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe) | 155 | e_info(hw, "VF requests change max MTU to %d\n", new_mtu); |
156 | } | ||
157 | |||
158 | static void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe) | ||
114 | { | 159 | { |
115 | u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf)); | 160 | u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf)); |
116 | vmolr |= (IXGBE_VMOLR_ROMPE | | 161 | vmolr |= (IXGBE_VMOLR_ROMPE | |
117 | IXGBE_VMOLR_ROPE | | ||
118 | IXGBE_VMOLR_BAM); | 162 | IXGBE_VMOLR_BAM); |
119 | if (aupe) | 163 | if (aupe) |
120 | vmolr |= IXGBE_VMOLR_AUPE; | 164 | vmolr |= IXGBE_VMOLR_AUPE; |
@@ -134,7 +178,7 @@ static void ixgbe_set_vmvir(struct ixgbe_adapter *adapter, u32 vid, u32 vf) | |||
134 | IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), 0); | 178 | IXGBE_WRITE_REG(hw, IXGBE_VMVIR(vf), 0); |
135 | } | 179 | } |
136 | 180 | ||
137 | inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf) | 181 | static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf) |
138 | { | 182 | { |
139 | struct ixgbe_hw *hw = &adapter->hw; | 183 | struct ixgbe_hw *hw = &adapter->hw; |
140 | int rar_entry = hw->mac.num_rar_entries - (vf + 1); | 184 | int rar_entry = hw->mac.num_rar_entries - (vf + 1); |
@@ -162,8 +206,8 @@ inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf) | |||
162 | hw->mac.ops.clear_rar(hw, rar_entry); | 206 | hw->mac.ops.clear_rar(hw, rar_entry); |
163 | } | 207 | } |
164 | 208 | ||
165 | int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter, | 209 | static int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter, |
166 | int vf, unsigned char *mac_addr) | 210 | int vf, unsigned char *mac_addr) |
167 | { | 211 | { |
168 | struct ixgbe_hw *hw = &adapter->hw; | 212 | struct ixgbe_hw *hw = &adapter->hw; |
169 | int rar_entry = hw->mac.num_rar_entries - (vf + 1); | 213 | int rar_entry = hw->mac.num_rar_entries - (vf + 1); |
@@ -174,11 +218,65 @@ int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter, | |||
174 | return 0; | 218 | return 0; |
175 | } | 219 | } |
176 | 220 | ||
221 | static 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 | |||
177 | int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask) | 276 | int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask) |
178 | { | 277 | { |
179 | unsigned char vf_mac_addr[6]; | 278 | unsigned char vf_mac_addr[6]; |
180 | struct net_device *netdev = pci_get_drvdata(pdev); | 279 | struct ixgbe_adapter *adapter = pci_get_drvdata(pdev); |
181 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||
182 | unsigned int vfn = (event_mask & 0x3f); | 280 | unsigned int vfn = (event_mask & 0x3f); |
183 | 281 | ||
184 | bool enable = ((event_mask & 0x10000000U) != 0); | 282 | bool enable = ((event_mask & 0x10000000U) != 0); |
@@ -197,7 +295,7 @@ int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask) | |||
197 | return 0; | 295 | return 0; |
198 | } | 296 | } |
199 | 297 | ||
200 | inline void ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf) | 298 | static inline void ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf) |
201 | { | 299 | { |
202 | struct ixgbe_hw *hw = &adapter->hw; | 300 | struct ixgbe_hw *hw = &adapter->hw; |
203 | u32 reg; | 301 | u32 reg; |
@@ -215,18 +313,24 @@ inline void ixgbe_vf_reset_msg(struct ixgbe_adapter *adapter, u32 vf) | |||
215 | reg |= (reg | (1 << vf_shift)); | 313 | reg |= (reg | (1 << vf_shift)); |
216 | IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), reg); | 314 | IXGBE_WRITE_REG(hw, IXGBE_VFRE(reg_offset), reg); |
217 | 315 | ||
316 | /* Enable counting of spoofed packets in the SSVPC register */ | ||
317 | reg = IXGBE_READ_REG(hw, IXGBE_VMECM(reg_offset)); | ||
318 | reg |= (1 << vf_shift); | ||
319 | IXGBE_WRITE_REG(hw, IXGBE_VMECM(reg_offset), reg); | ||
320 | |||
218 | ixgbe_vf_reset_event(adapter, vf); | 321 | ixgbe_vf_reset_event(adapter, vf); |
219 | } | 322 | } |
220 | 323 | ||
221 | static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) | 324 | static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) |
222 | { | 325 | { |
223 | u32 mbx_size = IXGBE_VFMAILBOX_SIZE; | 326 | u32 mbx_size = IXGBE_VFMAILBOX_SIZE; |
224 | u32 msgbuf[mbx_size]; | 327 | u32 msgbuf[IXGBE_VFMAILBOX_SIZE]; |
225 | struct ixgbe_hw *hw = &adapter->hw; | 328 | struct ixgbe_hw *hw = &adapter->hw; |
226 | s32 retval; | 329 | s32 retval; |
227 | int entries; | 330 | int entries; |
228 | u16 *hash_list; | 331 | u16 *hash_list; |
229 | int add, vid; | 332 | int add, vid, index; |
333 | u8 *new_mac; | ||
230 | 334 | ||
231 | retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf); | 335 | retval = ixgbe_read_mbx(hw, msgbuf, mbx_size, vf); |
232 | 336 | ||
@@ -244,15 +348,22 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) | |||
244 | 348 | ||
245 | if (msgbuf[0] == IXGBE_VF_RESET) { | 349 | if (msgbuf[0] == IXGBE_VF_RESET) { |
246 | unsigned char *vf_mac = adapter->vfinfo[vf].vf_mac_addresses; | 350 | unsigned char *vf_mac = adapter->vfinfo[vf].vf_mac_addresses; |
247 | u8 *addr = (u8 *)(&msgbuf[1]); | 351 | new_mac = (u8 *)(&msgbuf[1]); |
248 | e_info(probe, "VF Reset msg received from vf %d\n", vf); | 352 | e_info(probe, "VF Reset msg received from vf %d\n", vf); |
249 | adapter->vfinfo[vf].clear_to_send = false; | 353 | adapter->vfinfo[vf].clear_to_send = false; |
250 | ixgbe_vf_reset_msg(adapter, vf); | 354 | ixgbe_vf_reset_msg(adapter, vf); |
251 | adapter->vfinfo[vf].clear_to_send = true; | 355 | adapter->vfinfo[vf].clear_to_send = true; |
252 | 356 | ||
357 | if (is_valid_ether_addr(new_mac) && | ||
358 | !adapter->vfinfo[vf].pf_set_mac) | ||
359 | ixgbe_set_vf_mac(adapter, vf, vf_mac); | ||
360 | else | ||
361 | ixgbe_set_vf_mac(adapter, | ||
362 | vf, adapter->vfinfo[vf].vf_mac_addresses); | ||
363 | |||
253 | /* reply to reset with ack and vf mac address */ | 364 | /* reply to reset with ack and vf mac address */ |
254 | msgbuf[0] = IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_ACK; | 365 | msgbuf[0] = IXGBE_VF_RESET | IXGBE_VT_MSGTYPE_ACK; |
255 | memcpy(addr, vf_mac, IXGBE_ETH_LENGTH_OF_ADDRESS); | 366 | memcpy(new_mac, vf_mac, IXGBE_ETH_LENGTH_OF_ADDRESS); |
256 | /* | 367 | /* |
257 | * Piggyback the multicast filter type so VF can compute the | 368 | * Piggyback the multicast filter type so VF can compute the |
258 | * correct vectors | 369 | * correct vectors |
@@ -271,14 +382,16 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) | |||
271 | 382 | ||
272 | switch ((msgbuf[0] & 0xFFFF)) { | 383 | switch ((msgbuf[0] & 0xFFFF)) { |
273 | case IXGBE_VF_SET_MAC_ADDR: | 384 | case IXGBE_VF_SET_MAC_ADDR: |
274 | { | 385 | new_mac = ((u8 *)(&msgbuf[1])); |
275 | u8 *new_mac = ((u8 *)(&msgbuf[1])); | 386 | if (is_valid_ether_addr(new_mac) && |
276 | if (is_valid_ether_addr(new_mac) && | 387 | !adapter->vfinfo[vf].pf_set_mac) { |
277 | !adapter->vfinfo[vf].pf_set_mac) | 388 | ixgbe_set_vf_mac(adapter, vf, new_mac); |
278 | ixgbe_set_vf_mac(adapter, vf, new_mac); | 389 | } else if (memcmp(adapter->vfinfo[vf].vf_mac_addresses, |
279 | else | 390 | new_mac, ETH_ALEN)) { |
280 | ixgbe_set_vf_mac(adapter, | 391 | e_warn(drv, "VF %d attempted to override " |
281 | vf, adapter->vfinfo[vf].vf_mac_addresses); | 392 | "administratively set MAC address\nReload " |
393 | "the VF driver to resume operations\n", vf); | ||
394 | retval = -1; | ||
282 | } | 395 | } |
283 | break; | 396 | break; |
284 | case IXGBE_VF_SET_MULTICAST: | 397 | case IXGBE_VF_SET_MULTICAST: |
@@ -289,13 +402,39 @@ static int ixgbe_rcv_msg_from_vf(struct ixgbe_adapter *adapter, u32 vf) | |||
289 | hash_list, vf); | 402 | hash_list, vf); |
290 | break; | 403 | break; |
291 | case IXGBE_VF_SET_LPE: | 404 | case IXGBE_VF_SET_LPE: |
292 | WARN_ON((msgbuf[0] & 0xFFFF) == IXGBE_VF_SET_LPE); | 405 | ixgbe_set_vf_lpe(adapter, msgbuf); |
293 | break; | 406 | break; |
294 | case IXGBE_VF_SET_VLAN: | 407 | case IXGBE_VF_SET_VLAN: |
295 | add = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) | 408 | add = (msgbuf[0] & IXGBE_VT_MSGINFO_MASK) |
296 | >> IXGBE_VT_MSGINFO_SHIFT; | 409 | >> IXGBE_VT_MSGINFO_SHIFT; |
297 | vid = (msgbuf[1] & IXGBE_VLVF_VLANID_MASK); | 410 | vid = (msgbuf[1] & IXGBE_VLVF_VLANID_MASK); |
298 | retval = ixgbe_set_vf_vlan(adapter, add, vid, vf); | 411 | if (adapter->vfinfo[vf].pf_vlan) { |
412 | e_warn(drv, "VF %d attempted to override " | ||
413 | "administratively set VLAN configuration\n" | ||
414 | "Reload the VF driver to resume operations\n", | ||
415 | vf); | ||
416 | retval = -1; | ||
417 | } else { | ||
418 | retval = ixgbe_set_vf_vlan(adapter, add, vid, vf); | ||
419 | } | ||
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])); | ||
299 | break; | 438 | break; |
300 | default: | 439 | default: |
301 | e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]); | 440 | e_err(drv, "Unhandled Msg %8.8x\n", msgbuf[0]); |
@@ -394,6 +533,7 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos) | |||
394 | { | 533 | { |
395 | int err = 0; | 534 | int err = 0; |
396 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | 535 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
536 | struct ixgbe_hw *hw = &adapter->hw; | ||
397 | 537 | ||
398 | if ((vf >= adapter->num_vfs) || (vlan > 4095) || (qos > 7)) | 538 | if ((vf >= adapter->num_vfs) || (vlan > 4095) || (qos > 7)) |
399 | return -EINVAL; | 539 | return -EINVAL; |
@@ -402,7 +542,9 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos) | |||
402 | if (err) | 542 | if (err) |
403 | goto out; | 543 | goto out; |
404 | ixgbe_set_vmvir(adapter, vlan | (qos << VLAN_PRIO_SHIFT), vf); | 544 | ixgbe_set_vmvir(adapter, vlan | (qos << VLAN_PRIO_SHIFT), vf); |
405 | ixgbe_set_vmolr(&adapter->hw, vf, false); | 545 | ixgbe_set_vmolr(hw, vf, false); |
546 | if (adapter->antispoofing_enabled) | ||
547 | hw->mac.ops.set_vlan_anti_spoofing(hw, true, vf); | ||
406 | adapter->vfinfo[vf].pf_vlan = vlan; | 548 | adapter->vfinfo[vf].pf_vlan = vlan; |
407 | adapter->vfinfo[vf].pf_qos = qos; | 549 | adapter->vfinfo[vf].pf_qos = qos; |
408 | dev_info(&adapter->pdev->dev, | 550 | dev_info(&adapter->pdev->dev, |
@@ -419,7 +561,8 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos) | |||
419 | err = ixgbe_set_vf_vlan(adapter, false, | 561 | err = ixgbe_set_vf_vlan(adapter, false, |
420 | adapter->vfinfo[vf].pf_vlan, vf); | 562 | adapter->vfinfo[vf].pf_vlan, vf); |
421 | ixgbe_set_vmvir(adapter, vlan, vf); | 563 | ixgbe_set_vmvir(adapter, vlan, vf); |
422 | ixgbe_set_vmolr(&adapter->hw, vf, true); | 564 | ixgbe_set_vmolr(hw, vf, true); |
565 | hw->mac.ops.set_vlan_anti_spoofing(hw, false, vf); | ||
423 | adapter->vfinfo[vf].pf_vlan = 0; | 566 | adapter->vfinfo[vf].pf_vlan = 0; |
424 | adapter->vfinfo[vf].pf_qos = 0; | 567 | adapter->vfinfo[vf].pf_qos = 0; |
425 | } | 568 | } |
@@ -427,9 +570,90 @@ out: | |||
427 | return err; | 570 | return err; |
428 | } | 571 | } |
429 | 572 | ||
573 | static int ixgbe_link_mbps(int internal_link_speed) | ||
574 | { | ||
575 | switch (internal_link_speed) { | ||
576 | case IXGBE_LINK_SPEED_100_FULL: | ||
577 | return 100; | ||
578 | case IXGBE_LINK_SPEED_1GB_FULL: | ||
579 | return 1000; | ||
580 | case IXGBE_LINK_SPEED_10GB_FULL: | ||
581 | return 10000; | ||
582 | default: | ||
583 | return 0; | ||
584 | } | ||
585 | } | ||
586 | |||
587 | static void ixgbe_set_vf_rate_limit(struct ixgbe_hw *hw, int vf, int tx_rate, | ||
588 | int link_speed) | ||
589 | { | ||
590 | int rf_dec, rf_int; | ||
591 | u32 bcnrc_val; | ||
592 | |||
593 | if (tx_rate != 0) { | ||
594 | /* Calculate the rate factor values to set */ | ||
595 | rf_int = link_speed / tx_rate; | ||
596 | rf_dec = (link_speed - (rf_int * tx_rate)); | ||
597 | rf_dec = (rf_dec * (1<<IXGBE_RTTBCNRC_RF_INT_SHIFT)) / tx_rate; | ||
598 | |||
599 | bcnrc_val = IXGBE_RTTBCNRC_RS_ENA; | ||
600 | bcnrc_val |= ((rf_int<<IXGBE_RTTBCNRC_RF_INT_SHIFT) & | ||
601 | IXGBE_RTTBCNRC_RF_INT_MASK); | ||
602 | bcnrc_val |= (rf_dec & IXGBE_RTTBCNRC_RF_DEC_MASK); | ||
603 | } else { | ||
604 | bcnrc_val = 0; | ||
605 | } | ||
606 | |||
607 | IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, 2*vf); /* vf Y uses queue 2*Y */ | ||
608 | IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, bcnrc_val); | ||
609 | } | ||
610 | |||
611 | void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter) | ||
612 | { | ||
613 | int actual_link_speed, i; | ||
614 | bool reset_rate = false; | ||
615 | |||
616 | /* VF Tx rate limit was not set */ | ||
617 | if (adapter->vf_rate_link_speed == 0) | ||
618 | return; | ||
619 | |||
620 | actual_link_speed = ixgbe_link_mbps(adapter->link_speed); | ||
621 | if (actual_link_speed != adapter->vf_rate_link_speed) { | ||
622 | reset_rate = true; | ||
623 | adapter->vf_rate_link_speed = 0; | ||
624 | dev_info(&adapter->pdev->dev, | ||
625 | "Link speed has been changed. VF Transmit rate " | ||
626 | "is disabled\n"); | ||
627 | } | ||
628 | |||
629 | for (i = 0; i < adapter->num_vfs; i++) { | ||
630 | if (reset_rate) | ||
631 | adapter->vfinfo[i].tx_rate = 0; | ||
632 | |||
633 | ixgbe_set_vf_rate_limit(&adapter->hw, i, | ||
634 | adapter->vfinfo[i].tx_rate, | ||
635 | actual_link_speed); | ||
636 | } | ||
637 | } | ||
638 | |||
430 | int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate) | 639 | int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate) |
431 | { | 640 | { |
432 | return -EOPNOTSUPP; | 641 | struct ixgbe_adapter *adapter = netdev_priv(netdev); |
642 | struct ixgbe_hw *hw = &adapter->hw; | ||
643 | int actual_link_speed; | ||
644 | |||
645 | actual_link_speed = ixgbe_link_mbps(adapter->link_speed); | ||
646 | if ((vf >= adapter->num_vfs) || (!adapter->link_up) || | ||
647 | (tx_rate > actual_link_speed) || (actual_link_speed != 10000) || | ||
648 | ((tx_rate != 0) && (tx_rate <= 10))) | ||
649 | /* rate limit cannot be set to 10Mb or less in 10Gb adapters */ | ||
650 | return -EINVAL; | ||
651 | |||
652 | adapter->vf_rate_link_speed = actual_link_speed; | ||
653 | adapter->vfinfo[vf].tx_rate = (u16)tx_rate; | ||
654 | ixgbe_set_vf_rate_limit(hw, vf, tx_rate, actual_link_speed); | ||
655 | |||
656 | return 0; | ||
433 | } | 657 | } |
434 | 658 | ||
435 | int ixgbe_ndo_get_vf_config(struct net_device *netdev, | 659 | int ixgbe_ndo_get_vf_config(struct net_device *netdev, |
@@ -440,7 +664,7 @@ int ixgbe_ndo_get_vf_config(struct net_device *netdev, | |||
440 | return -EINVAL; | 664 | return -EINVAL; |
441 | ivi->vf = vf; | 665 | ivi->vf = vf; |
442 | memcpy(&ivi->mac, adapter->vfinfo[vf].vf_mac_addresses, ETH_ALEN); | 666 | memcpy(&ivi->mac, adapter->vfinfo[vf].vf_mac_addresses, ETH_ALEN); |
443 | ivi->tx_rate = 0; | 667 | ivi->tx_rate = adapter->vfinfo[vf].tx_rate; |
444 | ivi->vlan = adapter->vfinfo[vf].pf_vlan; | 668 | ivi->vlan = adapter->vfinfo[vf].pf_vlan; |
445 | ivi->qos = adapter->vfinfo[vf].pf_qos; | 669 | ivi->qos = adapter->vfinfo[vf].pf_qos; |
446 | return 0; | 670 | return 0; |