diff options
author | Greg Rose <gregory.v.rose@intel.com> | 2011-05-12 21:33:42 -0400 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-05-14 20:50:44 -0400 |
commit | 46ec20ff7d6f9f011e06d58e4e87153ed8c893ed (patch) | |
tree | d2976bcdef595eb8c3c14dd4d9ad036bbc1293eb /drivers/net/ixgbevf | |
parent | d64a6f4dca0b45495dd5be8116b618d9cc004eea (diff) |
ixgbevf: Add macvlan support in the set rx mode op
Implement setup of unicast address list in the VF driver's set_rx_mode
netdev op. Unicast addresses are sent to the PF via a mailbox message
and the PF will check if it has room in the RAR table and if so set the
filter for the VF.
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/ixgbevf')
-rw-r--r-- | drivers/net/ixgbevf/ixgbevf_main.c | 30 | ||||
-rw-r--r-- | drivers/net/ixgbevf/mbx.h | 1 | ||||
-rw-r--r-- | drivers/net/ixgbevf/vf.c | 34 | ||||
-rw-r--r-- | drivers/net/ixgbevf/vf.h | 1 |
4 files changed, 66 insertions, 0 deletions
diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c index 05fa7c85deed..d7ab202fb95c 100644 --- a/drivers/net/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ixgbevf/ixgbevf_main.c | |||
@@ -1460,6 +1460,34 @@ static void ixgbevf_restore_vlan(struct ixgbevf_adapter *adapter) | |||
1460 | } | 1460 | } |
1461 | } | 1461 | } |
1462 | 1462 | ||
1463 | static int ixgbevf_write_uc_addr_list(struct net_device *netdev) | ||
1464 | { | ||
1465 | struct ixgbevf_adapter *adapter = netdev_priv(netdev); | ||
1466 | struct ixgbe_hw *hw = &adapter->hw; | ||
1467 | int count = 0; | ||
1468 | |||
1469 | if ((netdev_uc_count(netdev)) > 10) { | ||
1470 | printk(KERN_ERR "Too many unicast filters - No Space\n"); | ||
1471 | return -ENOSPC; | ||
1472 | } | ||
1473 | |||
1474 | if (!netdev_uc_empty(netdev)) { | ||
1475 | struct netdev_hw_addr *ha; | ||
1476 | netdev_for_each_uc_addr(ha, netdev) { | ||
1477 | hw->mac.ops.set_uc_addr(hw, ++count, ha->addr); | ||
1478 | udelay(200); | ||
1479 | } | ||
1480 | } else { | ||
1481 | /* | ||
1482 | * If the list is empty then send message to PF driver to | ||
1483 | * clear all macvlans on this VF. | ||
1484 | */ | ||
1485 | hw->mac.ops.set_uc_addr(hw, 0, NULL); | ||
1486 | } | ||
1487 | |||
1488 | return count; | ||
1489 | } | ||
1490 | |||
1463 | /** | 1491 | /** |
1464 | * ixgbevf_set_rx_mode - Multicast set | 1492 | * ixgbevf_set_rx_mode - Multicast set |
1465 | * @netdev: network interface device structure | 1493 | * @netdev: network interface device structure |
@@ -1476,6 +1504,8 @@ static void ixgbevf_set_rx_mode(struct net_device *netdev) | |||
1476 | /* reprogram multicast list */ | 1504 | /* reprogram multicast list */ |
1477 | if (hw->mac.ops.update_mc_addr_list) | 1505 | if (hw->mac.ops.update_mc_addr_list) |
1478 | hw->mac.ops.update_mc_addr_list(hw, netdev); | 1506 | hw->mac.ops.update_mc_addr_list(hw, netdev); |
1507 | |||
1508 | ixgbevf_write_uc_addr_list(netdev); | ||
1479 | } | 1509 | } |
1480 | 1510 | ||
1481 | static void ixgbevf_napi_enable_all(struct ixgbevf_adapter *adapter) | 1511 | static void ixgbevf_napi_enable_all(struct ixgbevf_adapter *adapter) |
diff --git a/drivers/net/ixgbevf/mbx.h b/drivers/net/ixgbevf/mbx.h index b2b5bf5daa3d..ea393eb03f3a 100644 --- a/drivers/net/ixgbevf/mbx.h +++ b/drivers/net/ixgbevf/mbx.h | |||
@@ -81,6 +81,7 @@ | |||
81 | #define IXGBE_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */ | 81 | #define IXGBE_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */ |
82 | #define IXGBE_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */ | 82 | #define IXGBE_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */ |
83 | #define IXGBE_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE */ | 83 | #define IXGBE_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE */ |
84 | #define IXGBE_VF_SET_MACVLAN 0x06 /* VF requests PF for unicast filter */ | ||
84 | 85 | ||
85 | /* length of permanent address message returned from PF */ | 86 | /* length of permanent address message returned from PF */ |
86 | #define IXGBE_VF_PERMADDR_MSG_LEN 4 | 87 | #define IXGBE_VF_PERMADDR_MSG_LEN 4 |
diff --git a/drivers/net/ixgbevf/vf.c b/drivers/net/ixgbevf/vf.c index eecd3bf6833f..aa3682e8c473 100644 --- a/drivers/net/ixgbevf/vf.c +++ b/drivers/net/ixgbevf/vf.c | |||
@@ -216,6 +216,39 @@ static s32 ixgbevf_get_mac_addr_vf(struct ixgbe_hw *hw, u8 *mac_addr) | |||
216 | return 0; | 216 | return 0; |
217 | } | 217 | } |
218 | 218 | ||
219 | static s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr) | ||
220 | { | ||
221 | struct ixgbe_mbx_info *mbx = &hw->mbx; | ||
222 | u32 msgbuf[3]; | ||
223 | u8 *msg_addr = (u8 *)(&msgbuf[1]); | ||
224 | s32 ret_val; | ||
225 | |||
226 | memset(msgbuf, 0, sizeof(msgbuf)); | ||
227 | /* | ||
228 | * If index is one then this is the start of a new list and needs | ||
229 | * indication to the PF so it can do it's own list management. | ||
230 | * If it is zero then that tells the PF to just clear all of | ||
231 | * this VF's macvlans and there is no new list. | ||
232 | */ | ||
233 | msgbuf[0] |= index << IXGBE_VT_MSGINFO_SHIFT; | ||
234 | msgbuf[0] |= IXGBE_VF_SET_MACVLAN; | ||
235 | if (addr) | ||
236 | memcpy(msg_addr, addr, 6); | ||
237 | ret_val = mbx->ops.write_posted(hw, msgbuf, 3); | ||
238 | |||
239 | if (!ret_val) | ||
240 | ret_val = mbx->ops.read_posted(hw, msgbuf, 3); | ||
241 | |||
242 | msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS; | ||
243 | |||
244 | if (!ret_val) | ||
245 | if (msgbuf[0] == | ||
246 | (IXGBE_VF_SET_MACVLAN | IXGBE_VT_MSGTYPE_NACK)) | ||
247 | ret_val = -ENOMEM; | ||
248 | |||
249 | return ret_val; | ||
250 | } | ||
251 | |||
219 | /** | 252 | /** |
220 | * ixgbevf_set_rar_vf - set device MAC address | 253 | * ixgbevf_set_rar_vf - set device MAC address |
221 | * @hw: pointer to hardware structure | 254 | * @hw: pointer to hardware structure |
@@ -378,6 +411,7 @@ static struct ixgbe_mac_operations ixgbevf_mac_ops = { | |||
378 | .check_link = ixgbevf_check_mac_link_vf, | 411 | .check_link = ixgbevf_check_mac_link_vf, |
379 | .set_rar = ixgbevf_set_rar_vf, | 412 | .set_rar = ixgbevf_set_rar_vf, |
380 | .update_mc_addr_list = ixgbevf_update_mc_addr_list_vf, | 413 | .update_mc_addr_list = ixgbevf_update_mc_addr_list_vf, |
414 | .set_uc_addr = ixgbevf_set_uc_addr_vf, | ||
381 | .set_vfta = ixgbevf_set_vfta_vf, | 415 | .set_vfta = ixgbevf_set_vfta_vf, |
382 | }; | 416 | }; |
383 | 417 | ||
diff --git a/drivers/net/ixgbevf/vf.h b/drivers/net/ixgbevf/vf.h index 23eb114c149f..10306b492ee6 100644 --- a/drivers/net/ixgbevf/vf.h +++ b/drivers/net/ixgbevf/vf.h | |||
@@ -62,6 +62,7 @@ struct ixgbe_mac_operations { | |||
62 | 62 | ||
63 | /* RAR, Multicast, VLAN */ | 63 | /* RAR, Multicast, VLAN */ |
64 | s32 (*set_rar)(struct ixgbe_hw *, u32, u8 *, u32); | 64 | s32 (*set_rar)(struct ixgbe_hw *, u32, u8 *, u32); |
65 | s32 (*set_uc_addr)(struct ixgbe_hw *, u32, u8 *); | ||
65 | s32 (*init_rx_addrs)(struct ixgbe_hw *); | 66 | s32 (*init_rx_addrs)(struct ixgbe_hw *); |
66 | s32 (*update_mc_addr_list)(struct ixgbe_hw *, struct net_device *); | 67 | s32 (*update_mc_addr_list)(struct ixgbe_hw *, struct net_device *); |
67 | s32 (*enable_mc)(struct ixgbe_hw *); | 68 | s32 (*enable_mc)(struct ixgbe_hw *); |