aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tg3.c
diff options
context:
space:
mode:
authorMatt Carlson <mcarlson@broadcom.com>2009-09-01 09:04:37 -0400
committerDavid S. Miller <davem@davemloft.net>2009-09-02 03:43:39 -0400
commitf77a6a8e6cee17b21a43bdf6b853cc2fc0e2c4df (patch)
treee604b171d1579cc6cc61b8124425fd331486bf57 /drivers/net/tg3.c
parent646c9eddcffd202bb0f3d906cecf94eaf10cad31 (diff)
tg3: Add tx and rx ring resource tracking
This patch adds code to assign status block, tx producer ring and rx return ring resources needed for the other interrupt vectors. 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.c242
1 files changed, 158 insertions, 84 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 4d16ce05dba4..58a8986f3e0a 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -5722,28 +5722,31 @@ err_out:
5722 */ 5722 */
5723static void tg3_free_rings(struct tg3 *tp) 5723static void tg3_free_rings(struct tg3 *tp)
5724{ 5724{
5725 struct tg3_napi *tnapi = &tp->napi[0]; 5725 int i, j;
5726 int i;
5727 5726
5728 for (i = 0; i < TG3_TX_RING_SIZE; ) { 5727 for (j = 0; j < tp->irq_cnt; j++) {
5729 struct tx_ring_info *txp; 5728 struct tg3_napi *tnapi = &tp->napi[j];
5730 struct sk_buff *skb;
5731 5729
5732 txp = &tnapi->tx_buffers[i]; 5730 for (i = 0; i < TG3_TX_RING_SIZE; ) {
5733 skb = txp->skb; 5731 struct tx_ring_info *txp;
5732 struct sk_buff *skb;
5734 5733
5735 if (skb == NULL) { 5734 txp = &tnapi->tx_buffers[i];
5736 i++; 5735 skb = txp->skb;
5737 continue;
5738 }
5739 5736
5740 skb_dma_unmap(&tp->pdev->dev, skb, DMA_TO_DEVICE); 5737 if (skb == NULL) {
5738 i++;
5739 continue;
5740 }
5741 5741
5742 txp->skb = NULL; 5742 skb_dma_unmap(&tp->pdev->dev, skb, DMA_TO_DEVICE);
5743 5743
5744 i += skb_shinfo(skb)->nr_frags + 1; 5744 txp->skb = NULL;
5745 5745
5746 dev_kfree_skb_any(skb); 5746 i += skb_shinfo(skb)->nr_frags + 1;
5747
5748 dev_kfree_skb_any(skb);
5749 }
5747 } 5750 }
5748 5751
5749 tg3_rx_prodring_free(tp, &tp->prodring[0]); 5752 tg3_rx_prodring_free(tp, &tp->prodring[0]);
@@ -5758,16 +5761,27 @@ static void tg3_free_rings(struct tg3 *tp)
5758 */ 5761 */
5759static int tg3_init_rings(struct tg3 *tp) 5762static int tg3_init_rings(struct tg3 *tp)
5760{ 5763{
5761 struct tg3_napi *tnapi = &tp->napi[0]; 5764 int i;
5762 5765
5763 /* Free up all the SKBs. */ 5766 /* Free up all the SKBs. */
5764 tg3_free_rings(tp); 5767 tg3_free_rings(tp);
5765 5768
5766 /* Zero out all descriptors. */ 5769 for (i = 0; i < tp->irq_cnt; i++) {
5767 memset(tnapi->tx_ring, 0, TG3_TX_RING_BYTES); 5770 struct tg3_napi *tnapi = &tp->napi[i];
5768 5771
5769 tnapi->rx_rcb_ptr = 0; 5772 tnapi->last_tag = 0;
5770 memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp)); 5773 tnapi->last_irq_tag = 0;
5774 tnapi->hw_status->status = 0;
5775 tnapi->hw_status->status_tag = 0;
5776 memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
5777
5778 tnapi->tx_prod = 0;
5779 tnapi->tx_cons = 0;
5780 memset(tnapi->tx_ring, 0, TG3_TX_RING_BYTES);
5781
5782 tnapi->rx_rcb_ptr = 0;
5783 memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
5784 }
5771 5785
5772 return tg3_rx_prodring_alloc(tp, &tp->prodring[0]); 5786 return tg3_rx_prodring_alloc(tp, &tp->prodring[0]);
5773} 5787}
@@ -5778,31 +5792,41 @@ static int tg3_init_rings(struct tg3 *tp)
5778 */ 5792 */
5779static void tg3_free_consistent(struct tg3 *tp) 5793static void tg3_free_consistent(struct tg3 *tp)
5780{ 5794{
5781 struct tg3_napi *tnapi = &tp->napi[0]; 5795 int i;
5782 5796
5783 kfree(tnapi->tx_buffers); 5797 for (i = 0; i < tp->irq_cnt; i++) {
5784 tnapi->tx_buffers = NULL; 5798 struct tg3_napi *tnapi = &tp->napi[i];
5785 if (tnapi->tx_ring) { 5799
5786 pci_free_consistent(tp->pdev, TG3_TX_RING_BYTES, 5800 if (tnapi->tx_ring) {
5787 tnapi->tx_ring, tnapi->tx_desc_mapping); 5801 pci_free_consistent(tp->pdev, TG3_TX_RING_BYTES,
5788 tnapi->tx_ring = NULL; 5802 tnapi->tx_ring, tnapi->tx_desc_mapping);
5789 } 5803 tnapi->tx_ring = NULL;
5790 if (tnapi->rx_rcb) { 5804 }
5791 pci_free_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES(tp), 5805
5792 tnapi->rx_rcb, tnapi->rx_rcb_mapping); 5806 kfree(tnapi->tx_buffers);
5793 tnapi->rx_rcb = NULL; 5807 tnapi->tx_buffers = NULL;
5794 } 5808
5795 if (tnapi->hw_status) { 5809 if (tnapi->rx_rcb) {
5796 pci_free_consistent(tp->pdev, TG3_HW_STATUS_SIZE, 5810 pci_free_consistent(tp->pdev, TG3_RX_RCB_RING_BYTES(tp),
5797 tnapi->hw_status, 5811 tnapi->rx_rcb,
5798 tnapi->status_mapping); 5812 tnapi->rx_rcb_mapping);
5799 tnapi->hw_status = NULL; 5813 tnapi->rx_rcb = NULL;
5814 }
5815
5816 if (tnapi->hw_status) {
5817 pci_free_consistent(tp->pdev, TG3_HW_STATUS_SIZE,
5818 tnapi->hw_status,
5819 tnapi->status_mapping);
5820 tnapi->hw_status = NULL;
5821 }
5800 } 5822 }
5823
5801 if (tp->hw_stats) { 5824 if (tp->hw_stats) {
5802 pci_free_consistent(tp->pdev, sizeof(struct tg3_hw_stats), 5825 pci_free_consistent(tp->pdev, sizeof(struct tg3_hw_stats),
5803 tp->hw_stats, tp->stats_mapping); 5826 tp->hw_stats, tp->stats_mapping);
5804 tp->hw_stats = NULL; 5827 tp->hw_stats = NULL;
5805 } 5828 }
5829
5806 tg3_rx_prodring_fini(tp, &tp->prodring[0]); 5830 tg3_rx_prodring_fini(tp, &tp->prodring[0]);
5807} 5831}
5808 5832
@@ -5812,44 +5836,49 @@ static void tg3_free_consistent(struct tg3 *tp)
5812 */ 5836 */
5813static int tg3_alloc_consistent(struct tg3 *tp) 5837static int tg3_alloc_consistent(struct tg3 *tp)
5814{ 5838{
5815 struct tg3_napi *tnapi = &tp->napi[0]; 5839 int i;
5816 5840
5817 if (tg3_rx_prodring_init(tp, &tp->prodring[0])) 5841 if (tg3_rx_prodring_init(tp, &tp->prodring[0]))
5818 return -ENOMEM; 5842 return -ENOMEM;
5819 5843
5820 tnapi->tx_buffers = kzalloc(sizeof(struct tx_ring_info) * 5844 tp->hw_stats = pci_alloc_consistent(tp->pdev,
5821 TG3_TX_RING_SIZE, GFP_KERNEL); 5845 sizeof(struct tg3_hw_stats),
5822 if (!tnapi->tx_buffers) 5846 &tp->stats_mapping);
5847 if (!tp->hw_stats)
5823 goto err_out; 5848 goto err_out;
5824 5849
5825 tnapi->tx_ring = pci_alloc_consistent(tp->pdev, TG3_TX_RING_BYTES, 5850 memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats));
5826 &tnapi->tx_desc_mapping);
5827 if (!tnapi->tx_ring)
5828 goto err_out;
5829 5851
5830 tnapi->hw_status = pci_alloc_consistent(tp->pdev, 5852 for (i = 0; i < tp->irq_cnt; i++) {
5831 TG3_HW_STATUS_SIZE, 5853 struct tg3_napi *tnapi = &tp->napi[i];
5832 &tnapi->status_mapping);
5833 if (!tnapi->hw_status)
5834 goto err_out;
5835 5854
5836 memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE); 5855 tnapi->hw_status = pci_alloc_consistent(tp->pdev,
5856 TG3_HW_STATUS_SIZE,
5857 &tnapi->status_mapping);
5858 if (!tnapi->hw_status)
5859 goto err_out;
5837 5860
5838 tnapi->rx_rcb = pci_alloc_consistent(tp->pdev, 5861 memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
5839 TG3_RX_RCB_RING_BYTES(tp),
5840 &tnapi->rx_rcb_mapping);
5841 if (!tnapi->rx_rcb)
5842 goto err_out;
5843 5862
5844 memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp)); 5863 tnapi->rx_rcb = pci_alloc_consistent(tp->pdev,
5864 TG3_RX_RCB_RING_BYTES(tp),
5865 &tnapi->rx_rcb_mapping);
5866 if (!tnapi->rx_rcb)
5867 goto err_out;
5845 5868
5846 tp->hw_stats = pci_alloc_consistent(tp->pdev, 5869 memset(tnapi->rx_rcb, 0, TG3_RX_RCB_RING_BYTES(tp));
5847 sizeof(struct tg3_hw_stats),
5848 &tp->stats_mapping);
5849 if (!tp->hw_stats)
5850 goto err_out;
5851 5870
5852 memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats)); 5871 tnapi->tx_buffers = kzalloc(sizeof(struct tx_ring_info) *
5872 TG3_TX_RING_SIZE, GFP_KERNEL);
5873 if (!tnapi->tx_buffers)
5874 goto err_out;
5875
5876 tnapi->tx_ring = pci_alloc_consistent(tp->pdev,
5877 TG3_TX_RING_BYTES,
5878 &tnapi->tx_desc_mapping);
5879 if (!tnapi->tx_ring)
5880 goto err_out;
5881 }
5853 5882
5854 return 0; 5883 return 0;
5855 5884
@@ -5910,7 +5939,6 @@ static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit, int
5910static int tg3_abort_hw(struct tg3 *tp, int silent) 5939static int tg3_abort_hw(struct tg3 *tp, int silent)
5911{ 5940{
5912 int i, err; 5941 int i, err;
5913 struct tg3_napi *tnapi = &tp->napi[0];
5914 5942
5915 tg3_disable_ints(tp); 5943 tg3_disable_ints(tp);
5916 5944
@@ -5962,8 +5990,11 @@ static int tg3_abort_hw(struct tg3 *tp, int silent)
5962 err |= tg3_stop_block(tp, BUFMGR_MODE, BUFMGR_MODE_ENABLE, silent); 5990 err |= tg3_stop_block(tp, BUFMGR_MODE, BUFMGR_MODE_ENABLE, silent);
5963 err |= tg3_stop_block(tp, MEMARB_MODE, MEMARB_MODE_ENABLE, silent); 5991 err |= tg3_stop_block(tp, MEMARB_MODE, MEMARB_MODE_ENABLE, silent);
5964 5992
5965 if (tnapi->hw_status) 5993 for (i = 0; i < tp->irq_cnt; i++) {
5966 memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE); 5994 struct tg3_napi *tnapi = &tp->napi[i];
5995 if (tnapi->hw_status)
5996 memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
5997 }
5967 if (tp->hw_stats) 5998 if (tp->hw_stats)
5968 memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats)); 5999 memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats));
5969 6000
@@ -6290,12 +6321,15 @@ static int tg3_chip_reset(struct tg3 *tp)
6290 * sharing or irqpoll. 6321 * sharing or irqpoll.
6291 */ 6322 */
6292 tp->tg3_flags |= TG3_FLAG_CHIP_RESETTING; 6323 tp->tg3_flags |= TG3_FLAG_CHIP_RESETTING;
6293 if (tp->napi[0].hw_status) { 6324 for (i = 0; i < tp->irq_cnt; i++) {
6294 tp->napi[0].hw_status->status = 0; 6325 struct tg3_napi *tnapi = &tp->napi[i];
6295 tp->napi[0].hw_status->status_tag = 0; 6326 if (tnapi->hw_status) {
6327 tnapi->hw_status->status = 0;
6328 tnapi->hw_status->status_tag = 0;
6329 }
6330 tnapi->last_tag = 0;
6331 tnapi->last_irq_tag = 0;
6296 } 6332 }
6297 tp->napi[0].last_tag = 0;
6298 tp->napi[0].last_irq_tag = 0;
6299 smp_mb(); 6333 smp_mb();
6300 6334
6301 for (i = 0; i < tp->irq_cnt; i++) 6335 for (i = 0; i < tp->irq_cnt; i++)
@@ -6829,7 +6863,7 @@ static void __tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec)
6829static void tg3_rings_reset(struct tg3 *tp) 6863static void tg3_rings_reset(struct tg3 *tp)
6830{ 6864{
6831 int i; 6865 int i;
6832 u32 txrcb, rxrcb, limit; 6866 u32 stblk, txrcb, rxrcb, limit;
6833 struct tg3_napi *tnapi = &tp->napi[0]; 6867 struct tg3_napi *tnapi = &tp->napi[0];
6834 6868
6835 /* Disable all transmit rings but the first. */ 6869 /* Disable all transmit rings but the first. */
@@ -6861,10 +6895,20 @@ static void tg3_rings_reset(struct tg3 *tp)
6861 tw32_mailbox_f(tp->napi[0].int_mbox, 1); 6895 tw32_mailbox_f(tp->napi[0].int_mbox, 1);
6862 6896
6863 /* Zero mailbox registers. */ 6897 /* Zero mailbox registers. */
6864 tp->napi[0].tx_prod = 0; 6898 if (tp->tg3_flags & TG3_FLAG_SUPPORT_MSIX) {
6865 tp->napi[0].tx_cons = 0; 6899 for (i = 1; i < TG3_IRQ_MAX_VECS; i++) {
6866 tw32_mailbox(tp->napi[0].prodmbox, 0); 6900 tp->napi[i].tx_prod = 0;
6867 tw32_rx_mbox(tp->napi[0].consmbox, 0); 6901 tp->napi[i].tx_cons = 0;
6902 tw32_mailbox(tp->napi[i].prodmbox, 0);
6903 tw32_rx_mbox(tp->napi[i].consmbox, 0);
6904 tw32_mailbox_f(tp->napi[i].int_mbox, 1);
6905 }
6906 } else {
6907 tp->napi[0].tx_prod = 0;
6908 tp->napi[0].tx_cons = 0;
6909 tw32_mailbox(tp->napi[0].prodmbox, 0);
6910 tw32_rx_mbox(tp->napi[0].consmbox, 0);
6911 }
6868 6912
6869 /* Make sure the NIC-based send BD rings are disabled. */ 6913 /* Make sure the NIC-based send BD rings are disabled. */
6870 if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { 6914 if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
@@ -6885,14 +6929,44 @@ static void tg3_rings_reset(struct tg3 *tp)
6885 tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW, 6929 tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW,
6886 ((u64) tnapi->status_mapping & 0xffffffff)); 6930 ((u64) tnapi->status_mapping & 0xffffffff));
6887 6931
6888 tg3_set_bdinfo(tp, txrcb, tnapi->tx_desc_mapping, 6932 if (tnapi->tx_ring) {
6889 (TG3_TX_RING_SIZE << 6933 tg3_set_bdinfo(tp, txrcb, tnapi->tx_desc_mapping,
6890 BDINFO_FLAGS_MAXLEN_SHIFT), 6934 (TG3_TX_RING_SIZE <<
6891 NIC_SRAM_TX_BUFFER_DESC); 6935 BDINFO_FLAGS_MAXLEN_SHIFT),
6936 NIC_SRAM_TX_BUFFER_DESC);
6937 txrcb += TG3_BDINFO_SIZE;
6938 }
6892 6939
6893 tg3_set_bdinfo(tp, rxrcb, tnapi->rx_rcb_mapping, 6940 if (tnapi->rx_rcb) {
6894 (TG3_RX_RCB_RING_SIZE(tp) << 6941 tg3_set_bdinfo(tp, rxrcb, tnapi->rx_rcb_mapping,
6895 BDINFO_FLAGS_MAXLEN_SHIFT), 0); 6942 (TG3_RX_RCB_RING_SIZE(tp) <<
6943 BDINFO_FLAGS_MAXLEN_SHIFT), 0);
6944 rxrcb += TG3_BDINFO_SIZE;
6945 }
6946
6947 stblk = HOSTCC_STATBLCK_RING1;
6948
6949 for (i = 1, tnapi++; i < tp->irq_cnt; i++, tnapi++) {
6950 u64 mapping = (u64)tnapi->status_mapping;
6951 tw32(stblk + TG3_64BIT_REG_HIGH, mapping >> 32);
6952 tw32(stblk + TG3_64BIT_REG_LOW, mapping & 0xffffffff);
6953
6954 /* Clear status block in ram. */
6955 memset(tnapi->hw_status, 0, TG3_HW_STATUS_SIZE);
6956
6957 tg3_set_bdinfo(tp, txrcb, tnapi->tx_desc_mapping,
6958 (TG3_TX_RING_SIZE <<
6959 BDINFO_FLAGS_MAXLEN_SHIFT),
6960 NIC_SRAM_TX_BUFFER_DESC);
6961
6962 tg3_set_bdinfo(tp, rxrcb, tnapi->rx_rcb_mapping,
6963 (TG3_RX_RCB_RING_SIZE(tp) <<
6964 BDINFO_FLAGS_MAXLEN_SHIFT), 0);
6965
6966 stblk += 8;
6967 txrcb += TG3_BDINFO_SIZE;
6968 rxrcb += TG3_BDINFO_SIZE;
6969 }
6896} 6970}
6897 6971
6898/* tp->lock is held. */ 6972/* tp->lock is held. */