aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2005-12-09 14:35:01 -0500
committerJeff Garzik <jgarzik@pobox.com>2005-12-12 15:27:20 -0500
commit6cdbbdf3055f4657c9d6ccc79257bbcac1a9a1fc (patch)
treec3910bd44972cb55e29a112fa932a35b17910373 /drivers/net
parent734d18684695dd1c6a9527b50e01bba4acab4738 (diff)
[PATCH] sky2: tx/rx ring data structure split
Split Tx and Rx ring into two different data structures. Tx needs the next value (to handle partial status), and Rx always needs the mapaddr (to handle resubmitting same buffer). Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/sky2.c24
-rw-r--r--drivers/net/sky2.h9
2 files changed, 20 insertions, 13 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index b1a5886a48a0..1eefacbfcd2e 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -958,7 +958,7 @@ static int sky2_up(struct net_device *dev)
958 if (!sky2->tx_le) 958 if (!sky2->tx_le)
959 goto err_out; 959 goto err_out;
960 960
961 sky2->tx_ring = kzalloc(TX_RING_SIZE * sizeof(struct ring_info), 961 sky2->tx_ring = kcalloc(TX_RING_SIZE, sizeof(struct tx_ring_info),
962 GFP_KERNEL); 962 GFP_KERNEL);
963 if (!sky2->tx_ring) 963 if (!sky2->tx_ring)
964 goto err_out; 964 goto err_out;
@@ -970,7 +970,7 @@ static int sky2_up(struct net_device *dev)
970 goto err_out; 970 goto err_out;
971 memset(sky2->rx_le, 0, RX_LE_BYTES); 971 memset(sky2->rx_le, 0, RX_LE_BYTES);
972 972
973 sky2->rx_ring = kzalloc(sky2->rx_pending * sizeof(struct ring_info), 973 sky2->rx_ring = kcalloc(sky2->rx_pending, sizeof(struct ring_info),
974 GFP_KERNEL); 974 GFP_KERNEL);
975 if (!sky2->rx_ring) 975 if (!sky2->rx_ring)
976 goto err_out; 976 goto err_out;
@@ -1070,7 +1070,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1070 struct sky2_port *sky2 = netdev_priv(dev); 1070 struct sky2_port *sky2 = netdev_priv(dev);
1071 struct sky2_hw *hw = sky2->hw; 1071 struct sky2_hw *hw = sky2->hw;
1072 struct sky2_tx_le *le = NULL; 1072 struct sky2_tx_le *le = NULL;
1073 struct ring_info *re; 1073 struct tx_ring_info *re;
1074 unsigned i, len; 1074 unsigned i, len;
1075 dma_addr_t mapping; 1075 dma_addr_t mapping;
1076 u32 addr64; 1076 u32 addr64;
@@ -1173,11 +1173,11 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1173 1173
1174 /* Record the transmit mapping info */ 1174 /* Record the transmit mapping info */
1175 re->skb = skb; 1175 re->skb = skb;
1176 re->mapaddr = mapping; 1176 pci_unmap_addr_set(re, mapaddr, mapping);
1177 1177
1178 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 1178 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
1179 skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 1179 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
1180 struct ring_info *fre; 1180 struct tx_ring_info *fre;
1181 1181
1182 mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset, 1182 mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset,
1183 frag->size, PCI_DMA_TODEVICE); 1183 frag->size, PCI_DMA_TODEVICE);
@@ -1198,9 +1198,9 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1198 1198
1199 fre = sky2->tx_ring 1199 fre = sky2->tx_ring
1200 + ((re - sky2->tx_ring) + i + 1) % TX_RING_SIZE; 1200 + ((re - sky2->tx_ring) + i + 1) % TX_RING_SIZE;
1201 fre->skb = NULL; 1201 pci_unmap_addr_set(fre, mapaddr, mapping);
1202 fre->mapaddr = mapping;
1203 } 1202 }
1203
1204 re->idx = sky2->tx_prod; 1204 re->idx = sky2->tx_prod;
1205 le->ctrl |= EOP; 1205 le->ctrl |= EOP;
1206 1206
@@ -1239,7 +1239,7 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
1239 spin_lock(&sky2->tx_lock); 1239 spin_lock(&sky2->tx_lock);
1240 1240
1241 while (sky2->tx_cons != done) { 1241 while (sky2->tx_cons != done) {
1242 struct ring_info *re = sky2->tx_ring + sky2->tx_cons; 1242 struct tx_ring_info *re = sky2->tx_ring + sky2->tx_cons;
1243 struct sk_buff *skb; 1243 struct sk_buff *skb;
1244 1244
1245 /* Check for partial status */ 1245 /* Check for partial status */
@@ -1248,15 +1248,17 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
1248 goto out; 1248 goto out;
1249 1249
1250 skb = re->skb; 1250 skb = re->skb;
1251 pci_unmap_single(sky2->hw->pdev, re->mapaddr, 1251 pci_unmap_single(sky2->hw->pdev,
1252 pci_unmap_addr(re, mapaddr),
1252 skb_headlen(skb), PCI_DMA_TODEVICE); 1253 skb_headlen(skb), PCI_DMA_TODEVICE);
1253 1254
1254 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 1255 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
1255 struct ring_info *fre; 1256 struct tx_ring_info *fre;
1256 fre = 1257 fre =
1257 sky2->tx_ring + (sky2->tx_cons + i + 1258 sky2->tx_ring + (sky2->tx_cons + i +
1258 1) % TX_RING_SIZE; 1259 1) % TX_RING_SIZE;
1259 pci_unmap_page(sky2->hw->pdev, fre->mapaddr, 1260 pci_unmap_page(sky2->hw->pdev,
1261 pci_unmap_addr(fre, mapaddr),
1260 skb_shinfo(skb)->frags[i].size, 1262 skb_shinfo(skb)->frags[i].size,
1261 PCI_DMA_TODEVICE); 1263 PCI_DMA_TODEVICE);
1262 } 1264 }
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 1a91c2d4561c..95518921001c 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -1777,10 +1777,15 @@ struct sky2_status_le {
1777 u8 opcode; 1777 u8 opcode;
1778} __attribute((packed)); 1778} __attribute((packed));
1779 1779
1780struct tx_ring_info {
1781 struct sk_buff *skb;
1782 DECLARE_PCI_UNMAP_ADDR(mapaddr);
1783 u16 idx;
1784};
1785
1780struct ring_info { 1786struct ring_info {
1781 struct sk_buff *skb; 1787 struct sk_buff *skb;
1782 dma_addr_t mapaddr; 1788 dma_addr_t mapaddr;
1783 u16 idx;
1784}; 1789};
1785 1790
1786struct sky2_port { 1791struct sky2_port {
@@ -1790,7 +1795,7 @@ struct sky2_port {
1790 u32 msg_enable; 1795 u32 msg_enable;
1791 1796
1792 spinlock_t tx_lock ____cacheline_aligned_in_smp; 1797 spinlock_t tx_lock ____cacheline_aligned_in_smp;
1793 struct ring_info *tx_ring; 1798 struct tx_ring_info *tx_ring;
1794 struct sky2_tx_le *tx_le; 1799 struct sky2_tx_le *tx_le;
1795 u16 tx_cons; /* next le to check */ 1800 u16 tx_cons; /* next le to check */
1796 u16 tx_prod; /* next le to use */ 1801 u16 tx_prod; /* next le to use */