diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/benet/be.h | 14 | ||||
-rw-r--r-- | drivers/net/benet/be_main.c | 54 |
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 | ||
416 | static 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 | |||
416 | extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, | 430 | extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, |
417 | u16 num_popped); | 431 | u16 num_popped); |
418 | extern void be_link_status_update(struct be_adapter *adapter, bool link_up); | 432 | extern 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 | */ | ||
2097 | static 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 | |||
2120 | static 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 | |||
2091 | static int be_setup(struct be_adapter *adapter) | 2132 | static 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 | ||
2201 | mcc_q_destroy: | ||
2202 | if (be_physfn(adapter)) | ||
2203 | be_vf_eth_addr_rem(adapter); | ||
2204 | be_mcc_queues_destroy(adapter); | ||
2154 | rx_qs_destroy: | 2205 | rx_qs_destroy: |
2155 | be_rx_queues_destroy(adapter); | 2206 | be_rx_queues_destroy(adapter); |
2156 | tx_qs_destroy: | 2207 | tx_qs_destroy: |
@@ -2167,6 +2218,9 @@ do_none: | |||
2167 | 2218 | ||
2168 | static int be_clear(struct be_adapter *adapter) | 2219 | static 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); |