diff options
author | Stephen Hemminger <shemminger@osdl.org> | 2005-12-09 14:35:00 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-12-12 15:27:20 -0500 |
commit | 734d18684695dd1c6a9527b50e01bba4acab4738 (patch) | |
tree | a080ae5a4e4c6fe3a7ee5897b1e5a01c726267d4 /drivers/net/sky2.c | |
parent | 129372d0524c9124d5693f63c1d3c1ce2e3714ce (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.c | 57 |
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 */ |
732 | static inline void sky2_rx_add(struct sky2_port *sky2, struct ring_info *re) | 732 | static 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)) | ||
899 | static 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) | |||
915 | static int sky2_rx_start(struct sky2_port *sky2) | 909 | static 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 */ | ||
1576 | static inline unsigned sky2_buf_size(int mtu) | ||
1577 | { | ||
1578 | return roundup(mtu + ETH_HLEN + 4, 8); | ||
1579 | } | ||
1580 | |||
1582 | static int sky2_change_mtu(struct net_device *dev, int new_mtu) | 1581 | static 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); |
1688 | resubmit: | 1686 | resubmit: |
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 | ||