aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/pch_gbe/pch_gbe_main.c97
1 files changed, 55 insertions, 42 deletions
diff --git a/drivers/net/pch_gbe/pch_gbe_main.c b/drivers/net/pch_gbe/pch_gbe_main.c
index 4c9a7d4f3fca..f52d852569fb 100644
--- a/drivers/net/pch_gbe/pch_gbe_main.c
+++ b/drivers/net/pch_gbe/pch_gbe_main.c
@@ -29,6 +29,7 @@ const char pch_driver_version[] = DRV_VERSION;
29#define PCH_GBE_SHORT_PKT 64 29#define PCH_GBE_SHORT_PKT 64
30#define DSC_INIT16 0xC000 30#define DSC_INIT16 0xC000
31#define PCH_GBE_DMA_ALIGN 0 31#define PCH_GBE_DMA_ALIGN 0
32#define PCH_GBE_DMA_PADDING 2
32#define PCH_GBE_WATCHDOG_PERIOD (1 * HZ) /* watchdog time */ 33#define PCH_GBE_WATCHDOG_PERIOD (1 * HZ) /* watchdog time */
33#define PCH_GBE_COPYBREAK_DEFAULT 256 34#define PCH_GBE_COPYBREAK_DEFAULT 256
34#define PCH_GBE_PCI_BAR 1 35#define PCH_GBE_PCI_BAR 1
@@ -1365,16 +1366,13 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter,
1365 struct pch_gbe_buffer *buffer_info; 1366 struct pch_gbe_buffer *buffer_info;
1366 struct pch_gbe_rx_desc *rx_desc; 1367 struct pch_gbe_rx_desc *rx_desc;
1367 u32 length; 1368 u32 length;
1368 unsigned char tmp_packet[ETH_HLEN];
1369 unsigned int i; 1369 unsigned int i;
1370 unsigned int cleaned_count = 0; 1370 unsigned int cleaned_count = 0;
1371 bool cleaned = false; 1371 bool cleaned = false;
1372 struct sk_buff *skb; 1372 struct sk_buff *skb, *new_skb;
1373 u8 dma_status; 1373 u8 dma_status;
1374 u16 gbec_status; 1374 u16 gbec_status;
1375 u32 tcp_ip_status; 1375 u32 tcp_ip_status;
1376 u8 skb_copy_flag = 0;
1377 u8 skb_padding_flag = 0;
1378 1376
1379 i = rx_ring->next_to_clean; 1377 i = rx_ring->next_to_clean;
1380 1378
@@ -1418,55 +1416,70 @@ pch_gbe_clean_rx(struct pch_gbe_adapter *adapter,
1418 pr_err("Receive CRC Error\n"); 1416 pr_err("Receive CRC Error\n");
1419 } else { 1417 } else {
1420 /* get receive length */ 1418 /* get receive length */
1421 /* length convert[-3], padding[-2] */ 1419 /* length convert[-3] */
1422 length = (rx_desc->rx_words_eob) - 3 - 2; 1420 length = (rx_desc->rx_words_eob) - 3;
1423 1421
1424 /* Decide the data conversion method */ 1422 /* Decide the data conversion method */
1425 if (!adapter->rx_csum) { 1423 if (!adapter->rx_csum) {
1426 /* [Header:14][payload] */ 1424 /* [Header:14][payload] */
1427 skb_padding_flag = 0; 1425 if (NET_IP_ALIGN) {
1428 skb_copy_flag = 1; 1426 /* Because alignment differs,
1427 * the new_skb is newly allocated,
1428 * and data is copied to new_skb.*/
1429 new_skb = netdev_alloc_skb(netdev,
1430 length + NET_IP_ALIGN);
1431 if (!new_skb) {
1432 /* dorrop error */
1433 pr_err("New skb allocation "
1434 "Error\n");
1435 goto dorrop;
1436 }
1437 skb_reserve(new_skb, NET_IP_ALIGN);
1438 memcpy(new_skb->data, skb->data,
1439 length);
1440 skb = new_skb;
1441 } else {
1442 /* DMA buffer is used as SKB as it is.*/
1443 buffer_info->skb = NULL;
1444 }
1429 } else { 1445 } else {
1430 /* [Header:14][padding:2][payload] */ 1446 /* [Header:14][padding:2][payload] */
1431 skb_padding_flag = 1; 1447 /* The length includes padding length */
1432 if (length < copybreak) 1448 length = length - PCH_GBE_DMA_PADDING;
1433 skb_copy_flag = 1; 1449 if ((length < copybreak) ||
1434 else 1450 (NET_IP_ALIGN != PCH_GBE_DMA_PADDING)) {
1435 skb_copy_flag = 0; 1451 /* Because alignment differs,
1436 } 1452 * the new_skb is newly allocated,
1437 1453 * and data is copied to new_skb.
1438 /* Data conversion */ 1454 * Padding data is deleted
1439 if (skb_copy_flag) { /* recycle skb */ 1455 * at the time of a copy.*/
1440 struct sk_buff *new_skb; 1456 new_skb = netdev_alloc_skb(netdev,
1441 new_skb = 1457 length + NET_IP_ALIGN);
1442 netdev_alloc_skb(netdev, 1458 if (!new_skb) {
1443 length + NET_IP_ALIGN); 1459 /* dorrop error */
1444 if (new_skb) { 1460 pr_err("New skb allocation "
1445 if (!skb_padding_flag) { 1461 "Error\n");
1446 skb_reserve(new_skb, 1462 goto dorrop;
1447 NET_IP_ALIGN);
1448 } 1463 }
1464 skb_reserve(new_skb, NET_IP_ALIGN);
1449 memcpy(new_skb->data, skb->data, 1465 memcpy(new_skb->data, skb->data,
1450 length); 1466 ETH_HLEN);
1451 /* save the skb 1467 memcpy(&new_skb->data[ETH_HLEN],
1452 * in buffer_info as good */ 1468 &skb->data[ETH_HLEN +
1469 PCH_GBE_DMA_PADDING],
1470 length - ETH_HLEN);
1453 skb = new_skb; 1471 skb = new_skb;
1454 } else if (!skb_padding_flag) { 1472 } else {
1455 /* dorrop error */ 1473 /* Padding data is deleted
1456 pr_err("New skb allocation Error\n"); 1474 * by moving header data.*/
1457 goto dorrop; 1475 memmove(&skb->data[PCH_GBE_DMA_PADDING],
1476 &skb->data[0], ETH_HLEN);
1477 skb_reserve(skb, NET_IP_ALIGN);
1478 buffer_info->skb = NULL;
1458 } 1479 }
1459 } else {
1460 buffer_info->skb = NULL;
1461 } 1480 }
1462 if (skb_padding_flag) { 1481 /* The length includes FCS length */
1463 memcpy(&tmp_packet[0], &skb->data[0], ETH_HLEN); 1482 length = length - ETH_FCS_LEN;
1464 memcpy(&skb->data[NET_IP_ALIGN], &tmp_packet[0],
1465 ETH_HLEN);
1466 skb_reserve(skb, NET_IP_ALIGN);
1467
1468 }
1469
1470 /* update status of driver */ 1483 /* update status of driver */
1471 adapter->stats.rx_bytes += length; 1484 adapter->stats.rx_bytes += length;
1472 adapter->stats.rx_packets++; 1485 adapter->stats.rx_packets++;