aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAjit Khaparde <ajitk@serverengines.com>2010-08-24 20:32:33 -0400
committerDavid S. Miller <davem@davemloft.net>2010-08-25 19:41:25 -0400
commit6d87f5c3ac5856bf1309700e2f15e2e7fcd3c578 (patch)
tree2ba12a7c04aeb3ecef77881f03147b334dc9fe9b /drivers/net
parentaa7c6e5fa08bb5014b6432a690d28748f11e93fc (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')
-rw-r--r--drivers/net/benet/be.h14
-rw-r--r--drivers/net/benet/be_main.c54
2 files changed, 68 insertions, 0 deletions
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 99197bd54da5..d1fb7928ffc5 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -413,6 +413,20 @@ static inline void be_check_sriov_fn_type(struct be_adapter *adapter)
413 adapter->is_virtfn = (data != 0xAA); 413 adapter->is_virtfn = (data != 0xAA);
414} 414}
415 415
416static inline void be_vf_eth_addr_generate(struct be_adapter *adapter, u8 *mac)
417{
418 u32 addr;
419
420 addr = jhash(adapter->netdev->dev_addr, ETH_ALEN, 0);
421
422 mac[5] = (u8)(addr & 0xFF);
423 mac[4] = (u8)((addr >> 8) & 0xFF);
424 mac[3] = (u8)((addr >> 16) & 0xFF);
425 mac[2] = 0xC9;
426 mac[1] = 0x00;
427 mac[0] = 0x00;
428}
429
416extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, 430extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm,
417 u16 num_popped); 431 u16 num_popped);
418extern void be_link_status_update(struct be_adapter *adapter, bool link_up); 432extern void be_link_status_update(struct be_adapter *adapter, bool link_up);
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index b89bae029620..9db10fec8235 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)
2088 return status; 2088 return status;
2089} 2089}
2090 2090
2091/*
2092 * Generate a seed MAC address from the PF MAC Address using jhash.
2093 * MAC Address for VFs are assigned incrementally starting from the seed.
2094 * These addresses are programmed in the ASIC by the PF and the VF driver
2095 * queries for the MAC address during its probe.
2096 */
2097static inline int be_vf_eth_addr_config(struct be_adapter *adapter)
2098{
2099 u32 vf = 0;
2100 int status;
2101 u8 mac[ETH_ALEN];
2102
2103 be_vf_eth_addr_generate(adapter, mac);
2104
2105 for (vf = 0; vf < num_vfs; vf++) {
2106 status = be_cmd_pmac_add(adapter, mac,
2107 adapter->vf_cfg[vf].vf_if_handle,
2108 &adapter->vf_cfg[vf].vf_pmac_id);
2109 if (status)
2110 dev_err(&adapter->pdev->dev,
2111 "Mac address add failed for VF %d\n", vf);
2112 else
2113 memcpy(adapter->vf_cfg[vf].vf_mac_addr, mac, ETH_ALEN);
2114
2115 mac[5] += 1;
2116 }
2117 return status;
2118}
2119
2120static inline void be_vf_eth_addr_rem(struct be_adapter *adapter)
2121{
2122 u32 vf;
2123
2124 for (vf = 0; vf < num_vfs; vf++) {
2125 if (adapter->vf_cfg[vf].vf_pmac_id != BE_INVALID_PMAC_ID)
2126 be_cmd_pmac_del(adapter,
2127 adapter->vf_cfg[vf].vf_if_handle,
2128 adapter->vf_cfg[vf].vf_pmac_id);
2129 }
2130}
2131
2091static int be_setup(struct be_adapter *adapter) 2132static int be_setup(struct be_adapter *adapter)
2092{ 2133{
2093 struct net_device *netdev = adapter->netdev; 2134 struct net_device *netdev = adapter->netdev;
@@ -2147,10 +2188,20 @@ static int be_setup(struct be_adapter *adapter)
2147 if (status != 0) 2188 if (status != 0)
2148 goto rx_qs_destroy; 2189 goto rx_qs_destroy;
2149 2190
2191 if (be_physfn(adapter)) {
2192 status = be_vf_eth_addr_config(adapter);
2193 if (status)
2194 goto mcc_q_destroy;
2195 }
2196
2150 adapter->link_speed = -1; 2197 adapter->link_speed = -1;
2151 2198
2152 return 0; 2199 return 0;
2153 2200
2201mcc_q_destroy:
2202 if (be_physfn(adapter))
2203 be_vf_eth_addr_rem(adapter);
2204 be_mcc_queues_destroy(adapter);
2154rx_qs_destroy: 2205rx_qs_destroy:
2155 be_rx_queues_destroy(adapter); 2206 be_rx_queues_destroy(adapter);
2156tx_qs_destroy: 2207tx_qs_destroy:
@@ -2167,6 +2218,9 @@ do_none:
2167 2218
2168static int be_clear(struct be_adapter *adapter) 2219static int be_clear(struct be_adapter *adapter)
2169{ 2220{
2221 if (be_physfn(adapter))
2222 be_vf_eth_addr_rem(adapter);
2223
2170 be_mcc_queues_destroy(adapter); 2224 be_mcc_queues_destroy(adapter);
2171 be_rx_queues_destroy(adapter); 2225 be_rx_queues_destroy(adapter);
2172 be_tx_queues_destroy(adapter); 2226 be_tx_queues_destroy(adapter);