diff options
author | Stephen Hemminger <shemminger@osdl.org> | 2006-09-26 14:57:43 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-09-27 17:56:31 -0400 |
commit | 14d0263fea0613d4f83dc5e3ad4631f363d1689f (patch) | |
tree | b8c9976416cb1c031f10de3ba4107b251f3b7850 /drivers | |
parent | 2bb8c26242c2393b097a993ffe9b003ec9b85395 (diff) |
[PATCH] sky2: fragmented receive for large MTU
Use hardware support for chained receive to break up large frames
into multiple pages. This avoids having to do a mult-page allocation
that can fail on a busy system due to fragmented memory.
For normal size MTU, this code behaves the same.
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/sky2.c | 290 | ||||
-rw-r--r-- | drivers/net/sky2.h | 10 |
2 files changed, 219 insertions, 81 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index c83d7262a5a8..7b19db598ff4 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -56,13 +56,12 @@ | |||
56 | /* | 56 | /* |
57 | * The Yukon II chipset takes 64 bit command blocks (called list elements) | 57 | * The Yukon II chipset takes 64 bit command blocks (called list elements) |
58 | * that are organized into three (receive, transmit, status) different rings | 58 | * that are organized into three (receive, transmit, status) different rings |
59 | * similar to Tigon3. A transmit can require several elements; | 59 | * similar to Tigon3. |
60 | * a receive requires one (or two if using 64 bit dma). | ||
61 | */ | 60 | */ |
62 | 61 | ||
63 | #define RX_LE_SIZE 512 | 62 | #define RX_LE_SIZE 1024 |
64 | #define RX_LE_BYTES (RX_LE_SIZE*sizeof(struct sky2_rx_le)) | 63 | #define RX_LE_BYTES (RX_LE_SIZE*sizeof(struct sky2_rx_le)) |
65 | #define RX_MAX_PENDING (RX_LE_SIZE/2 - 2) | 64 | #define RX_MAX_PENDING (RX_LE_SIZE/6 - 2) |
66 | #define RX_DEF_PENDING RX_MAX_PENDING | 65 | #define RX_DEF_PENDING RX_MAX_PENDING |
67 | #define RX_SKB_ALIGN 8 | 66 | #define RX_SKB_ALIGN 8 |
68 | #define RX_BUF_WRITE 16 | 67 | #define RX_BUF_WRITE 16 |
@@ -74,7 +73,6 @@ | |||
74 | 73 | ||
75 | #define STATUS_RING_SIZE 2048 /* 2 ports * (TX + 2*RX) */ | 74 | #define STATUS_RING_SIZE 2048 /* 2 ports * (TX + 2*RX) */ |
76 | #define STATUS_LE_BYTES (STATUS_RING_SIZE*sizeof(struct sky2_status_le)) | 75 | #define STATUS_LE_BYTES (STATUS_RING_SIZE*sizeof(struct sky2_status_le)) |
77 | #define ETH_JUMBO_MTU 9000 | ||
78 | #define TX_WATCHDOG (5 * HZ) | 76 | #define TX_WATCHDOG (5 * HZ) |
79 | #define NAPI_WEIGHT 64 | 77 | #define NAPI_WEIGHT 64 |
80 | #define PHY_RETRIES 1000 | 78 | #define PHY_RETRIES 1000 |
@@ -90,7 +88,7 @@ static int debug = -1; /* defaults above */ | |||
90 | module_param(debug, int, 0); | 88 | module_param(debug, int, 0); |
91 | MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); | 89 | MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); |
92 | 90 | ||
93 | static int copybreak __read_mostly = 256; | 91 | static int copybreak __read_mostly = 128; |
94 | module_param(copybreak, int, 0); | 92 | module_param(copybreak, int, 0); |
95 | MODULE_PARM_DESC(copybreak, "Receive copy threshold"); | 93 | MODULE_PARM_DESC(copybreak, "Receive copy threshold"); |
96 | 94 | ||
@@ -803,12 +801,12 @@ static inline u32 high32(dma_addr_t a) | |||
803 | return sizeof(a) > sizeof(u32) ? (a >> 16) >> 16 : 0; | 801 | return sizeof(a) > sizeof(u32) ? (a >> 16) >> 16 : 0; |
804 | } | 802 | } |
805 | 803 | ||
806 | /* Build description to hardware about buffer */ | 804 | /* Build description to hardware for one receive segment */ |
807 | static void sky2_rx_add(struct sky2_port *sky2, dma_addr_t map) | 805 | static void sky2_rx_add(struct sky2_port *sky2, u8 op, |
806 | dma_addr_t map, unsigned len) | ||
808 | { | 807 | { |
809 | struct sky2_rx_le *le; | 808 | struct sky2_rx_le *le; |
810 | u32 hi = high32(map); | 809 | u32 hi = high32(map); |
811 | u16 len = sky2->rx_bufsize; | ||
812 | 810 | ||
813 | if (sky2->rx_addr64 != hi) { | 811 | if (sky2->rx_addr64 != hi) { |
814 | le = sky2_next_rx(sky2); | 812 | le = sky2_next_rx(sky2); |
@@ -820,9 +818,52 @@ static void sky2_rx_add(struct sky2_port *sky2, dma_addr_t map) | |||
820 | le = sky2_next_rx(sky2); | 818 | le = sky2_next_rx(sky2); |
821 | le->addr = cpu_to_le32((u32) map); | 819 | le->addr = cpu_to_le32((u32) map); |
822 | le->length = cpu_to_le16(len); | 820 | le->length = cpu_to_le16(len); |
823 | le->opcode = OP_PACKET | HW_OWNER; | 821 | le->opcode = op | HW_OWNER; |
824 | } | 822 | } |
825 | 823 | ||
824 | /* Build description to hardware for one possibly fragmented skb */ | ||
825 | static void sky2_rx_submit(struct sky2_port *sky2, | ||
826 | const struct rx_ring_info *re) | ||
827 | { | ||
828 | int i; | ||
829 | |||
830 | sky2_rx_add(sky2, OP_PACKET, re->data_addr, sky2->rx_data_size); | ||
831 | |||
832 | for (i = 0; i < skb_shinfo(re->skb)->nr_frags; i++) | ||
833 | sky2_rx_add(sky2, OP_BUFFER, re->frag_addr[i], PAGE_SIZE); | ||
834 | } | ||
835 | |||
836 | |||
837 | static void sky2_rx_map_skb(struct pci_dev *pdev, struct rx_ring_info *re, | ||
838 | unsigned size) | ||
839 | { | ||
840 | struct sk_buff *skb = re->skb; | ||
841 | int i; | ||
842 | |||
843 | re->data_addr = pci_map_single(pdev, skb->data, size, PCI_DMA_FROMDEVICE); | ||
844 | pci_unmap_len_set(re, data_size, size); | ||
845 | |||
846 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) | ||
847 | re->frag_addr[i] = pci_map_page(pdev, | ||
848 | skb_shinfo(skb)->frags[i].page, | ||
849 | skb_shinfo(skb)->frags[i].page_offset, | ||
850 | skb_shinfo(skb)->frags[i].size, | ||
851 | PCI_DMA_FROMDEVICE); | ||
852 | } | ||
853 | |||
854 | static void sky2_rx_unmap_skb(struct pci_dev *pdev, struct rx_ring_info *re) | ||
855 | { | ||
856 | struct sk_buff *skb = re->skb; | ||
857 | int i; | ||
858 | |||
859 | pci_unmap_single(pdev, re->data_addr, pci_unmap_len(re, data_size), | ||
860 | PCI_DMA_FROMDEVICE); | ||
861 | |||
862 | for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) | ||
863 | pci_unmap_page(pdev, re->frag_addr[i], | ||
864 | skb_shinfo(skb)->frags[i].size, | ||
865 | PCI_DMA_FROMDEVICE); | ||
866 | } | ||
826 | 867 | ||
827 | /* Tell chip where to start receive checksum. | 868 | /* Tell chip where to start receive checksum. |
828 | * Actually has two checksums, but set both same to avoid possible byte | 869 | * Actually has two checksums, but set both same to avoid possible byte |
@@ -886,9 +927,7 @@ static void sky2_rx_clean(struct sky2_port *sky2) | |||
886 | struct rx_ring_info *re = sky2->rx_ring + i; | 927 | struct rx_ring_info *re = sky2->rx_ring + i; |
887 | 928 | ||
888 | if (re->skb) { | 929 | if (re->skb) { |
889 | pci_unmap_single(sky2->hw->pdev, | 930 | sky2_rx_unmap_skb(sky2->hw->pdev, re); |
890 | re->mapaddr, sky2->rx_bufsize, | ||
891 | PCI_DMA_FROMDEVICE); | ||
892 | kfree_skb(re->skb); | 931 | kfree_skb(re->skb); |
893 | re->skb = NULL; | 932 | re->skb = NULL; |
894 | } | 933 | } |
@@ -969,38 +1008,57 @@ static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) | |||
969 | #endif | 1008 | #endif |
970 | 1009 | ||
971 | /* | 1010 | /* |
1011 | * Allocate an skb for receiving. If the MTU is large enough | ||
1012 | * make the skb non-linear with a fragment list of pages. | ||
1013 | * | ||
972 | * It appears the hardware has a bug in the FIFO logic that | 1014 | * It appears the hardware has a bug in the FIFO logic that |
973 | * cause it to hang if the FIFO gets overrun and the receive buffer | 1015 | * cause it to hang if the FIFO gets overrun and the receive buffer |
974 | * is not 64 byte aligned. The buffer returned from netdev_alloc_skb is | 1016 | * is not 64 byte aligned. The buffer returned from netdev_alloc_skb is |
975 | * aligned except if slab debugging is enabled. | 1017 | * aligned except if slab debugging is enabled. |
976 | */ | 1018 | */ |
977 | static inline struct sk_buff *sky2_alloc_skb(struct net_device *dev, | 1019 | static struct sk_buff *sky2_rx_alloc(struct sky2_port *sky2) |
978 | unsigned int length, | ||
979 | gfp_t gfp_mask) | ||
980 | { | 1020 | { |
981 | struct sk_buff *skb; | 1021 | struct sk_buff *skb; |
1022 | unsigned long p; | ||
1023 | int i; | ||
982 | 1024 | ||
983 | skb = __netdev_alloc_skb(dev, length + RX_SKB_ALIGN, gfp_mask); | 1025 | skb = netdev_alloc_skb(sky2->netdev, sky2->rx_data_size + RX_SKB_ALIGN); |
984 | if (likely(skb)) { | 1026 | if (!skb) |
985 | unsigned long p = (unsigned long) skb->data; | 1027 | goto nomem; |
986 | skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p); | 1028 | |
1029 | p = (unsigned long) skb->data; | ||
1030 | skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p); | ||
1031 | |||
1032 | for (i = 0; i < sky2->rx_nfrags; i++) { | ||
1033 | struct page *page = alloc_page(GFP_ATOMIC); | ||
1034 | |||
1035 | if (!page) | ||
1036 | goto free_partial; | ||
1037 | skb_fill_page_desc(skb, i, page, 0, PAGE_SIZE); | ||
987 | } | 1038 | } |
988 | 1039 | ||
989 | return skb; | 1040 | return skb; |
1041 | free_partial: | ||
1042 | kfree_skb(skb); | ||
1043 | nomem: | ||
1044 | return NULL; | ||
990 | } | 1045 | } |
991 | 1046 | ||
992 | /* | 1047 | /* |
993 | * Allocate and setup receiver buffer pool. | 1048 | * Allocate and setup receiver buffer pool. |
994 | * In case of 64 bit dma, there are 2X as many list elements | 1049 | * Normal case this ends up creating one list element for skb |
995 | * available as ring entries | 1050 | * in the receive ring. Worst case if using large MTU and each |
996 | * and need to reserve one list element so we don't wrap around. | 1051 | * allocation falls on a different 64 bit region, that results |
1052 | * in 6 list elements per ring entry. | ||
1053 | * One element is used for checksum enable/disable, and one | ||
1054 | * extra to avoid wrap. | ||
997 | */ | 1055 | */ |
998 | static int sky2_rx_start(struct sky2_port *sky2) | 1056 | static int sky2_rx_start(struct sky2_port *sky2) |
999 | { | 1057 | { |
1000 | struct sky2_hw *hw = sky2->hw; | 1058 | struct sky2_hw *hw = sky2->hw; |
1059 | struct rx_ring_info *re; | ||
1001 | unsigned rxq = rxqaddr[sky2->port]; | 1060 | unsigned rxq = rxqaddr[sky2->port]; |
1002 | int i; | 1061 | unsigned i, size, space, thresh; |
1003 | unsigned thresh; | ||
1004 | 1062 | ||
1005 | sky2->rx_put = sky2->rx_next = 0; | 1063 | sky2->rx_put = sky2->rx_next = 0; |
1006 | sky2_qset(hw, rxq); | 1064 | sky2_qset(hw, rxq); |
@@ -1013,27 +1071,56 @@ static int sky2_rx_start(struct sky2_port *sky2) | |||
1013 | sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1); | 1071 | sky2_prefetch_init(hw, rxq, sky2->rx_le_map, RX_LE_SIZE - 1); |
1014 | 1072 | ||
1015 | rx_set_checksum(sky2); | 1073 | rx_set_checksum(sky2); |
1074 | |||
1075 | /* Space needed for frame data + headers rounded up */ | ||
1076 | size = ALIGN(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8) | ||
1077 | + 8; | ||
1078 | |||
1079 | /* Stopping point for hardware truncation */ | ||
1080 | thresh = (size - 8) / sizeof(u32); | ||
1081 | |||
1082 | /* Account for overhead of skb - to avoid order > 0 allocation */ | ||
1083 | space = SKB_DATA_ALIGN(size) + NET_SKB_PAD | ||
1084 | + sizeof(struct skb_shared_info); | ||
1085 | |||
1086 | sky2->rx_nfrags = space >> PAGE_SHIFT; | ||
1087 | BUG_ON(sky2->rx_nfrags > ARRAY_SIZE(re->frag_addr)); | ||
1088 | |||
1089 | if (sky2->rx_nfrags != 0) { | ||
1090 | /* Compute residue after pages */ | ||
1091 | space = sky2->rx_nfrags << PAGE_SHIFT; | ||
1092 | |||
1093 | if (space < size) | ||
1094 | size -= space; | ||
1095 | else | ||
1096 | size = 0; | ||
1097 | |||
1098 | /* Optimize to handle small packets and headers */ | ||
1099 | if (size < copybreak) | ||
1100 | size = copybreak; | ||
1101 | if (size < ETH_HLEN) | ||
1102 | size = ETH_HLEN; | ||
1103 | } | ||
1104 | sky2->rx_data_size = size; | ||
1105 | |||
1106 | /* Fill Rx ring */ | ||
1016 | for (i = 0; i < sky2->rx_pending; i++) { | 1107 | for (i = 0; i < sky2->rx_pending; i++) { |
1017 | struct rx_ring_info *re = sky2->rx_ring + i; | 1108 | re = sky2->rx_ring + i; |
1018 | 1109 | ||
1019 | re->skb = sky2_alloc_skb(sky2->netdev, sky2->rx_bufsize, | 1110 | re->skb = sky2_rx_alloc(sky2); |
1020 | GFP_KERNEL); | ||
1021 | if (!re->skb) | 1111 | if (!re->skb) |
1022 | goto nomem; | 1112 | goto nomem; |
1023 | 1113 | ||
1024 | re->mapaddr = pci_map_single(hw->pdev, re->skb->data, | 1114 | sky2_rx_map_skb(hw->pdev, re, sky2->rx_data_size); |
1025 | sky2->rx_bufsize, PCI_DMA_FROMDEVICE); | 1115 | sky2_rx_submit(sky2, re); |
1026 | sky2_rx_add(sky2, re->mapaddr); | ||
1027 | } | 1116 | } |
1028 | 1117 | ||
1029 | |||
1030 | /* | 1118 | /* |
1031 | * The receiver hangs if it receives frames larger than the | 1119 | * The receiver hangs if it receives frames larger than the |
1032 | * packet buffer. As a workaround, truncate oversize frames, but | 1120 | * packet buffer. As a workaround, truncate oversize frames, but |
1033 | * the register is limited to 9 bits, so if you do frames > 2052 | 1121 | * the register is limited to 9 bits, so if you do frames > 2052 |
1034 | * you better get the MTU right! | 1122 | * you better get the MTU right! |
1035 | */ | 1123 | */ |
1036 | thresh = (sky2->rx_bufsize - 8) / sizeof(u32); | ||
1037 | if (thresh > 0x1ff) | 1124 | if (thresh > 0x1ff) |
1038 | sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_OFF); | 1125 | sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_OFF); |
1039 | else { | 1126 | else { |
@@ -1041,7 +1128,6 @@ static int sky2_rx_start(struct sky2_port *sky2) | |||
1041 | sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_ON); | 1128 | sky2_write32(hw, SK_REG(sky2->port, RX_GMF_CTRL_T), RX_TRUNC_ON); |
1042 | } | 1129 | } |
1043 | 1130 | ||
1044 | |||
1045 | /* Tell chip about available buffers */ | 1131 | /* Tell chip about available buffers */ |
1046 | sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put); | 1132 | sky2_write16(hw, Y2_QADDR(rxq, PREF_UNIT_PUT_IDX), sky2->rx_put); |
1047 | return 0; | 1133 | return 0; |
@@ -1743,15 +1829,6 @@ static void sky2_tx_timeout(struct net_device *dev) | |||
1743 | } | 1829 | } |
1744 | } | 1830 | } |
1745 | 1831 | ||
1746 | |||
1747 | /* Want receive buffer size to be multiple of 64 bits | ||
1748 | * and incl room for vlan and truncation | ||
1749 | */ | ||
1750 | static inline unsigned sky2_buf_size(int mtu) | ||
1751 | { | ||
1752 | return ALIGN(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8; | ||
1753 | } | ||
1754 | |||
1755 | static int sky2_change_mtu(struct net_device *dev, int new_mtu) | 1832 | static int sky2_change_mtu(struct net_device *dev, int new_mtu) |
1756 | { | 1833 | { |
1757 | struct sky2_port *sky2 = netdev_priv(dev); | 1834 | struct sky2_port *sky2 = netdev_priv(dev); |
@@ -1786,7 +1863,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) | |||
1786 | sky2_rx_clean(sky2); | 1863 | sky2_rx_clean(sky2); |
1787 | 1864 | ||
1788 | dev->mtu = new_mtu; | 1865 | dev->mtu = new_mtu; |
1789 | sky2->rx_bufsize = sky2_buf_size(new_mtu); | 1866 | |
1790 | mode = DATA_BLIND_VAL(DATA_BLIND_DEF) | | 1867 | mode = DATA_BLIND_VAL(DATA_BLIND_DEF) | |
1791 | GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF); | 1868 | GM_SMOD_VLAN_ENA | IPG_DATA_VAL(IPG_DATA_DEF); |
1792 | 1869 | ||
@@ -1812,9 +1889,93 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) | |||
1812 | return err; | 1889 | return err; |
1813 | } | 1890 | } |
1814 | 1891 | ||
1892 | /* For small just reuse existing skb for next receive */ | ||
1893 | static struct sk_buff *receive_copy(struct sky2_port *sky2, | ||
1894 | const struct rx_ring_info *re, | ||
1895 | unsigned length) | ||
1896 | { | ||
1897 | struct sk_buff *skb; | ||
1898 | |||
1899 | skb = netdev_alloc_skb(sky2->netdev, length + 2); | ||
1900 | if (likely(skb)) { | ||
1901 | skb_reserve(skb, 2); | ||
1902 | pci_dma_sync_single_for_cpu(sky2->hw->pdev, re->data_addr, | ||
1903 | length, PCI_DMA_FROMDEVICE); | ||
1904 | memcpy(skb->data, re->skb->data, length); | ||
1905 | skb->ip_summed = re->skb->ip_summed; | ||
1906 | skb->csum = re->skb->csum; | ||
1907 | pci_dma_sync_single_for_device(sky2->hw->pdev, re->data_addr, | ||
1908 | length, PCI_DMA_FROMDEVICE); | ||
1909 | re->skb->ip_summed = CHECKSUM_NONE; | ||
1910 | __skb_put(skb, length); | ||
1911 | } | ||
1912 | return skb; | ||
1913 | } | ||
1914 | |||
1915 | /* Adjust length of skb with fragments to match received data */ | ||
1916 | static void skb_put_frags(struct sk_buff *skb, unsigned int hdr_space, | ||
1917 | unsigned int length) | ||
1918 | { | ||
1919 | int i, num_frags; | ||
1920 | unsigned int size; | ||
1921 | |||
1922 | /* put header into skb */ | ||
1923 | size = min(length, hdr_space); | ||
1924 | skb->tail += size; | ||
1925 | skb->len += size; | ||
1926 | length -= size; | ||
1927 | |||
1928 | num_frags = skb_shinfo(skb)->nr_frags; | ||
1929 | for (i = 0; i < num_frags; i++) { | ||
1930 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; | ||
1931 | |||
1932 | if (length == 0) { | ||
1933 | /* don't need this page */ | ||
1934 | __free_page(frag->page); | ||
1935 | --skb_shinfo(skb)->nr_frags; | ||
1936 | } else { | ||
1937 | size = min(length, (unsigned) PAGE_SIZE); | ||
1938 | |||
1939 | frag->size = size; | ||
1940 | skb->data_len += size; | ||
1941 | skb->truesize += size; | ||
1942 | skb->len += size; | ||
1943 | length -= size; | ||
1944 | } | ||
1945 | } | ||
1946 | } | ||
1947 | |||
1948 | /* Normal packet - take skb from ring element and put in a new one */ | ||
1949 | static struct sk_buff *receive_new(struct sky2_port *sky2, | ||
1950 | struct rx_ring_info *re, | ||
1951 | unsigned int length) | ||
1952 | { | ||
1953 | struct sk_buff *skb, *nskb; | ||
1954 | unsigned hdr_space = sky2->rx_data_size; | ||
1955 | |||
1956 | pr_debug(PFX "receive new length=%d\n", length); | ||
1957 | |||
1958 | /* Don't be tricky about reusing pages (yet) */ | ||
1959 | nskb = sky2_rx_alloc(sky2); | ||
1960 | if (unlikely(!nskb)) | ||
1961 | return NULL; | ||
1962 | |||
1963 | skb = re->skb; | ||
1964 | sky2_rx_unmap_skb(sky2->hw->pdev, re); | ||
1965 | |||
1966 | prefetch(skb->data); | ||
1967 | re->skb = nskb; | ||
1968 | sky2_rx_map_skb(sky2->hw->pdev, re, hdr_space); | ||
1969 | |||
1970 | if (skb_shinfo(skb)->nr_frags) | ||
1971 | skb_put_frags(skb, hdr_space, length); | ||
1972 | else | ||
1973 | skb_put(skb, hdr_space); | ||
1974 | return skb; | ||
1975 | } | ||
1976 | |||
1815 | /* | 1977 | /* |
1816 | * Receive one packet. | 1978 | * Receive one packet. |
1817 | * For small packets or errors, just reuse existing skb. | ||
1818 | * For larger packets, get new buffer. | 1979 | * For larger packets, get new buffer. |
1819 | */ | 1980 | */ |
1820 | static struct sk_buff *sky2_receive(struct net_device *dev, | 1981 | static struct sk_buff *sky2_receive(struct net_device *dev, |
@@ -1840,40 +2001,12 @@ static struct sk_buff *sky2_receive(struct net_device *dev, | |||
1840 | if (length > dev->mtu + ETH_HLEN) | 2001 | if (length > dev->mtu + ETH_HLEN) |
1841 | goto oversize; | 2002 | goto oversize; |
1842 | 2003 | ||
1843 | if (length < copybreak) { | 2004 | if (length < copybreak) |
1844 | skb = netdev_alloc_skb(dev, length + 2); | 2005 | skb = receive_copy(sky2, re, length); |
1845 | if (!skb) | 2006 | else |
1846 | goto resubmit; | 2007 | skb = receive_new(sky2, re, length); |
1847 | |||
1848 | skb_reserve(skb, 2); | ||
1849 | pci_dma_sync_single_for_cpu(sky2->hw->pdev, re->mapaddr, | ||
1850 | length, PCI_DMA_FROMDEVICE); | ||
1851 | memcpy(skb->data, re->skb->data, length); | ||
1852 | skb->ip_summed = re->skb->ip_summed; | ||
1853 | skb->csum = re->skb->csum; | ||
1854 | pci_dma_sync_single_for_device(sky2->hw->pdev, re->mapaddr, | ||
1855 | length, PCI_DMA_FROMDEVICE); | ||
1856 | } else { | ||
1857 | struct sk_buff *nskb; | ||
1858 | |||
1859 | nskb = sky2_alloc_skb(dev, sky2->rx_bufsize, GFP_ATOMIC); | ||
1860 | if (!nskb) | ||
1861 | goto resubmit; | ||
1862 | |||
1863 | skb = re->skb; | ||
1864 | re->skb = nskb; | ||
1865 | pci_unmap_single(sky2->hw->pdev, re->mapaddr, | ||
1866 | sky2->rx_bufsize, PCI_DMA_FROMDEVICE); | ||
1867 | prefetch(skb->data); | ||
1868 | |||
1869 | re->mapaddr = pci_map_single(sky2->hw->pdev, nskb->data, | ||
1870 | sky2->rx_bufsize, PCI_DMA_FROMDEVICE); | ||
1871 | } | ||
1872 | |||
1873 | skb_put(skb, length); | ||
1874 | resubmit: | 2008 | resubmit: |
1875 | re->skb->ip_summed = CHECKSUM_NONE; | 2009 | sky2_rx_submit(sky2, re); |
1876 | sky2_rx_add(sky2, re->mapaddr); | ||
1877 | 2010 | ||
1878 | return skb; | 2011 | return skb; |
1879 | 2012 | ||
@@ -3125,7 +3258,6 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, | |||
3125 | spin_lock_init(&sky2->phy_lock); | 3258 | spin_lock_init(&sky2->phy_lock); |
3126 | sky2->tx_pending = TX_DEF_PENDING; | 3259 | sky2->tx_pending = TX_DEF_PENDING; |
3127 | sky2->rx_pending = RX_DEF_PENDING; | 3260 | sky2->rx_pending = RX_DEF_PENDING; |
3128 | sky2->rx_bufsize = sky2_buf_size(ETH_DATA_LEN); | ||
3129 | 3261 | ||
3130 | hw->dev[port] = dev; | 3262 | hw->dev[port] = dev; |
3131 | 3263 | ||
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 403486a3831d..f66109a96d95 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h | |||
@@ -4,6 +4,8 @@ | |||
4 | #ifndef _SKY2_H | 4 | #ifndef _SKY2_H |
5 | #define _SKY2_H | 5 | #define _SKY2_H |
6 | 6 | ||
7 | #define ETH_JUMBO_MTU 9000 /* Maximum MTU supported */ | ||
8 | |||
7 | /* PCI device specific config registers */ | 9 | /* PCI device specific config registers */ |
8 | enum { | 10 | enum { |
9 | PCI_DEV_REG1 = 0x40, | 11 | PCI_DEV_REG1 = 0x40, |
@@ -1779,7 +1781,9 @@ struct tx_ring_info { | |||
1779 | 1781 | ||
1780 | struct rx_ring_info { | 1782 | struct rx_ring_info { |
1781 | struct sk_buff *skb; | 1783 | struct sk_buff *skb; |
1782 | dma_addr_t mapaddr; | 1784 | dma_addr_t data_addr; |
1785 | DECLARE_PCI_UNMAP_ADDR(data_size); | ||
1786 | dma_addr_t frag_addr[ETH_JUMBO_MTU >> PAGE_SHIFT]; | ||
1783 | }; | 1787 | }; |
1784 | 1788 | ||
1785 | struct sky2_port { | 1789 | struct sky2_port { |
@@ -1804,7 +1808,9 @@ struct sky2_port { | |||
1804 | u16 rx_next; /* next re to check */ | 1808 | u16 rx_next; /* next re to check */ |
1805 | u16 rx_put; /* next le index to use */ | 1809 | u16 rx_put; /* next le index to use */ |
1806 | u16 rx_pending; | 1810 | u16 rx_pending; |
1807 | u16 rx_bufsize; | 1811 | u16 rx_data_size; |
1812 | u16 rx_nfrags; | ||
1813 | |||
1808 | #ifdef SKY2_VLAN_TAG_USED | 1814 | #ifdef SKY2_VLAN_TAG_USED |
1809 | u16 rx_tag; | 1815 | u16 rx_tag; |
1810 | struct vlan_group *vlgrp; | 1816 | struct vlan_group *vlgrp; |