aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Kirsher <jeffrey.t.kirsher@intel.com>2006-03-02 21:18:32 -0500
committerroot <root@jk-desktop.jf.intel.com>2006-03-02 21:18:32 -0500
commit8df06e504e999ff729f1b2a2e573d96bf3690dbc (patch)
tree4087b617fe36c969577739d27fa99955362d093c
parent497fce5e72a21f45929a786bf416ac03cbe09e2f (diff)
e1000: Fix RSS if enabled in mid-connection
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com> Signed-off-by: John Ronciak <john.ronciak@intel.com>
-rw-r--r--drivers/net/e1000/e1000_hw.c30
-rw-r--r--drivers/net/e1000/e1000_hw.h1
2 files changed, 30 insertions, 1 deletions
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index 1b8869e39533..5ee42c75adb1 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -4755,8 +4755,36 @@ e1000_rar_set(struct e1000_hw *hw,
4755 rar_low = ((uint32_t) addr[0] | 4755 rar_low = ((uint32_t) addr[0] |
4756 ((uint32_t) addr[1] << 8) | 4756 ((uint32_t) addr[1] << 8) |
4757 ((uint32_t) addr[2] << 16) | ((uint32_t) addr[3] << 24)); 4757 ((uint32_t) addr[2] << 16) | ((uint32_t) addr[3] << 24));
4758 rar_high = ((uint32_t) addr[4] | ((uint32_t) addr[5] << 8));
4758 4759
4759 rar_high = ((uint32_t) addr[4] | ((uint32_t) addr[5] << 8) | E1000_RAH_AV); 4760 /* Disable Rx and flush all Rx frames before enabling RSS to avoid Rx
4761 * unit hang.
4762 *
4763 * Description:
4764 * If there are any Rx frames queued up or otherwise present in the HW
4765 * before RSS is enabled, and then we enable RSS, the HW Rx unit will
4766 * hang. To work around this issue, we have to disable receives and
4767 * flush out all Rx frames before we enable RSS. To do so, we modify we
4768 * redirect all Rx traffic to manageability and then reset the HW.
4769 * This flushes away Rx frames, and (since the redirections to
4770 * manageability persists across resets) keeps new ones from coming in
4771 * while we work. Then, we clear the Address Valid AV bit for all MAC
4772 * addresses and undo the re-direction to manageability.
4773 * Now, frames are coming in again, but the MAC won't accept them, so
4774 * far so good. We now proceed to initialize RSS (if necessary) and
4775 * configure the Rx unit. Last, we re-enable the AV bits and continue
4776 * on our merry way.
4777 */
4778 switch (hw->mac_type) {
4779 case e1000_82571:
4780 case e1000_82572:
4781 if (hw->leave_av_bit_off == TRUE)
4782 break;
4783 default:
4784 /* Indicate to hardware the Address is Valid. */
4785 rar_high |= E1000_RAH_AV;
4786 break;
4787 }
4760 4788
4761 E1000_WRITE_REG_ARRAY(hw, RA, (index << 1), rar_low); 4789 E1000_WRITE_REG_ARRAY(hw, RA, (index << 1), rar_low);
4762 E1000_WRITE_REG_ARRAY(hw, RA, ((index << 1) + 1), rar_high); 4790 E1000_WRITE_REG_ARRAY(hw, RA, ((index << 1) + 1), rar_high);
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index f1219dd9dbac..0848e556b1a9 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -1361,6 +1361,7 @@ struct e1000_hw {
1361 boolean_t ifs_params_forced; 1361 boolean_t ifs_params_forced;
1362 boolean_t in_ifs_mode; 1362 boolean_t in_ifs_mode;
1363 boolean_t mng_reg_access_disabled; 1363 boolean_t mng_reg_access_disabled;
1364 boolean_t leave_av_bit_off;
1364}; 1365};
1365 1366
1366 1367