From 156b4343aedf13cc6b0444350d12e5c21ce3c02b Mon Sep 17 00:00:00 2001 From: Greg Rose Date: Fri, 13 May 2011 01:33:42 +0000 Subject: [PATCH] --- yaml --- r: 247459 b: refs/heads/master c: 46ec20ff7d6f9f011e06d58e4e87153ed8c893ed h: refs/heads/master i: 247457: 68e73934d94b744aa835dfd236af4e2b166e5cea 247455: 8e2c258a6c4b1086ab8c517178722f40eb766f23 v: v3 --- [refs] | 2 +- trunk/drivers/net/ixgbevf/ixgbevf_main.c | 30 +++++++++++++++++++++ trunk/drivers/net/ixgbevf/mbx.h | 1 + trunk/drivers/net/ixgbevf/vf.c | 34 ++++++++++++++++++++++++ trunk/drivers/net/ixgbevf/vf.h | 1 + 5 files changed, 67 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 04ccee289d4e..d04f38b26140 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: d64a6f4dca0b45495dd5be8116b618d9cc004eea +refs/heads/master: 46ec20ff7d6f9f011e06d58e4e87153ed8c893ed diff --git a/trunk/drivers/net/ixgbevf/ixgbevf_main.c b/trunk/drivers/net/ixgbevf/ixgbevf_main.c index 05fa7c85deed..d7ab202fb95c 100644 --- a/trunk/drivers/net/ixgbevf/ixgbevf_main.c +++ b/trunk/drivers/net/ixgbevf/ixgbevf_main.c @@ -1460,6 +1460,34 @@ static void ixgbevf_restore_vlan(struct ixgbevf_adapter *adapter) } } +static int ixgbevf_write_uc_addr_list(struct net_device *netdev) +{ + struct ixgbevf_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; + int count = 0; + + if ((netdev_uc_count(netdev)) > 10) { + printk(KERN_ERR "Too many unicast filters - No Space\n"); + return -ENOSPC; + } + + if (!netdev_uc_empty(netdev)) { + struct netdev_hw_addr *ha; + netdev_for_each_uc_addr(ha, netdev) { + hw->mac.ops.set_uc_addr(hw, ++count, ha->addr); + udelay(200); + } + } else { + /* + * If the list is empty then send message to PF driver to + * clear all macvlans on this VF. + */ + hw->mac.ops.set_uc_addr(hw, 0, NULL); + } + + return count; +} + /** * ixgbevf_set_rx_mode - Multicast set * @netdev: network interface device structure @@ -1476,6 +1504,8 @@ static void ixgbevf_set_rx_mode(struct net_device *netdev) /* reprogram multicast list */ if (hw->mac.ops.update_mc_addr_list) hw->mac.ops.update_mc_addr_list(hw, netdev); + + ixgbevf_write_uc_addr_list(netdev); } static void ixgbevf_napi_enable_all(struct ixgbevf_adapter *adapter) diff --git a/trunk/drivers/net/ixgbevf/mbx.h b/trunk/drivers/net/ixgbevf/mbx.h index b2b5bf5daa3d..ea393eb03f3a 100644 --- a/trunk/drivers/net/ixgbevf/mbx.h +++ b/trunk/drivers/net/ixgbevf/mbx.h @@ -81,6 +81,7 @@ #define IXGBE_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */ #define IXGBE_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */ #define IXGBE_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE */ +#define IXGBE_VF_SET_MACVLAN 0x06 /* VF requests PF for unicast filter */ /* length of permanent address message returned from PF */ #define IXGBE_VF_PERMADDR_MSG_LEN 4 diff --git a/trunk/drivers/net/ixgbevf/vf.c b/trunk/drivers/net/ixgbevf/vf.c index eecd3bf6833f..aa3682e8c473 100644 --- a/trunk/drivers/net/ixgbevf/vf.c +++ b/trunk/drivers/net/ixgbevf/vf.c @@ -216,6 +216,39 @@ static s32 ixgbevf_get_mac_addr_vf(struct ixgbe_hw *hw, u8 *mac_addr) return 0; } +static s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr) +{ + struct ixgbe_mbx_info *mbx = &hw->mbx; + u32 msgbuf[3]; + u8 *msg_addr = (u8 *)(&msgbuf[1]); + s32 ret_val; + + memset(msgbuf, 0, sizeof(msgbuf)); + /* + * If index is one then this is the start of a new list and needs + * indication to the PF so it can do it's own list management. + * If it is zero then that tells the PF to just clear all of + * this VF's macvlans and there is no new list. + */ + msgbuf[0] |= index << IXGBE_VT_MSGINFO_SHIFT; + msgbuf[0] |= IXGBE_VF_SET_MACVLAN; + if (addr) + memcpy(msg_addr, addr, 6); + ret_val = mbx->ops.write_posted(hw, msgbuf, 3); + + if (!ret_val) + ret_val = mbx->ops.read_posted(hw, msgbuf, 3); + + msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS; + + if (!ret_val) + if (msgbuf[0] == + (IXGBE_VF_SET_MACVLAN | IXGBE_VT_MSGTYPE_NACK)) + ret_val = -ENOMEM; + + return ret_val; +} + /** * ixgbevf_set_rar_vf - set device MAC address * @hw: pointer to hardware structure @@ -378,6 +411,7 @@ static struct ixgbe_mac_operations ixgbevf_mac_ops = { .check_link = ixgbevf_check_mac_link_vf, .set_rar = ixgbevf_set_rar_vf, .update_mc_addr_list = ixgbevf_update_mc_addr_list_vf, + .set_uc_addr = ixgbevf_set_uc_addr_vf, .set_vfta = ixgbevf_set_vfta_vf, }; diff --git a/trunk/drivers/net/ixgbevf/vf.h b/trunk/drivers/net/ixgbevf/vf.h index 23eb114c149f..10306b492ee6 100644 --- a/trunk/drivers/net/ixgbevf/vf.h +++ b/trunk/drivers/net/ixgbevf/vf.h @@ -62,6 +62,7 @@ struct ixgbe_mac_operations { /* RAR, Multicast, VLAN */ s32 (*set_rar)(struct ixgbe_hw *, u32, u8 *, u32); + s32 (*set_uc_addr)(struct ixgbe_hw *, u32, u8 *); s32 (*init_rx_addrs)(struct ixgbe_hw *); s32 (*update_mc_addr_list)(struct ixgbe_hw *, struct net_device *); s32 (*enable_mc)(struct ixgbe_hw *);