diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/igb/e1000_mac.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/igb/e1000_mac.c')
-rw-r--r-- | drivers/net/igb/e1000_mac.c | 176 |
1 files changed, 56 insertions, 120 deletions
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c index 7d76bb085e10..be8d010e4021 100644 --- a/drivers/net/igb/e1000_mac.c +++ b/drivers/net/igb/e1000_mac.c | |||
@@ -185,13 +185,12 @@ s32 igb_check_alt_mac_addr(struct e1000_hw *hw) | |||
185 | } | 185 | } |
186 | 186 | ||
187 | if (nvm_alt_mac_addr_offset == 0xFFFF) { | 187 | if (nvm_alt_mac_addr_offset == 0xFFFF) { |
188 | ret_val = -(E1000_NOT_IMPLEMENTED); | 188 | /* There is no Alternate MAC Address */ |
189 | goto out; | 189 | goto out; |
190 | } | 190 | } |
191 | 191 | ||
192 | if (hw->bus.func == E1000_FUNC_1) | 192 | if (hw->bus.func == E1000_FUNC_1) |
193 | nvm_alt_mac_addr_offset += ETH_ALEN/sizeof(u16); | 193 | nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1; |
194 | |||
195 | for (i = 0; i < ETH_ALEN; i += 2) { | 194 | for (i = 0; i < ETH_ALEN; i += 2) { |
196 | offset = nvm_alt_mac_addr_offset + (i >> 1); | 195 | offset = nvm_alt_mac_addr_offset + (i >> 1); |
197 | ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data); | 196 | ret_val = hw->nvm.ops.read(hw, offset, 1, &nvm_data); |
@@ -206,14 +205,16 @@ s32 igb_check_alt_mac_addr(struct e1000_hw *hw) | |||
206 | 205 | ||
207 | /* if multicast bit is set, the alternate address will not be used */ | 206 | /* if multicast bit is set, the alternate address will not be used */ |
208 | if (alt_mac_addr[0] & 0x01) { | 207 | if (alt_mac_addr[0] & 0x01) { |
209 | ret_val = -(E1000_NOT_IMPLEMENTED); | 208 | hw_dbg("Ignoring Alternate Mac Address with MC bit set\n"); |
210 | goto out; | 209 | goto out; |
211 | } | 210 | } |
212 | 211 | ||
213 | for (i = 0; i < ETH_ALEN; i++) | 212 | /* |
214 | hw->mac.addr[i] = hw->mac.perm_addr[i] = alt_mac_addr[i]; | 213 | * We have a valid alternate MAC address, and we want to treat it the |
215 | 214 | * same as the normal permanent MAC address stored by the HW into the | |
216 | hw->mac.ops.rar_set(hw, hw->mac.perm_addr, 0); | 215 | * RAR. Do this by mapping this address into RAR0. |
216 | */ | ||
217 | hw->mac.ops.rar_set(hw, alt_mac_addr, 0); | ||
217 | 218 | ||
218 | out: | 219 | out: |
219 | return ret_val; | 220 | return ret_val; |
@@ -246,8 +247,15 @@ void igb_rar_set(struct e1000_hw *hw, u8 *addr, u32 index) | |||
246 | if (rar_low || rar_high) | 247 | if (rar_low || rar_high) |
247 | rar_high |= E1000_RAH_AV; | 248 | rar_high |= E1000_RAH_AV; |
248 | 249 | ||
250 | /* | ||
251 | * Some bridges will combine consecutive 32-bit writes into | ||
252 | * a single burst write, which will malfunction on some parts. | ||
253 | * The flushes avoid this. | ||
254 | */ | ||
249 | wr32(E1000_RAL(index), rar_low); | 255 | wr32(E1000_RAL(index), rar_low); |
256 | wrfl(); | ||
250 | wr32(E1000_RAH(index), rar_high); | 257 | wr32(E1000_RAH(index), rar_high); |
258 | wrfl(); | ||
251 | } | 259 | } |
252 | 260 | ||
253 | /** | 261 | /** |
@@ -399,45 +407,43 @@ void igb_update_mc_addr_list(struct e1000_hw *hw, | |||
399 | **/ | 407 | **/ |
400 | void igb_clear_hw_cntrs_base(struct e1000_hw *hw) | 408 | void igb_clear_hw_cntrs_base(struct e1000_hw *hw) |
401 | { | 409 | { |
402 | u32 temp; | 410 | rd32(E1000_CRCERRS); |
403 | 411 | rd32(E1000_SYMERRS); | |
404 | temp = rd32(E1000_CRCERRS); | 412 | rd32(E1000_MPC); |
405 | temp = rd32(E1000_SYMERRS); | 413 | rd32(E1000_SCC); |
406 | temp = rd32(E1000_MPC); | 414 | rd32(E1000_ECOL); |
407 | temp = rd32(E1000_SCC); | 415 | rd32(E1000_MCC); |
408 | temp = rd32(E1000_ECOL); | 416 | rd32(E1000_LATECOL); |
409 | temp = rd32(E1000_MCC); | 417 | rd32(E1000_COLC); |
410 | temp = rd32(E1000_LATECOL); | 418 | rd32(E1000_DC); |
411 | temp = rd32(E1000_COLC); | 419 | rd32(E1000_SEC); |
412 | temp = rd32(E1000_DC); | 420 | rd32(E1000_RLEC); |
413 | temp = rd32(E1000_SEC); | 421 | rd32(E1000_XONRXC); |
414 | temp = rd32(E1000_RLEC); | 422 | rd32(E1000_XONTXC); |
415 | temp = rd32(E1000_XONRXC); | 423 | rd32(E1000_XOFFRXC); |
416 | temp = rd32(E1000_XONTXC); | 424 | rd32(E1000_XOFFTXC); |
417 | temp = rd32(E1000_XOFFRXC); | 425 | rd32(E1000_FCRUC); |
418 | temp = rd32(E1000_XOFFTXC); | 426 | rd32(E1000_GPRC); |
419 | temp = rd32(E1000_FCRUC); | 427 | rd32(E1000_BPRC); |
420 | temp = rd32(E1000_GPRC); | 428 | rd32(E1000_MPRC); |
421 | temp = rd32(E1000_BPRC); | 429 | rd32(E1000_GPTC); |
422 | temp = rd32(E1000_MPRC); | 430 | rd32(E1000_GORCL); |
423 | temp = rd32(E1000_GPTC); | 431 | rd32(E1000_GORCH); |
424 | temp = rd32(E1000_GORCL); | 432 | rd32(E1000_GOTCL); |
425 | temp = rd32(E1000_GORCH); | 433 | rd32(E1000_GOTCH); |
426 | temp = rd32(E1000_GOTCL); | 434 | rd32(E1000_RNBC); |
427 | temp = rd32(E1000_GOTCH); | 435 | rd32(E1000_RUC); |
428 | temp = rd32(E1000_RNBC); | 436 | rd32(E1000_RFC); |
429 | temp = rd32(E1000_RUC); | 437 | rd32(E1000_ROC); |
430 | temp = rd32(E1000_RFC); | 438 | rd32(E1000_RJC); |
431 | temp = rd32(E1000_ROC); | 439 | rd32(E1000_TORL); |
432 | temp = rd32(E1000_RJC); | 440 | rd32(E1000_TORH); |
433 | temp = rd32(E1000_TORL); | 441 | rd32(E1000_TOTL); |
434 | temp = rd32(E1000_TORH); | 442 | rd32(E1000_TOTH); |
435 | temp = rd32(E1000_TOTL); | 443 | rd32(E1000_TPR); |
436 | temp = rd32(E1000_TOTH); | 444 | rd32(E1000_TPT); |
437 | temp = rd32(E1000_TPR); | 445 | rd32(E1000_MPTC); |
438 | temp = rd32(E1000_TPT); | 446 | rd32(E1000_BPTC); |
439 | temp = rd32(E1000_MPTC); | ||
440 | temp = rd32(E1000_BPTC); | ||
441 | } | 447 | } |
442 | 448 | ||
443 | /** | 449 | /** |
@@ -1298,76 +1304,6 @@ out: | |||
1298 | } | 1304 | } |
1299 | 1305 | ||
1300 | /** | 1306 | /** |
1301 | * igb_reset_adaptive - Reset Adaptive Interframe Spacing | ||
1302 | * @hw: pointer to the HW structure | ||
1303 | * | ||
1304 | * Reset the Adaptive Interframe Spacing throttle to default values. | ||
1305 | **/ | ||
1306 | void igb_reset_adaptive(struct e1000_hw *hw) | ||
1307 | { | ||
1308 | struct e1000_mac_info *mac = &hw->mac; | ||
1309 | |||
1310 | if (!mac->adaptive_ifs) { | ||
1311 | hw_dbg("Not in Adaptive IFS mode!\n"); | ||
1312 | goto out; | ||
1313 | } | ||
1314 | |||
1315 | if (!mac->ifs_params_forced) { | ||
1316 | mac->current_ifs_val = 0; | ||
1317 | mac->ifs_min_val = IFS_MIN; | ||
1318 | mac->ifs_max_val = IFS_MAX; | ||
1319 | mac->ifs_step_size = IFS_STEP; | ||
1320 | mac->ifs_ratio = IFS_RATIO; | ||
1321 | } | ||
1322 | |||
1323 | mac->in_ifs_mode = false; | ||
1324 | wr32(E1000_AIT, 0); | ||
1325 | out: | ||
1326 | return; | ||
1327 | } | ||
1328 | |||
1329 | /** | ||
1330 | * igb_update_adaptive - Update Adaptive Interframe Spacing | ||
1331 | * @hw: pointer to the HW structure | ||
1332 | * | ||
1333 | * Update the Adaptive Interframe Spacing Throttle value based on the | ||
1334 | * time between transmitted packets and time between collisions. | ||
1335 | **/ | ||
1336 | void igb_update_adaptive(struct e1000_hw *hw) | ||
1337 | { | ||
1338 | struct e1000_mac_info *mac = &hw->mac; | ||
1339 | |||
1340 | if (!mac->adaptive_ifs) { | ||
1341 | hw_dbg("Not in Adaptive IFS mode!\n"); | ||
1342 | goto out; | ||
1343 | } | ||
1344 | |||
1345 | if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) { | ||
1346 | if (mac->tx_packet_delta > MIN_NUM_XMITS) { | ||
1347 | mac->in_ifs_mode = true; | ||
1348 | if (mac->current_ifs_val < mac->ifs_max_val) { | ||
1349 | if (!mac->current_ifs_val) | ||
1350 | mac->current_ifs_val = mac->ifs_min_val; | ||
1351 | else | ||
1352 | mac->current_ifs_val += | ||
1353 | mac->ifs_step_size; | ||
1354 | wr32(E1000_AIT, | ||
1355 | mac->current_ifs_val); | ||
1356 | } | ||
1357 | } | ||
1358 | } else { | ||
1359 | if (mac->in_ifs_mode && | ||
1360 | (mac->tx_packet_delta <= MIN_NUM_XMITS)) { | ||
1361 | mac->current_ifs_val = 0; | ||
1362 | mac->in_ifs_mode = false; | ||
1363 | wr32(E1000_AIT, 0); | ||
1364 | } | ||
1365 | } | ||
1366 | out: | ||
1367 | return; | ||
1368 | } | ||
1369 | |||
1370 | /** | ||
1371 | * igb_validate_mdi_setting - Verify MDI/MDIx settings | 1307 | * igb_validate_mdi_setting - Verify MDI/MDIx settings |
1372 | * @hw: pointer to the HW structure | 1308 | * @hw: pointer to the HW structure |
1373 | * | 1309 | * |
@@ -1431,7 +1367,8 @@ out: | |||
1431 | * igb_enable_mng_pass_thru - Enable processing of ARP's | 1367 | * igb_enable_mng_pass_thru - Enable processing of ARP's |
1432 | * @hw: pointer to the HW structure | 1368 | * @hw: pointer to the HW structure |
1433 | * | 1369 | * |
1434 | * Verifies the hardware needs to allow ARPs to be processed by the host. | 1370 | * Verifies the hardware needs to leave interface enabled so that frames can |
1371 | * be directed to and from the management interface. | ||
1435 | **/ | 1372 | **/ |
1436 | bool igb_enable_mng_pass_thru(struct e1000_hw *hw) | 1373 | bool igb_enable_mng_pass_thru(struct e1000_hw *hw) |
1437 | { | 1374 | { |
@@ -1444,8 +1381,7 @@ bool igb_enable_mng_pass_thru(struct e1000_hw *hw) | |||
1444 | 1381 | ||
1445 | manc = rd32(E1000_MANC); | 1382 | manc = rd32(E1000_MANC); |
1446 | 1383 | ||
1447 | if (!(manc & E1000_MANC_RCV_TCO_EN) || | 1384 | if (!(manc & E1000_MANC_RCV_TCO_EN)) |
1448 | !(manc & E1000_MANC_EN_MAC_ADDR_FILTER)) | ||
1449 | goto out; | 1385 | goto out; |
1450 | 1386 | ||
1451 | if (hw->mac.arc_subsystem_valid) { | 1387 | if (hw->mac.arc_subsystem_valid) { |