aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Carlson <mcarlson@broadcom.com>2009-09-01 09:13:00 -0400
committerDavid S. Miller <davem@davemloft.net>2009-09-02 03:43:49 -0400
commitbaf8a94a572928710e9e60967d153a7bf3aebd9c (patch)
treea61c57ab84e29bd536c98b9e43129fc30d86abfa
parentb6080e126012047d42e53154189fdca286d0600e (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>
-rw-r--r--drivers/net/tg3.c53
-rw-r--r--drivers/net/tg3.h25
2 files changed, 76 insertions, 2 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 }
8145defcfg: 8195defcfg:
@@ -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
8162static int tg3_open(struct net_device *dev) 8213static int tg3_open(struct net_device *dev)
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 978b6d9546fb..348add254d11 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -446,6 +446,12 @@
446#define RX_MODE_PROMISC 0x00000100 446#define RX_MODE_PROMISC 0x00000100
447#define RX_MODE_NO_CRC_CHECK 0x00000200 447#define RX_MODE_NO_CRC_CHECK 0x00000200
448#define RX_MODE_KEEP_VLAN_TAG 0x00000400 448#define RX_MODE_KEEP_VLAN_TAG 0x00000400
449#define RX_MODE_RSS_IPV4_HASH_EN 0x00010000
450#define RX_MODE_RSS_TCP_IPV4_HASH_EN 0x00020000
451#define RX_MODE_RSS_IPV6_HASH_EN 0x00040000
452#define RX_MODE_RSS_TCP_IPV6_HASH_EN 0x00080000
453#define RX_MODE_RSS_ITBL_HASH_BITS_7 0x00700000
454#define RX_MODE_RSS_ENABLE 0x00800000
449#define RX_MODE_IPV6_CSUM_ENABLE 0x01000000 455#define RX_MODE_IPV6_CSUM_ENABLE 0x01000000
450#define MAC_RX_STATUS 0x0000046c 456#define MAC_RX_STATUS 0x0000046c
451#define RX_STATUS_REMOTE_TX_XOFFED 0x00000001 457#define RX_STATUS_REMOTE_TX_XOFFED 0x00000001
@@ -690,7 +696,22 @@
690/* 0x5b8 --> 0x600 unused */ 696/* 0x5b8 --> 0x600 unused */
691#define MAC_TX_MAC_STATE_BASE 0x00000600 /* 16 bytes */ 697#define MAC_TX_MAC_STATE_BASE 0x00000600 /* 16 bytes */
692#define MAC_RX_MAC_STATE_BASE 0x00000610 /* 20 bytes */ 698#define MAC_RX_MAC_STATE_BASE 0x00000610 /* 20 bytes */
693/* 0x624 --> 0x800 unused */ 699/* 0x624 --> 0x670 unused */
700
701#define MAC_RSS_INDIR_TBL_0 0x00000630
702
703#define MAC_RSS_HASH_KEY_0 0x00000670
704#define MAC_RSS_HASH_KEY_1 0x00000674
705#define MAC_RSS_HASH_KEY_2 0x00000678
706#define MAC_RSS_HASH_KEY_3 0x0000067c
707#define MAC_RSS_HASH_KEY_4 0x00000680
708#define MAC_RSS_HASH_KEY_5 0x00000684
709#define MAC_RSS_HASH_KEY_6 0x00000688
710#define MAC_RSS_HASH_KEY_7 0x0000068c
711#define MAC_RSS_HASH_KEY_8 0x00000690
712#define MAC_RSS_HASH_KEY_9 0x00000694
713/* 0x698 --> 0x800 unused */
714
694#define MAC_TX_STATS_OCTETS 0x00000800 715#define MAC_TX_STATS_OCTETS 0x00000800
695#define MAC_TX_STATS_RESV1 0x00000804 716#define MAC_TX_STATS_RESV1 0x00000804
696#define MAC_TX_STATS_COLLISIONS 0x00000808 717#define MAC_TX_STATS_COLLISIONS 0x00000808
@@ -1465,6 +1486,7 @@
1465#define MSGINT_MODE 0x00006000 1486#define MSGINT_MODE 0x00006000
1466#define MSGINT_MODE_RESET 0x00000001 1487#define MSGINT_MODE_RESET 0x00000001
1467#define MSGINT_MODE_ENABLE 0x00000002 1488#define MSGINT_MODE_ENABLE 0x00000002
1489#define MSGINT_MODE_MULTIVEC_EN 0x00000080
1468#define MSGINT_STATUS 0x00006004 1490#define MSGINT_STATUS 0x00006004
1469#define MSGINT_FIFO 0x00006008 1491#define MSGINT_FIFO 0x00006008
1470/* 0x600c --> 0x6400 unused */ 1492/* 0x600c --> 0x6400 unused */
@@ -2704,6 +2726,7 @@ struct tg3 {
2704#define TG3_FLG3_NO_NVRAM 0x00004000 2726#define TG3_FLG3_NO_NVRAM 0x00004000
2705#define TG3_FLG3_TOGGLE_10_100_L1PLLPD 0x00008000 2727#define TG3_FLG3_TOGGLE_10_100_L1PLLPD 0x00008000
2706#define TG3_FLG3_PHY_IS_FET 0x00010000 2728#define TG3_FLG3_PHY_IS_FET 0x00010000
2729#define TG3_FLG3_ENABLE_RSS 0x00020000
2707 2730
2708 struct timer_list timer; 2731 struct timer_list timer;
2709 u16 timer_counter; 2732 u16 timer_counter;