diff options
author | Ajit Khaparde <ajitk@serverengines.com> | 2010-08-25 00:32:33 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-08-25 16:41:25 -0700 |
commit | 6d87f5c3ac5856bf1309700e2f15e2e7fcd3c578 (patch) | |
tree | 2ba12a7c04aeb3ecef77881f03147b334dc9fe9b /drivers/net/benet/be_main.c | |
parent | aa7c6e5fa08bb5014b6432a690d28748f11e93fc (diff) |
be2net: fix to dynamically generate MAC Address for VFs
The BE ASIC/firmware doesnot reserve and assign MAC address for VFs.
This results in the VF interfaces being created with MAC Address 0.
The code change proposed takes the MAC address of PF to generate a seed.
MAC Address for VFs are assigned incrementally starting from the seed.
These addresses are programmed in the ASIC by the PF and the VF driver
queries for the MAC address during its probe.
Signed-off-by: Ajit Khaparde <ajitk@serverengines.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/benet/be_main.c')
-rw-r--r-- | drivers/net/benet/be_main.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index b89bae02962..9db10fec823 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c @@ -2088,6 +2088,47 @@ static int be_setup_wol(struct be_adapter *adapter, bool enable) return status; } +/* + * Generate a seed MAC address from the PF MAC Address using jhash. + * MAC Address for VFs are assigned incrementally starting from the seed. + * These addresses are programmed in the ASIC by the PF and the VF driver + * queries for the MAC address during its probe. + */ +static inline int be_vf_eth_addr_config(struct be_adapter *adapter) +{ + u32 vf = 0; + int status; + u8 mac[ETH_ALEN]; + + be_vf_eth_addr_generate(adapter, mac); + + for (vf = 0; vf < num_vfs; vf++) { + status = be_cmd_pmac_add(adapter, mac, + adapter->vf_cfg[vf].vf_if_handle, + &adapter->vf_cfg[vf].vf_pmac_id); + if (status) + dev_err(&adapter->pdev->dev, + "Mac address add failed for VF %d\n", vf); + else + memcpy(adapter->vf_cfg[vf].vf_mac_addr, mac, ETH_ALEN); + + mac[5] += 1; + } + return status; +} + +static inline void be_vf_eth_addr_rem(struct be_adapter *adapter) +{ + u32 vf; + + for (vf = 0; vf < num_vfs; vf++) { + if (adapter->vf_cfg[vf].vf_pmac_id != BE_INVALID_PMAC_ID) + be_cmd_pmac_del(adapter, + adapter->vf_cfg[vf].vf_if_handle, + adapter->vf_cfg[vf].vf_pmac_id); + } +} + static int be_setup(struct be_adapter *adapter) { struct net_device *netdev = adapter->netdev; @@ -2147,10 +2188,20 @@ static int be_setup(struct be_adapter *adapter) if (status != 0) goto rx_qs_destroy; + if (be_physfn(adapter)) { + status = be_vf_eth_addr_config(adapter); + if (status) + goto mcc_q_destroy; + } + adapter->link_speed = -1; return 0; +mcc_q_destroy: + if (be_physfn(adapter)) + be_vf_eth_addr_rem(adapter); + be_mcc_queues_destroy(adapter); rx_qs_destroy: be_rx_queues_destroy(adapter); tx_qs_destroy: @@ -2167,6 +2218,9 @@ do_none: static int be_clear(struct be_adapter *adapter) { + if (be_physfn(adapter)) + be_vf_eth_addr_rem(adapter); + be_mcc_queues_destroy(adapter); be_rx_queues_destroy(adapter); be_tx_queues_destroy(adapter); |