diff options
-rw-r--r-- | drivers/net/tg3.c | 242 | ||||
-rw-r--r-- | drivers/net/tg3.h | 3 |
2 files changed, 160 insertions, 85 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 | */ |
5723 | static void tg3_free_rings(struct tg3 *tp) | 5723 | static 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 | */ |
5759 | static int tg3_init_rings(struct tg3 *tp) | 5762 | static 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 | */ |
5779 | static void tg3_free_consistent(struct tg3 *tp) | 5793 | static 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 | */ |
5813 | static int tg3_alloc_consistent(struct tg3 *tp) | 5837 | static 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 | |||
5910 | static int tg3_abort_hw(struct tg3 *tp, int silent) | 5939 | static 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) | |||
6829 | static void tg3_rings_reset(struct tg3 *tp) | 6863 | static 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. */ |
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 65bbd773606f..6452d48201e4 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h | |||
@@ -1117,7 +1117,8 @@ | |||
1117 | #define HOSTCC_SND_CON_IDX_13 0x00003cf4 | 1117 | #define HOSTCC_SND_CON_IDX_13 0x00003cf4 |
1118 | #define HOSTCC_SND_CON_IDX_14 0x00003cf8 | 1118 | #define HOSTCC_SND_CON_IDX_14 0x00003cf8 |
1119 | #define HOSTCC_SND_CON_IDX_15 0x00003cfc | 1119 | #define HOSTCC_SND_CON_IDX_15 0x00003cfc |
1120 | /* 0x3d00 --> 0x4000 unused */ | 1120 | #define HOSTCC_STATBLCK_RING1 0x00003d00 |
1121 | /* 0x3d04 --> 0x4000 unused */ | ||
1121 | 1122 | ||
1122 | /* Memory arbiter control registers */ | 1123 | /* Memory arbiter control registers */ |
1123 | #define MEMARB_MODE 0x00004000 | 1124 | #define MEMARB_MODE 0x00004000 |