aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorBrice Goglin <brice@myri.com>2006-12-11 05:26:12 -0500
committerJeff Garzik <jeff@garzik.org>2006-12-11 09:54:06 -0500
commit52ea6fb39b6fd08ec8718b92cddb3fed2165a921 (patch)
tree7faa596e413510b1f6a84e683ac77e8e2bbdf395 /drivers/net
parentc7dab99b080accb2751c96bf66cd5ab12c78f8e4 (diff)
[PATCH] myri10ge: drop contiguous skb routines
Drop the old routines that used the physically contigous skb now that we use the physical pages. And rename myri10ge_page_rx_done() to myri10ge_rx_done() as it was previously. Signed-off-by: Brice Goglin <brice@myri.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/myri10ge/myri10ge.c212
1 files changed, 8 insertions, 204 deletions
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 4d2be9c59164..711a8bf08fac 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -97,7 +97,6 @@ MODULE_LICENSE("Dual BSD/GPL");
97#define MYRI10GE_MAX_FRAGS_PER_FRAME (MYRI10GE_MAX_ETHER_MTU/MYRI10GE_ALLOC_SIZE + 1) 97#define MYRI10GE_MAX_FRAGS_PER_FRAME (MYRI10GE_MAX_ETHER_MTU/MYRI10GE_ALLOC_SIZE + 1)
98 98
99struct myri10ge_rx_buffer_state { 99struct myri10ge_rx_buffer_state {
100 struct sk_buff *skb;
101 struct page *page; 100 struct page *page;
102 int page_offset; 101 int page_offset;
103 DECLARE_PCI_UNMAP_ADDR(bus) 102 DECLARE_PCI_UNMAP_ADDR(bus)
@@ -250,11 +249,6 @@ module_param(myri10ge_force_firmware, int, S_IRUGO);
250MODULE_PARM_DESC(myri10ge_force_firmware, 249MODULE_PARM_DESC(myri10ge_force_firmware,
251 "Force firmware to assume aligned completions\n"); 250 "Force firmware to assume aligned completions\n");
252 251
253static int myri10ge_skb_cross_4k = 0;
254module_param(myri10ge_skb_cross_4k, int, S_IRUGO | S_IWUSR);
255MODULE_PARM_DESC(myri10ge_skb_cross_4k,
256 "Can a small skb cross a 4KB boundary?\n");
257
258static int myri10ge_initial_mtu = MYRI10GE_MAX_ETHER_MTU - ETH_HLEN; 252static int myri10ge_initial_mtu = MYRI10GE_MAX_ETHER_MTU - ETH_HLEN;
259module_param(myri10ge_initial_mtu, int, S_IRUGO); 253module_param(myri10ge_initial_mtu, int, S_IRUGO);
260MODULE_PARM_DESC(myri10ge_initial_mtu, "Initial MTU\n"); 254MODULE_PARM_DESC(myri10ge_initial_mtu, "Initial MTU\n");
@@ -820,148 +814,6 @@ myri10ge_submit_8rx(struct mcp_kreq_ether_recv __iomem * dst,
820 mb(); 814 mb();
821} 815}
822 816
823/*
824 * Set of routines to get a new receive buffer. Any buffer which
825 * crosses a 4KB boundary must start on a 4KB boundary due to PCIe
826 * wdma restrictions. We also try to align any smaller allocation to
827 * at least a 16 byte boundary for efficiency. We assume the linux
828 * memory allocator works by powers of 2, and will not return memory
829 * smaller than 2KB which crosses a 4KB boundary. If it does, we fall
830 * back to allocating 2x as much space as required.
831 *
832 * We intend to replace large (>4KB) skb allocations by using
833 * pages directly and building a fraglist in the near future.
834 */
835
836static inline struct sk_buff *myri10ge_alloc_big(struct net_device *dev,
837 int bytes)
838{
839 struct sk_buff *skb;
840 unsigned long data, roundup;
841
842 skb = netdev_alloc_skb(dev, bytes + 4096 + MXGEFW_PAD);
843 if (skb == NULL)
844 return NULL;
845
846 /* Correct skb->truesize so that socket buffer
847 * accounting is not confused the rounding we must
848 * do to satisfy alignment constraints.
849 */
850 skb->truesize -= 4096;
851
852 data = (unsigned long)(skb->data);
853 roundup = (-data) & (4095);
854 skb_reserve(skb, roundup);
855 return skb;
856}
857
858/* Allocate 2x as much space as required and use whichever portion
859 * does not cross a 4KB boundary */
860static inline struct sk_buff *myri10ge_alloc_small_safe(struct net_device *dev,
861 unsigned int bytes)
862{
863 struct sk_buff *skb;
864 unsigned long data, boundary;
865
866 skb = netdev_alloc_skb(dev, 2 * (bytes + MXGEFW_PAD) - 1);
867 if (unlikely(skb == NULL))
868 return NULL;
869
870 /* Correct skb->truesize so that socket buffer
871 * accounting is not confused the rounding we must
872 * do to satisfy alignment constraints.
873 */
874 skb->truesize -= bytes + MXGEFW_PAD;
875
876 data = (unsigned long)(skb->data);
877 boundary = (data + 4095UL) & ~4095UL;
878 if ((boundary - data) >= (bytes + MXGEFW_PAD))
879 return skb;
880
881 skb_reserve(skb, boundary - data);
882 return skb;
883}
884
885/* Allocate just enough space, and verify that the allocated
886 * space does not cross a 4KB boundary */
887static inline struct sk_buff *myri10ge_alloc_small(struct net_device *dev,
888 int bytes)
889{
890 struct sk_buff *skb;
891 unsigned long roundup, data, end;
892
893 skb = netdev_alloc_skb(dev, bytes + 16 + MXGEFW_PAD);
894 if (unlikely(skb == NULL))
895 return NULL;
896
897 /* Round allocated buffer to 16 byte boundary */
898 data = (unsigned long)(skb->data);
899 roundup = (-data) & 15UL;
900 skb_reserve(skb, roundup);
901 /* Verify that the data buffer does not cross a page boundary */
902 data = (unsigned long)(skb->data);
903 end = data + bytes + MXGEFW_PAD - 1;
904 if (unlikely(((end >> 12) != (data >> 12)) && (data & 4095UL))) {
905 printk(KERN_NOTICE
906 "myri10ge_alloc_small: small skb crossed 4KB boundary\n");
907 myri10ge_skb_cross_4k = 1;
908 dev_kfree_skb_any(skb);
909 skb = myri10ge_alloc_small_safe(dev, bytes);
910 }
911 return skb;
912}
913
914static inline int
915myri10ge_getbuf(struct myri10ge_rx_buf *rx, struct myri10ge_priv *mgp,
916 int bytes, int idx)
917{
918 struct net_device *dev = mgp->dev;
919 struct pci_dev *pdev = mgp->pdev;
920 struct sk_buff *skb;
921 dma_addr_t bus;
922 int len, retval = 0;
923
924 bytes += VLAN_HLEN; /* account for 802.1q vlan tag */
925
926 if ((bytes + MXGEFW_PAD) > (4096 - 16) /* linux overhead */ )
927 skb = myri10ge_alloc_big(dev, bytes);
928 else if (myri10ge_skb_cross_4k)
929 skb = myri10ge_alloc_small_safe(dev, bytes);
930 else
931 skb = myri10ge_alloc_small(dev, bytes);
932
933 if (unlikely(skb == NULL)) {
934 rx->alloc_fail++;
935 retval = -ENOBUFS;
936 goto done;
937 }
938
939 /* set len so that it only covers the area we
940 * need mapped for DMA */
941 len = bytes + MXGEFW_PAD;
942
943 bus = pci_map_single(pdev, skb->data, len, PCI_DMA_FROMDEVICE);
944 rx->info[idx].skb = skb;
945 pci_unmap_addr_set(&rx->info[idx], bus, bus);
946 pci_unmap_len_set(&rx->info[idx], len, len);
947 rx->shadow[idx].addr_low = htonl(MYRI10GE_LOWPART_TO_U32(bus));
948 rx->shadow[idx].addr_high = htonl(MYRI10GE_HIGHPART_TO_U32(bus));
949
950done:
951 /* copy 8 descriptors (64-bytes) to the mcp at a time */
952 if ((idx & 7) == 7) {
953 if (rx->wc_fifo == NULL)
954 myri10ge_submit_8rx(&rx->lanai[idx - 7],
955 &rx->shadow[idx - 7]);
956 else {
957 mb();
958 myri10ge_pio_copy(rx->wc_fifo,
959 &rx->shadow[idx - 7], 64);
960 }
961 }
962 return retval;
963}
964
965static inline void myri10ge_vlan_ip_csum(struct sk_buff *skb, __wsum hw_csum) 817static inline void myri10ge_vlan_ip_csum(struct sk_buff *skb, __wsum hw_csum)
966{ 818{
967 struct vlan_hdr *vh = (struct vlan_hdr *)(skb->data); 819 struct vlan_hdr *vh = (struct vlan_hdr *)(skb->data);
@@ -1084,8 +936,8 @@ myri10ge_unmap_rx_page(struct pci_dev *pdev,
1084 * page into an skb */ 936 * page into an skb */
1085 937
1086static inline int 938static inline int
1087myri10ge_page_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx, 939myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
1088 int bytes, int len, __wsum csum) 940 int bytes, int len, __wsum csum)
1089{ 941{
1090 struct sk_buff *skb; 942 struct sk_buff *skb;
1091 struct skb_frag_struct rx_frags[MYRI10GE_MAX_FRAGS_PER_FRAME]; 943 struct skb_frag_struct rx_frags[MYRI10GE_MAX_FRAGS_PER_FRAME];
@@ -1148,54 +1000,6 @@ myri10ge_page_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
1148 return 1; 1000 return 1;
1149} 1001}
1150 1002
1151static inline unsigned long
1152myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
1153 int bytes, int len, __wsum csum)
1154{
1155 dma_addr_t bus;
1156 struct sk_buff *skb;
1157 int idx, unmap_len;
1158
1159 idx = rx->cnt & rx->mask;
1160 rx->cnt++;
1161
1162 /* save a pointer to the received skb */
1163 skb = rx->info[idx].skb;
1164 bus = pci_unmap_addr(&rx->info[idx], bus);
1165 unmap_len = pci_unmap_len(&rx->info[idx], len);
1166
1167 /* try to replace the received skb */
1168 if (myri10ge_getbuf(rx, mgp, bytes, idx)) {
1169 /* drop the frame -- the old skbuf is re-cycled */
1170 mgp->stats.rx_dropped += 1;
1171 return 0;
1172 }
1173
1174 /* unmap the recvd skb */
1175 pci_unmap_single(mgp->pdev, bus, unmap_len, PCI_DMA_FROMDEVICE);
1176
1177 /* mcp implicitly skips 1st bytes so that packet is properly
1178 * aligned */
1179 skb_reserve(skb, MXGEFW_PAD);
1180
1181 /* set the length of the frame */
1182 skb_put(skb, len);
1183
1184 skb->protocol = eth_type_trans(skb, mgp->dev);
1185 if (mgp->csum_flag) {
1186 if ((skb->protocol == htons(ETH_P_IP)) ||
1187 (skb->protocol == htons(ETH_P_IPV6))) {
1188 skb->csum = csum;
1189 skb->ip_summed = CHECKSUM_COMPLETE;
1190 } else
1191 myri10ge_vlan_ip_csum(skb, csum);
1192 }
1193
1194 netif_receive_skb(skb);
1195 mgp->dev->last_rx = jiffies;
1196 return 1;
1197}
1198
1199static inline void myri10ge_tx_done(struct myri10ge_priv *mgp, int mcp_index) 1003static inline void myri10ge_tx_done(struct myri10ge_priv *mgp, int mcp_index)
1200{ 1004{
1201 struct pci_dev *pdev = mgp->pdev; 1005 struct pci_dev *pdev = mgp->pdev;
@@ -1264,13 +1068,13 @@ static inline void myri10ge_clean_rx_done(struct myri10ge_priv *mgp, int *limit)
1264 rx_done->entry[idx].length = 0; 1068 rx_done->entry[idx].length = 0;
1265 checksum = csum_unfold(rx_done->entry[idx].checksum); 1069 checksum = csum_unfold(rx_done->entry[idx].checksum);
1266 if (length <= mgp->small_bytes) 1070 if (length <= mgp->small_bytes)
1267 rx_ok = myri10ge_page_rx_done(mgp, &mgp->rx_small, 1071 rx_ok = myri10ge_rx_done(mgp, &mgp->rx_small,
1268 mgp->small_bytes, 1072 mgp->small_bytes,
1269 length, checksum); 1073 length, checksum);
1270 else 1074 else
1271 rx_ok = myri10ge_page_rx_done(mgp, &mgp->rx_big, 1075 rx_ok = myri10ge_rx_done(mgp, &mgp->rx_big,
1272 mgp->big_bytes, 1076 mgp->big_bytes,
1273 length, checksum); 1077 length, checksum);
1274 rx_packets += rx_ok; 1078 rx_packets += rx_ok;
1275 rx_bytes += rx_ok * (unsigned long)length; 1079 rx_bytes += rx_ok * (unsigned long)length;
1276 cnt++; 1080 cnt++;