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 | |
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>
-rw-r--r-- | drivers/net/tg3.c | 53 | ||||
-rw-r--r-- | drivers/net/tg3.h | 25 |
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 | } |
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) |
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; |