diff options
Diffstat (limited to 'drivers/net/e1000e')
-rw-r--r-- | drivers/net/e1000e/lib.c | 62 |
1 files changed, 18 insertions, 44 deletions
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c index ac2f34e1836d..18a4f5902f3b 100644 --- a/drivers/net/e1000e/lib.c +++ b/drivers/net/e1000e/lib.c | |||
@@ -159,41 +159,6 @@ void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index) | |||
159 | } | 159 | } |
160 | 160 | ||
161 | /** | 161 | /** |
162 | * e1000_mta_set - Set multicast filter table address | ||
163 | * @hw: pointer to the HW structure | ||
164 | * @hash_value: determines the MTA register and bit to set | ||
165 | * | ||
166 | * The multicast table address is a register array of 32-bit registers. | ||
167 | * The hash_value is used to determine what register the bit is in, the | ||
168 | * current value is read, the new bit is OR'd in and the new value is | ||
169 | * written back into the register. | ||
170 | **/ | ||
171 | static void e1000_mta_set(struct e1000_hw *hw, u32 hash_value) | ||
172 | { | ||
173 | u32 hash_bit, hash_reg, mta; | ||
174 | |||
175 | /* | ||
176 | * The MTA is a register array of 32-bit registers. It is | ||
177 | * treated like an array of (32*mta_reg_count) bits. We want to | ||
178 | * set bit BitArray[hash_value]. So we figure out what register | ||
179 | * the bit is in, read it, OR in the new bit, then write | ||
180 | * back the new value. The (hw->mac.mta_reg_count - 1) serves as a | ||
181 | * mask to bits 31:5 of the hash value which gives us the | ||
182 | * register we're modifying. The hash bit within that register | ||
183 | * is determined by the lower 5 bits of the hash value. | ||
184 | */ | ||
185 | hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1); | ||
186 | hash_bit = hash_value & 0x1F; | ||
187 | |||
188 | mta = E1000_READ_REG_ARRAY(hw, E1000_MTA, hash_reg); | ||
189 | |||
190 | mta |= (1 << hash_bit); | ||
191 | |||
192 | E1000_WRITE_REG_ARRAY(hw, E1000_MTA, hash_reg, mta); | ||
193 | e1e_flush(); | ||
194 | } | ||
195 | |||
196 | /** | ||
197 | * e1000_hash_mc_addr - Generate a multicast hash value | 162 | * e1000_hash_mc_addr - Generate a multicast hash value |
198 | * @hw: pointer to the HW structure | 163 | * @hw: pointer to the HW structure |
199 | * @mc_addr: pointer to a multicast address | 164 | * @mc_addr: pointer to a multicast address |
@@ -281,8 +246,13 @@ void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw, | |||
281 | u8 *mc_addr_list, u32 mc_addr_count, | 246 | u8 *mc_addr_list, u32 mc_addr_count, |
282 | u32 rar_used_count, u32 rar_count) | 247 | u32 rar_used_count, u32 rar_count) |
283 | { | 248 | { |
284 | u32 hash_value; | ||
285 | u32 i; | 249 | u32 i; |
250 | u32 *mcarray = kzalloc(hw->mac.mta_reg_count * sizeof(u32), GFP_ATOMIC); | ||
251 | |||
252 | if (!mcarray) { | ||
253 | printk(KERN_ERR "multicast array memory allocation failed\n"); | ||
254 | return; | ||
255 | } | ||
286 | 256 | ||
287 | /* | 257 | /* |
288 | * Load the first set of multicast addresses into the exact | 258 | * Load the first set of multicast addresses into the exact |
@@ -302,20 +272,24 @@ void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw, | |||
302 | } | 272 | } |
303 | } | 273 | } |
304 | 274 | ||
305 | /* Clear the old settings from the MTA */ | ||
306 | hw_dbg(hw, "Clearing MTA\n"); | ||
307 | for (i = 0; i < hw->mac.mta_reg_count; i++) { | ||
308 | E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, 0); | ||
309 | e1e_flush(); | ||
310 | } | ||
311 | |||
312 | /* Load any remaining multicast addresses into the hash table. */ | 275 | /* Load any remaining multicast addresses into the hash table. */ |
313 | for (; mc_addr_count > 0; mc_addr_count--) { | 276 | for (; mc_addr_count > 0; mc_addr_count--) { |
277 | u32 hash_value, hash_reg, hash_bit, mta; | ||
314 | hash_value = e1000_hash_mc_addr(hw, mc_addr_list); | 278 | hash_value = e1000_hash_mc_addr(hw, mc_addr_list); |
315 | hw_dbg(hw, "Hash value = 0x%03X\n", hash_value); | 279 | hw_dbg(hw, "Hash value = 0x%03X\n", hash_value); |
316 | e1000_mta_set(hw, hash_value); | 280 | hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1); |
281 | hash_bit = hash_value & 0x1F; | ||
282 | mta = (1 << hash_bit); | ||
283 | mcarray[hash_reg] |= mta; | ||
317 | mc_addr_list += ETH_ALEN; | 284 | mc_addr_list += ETH_ALEN; |
318 | } | 285 | } |
286 | |||
287 | /* write the hash table completely */ | ||
288 | for (i = 0; i < hw->mac.mta_reg_count; i++) | ||
289 | E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, mcarray[i]); | ||
290 | |||
291 | e1e_flush(); | ||
292 | kfree(mcarray); | ||
319 | } | 293 | } |
320 | 294 | ||
321 | /** | 295 | /** |