diff options
author | Matt Carlson <mcarlson@broadcom.com> | 2009-09-01 09:13:00 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-09-02 03:43:49 -0400 |
commit | baf8a94a572928710e9e60967d153a7bf3aebd9c (patch) | |
tree | a61c57ab84e29bd536c98b9e43129fc30d86abfa /drivers/net/tg3.c | |
parent | b6080e126012047d42e53154189fdca286d0600e (diff) |
tg3: Add RSS support
This patch adds code needed to enable RSS.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Benjamin Li <benli@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r-- | drivers/net/tg3.c | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index f51c29c64741..26e9db8c1b95 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -102,6 +102,7 @@ | |||
102 | #define TG3_DEF_RX_RING_PENDING 200 | 102 | #define TG3_DEF_RX_RING_PENDING 200 |
103 | #define TG3_RX_JUMBO_RING_SIZE 256 | 103 | #define TG3_RX_JUMBO_RING_SIZE 256 |
104 | #define TG3_DEF_RX_JUMBO_RING_PENDING 100 | 104 | #define TG3_DEF_RX_JUMBO_RING_PENDING 100 |
105 | #define TG3_RSS_INDIR_TBL_SIZE 128 | ||
105 | 106 | ||
106 | /* Do not place this n-ring entries value into the tp struct itself, | 107 | /* Do not place this n-ring entries value into the tp struct itself, |
107 | * we really want to expose these constants to GCC so that modulo et | 108 | * we really want to expose these constants to GCC so that modulo et |
@@ -7497,6 +7498,12 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) | |||
7497 | tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl); | 7498 | tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl); |
7498 | udelay(100); | 7499 | udelay(100); |
7499 | 7500 | ||
7501 | if (tp->tg3_flags2 & TG3_FLG2_USING_MSIX) { | ||
7502 | val = tr32(MSGINT_MODE); | ||
7503 | val |= MSGINT_MODE_MULTIVEC_EN | MSGINT_MODE_ENABLE; | ||
7504 | tw32(MSGINT_MODE, val); | ||
7505 | } | ||
7506 | |||
7500 | if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { | 7507 | if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { |
7501 | tw32_f(DMAC_MODE, DMAC_MODE_ENABLE); | 7508 | tw32_f(DMAC_MODE, DMAC_MODE_ENABLE); |
7502 | udelay(40); | 7509 | udelay(40); |
@@ -7565,7 +7572,10 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) | |||
7565 | tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE); | 7572 | tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE); |
7566 | if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) | 7573 | if (tp->tg3_flags2 & TG3_FLG2_HW_TSO) |
7567 | tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE | 0x8); | 7574 | tw32(SNDDATAI_MODE, SNDDATAI_MODE_ENABLE | 0x8); |
7568 | tw32(SNDBDI_MODE, SNDBDI_MODE_ENABLE | SNDBDI_MODE_ATTN_ENABLE); | 7575 | val = SNDBDI_MODE_ENABLE | SNDBDI_MODE_ATTN_ENABLE; |
7576 | if (tp->tg3_flags2 & TG3_FLG2_USING_MSIX) | ||
7577 | val |= SNDBDI_MODE_MULTI_TXQ_EN; | ||
7578 | tw32(SNDBDI_MODE, val); | ||
7569 | tw32(SNDBDS_MODE, SNDBDS_MODE_ENABLE | SNDBDS_MODE_ATTN_ENABLE); | 7579 | tw32(SNDBDS_MODE, SNDBDS_MODE_ENABLE | SNDBDS_MODE_ATTN_ENABLE); |
7570 | 7580 | ||
7571 | if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0) { | 7581 | if (tp->pci_chip_rev_id == CHIPREV_ID_5701_A0) { |
@@ -7584,10 +7594,46 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) | |||
7584 | tw32_f(MAC_TX_MODE, tp->tx_mode); | 7594 | tw32_f(MAC_TX_MODE, tp->tx_mode); |
7585 | udelay(100); | 7595 | udelay(100); |
7586 | 7596 | ||
7597 | if (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) { | ||
7598 | u32 reg = MAC_RSS_INDIR_TBL_0; | ||
7599 | u8 *ent = (u8 *)&val; | ||
7600 | |||
7601 | /* Setup the indirection table */ | ||
7602 | for (i = 0; i < TG3_RSS_INDIR_TBL_SIZE; i++) { | ||
7603 | int idx = i % sizeof(val); | ||
7604 | |||
7605 | ent[idx] = i % (tp->irq_cnt - 1); | ||
7606 | if (idx == sizeof(val) - 1) { | ||
7607 | tw32(reg, val); | ||
7608 | reg += 4; | ||
7609 | } | ||
7610 | } | ||
7611 | |||
7612 | /* Setup the "secret" hash key. */ | ||
7613 | tw32(MAC_RSS_HASH_KEY_0, 0x5f865437); | ||
7614 | tw32(MAC_RSS_HASH_KEY_1, 0xe4ac62cc); | ||
7615 | tw32(MAC_RSS_HASH_KEY_2, 0x50103a45); | ||
7616 | tw32(MAC_RSS_HASH_KEY_3, 0x36621985); | ||
7617 | tw32(MAC_RSS_HASH_KEY_4, 0xbf14c0e8); | ||
7618 | tw32(MAC_RSS_HASH_KEY_5, 0x1bc27a1e); | ||
7619 | tw32(MAC_RSS_HASH_KEY_6, 0x84f4b556); | ||
7620 | tw32(MAC_RSS_HASH_KEY_7, 0x094ea6fe); | ||
7621 | tw32(MAC_RSS_HASH_KEY_8, 0x7dda01e7); | ||
7622 | tw32(MAC_RSS_HASH_KEY_9, 0xc04d7481); | ||
7623 | } | ||
7624 | |||
7587 | tp->rx_mode = RX_MODE_ENABLE; | 7625 | tp->rx_mode = RX_MODE_ENABLE; |
7588 | if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS) | 7626 | if (tp->tg3_flags3 & TG3_FLG3_5755_PLUS) |
7589 | tp->rx_mode |= RX_MODE_IPV6_CSUM_ENABLE; | 7627 | tp->rx_mode |= RX_MODE_IPV6_CSUM_ENABLE; |
7590 | 7628 | ||
7629 | if (tp->tg3_flags3 & TG3_FLG3_ENABLE_RSS) | ||
7630 | tp->rx_mode |= RX_MODE_RSS_ENABLE | | ||
7631 | RX_MODE_RSS_ITBL_HASH_BITS_7 | | ||
7632 | RX_MODE_RSS_IPV6_HASH_EN | | ||
7633 | RX_MODE_RSS_TCP_IPV6_HASH_EN | | ||
7634 | RX_MODE_RSS_IPV4_HASH_EN | | ||
7635 | RX_MODE_RSS_TCP_IPV4_HASH_EN; | ||
7636 | |||
7591 | tw32_f(MAC_RX_MODE, tp->rx_mode); | 7637 | tw32_f(MAC_RX_MODE, tp->rx_mode); |
7592 | udelay(10); | 7638 | udelay(10); |
7593 | 7639 | ||
@@ -8112,6 +8158,8 @@ static bool tg3_enable_msix(struct tg3 *tp) | |||
8112 | tp->irq_cnt = rc; | 8158 | tp->irq_cnt = rc; |
8113 | } | 8159 | } |
8114 | 8160 | ||
8161 | tp->tg3_flags3 |= TG3_FLG3_ENABLE_RSS; | ||
8162 | |||
8115 | for (i = 0; i < tp->irq_max; i++) | 8163 | for (i = 0; i < tp->irq_max; i++) |
8116 | tp->napi[i].irq_vec = msix_ent[i].vector; | 8164 | tp->napi[i].irq_vec = msix_ent[i].vector; |
8117 | 8165 | ||
@@ -8140,6 +8188,8 @@ static void tg3_ints_init(struct tg3 *tp) | |||
8140 | 8188 | ||
8141 | if (tp->tg3_flags2 & TG3_FLG2_USING_MSI_OR_MSIX) { | 8189 | if (tp->tg3_flags2 & TG3_FLG2_USING_MSI_OR_MSIX) { |
8142 | u32 msi_mode = tr32(MSGINT_MODE); | 8190 | u32 msi_mode = tr32(MSGINT_MODE); |
8191 | if (tp->tg3_flags2 & TG3_FLG2_USING_MSIX) | ||
8192 | msi_mode |= MSGINT_MODE_MULTIVEC_EN; | ||
8143 | tw32(MSGINT_MODE, msi_mode | MSGINT_MODE_ENABLE); | 8193 | tw32(MSGINT_MODE, msi_mode | MSGINT_MODE_ENABLE); |
8144 | } | 8194 | } |
8145 | defcfg: | 8195 | defcfg: |
@@ -8157,6 +8207,7 @@ static void tg3_ints_fini(struct tg3 *tp) | |||
8157 | else if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) | 8207 | else if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) |
8158 | pci_disable_msi(tp->pdev); | 8208 | pci_disable_msi(tp->pdev); |
8159 | tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI_OR_MSIX; | 8209 | tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI_OR_MSIX; |
8210 | tp->tg3_flags3 &= ~TG3_FLG3_ENABLE_RSS; | ||
8160 | } | 8211 | } |
8161 | 8212 | ||
8162 | static int tg3_open(struct net_device *dev) | 8213 | static int tg3_open(struct net_device *dev) |