diff options
author | Andrew Gallatin <gallatin@myri.com> | 2012-11-30 03:31:58 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-11-30 13:44:04 -0500 |
commit | 4ca3221fe4b6c4c6c77352672942e8afa57d55e5 (patch) | |
tree | 4ceb69490b19d256e8b760535f854701066f8e7a /drivers/net/ethernet/myricom/myri10ge | |
parent | ba57b6f20429028127618230b74d55e8eb9cfce3 (diff) |
myri10ge: Convert from LRO to GRO
Convert myri10ge from LRO to GRO, and simplify the driver by removing
various LRO-related code which is no longer needed including
ndo_fix_features op, custom skb building from frags, and LRO
header parsing.
Signed-off-by: Andrew Gallatin <gallatin@myri.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/myricom/myri10ge')
-rw-r--r-- | drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 236 |
1 files changed, 34 insertions, 202 deletions
diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c index 83516e3369c9..84207c04530f 100644 --- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c | |||
@@ -50,7 +50,6 @@ | |||
50 | #include <linux/etherdevice.h> | 50 | #include <linux/etherdevice.h> |
51 | #include <linux/if_ether.h> | 51 | #include <linux/if_ether.h> |
52 | #include <linux/if_vlan.h> | 52 | #include <linux/if_vlan.h> |
53 | #include <linux/inet_lro.h> | ||
54 | #include <linux/dca.h> | 53 | #include <linux/dca.h> |
55 | #include <linux/ip.h> | 54 | #include <linux/ip.h> |
56 | #include <linux/inet.h> | 55 | #include <linux/inet.h> |
@@ -96,8 +95,6 @@ MODULE_LICENSE("Dual BSD/GPL"); | |||
96 | 95 | ||
97 | #define MYRI10GE_EEPROM_STRINGS_SIZE 256 | 96 | #define MYRI10GE_EEPROM_STRINGS_SIZE 256 |
98 | #define MYRI10GE_MAX_SEND_DESC_TSO ((65536 / 2048) * 2) | 97 | #define MYRI10GE_MAX_SEND_DESC_TSO ((65536 / 2048) * 2) |
99 | #define MYRI10GE_MAX_LRO_DESCRIPTORS 8 | ||
100 | #define MYRI10GE_LRO_MAX_PKTS 64 | ||
101 | 98 | ||
102 | #define MYRI10GE_NO_CONFIRM_DATA htonl(0xffffffff) | 99 | #define MYRI10GE_NO_CONFIRM_DATA htonl(0xffffffff) |
103 | #define MYRI10GE_NO_RESPONSE_RESULT 0xffffffff | 100 | #define MYRI10GE_NO_RESPONSE_RESULT 0xffffffff |
@@ -165,8 +162,6 @@ struct myri10ge_rx_done { | |||
165 | dma_addr_t bus; | 162 | dma_addr_t bus; |
166 | int cnt; | 163 | int cnt; |
167 | int idx; | 164 | int idx; |
168 | struct net_lro_mgr lro_mgr; | ||
169 | struct net_lro_desc lro_desc[MYRI10GE_MAX_LRO_DESCRIPTORS]; | ||
170 | }; | 165 | }; |
171 | 166 | ||
172 | struct myri10ge_slice_netstats { | 167 | struct myri10ge_slice_netstats { |
@@ -338,11 +333,6 @@ static int myri10ge_debug = -1; /* defaults above */ | |||
338 | module_param(myri10ge_debug, int, 0); | 333 | module_param(myri10ge_debug, int, 0); |
339 | MODULE_PARM_DESC(myri10ge_debug, "Debug level (0=none,...,16=all)"); | 334 | MODULE_PARM_DESC(myri10ge_debug, "Debug level (0=none,...,16=all)"); |
340 | 335 | ||
341 | static int myri10ge_lro_max_pkts = MYRI10GE_LRO_MAX_PKTS; | ||
342 | module_param(myri10ge_lro_max_pkts, int, S_IRUGO); | ||
343 | MODULE_PARM_DESC(myri10ge_lro_max_pkts, | ||
344 | "Number of LRO packets to be aggregated"); | ||
345 | |||
346 | static int myri10ge_fill_thresh = 256; | 336 | static int myri10ge_fill_thresh = 256; |
347 | module_param(myri10ge_fill_thresh, int, S_IRUGO | S_IWUSR); | 337 | module_param(myri10ge_fill_thresh, int, S_IRUGO | S_IWUSR); |
348 | MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed"); | 338 | MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed"); |
@@ -1197,36 +1187,6 @@ static inline void myri10ge_vlan_ip_csum(struct sk_buff *skb, __wsum hw_csum) | |||
1197 | } | 1187 | } |
1198 | } | 1188 | } |
1199 | 1189 | ||
1200 | static inline void | ||
1201 | myri10ge_rx_skb_build(struct sk_buff *skb, u8 * va, | ||
1202 | struct skb_frag_struct *rx_frags, int len, int hlen) | ||
1203 | { | ||
1204 | struct skb_frag_struct *skb_frags; | ||
1205 | |||
1206 | skb->len = skb->data_len = len; | ||
1207 | /* attach the page(s) */ | ||
1208 | |||
1209 | skb_frags = skb_shinfo(skb)->frags; | ||
1210 | while (len > 0) { | ||
1211 | memcpy(skb_frags, rx_frags, sizeof(*skb_frags)); | ||
1212 | len -= skb_frag_size(rx_frags); | ||
1213 | skb_frags++; | ||
1214 | rx_frags++; | ||
1215 | skb_shinfo(skb)->nr_frags++; | ||
1216 | } | ||
1217 | |||
1218 | /* pskb_may_pull is not available in irq context, but | ||
1219 | * skb_pull() (for ether_pad and eth_type_trans()) requires | ||
1220 | * the beginning of the packet in skb_headlen(), move it | ||
1221 | * manually */ | ||
1222 | skb_copy_to_linear_data(skb, va, hlen); | ||
1223 | skb_shinfo(skb)->frags[0].page_offset += hlen; | ||
1224 | skb_frag_size_sub(&skb_shinfo(skb)->frags[0], hlen); | ||
1225 | skb->data_len -= hlen; | ||
1226 | skb->tail += hlen; | ||
1227 | skb_pull(skb, MXGEFW_PAD); | ||
1228 | } | ||
1229 | |||
1230 | static void | 1190 | static void |
1231 | myri10ge_alloc_rx_pages(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx, | 1191 | myri10ge_alloc_rx_pages(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx, |
1232 | int bytes, int watchdog) | 1192 | int bytes, int watchdog) |
@@ -1304,18 +1264,14 @@ myri10ge_unmap_rx_page(struct pci_dev *pdev, | |||
1304 | } | 1264 | } |
1305 | } | 1265 | } |
1306 | 1266 | ||
1307 | #define MYRI10GE_HLEN 64 /* The number of bytes to copy from a | ||
1308 | * page into an skb */ | ||
1309 | |||
1310 | static inline int | 1267 | static inline int |
1311 | myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum, | 1268 | myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum) |
1312 | bool lro_enabled) | ||
1313 | { | 1269 | { |
1314 | struct myri10ge_priv *mgp = ss->mgp; | 1270 | struct myri10ge_priv *mgp = ss->mgp; |
1315 | struct sk_buff *skb; | 1271 | struct sk_buff *skb; |
1316 | struct skb_frag_struct rx_frags[MYRI10GE_MAX_FRAGS_PER_FRAME]; | 1272 | struct skb_frag_struct *rx_frags; |
1317 | struct myri10ge_rx_buf *rx; | 1273 | struct myri10ge_rx_buf *rx; |
1318 | int i, idx, hlen, remainder, bytes; | 1274 | int i, idx, remainder, bytes; |
1319 | struct pci_dev *pdev = mgp->pdev; | 1275 | struct pci_dev *pdev = mgp->pdev; |
1320 | struct net_device *dev = mgp->dev; | 1276 | struct net_device *dev = mgp->dev; |
1321 | u8 *va; | 1277 | u8 *va; |
@@ -1332,67 +1288,47 @@ myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum, | |||
1332 | idx = rx->cnt & rx->mask; | 1288 | idx = rx->cnt & rx->mask; |
1333 | va = page_address(rx->info[idx].page) + rx->info[idx].page_offset; | 1289 | va = page_address(rx->info[idx].page) + rx->info[idx].page_offset; |
1334 | prefetch(va); | 1290 | prefetch(va); |
1291 | |||
1292 | skb = napi_get_frags(&ss->napi); | ||
1293 | if (unlikely(skb == NULL)) { | ||
1294 | ss->stats.rx_dropped++; | ||
1295 | for (i = 0, remainder = len; remainder > 0; i++) { | ||
1296 | myri10ge_unmap_rx_page(pdev, &rx->info[idx], bytes); | ||
1297 | put_page(rx->info[idx].page); | ||
1298 | rx->cnt++; | ||
1299 | idx = rx->cnt & rx->mask; | ||
1300 | remainder -= MYRI10GE_ALLOC_SIZE; | ||
1301 | } | ||
1302 | return 0; | ||
1303 | } | ||
1304 | rx_frags = skb_shinfo(skb)->frags; | ||
1335 | /* Fill skb_frag_struct(s) with data from our receive */ | 1305 | /* Fill skb_frag_struct(s) with data from our receive */ |
1336 | for (i = 0, remainder = len; remainder > 0; i++) { | 1306 | for (i = 0, remainder = len; remainder > 0; i++) { |
1337 | myri10ge_unmap_rx_page(pdev, &rx->info[idx], bytes); | 1307 | myri10ge_unmap_rx_page(pdev, &rx->info[idx], bytes); |
1338 | __skb_frag_set_page(&rx_frags[i], rx->info[idx].page); | 1308 | skb_fill_page_desc(skb, i, rx->info[idx].page, |
1339 | rx_frags[i].page_offset = rx->info[idx].page_offset; | 1309 | rx->info[idx].page_offset, |
1340 | if (remainder < MYRI10GE_ALLOC_SIZE) | 1310 | remainder < MYRI10GE_ALLOC_SIZE ? |
1341 | skb_frag_size_set(&rx_frags[i], remainder); | 1311 | remainder : MYRI10GE_ALLOC_SIZE); |
1342 | else | ||
1343 | skb_frag_size_set(&rx_frags[i], MYRI10GE_ALLOC_SIZE); | ||
1344 | rx->cnt++; | 1312 | rx->cnt++; |
1345 | idx = rx->cnt & rx->mask; | 1313 | idx = rx->cnt & rx->mask; |
1346 | remainder -= MYRI10GE_ALLOC_SIZE; | 1314 | remainder -= MYRI10GE_ALLOC_SIZE; |
1347 | } | 1315 | } |
1348 | 1316 | ||
1349 | if (lro_enabled) { | 1317 | /* remove padding */ |
1350 | rx_frags[0].page_offset += MXGEFW_PAD; | 1318 | rx_frags[0].page_offset += MXGEFW_PAD; |
1351 | skb_frag_size_sub(&rx_frags[0], MXGEFW_PAD); | 1319 | rx_frags[0].size -= MXGEFW_PAD; |
1352 | len -= MXGEFW_PAD; | 1320 | len -= MXGEFW_PAD; |
1353 | lro_receive_frags(&ss->rx_done.lro_mgr, rx_frags, | ||
1354 | /* opaque, will come back in get_frag_header */ | ||
1355 | len, len, | ||
1356 | (void *)(__force unsigned long)csum, csum); | ||
1357 | 1321 | ||
1358 | return 1; | 1322 | skb->len = len; |
1359 | } | 1323 | skb->data_len = len; |
1360 | 1324 | skb->truesize += len; | |
1361 | hlen = MYRI10GE_HLEN > len ? len : MYRI10GE_HLEN; | 1325 | if (dev->features & NETIF_F_RXCSUM) { |
1362 | 1326 | skb->ip_summed = CHECKSUM_COMPLETE; | |
1363 | /* allocate an skb to attach the page(s) to. This is done | 1327 | skb->csum = csum; |
1364 | * after trying LRO, so as to avoid skb allocation overheads */ | ||
1365 | |||
1366 | skb = netdev_alloc_skb(dev, MYRI10GE_HLEN + 16); | ||
1367 | if (unlikely(skb == NULL)) { | ||
1368 | ss->stats.rx_dropped++; | ||
1369 | do { | ||
1370 | i--; | ||
1371 | __skb_frag_unref(&rx_frags[i]); | ||
1372 | } while (i != 0); | ||
1373 | return 0; | ||
1374 | } | ||
1375 | |||
1376 | /* Attach the pages to the skb, and trim off any padding */ | ||
1377 | myri10ge_rx_skb_build(skb, va, rx_frags, len, hlen); | ||
1378 | if (skb_frag_size(&skb_shinfo(skb)->frags[0]) <= 0) { | ||
1379 | skb_frag_unref(skb, 0); | ||
1380 | skb_shinfo(skb)->nr_frags = 0; | ||
1381 | } else { | ||
1382 | skb->truesize += bytes * skb_shinfo(skb)->nr_frags; | ||
1383 | } | 1328 | } |
1384 | skb->protocol = eth_type_trans(skb, dev); | ||
1385 | skb_record_rx_queue(skb, ss - &mgp->ss[0]); | 1329 | skb_record_rx_queue(skb, ss - &mgp->ss[0]); |
1386 | 1330 | ||
1387 | if (dev->features & NETIF_F_RXCSUM) { | 1331 | napi_gro_frags(&ss->napi); |
1388 | if ((skb->protocol == htons(ETH_P_IP)) || | ||
1389 | (skb->protocol == htons(ETH_P_IPV6))) { | ||
1390 | skb->csum = csum; | ||
1391 | skb->ip_summed = CHECKSUM_COMPLETE; | ||
1392 | } else | ||
1393 | myri10ge_vlan_ip_csum(skb, csum); | ||
1394 | } | ||
1395 | netif_receive_skb(skb); | ||
1396 | return 1; | 1332 | return 1; |
1397 | } | 1333 | } |
1398 | 1334 | ||
@@ -1480,18 +1416,11 @@ myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget) | |||
1480 | u16 length; | 1416 | u16 length; |
1481 | __wsum checksum; | 1417 | __wsum checksum; |
1482 | 1418 | ||
1483 | /* | ||
1484 | * Prevent compiler from generating more than one ->features memory | ||
1485 | * access to avoid theoretical race condition with functions that | ||
1486 | * change NETIF_F_LRO flag at runtime. | ||
1487 | */ | ||
1488 | bool lro_enabled = !!(ACCESS_ONCE(mgp->dev->features) & NETIF_F_LRO); | ||
1489 | |||
1490 | while (rx_done->entry[idx].length != 0 && work_done < budget) { | 1419 | while (rx_done->entry[idx].length != 0 && work_done < budget) { |
1491 | length = ntohs(rx_done->entry[idx].length); | 1420 | length = ntohs(rx_done->entry[idx].length); |
1492 | rx_done->entry[idx].length = 0; | 1421 | rx_done->entry[idx].length = 0; |
1493 | checksum = csum_unfold(rx_done->entry[idx].checksum); | 1422 | checksum = csum_unfold(rx_done->entry[idx].checksum); |
1494 | rx_ok = myri10ge_rx_done(ss, length, checksum, lro_enabled); | 1423 | rx_ok = myri10ge_rx_done(ss, length, checksum); |
1495 | rx_packets += rx_ok; | 1424 | rx_packets += rx_ok; |
1496 | rx_bytes += rx_ok * (unsigned long)length; | 1425 | rx_bytes += rx_ok * (unsigned long)length; |
1497 | cnt++; | 1426 | cnt++; |
@@ -1503,9 +1432,6 @@ myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget) | |||
1503 | ss->stats.rx_packets += rx_packets; | 1432 | ss->stats.rx_packets += rx_packets; |
1504 | ss->stats.rx_bytes += rx_bytes; | 1433 | ss->stats.rx_bytes += rx_bytes; |
1505 | 1434 | ||
1506 | if (lro_enabled) | ||
1507 | lro_flush_all(&rx_done->lro_mgr); | ||
1508 | |||
1509 | /* restock receive rings if needed */ | 1435 | /* restock receive rings if needed */ |
1510 | if (ss->rx_small.fill_cnt - ss->rx_small.cnt < myri10ge_fill_thresh) | 1436 | if (ss->rx_small.fill_cnt - ss->rx_small.cnt < myri10ge_fill_thresh) |
1511 | myri10ge_alloc_rx_pages(mgp, &ss->rx_small, | 1437 | myri10ge_alloc_rx_pages(mgp, &ss->rx_small, |
@@ -1779,7 +1705,6 @@ static const char myri10ge_gstrings_slice_stats[][ETH_GSTRING_LEN] = { | |||
1779 | "tx_pkt_start", "tx_pkt_done", "tx_req", "tx_done", | 1705 | "tx_pkt_start", "tx_pkt_done", "tx_req", "tx_done", |
1780 | "rx_small_cnt", "rx_big_cnt", | 1706 | "rx_small_cnt", "rx_big_cnt", |
1781 | "wake_queue", "stop_queue", "tx_linearized", | 1707 | "wake_queue", "stop_queue", "tx_linearized", |
1782 | "LRO aggregated", "LRO flushed", "LRO avg aggr", "LRO no_desc", | ||
1783 | }; | 1708 | }; |
1784 | 1709 | ||
1785 | #define MYRI10GE_NET_STATS_LEN 21 | 1710 | #define MYRI10GE_NET_STATS_LEN 21 |
@@ -1880,14 +1805,6 @@ myri10ge_get_ethtool_stats(struct net_device *netdev, | |||
1880 | data[i++] = (unsigned int)ss->tx.wake_queue; | 1805 | data[i++] = (unsigned int)ss->tx.wake_queue; |
1881 | data[i++] = (unsigned int)ss->tx.stop_queue; | 1806 | data[i++] = (unsigned int)ss->tx.stop_queue; |
1882 | data[i++] = (unsigned int)ss->tx.linearized; | 1807 | data[i++] = (unsigned int)ss->tx.linearized; |
1883 | data[i++] = ss->rx_done.lro_mgr.stats.aggregated; | ||
1884 | data[i++] = ss->rx_done.lro_mgr.stats.flushed; | ||
1885 | if (ss->rx_done.lro_mgr.stats.flushed) | ||
1886 | data[i++] = ss->rx_done.lro_mgr.stats.aggregated / | ||
1887 | ss->rx_done.lro_mgr.stats.flushed; | ||
1888 | else | ||
1889 | data[i++] = 0; | ||
1890 | data[i++] = ss->rx_done.lro_mgr.stats.no_desc; | ||
1891 | } | 1808 | } |
1892 | } | 1809 | } |
1893 | 1810 | ||
@@ -2271,67 +2188,6 @@ static void myri10ge_free_irq(struct myri10ge_priv *mgp) | |||
2271 | pci_disable_msix(pdev); | 2188 | pci_disable_msix(pdev); |
2272 | } | 2189 | } |
2273 | 2190 | ||
2274 | static int | ||
2275 | myri10ge_get_frag_header(struct skb_frag_struct *frag, void **mac_hdr, | ||
2276 | void **ip_hdr, void **tcpudp_hdr, | ||
2277 | u64 * hdr_flags, void *priv) | ||
2278 | { | ||
2279 | struct ethhdr *eh; | ||
2280 | struct vlan_ethhdr *veh; | ||
2281 | struct iphdr *iph; | ||
2282 | u8 *va = skb_frag_address(frag); | ||
2283 | unsigned long ll_hlen; | ||
2284 | /* passed opaque through lro_receive_frags() */ | ||
2285 | __wsum csum = (__force __wsum) (unsigned long)priv; | ||
2286 | |||
2287 | /* find the mac header, aborting if not IPv4 */ | ||
2288 | |||
2289 | eh = (struct ethhdr *)va; | ||
2290 | *mac_hdr = eh; | ||
2291 | ll_hlen = ETH_HLEN; | ||
2292 | if (eh->h_proto != htons(ETH_P_IP)) { | ||
2293 | if (eh->h_proto == htons(ETH_P_8021Q)) { | ||
2294 | veh = (struct vlan_ethhdr *)va; | ||
2295 | if (veh->h_vlan_encapsulated_proto != htons(ETH_P_IP)) | ||
2296 | return -1; | ||
2297 | |||
2298 | ll_hlen += VLAN_HLEN; | ||
2299 | |||
2300 | /* | ||
2301 | * HW checksum starts ETH_HLEN bytes into | ||
2302 | * frame, so we must subtract off the VLAN | ||
2303 | * header's checksum before csum can be used | ||
2304 | */ | ||
2305 | csum = csum_sub(csum, csum_partial(va + ETH_HLEN, | ||
2306 | VLAN_HLEN, 0)); | ||
2307 | } else { | ||
2308 | return -1; | ||
2309 | } | ||
2310 | } | ||
2311 | *hdr_flags = LRO_IPV4; | ||
2312 | |||
2313 | iph = (struct iphdr *)(va + ll_hlen); | ||
2314 | *ip_hdr = iph; | ||
2315 | if (iph->protocol != IPPROTO_TCP) | ||
2316 | return -1; | ||
2317 | if (ip_is_fragment(iph)) | ||
2318 | return -1; | ||
2319 | *hdr_flags |= LRO_TCP; | ||
2320 | *tcpudp_hdr = (u8 *) (*ip_hdr) + (iph->ihl << 2); | ||
2321 | |||
2322 | /* verify the IP checksum */ | ||
2323 | if (unlikely(ip_fast_csum((u8 *) iph, iph->ihl))) | ||
2324 | return -1; | ||
2325 | |||
2326 | /* verify the checksum */ | ||
2327 | if (unlikely(csum_tcpudp_magic(iph->saddr, iph->daddr, | ||
2328 | ntohs(iph->tot_len) - (iph->ihl << 2), | ||
2329 | IPPROTO_TCP, csum))) | ||
2330 | return -1; | ||
2331 | |||
2332 | return 0; | ||
2333 | } | ||
2334 | |||
2335 | static int myri10ge_get_txrx(struct myri10ge_priv *mgp, int slice) | 2191 | static int myri10ge_get_txrx(struct myri10ge_priv *mgp, int slice) |
2336 | { | 2192 | { |
2337 | struct myri10ge_cmd cmd; | 2193 | struct myri10ge_cmd cmd; |
@@ -2402,7 +2258,6 @@ static int myri10ge_open(struct net_device *dev) | |||
2402 | struct myri10ge_cmd cmd; | 2258 | struct myri10ge_cmd cmd; |
2403 | int i, status, big_pow2, slice; | 2259 | int i, status, big_pow2, slice; |
2404 | u8 *itable; | 2260 | u8 *itable; |
2405 | struct net_lro_mgr *lro_mgr; | ||
2406 | 2261 | ||
2407 | if (mgp->running != MYRI10GE_ETH_STOPPED) | 2262 | if (mgp->running != MYRI10GE_ETH_STOPPED) |
2408 | return -EBUSY; | 2263 | return -EBUSY; |
@@ -2513,19 +2368,6 @@ static int myri10ge_open(struct net_device *dev) | |||
2513 | goto abort_with_rings; | 2368 | goto abort_with_rings; |
2514 | } | 2369 | } |
2515 | 2370 | ||
2516 | lro_mgr = &ss->rx_done.lro_mgr; | ||
2517 | lro_mgr->dev = dev; | ||
2518 | lro_mgr->features = LRO_F_NAPI; | ||
2519 | lro_mgr->ip_summed = CHECKSUM_COMPLETE; | ||
2520 | lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY; | ||
2521 | lro_mgr->max_desc = MYRI10GE_MAX_LRO_DESCRIPTORS; | ||
2522 | lro_mgr->lro_arr = ss->rx_done.lro_desc; | ||
2523 | lro_mgr->get_frag_header = myri10ge_get_frag_header; | ||
2524 | lro_mgr->max_aggr = myri10ge_lro_max_pkts; | ||
2525 | lro_mgr->frag_align_pad = 2; | ||
2526 | if (lro_mgr->max_aggr > MAX_SKB_FRAGS) | ||
2527 | lro_mgr->max_aggr = MAX_SKB_FRAGS; | ||
2528 | |||
2529 | /* must happen prior to any irq */ | 2371 | /* must happen prior to any irq */ |
2530 | napi_enable(&(ss)->napi); | 2372 | napi_enable(&(ss)->napi); |
2531 | } | 2373 | } |
@@ -3143,15 +2985,6 @@ static int myri10ge_set_mac_address(struct net_device *dev, void *addr) | |||
3143 | return 0; | 2985 | return 0; |
3144 | } | 2986 | } |
3145 | 2987 | ||
3146 | static netdev_features_t myri10ge_fix_features(struct net_device *dev, | ||
3147 | netdev_features_t features) | ||
3148 | { | ||
3149 | if (!(features & NETIF_F_RXCSUM)) | ||
3150 | features &= ~NETIF_F_LRO; | ||
3151 | |||
3152 | return features; | ||
3153 | } | ||
3154 | |||
3155 | static int myri10ge_change_mtu(struct net_device *dev, int new_mtu) | 2988 | static int myri10ge_change_mtu(struct net_device *dev, int new_mtu) |
3156 | { | 2989 | { |
3157 | struct myri10ge_priv *mgp = netdev_priv(dev); | 2990 | struct myri10ge_priv *mgp = netdev_priv(dev); |
@@ -3878,7 +3711,6 @@ static const struct net_device_ops myri10ge_netdev_ops = { | |||
3878 | .ndo_get_stats64 = myri10ge_get_stats, | 3711 | .ndo_get_stats64 = myri10ge_get_stats, |
3879 | .ndo_validate_addr = eth_validate_addr, | 3712 | .ndo_validate_addr = eth_validate_addr, |
3880 | .ndo_change_mtu = myri10ge_change_mtu, | 3713 | .ndo_change_mtu = myri10ge_change_mtu, |
3881 | .ndo_fix_features = myri10ge_fix_features, | ||
3882 | .ndo_set_rx_mode = myri10ge_set_multicast_list, | 3714 | .ndo_set_rx_mode = myri10ge_set_multicast_list, |
3883 | .ndo_set_mac_address = myri10ge_set_mac_address, | 3715 | .ndo_set_mac_address = myri10ge_set_mac_address, |
3884 | }; | 3716 | }; |
@@ -4018,7 +3850,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
4018 | 3850 | ||
4019 | netdev->netdev_ops = &myri10ge_netdev_ops; | 3851 | netdev->netdev_ops = &myri10ge_netdev_ops; |
4020 | netdev->mtu = myri10ge_initial_mtu; | 3852 | netdev->mtu = myri10ge_initial_mtu; |
4021 | netdev->hw_features = mgp->features | NETIF_F_LRO | NETIF_F_RXCSUM; | 3853 | netdev->hw_features = mgp->features | NETIF_F_RXCSUM; |
4022 | netdev->features = netdev->hw_features; | 3854 | netdev->features = netdev->hw_features; |
4023 | 3855 | ||
4024 | if (dac_enabled) | 3856 | if (dac_enabled) |