aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/intel/ixgbe/ixgbe_main.c')
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c116
1 files changed, 1 insertions, 115 deletions
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 5a3efd9f9de0..166dc0015a5e 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -1521,120 +1521,6 @@ void ixgbe_alloc_rx_buffers(struct ixgbe_ring *rx_ring, u16 cleaned_count)
1521 ixgbe_release_rx_desc(rx_ring, i); 1521 ixgbe_release_rx_desc(rx_ring, i);
1522} 1522}
1523 1523
1524/**
1525 * ixgbe_get_headlen - determine size of header for RSC/LRO/GRO/FCOE
1526 * @data: pointer to the start of the headers
1527 * @max_len: total length of section to find headers in
1528 *
1529 * This function is meant to determine the length of headers that will
1530 * be recognized by hardware for LRO, GRO, and RSC offloads. The main
1531 * motivation of doing this is to only perform one pull for IPv4 TCP
1532 * packets so that we can do basic things like calculating the gso_size
1533 * based on the average data per packet.
1534 **/
1535static unsigned int ixgbe_get_headlen(unsigned char *data,
1536 unsigned int max_len)
1537{
1538 union {
1539 unsigned char *network;
1540 /* l2 headers */
1541 struct ethhdr *eth;
1542 struct vlan_hdr *vlan;
1543 /* l3 headers */
1544 struct iphdr *ipv4;
1545 struct ipv6hdr *ipv6;
1546 } hdr;
1547 __be16 protocol;
1548 u8 nexthdr = 0; /* default to not TCP */
1549 u8 hlen;
1550
1551 /* this should never happen, but better safe than sorry */
1552 if (max_len < ETH_HLEN)
1553 return max_len;
1554
1555 /* initialize network frame pointer */
1556 hdr.network = data;
1557
1558 /* set first protocol and move network header forward */
1559 protocol = hdr.eth->h_proto;
1560 hdr.network += ETH_HLEN;
1561
1562 /* handle any vlan tag if present */
1563 if (protocol == htons(ETH_P_8021Q)) {
1564 if ((hdr.network - data) > (max_len - VLAN_HLEN))
1565 return max_len;
1566
1567 protocol = hdr.vlan->h_vlan_encapsulated_proto;
1568 hdr.network += VLAN_HLEN;
1569 }
1570
1571 /* handle L3 protocols */
1572 if (protocol == htons(ETH_P_IP)) {
1573 if ((hdr.network - data) > (max_len - sizeof(struct iphdr)))
1574 return max_len;
1575
1576 /* access ihl as a u8 to avoid unaligned access on ia64 */
1577 hlen = (hdr.network[0] & 0x0F) << 2;
1578
1579 /* verify hlen meets minimum size requirements */
1580 if (hlen < sizeof(struct iphdr))
1581 return hdr.network - data;
1582
1583 /* record next protocol if header is present */
1584 if (!(hdr.ipv4->frag_off & htons(IP_OFFSET)))
1585 nexthdr = hdr.ipv4->protocol;
1586 } else if (protocol == htons(ETH_P_IPV6)) {
1587 if ((hdr.network - data) > (max_len - sizeof(struct ipv6hdr)))
1588 return max_len;
1589
1590 /* record next protocol */
1591 nexthdr = hdr.ipv6->nexthdr;
1592 hlen = sizeof(struct ipv6hdr);
1593#ifdef IXGBE_FCOE
1594 } else if (protocol == htons(ETH_P_FCOE)) {
1595 if ((hdr.network - data) > (max_len - FCOE_HEADER_LEN))
1596 return max_len;
1597 hlen = FCOE_HEADER_LEN;
1598#endif
1599 } else {
1600 return hdr.network - data;
1601 }
1602
1603 /* relocate pointer to start of L4 header */
1604 hdr.network += hlen;
1605
1606 /* finally sort out TCP/UDP */
1607 if (nexthdr == IPPROTO_TCP) {
1608 if ((hdr.network - data) > (max_len - sizeof(struct tcphdr)))
1609 return max_len;
1610
1611 /* access doff as a u8 to avoid unaligned access on ia64 */
1612 hlen = (hdr.network[12] & 0xF0) >> 2;
1613
1614 /* verify hlen meets minimum size requirements */
1615 if (hlen < sizeof(struct tcphdr))
1616 return hdr.network - data;
1617
1618 hdr.network += hlen;
1619 } else if (nexthdr == IPPROTO_UDP) {
1620 if ((hdr.network - data) > (max_len - sizeof(struct udphdr)))
1621 return max_len;
1622
1623 hdr.network += sizeof(struct udphdr);
1624 }
1625
1626 /*
1627 * If everything has gone correctly hdr.network should be the
1628 * data section of the packet and will be the end of the header.
1629 * If not then it probably represents the end of the last recognized
1630 * header.
1631 */
1632 if ((hdr.network - data) < max_len)
1633 return hdr.network - data;
1634 else
1635 return max_len;
1636}
1637
1638static void ixgbe_set_rsc_gso_size(struct ixgbe_ring *ring, 1524static void ixgbe_set_rsc_gso_size(struct ixgbe_ring *ring,
1639 struct sk_buff *skb) 1525 struct sk_buff *skb)
1640{ 1526{
@@ -1793,7 +1679,7 @@ static void ixgbe_pull_tail(struct ixgbe_ring *rx_ring,
1793 * we need the header to contain the greater of either ETH_HLEN or 1679 * we need the header to contain the greater of either ETH_HLEN or
1794 * 60 bytes if the skb->len is less than 60 for skb_pad. 1680 * 60 bytes if the skb->len is less than 60 for skb_pad.
1795 */ 1681 */
1796 pull_len = ixgbe_get_headlen(va, IXGBE_RX_HDR_SIZE); 1682 pull_len = eth_get_headlen(va, IXGBE_RX_HDR_SIZE);
1797 1683
1798 /* align pull length to size of long to optimize memcpy performance */ 1684 /* align pull length to size of long to optimize memcpy performance */
1799 skb_copy_to_linear_data(skb, va, ALIGN(pull_len, sizeof(long))); 1685 skb_copy_to_linear_data(skb, va, ALIGN(pull_len, sizeof(long)));