aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sky2.c
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2005-12-09 14:35:00 -0500
committerJeff Garzik <jgarzik@pobox.com>2005-12-12 15:27:20 -0500
commit734d18684695dd1c6a9527b50e01bba4acab4738 (patch)
treea080ae5a4e4c6fe3a7ee5897b1e5a01c726267d4 /drivers/net/sky2.c
parent129372d0524c9124d5693f63c1d3c1ce2e3714ce (diff)
[PATCH] sky2: map length optimization
Don't need to keep track of mapping length in ring structure because we can get the same info from other info. Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r--drivers/net/sky2.c57
1 files changed, 28 insertions, 29 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 2dd46a05fb30..b1a5886a48a0 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -729,23 +729,23 @@ static inline u32 high32(dma_addr_t a)
729} 729}
730 730
731/* Build description to hardware about buffer */ 731/* Build description to hardware about buffer */
732static inline void sky2_rx_add(struct sky2_port *sky2, struct ring_info *re) 732static inline void sky2_rx_add(struct sky2_port *sky2, dma_addr_t map)
733{ 733{
734 struct sky2_rx_le *le; 734 struct sky2_rx_le *le;
735 u32 hi = high32(re->mapaddr); 735 u32 hi = high32(map);
736 u16 len = sky2->rx_bufsize;
736 737
737 re->idx = sky2->rx_put;
738 if (sky2->rx_addr64 != hi) { 738 if (sky2->rx_addr64 != hi) {
739 le = sky2_next_rx(sky2); 739 le = sky2_next_rx(sky2);
740 le->addr = cpu_to_le32(hi); 740 le->addr = cpu_to_le32(hi);
741 le->ctrl = 0; 741 le->ctrl = 0;
742 le->opcode = OP_ADDR64 | HW_OWNER; 742 le->opcode = OP_ADDR64 | HW_OWNER;
743 sky2->rx_addr64 = high32(re->mapaddr + re->maplen); 743 sky2->rx_addr64 = high32(map + len);
744 } 744 }
745 745
746 le = sky2_next_rx(sky2); 746 le = sky2_next_rx(sky2);
747 le->addr = cpu_to_le32((u32) re->mapaddr); 747 le->addr = cpu_to_le32((u32) map);
748 le->length = cpu_to_le16(re->maplen); 748 le->length = cpu_to_le16(len);
749 le->ctrl = 0; 749 le->ctrl = 0;
750 le->opcode = OP_PACKET | HW_OWNER; 750 le->opcode = OP_PACKET | HW_OWNER;
751} 751}
@@ -814,7 +814,7 @@ static void sky2_rx_clean(struct sky2_port *sky2)
814 814
815 if (re->skb) { 815 if (re->skb) {
816 pci_unmap_single(sky2->hw->pdev, 816 pci_unmap_single(sky2->hw->pdev,
817 re->mapaddr, re->maplen, 817 re->mapaddr, sky2->rx_bufsize,
818 PCI_DMA_FROMDEVICE); 818 PCI_DMA_FROMDEVICE);
819 kfree_skb(re->skb); 819 kfree_skb(re->skb);
820 re->skb = NULL; 820 re->skb = NULL;
@@ -895,12 +895,6 @@ static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
895} 895}
896#endif 896#endif
897 897
898#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
899static inline unsigned rx_size(const struct sky2_port *sky2)
900{
901 return roundup(sky2->netdev->mtu + ETH_HLEN + 4, 8);
902}
903
904/* 898/*
905 * Allocate and setup receiver buffer pool. 899 * Allocate and setup receiver buffer pool.
906 * In case of 64 bit dma, there are 2X as many list elements 900 * In case of 64 bit dma, there are 2X as many list elements
@@ -915,7 +909,6 @@ static inline unsigned rx_size(const struct sky2_port *sky2)
915static int sky2_rx_start(struct sky2_port *sky2) 909static int sky2_rx_start(struct sky2_port *sky2)
916{ 910{
917 struct sky2_hw *hw = sky2->hw; 911 struct sky2_hw *hw = sky2->hw;
918 unsigned size = rx_size(sky2);
919 unsigned rxq = rxqaddr[sky2->port]; 912 unsigned rxq = rxqaddr[sky2->port];
920 int i; 913 int i;
921 914
@@ -927,14 +920,13 @@ static int sky2_rx_start(struct sky2_port *sky2)
927 for (i = 0; i < sky2->rx_pending; i++) { 920 for (i = 0; i < sky2->rx_pending; i++) {
928 struct ring_info *re = sky2->rx_ring + i; 921 struct ring_info *re = sky2->rx_ring + i;
929 922
930 re->skb = dev_alloc_skb(size); 923 re->skb = dev_alloc_skb(sky2->rx_bufsize);
931 if (!re->skb) 924 if (!re->skb)
932 goto nomem; 925 goto nomem;
933 926
934 re->mapaddr = pci_map_single(hw->pdev, re->skb->data, 927 re->mapaddr = pci_map_single(hw->pdev, re->skb->data,
935 size, PCI_DMA_FROMDEVICE); 928 sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
936 re->maplen = size; 929 sky2_rx_add(sky2, re->mapaddr);
937 sky2_rx_add(sky2, re);
938 } 930 }
939 931
940 /* Tell chip about available buffers */ 932 /* Tell chip about available buffers */
@@ -1182,7 +1174,6 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1182 /* Record the transmit mapping info */ 1174 /* Record the transmit mapping info */
1183 re->skb = skb; 1175 re->skb = skb;
1184 re->mapaddr = mapping; 1176 re->mapaddr = mapping;
1185 re->maplen = len;
1186 1177
1187 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 1178 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
1188 skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 1179 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
@@ -1209,7 +1200,6 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
1209 + ((re - sky2->tx_ring) + i + 1) % TX_RING_SIZE; 1200 + ((re - sky2->tx_ring) + i + 1) % TX_RING_SIZE;
1210 fre->skb = NULL; 1201 fre->skb = NULL;
1211 fre->mapaddr = mapping; 1202 fre->mapaddr = mapping;
1212 fre->maplen = frag->size;
1213 } 1203 }
1214 re->idx = sky2->tx_prod; 1204 re->idx = sky2->tx_prod;
1215 le->ctrl |= EOP; 1205 le->ctrl |= EOP;
@@ -1258,8 +1248,8 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
1258 goto out; 1248 goto out;
1259 1249
1260 skb = re->skb; 1250 skb = re->skb;
1261 pci_unmap_single(sky2->hw->pdev, 1251 pci_unmap_single(sky2->hw->pdev, re->mapaddr,
1262 re->mapaddr, re->maplen, PCI_DMA_TODEVICE); 1252 skb_headlen(skb), PCI_DMA_TODEVICE);
1263 1253
1264 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { 1254 for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
1265 struct ring_info *fre; 1255 struct ring_info *fre;
@@ -1267,7 +1257,8 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
1267 sky2->tx_ring + (sky2->tx_cons + i + 1257 sky2->tx_ring + (sky2->tx_cons + i +
1268 1) % TX_RING_SIZE; 1258 1) % TX_RING_SIZE;
1269 pci_unmap_page(sky2->hw->pdev, fre->mapaddr, 1259 pci_unmap_page(sky2->hw->pdev, fre->mapaddr,
1270 fre->maplen, PCI_DMA_TODEVICE); 1260 skb_shinfo(skb)->frags[i].size,
1261 PCI_DMA_TODEVICE);
1271 } 1262 }
1272 1263
1273 dev_kfree_skb_any(skb); 1264 dev_kfree_skb_any(skb);
@@ -1579,6 +1570,14 @@ static void sky2_tx_timeout(struct net_device *dev)
1579 sky2_tx_clean(sky2); 1570 sky2_tx_clean(sky2);
1580} 1571}
1581 1572
1573
1574#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
1575/* Want receive buffer size to be multiple of 64 bits, and incl room for vlan */
1576static inline unsigned sky2_buf_size(int mtu)
1577{
1578 return roundup(mtu + ETH_HLEN + 4, 8);
1579}
1580
1582static int sky2_change_mtu(struct net_device *dev, int new_mtu) 1581static int sky2_change_mtu(struct net_device *dev, int new_mtu)
1583{ 1582{
1584 struct sky2_port *sky2 = netdev_priv(dev); 1583 struct sky2_port *sky2 = netdev_priv(dev);
@@ -1609,6 +1608,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
1609 sky2_rx_clean(sky2); 1608 sky2_rx_clean(sky2);
1610 1609
1611 dev->mtu = new_mtu; 1610 dev->mtu = new_mtu;
1611 sky2->rx_bufsize = sky2_buf_size(new_mtu);
1612 mode = DATA_BLIND_VAL(DATA_BLIND_DEF) | 1612 mode = DATA_BLIND_VAL(DATA_BLIND_DEF) |
1613 GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF); 1613 GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF);
1614 1614
@@ -1639,7 +1639,6 @@ static struct sk_buff *sky2_receive(struct sky2_port *sky2,
1639{ 1639{
1640 struct ring_info *re = sky2->rx_ring + sky2->rx_next; 1640 struct ring_info *re = sky2->rx_ring + sky2->rx_next;
1641 struct sk_buff *skb = NULL; 1641 struct sk_buff *skb = NULL;
1642 const unsigned int bufsize = rx_size(sky2);
1643 1642
1644 if (unlikely(netif_msg_rx_status(sky2))) 1643 if (unlikely(netif_msg_rx_status(sky2)))
1645 printk(KERN_DEBUG PFX "%s: rx slot %u status 0x%x len %d\n", 1644 printk(KERN_DEBUG PFX "%s: rx slot %u status 0x%x len %d\n",
@@ -1669,25 +1668,24 @@ static struct sk_buff *sky2_receive(struct sky2_port *sky2,
1669 } else { 1668 } else {
1670 struct sk_buff *nskb; 1669 struct sk_buff *nskb;
1671 1670
1672 nskb = dev_alloc_skb(bufsize); 1671 nskb = dev_alloc_skb(sky2->rx_bufsize);
1673 if (!nskb) 1672 if (!nskb)
1674 goto resubmit; 1673 goto resubmit;
1675 1674
1676 skb = re->skb; 1675 skb = re->skb;
1677 re->skb = nskb; 1676 re->skb = nskb;
1678 pci_unmap_single(sky2->hw->pdev, re->mapaddr, 1677 pci_unmap_single(sky2->hw->pdev, re->mapaddr,
1679 re->maplen, PCI_DMA_FROMDEVICE); 1678 sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
1680 prefetch(skb->data); 1679 prefetch(skb->data);
1681 1680
1682 re->mapaddr = pci_map_single(sky2->hw->pdev, nskb->data, 1681 re->mapaddr = pci_map_single(sky2->hw->pdev, nskb->data,
1683 bufsize, PCI_DMA_FROMDEVICE); 1682 sky2->rx_bufsize, PCI_DMA_FROMDEVICE);
1684 re->maplen = bufsize;
1685 } 1683 }
1686 1684
1687 skb_put(skb, length); 1685 skb_put(skb, length);
1688resubmit: 1686resubmit:
1689 re->skb->ip_summed = CHECKSUM_NONE; 1687 re->skb->ip_summed = CHECKSUM_NONE;
1690 sky2_rx_add(sky2, re); 1688 sky2_rx_add(sky2, re->mapaddr);
1691 1689
1692 /* Tell receiver about new buffers. */ 1690 /* Tell receiver about new buffers. */
1693 sky2_put_idx(sky2->hw, rxqaddr[sky2->port], sky2->rx_put, 1691 sky2_put_idx(sky2->hw, rxqaddr[sky2->port], sky2->rx_put,
@@ -2919,6 +2917,7 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
2919 init_MUTEX(&sky2->phy_sema); 2917 init_MUTEX(&sky2->phy_sema);
2920 sky2->tx_pending = TX_DEF_PENDING; 2918 sky2->tx_pending = TX_DEF_PENDING;
2921 sky2->rx_pending = is_ec_a1(hw) ? 8 : RX_DEF_PENDING; 2919 sky2->rx_pending = is_ec_a1(hw) ? 8 : RX_DEF_PENDING;
2920 sky2->rx_bufsize = sky2_buf_size(ETH_DATA_LEN);
2922 2921
2923 hw->dev[port] = dev; 2922 hw->dev[port] = dev;
2924 2923