]> err.no Git - linux-2.6/blobdiff - drivers/net/atl1/atl1_main.c
[TCP]: Introduce tcp_hdrlen() and tcp_optlen()
[linux-2.6] / drivers / net / atl1 / atl1_main.c
index 88d4f70035bb3c106180adf2159137691745bc9d..8d5994751e2ef66e9e606c4de64e3d276cd3ce62 100644 (file)
@@ -408,7 +408,6 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter,
 static u16 atl1_alloc_rx_buffers(struct atl1_adapter *adapter)
 {
        struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
-       struct net_device *netdev = adapter->netdev;
        struct pci_dev *pdev = adapter->pdev;
        struct page *page;
        unsigned long offset;
@@ -444,7 +443,6 @@ static u16 atl1_alloc_rx_buffers(struct atl1_adapter *adapter)
                 * the 14 byte MAC header is removed
                 */
                skb_reserve(skb, NET_IP_ALIGN);
-               skb->dev = netdev;
 
                buffer_info->alloced = 1;
                buffer_info->skb = skb;
@@ -1296,19 +1294,20 @@ static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb,
                }
 
                if (skb->protocol == ntohs(ETH_P_IP)) {
-                       skb->nh.iph->tot_len = 0;
-                       skb->nh.iph->check = 0;
-                       skb->h.th->check =
-                           ~csum_tcpudp_magic(skb->nh.iph->saddr,
-                                              skb->nh.iph->daddr, 0,
-                                              IPPROTO_TCP, 0);
-                       ipofst = skb->nh.raw - skb->data;
+                       struct iphdr *iph = ip_hdr(skb);
+
+                       iph->tot_len = 0;
+                       iph->check = 0;
+                       skb->h.th->check = ~csum_tcpudp_magic(iph->saddr,
+                                                             iph->daddr, 0,
+                                                             IPPROTO_TCP, 0);
+                       ipofst = skb_network_offset(skb);
                        if (ipofst != ENET_HEADER_SIZE) /* 802.3 frame */
                                tso->tsopl |= 1 << TSO_PARAM_ETHTYPE_SHIFT;
 
-                       tso->tsopl |= (skb->nh.iph->ihl &
+                       tso->tsopl |= (iph->ihl &
                                CSUM_PARAM_IPHL_MASK) << CSUM_PARAM_IPHL_SHIFT;
-                       tso->tsopl |= ((skb->h.th->doff << 2) &
+                       tso->tsopl |= (tcp_hdrlen(skb) &
                                TSO_PARAM_TCPHDRLEN_MASK) << TSO_PARAM_TCPHDRLEN_SHIFT;
                        tso->tsopl |= (skb_shinfo(skb)->gso_size &
                                TSO_PARAM_MSS_MASK) << TSO_PARAM_MSS_SHIFT;
@@ -1327,8 +1326,8 @@ static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb,
        u8 css, cso;
 
        if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
-               cso = skb->h.raw - skb->data;
-               css = (skb->h.raw + skb->csum) - skb->data;
+               cso = skb_transport_offset(skb);
+               css = cso + skb->csum;
                if (unlikely(cso & 0x1)) {
                        printk(KERN_DEBUG "%s: payload offset != even number\n",
                                atl1_driver_name);
@@ -1370,8 +1369,7 @@ static void atl1_tx_map(struct atl1_adapter *adapter,
 
        if (tcp_seg) {
                /* TSO/GSO */
-               proto_hdr_len =
-                   ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
+               proto_hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
                buffer_info->length = proto_hdr_len;
                page = virt_to_page(skb->data);
                offset = (unsigned long)skb->data & ~PAGE_MASK;
@@ -1562,9 +1560,9 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        /* mss will be nonzero if we're doing segment offload (TSO/GSO) */
        mss = skb_shinfo(skb)->gso_size;
        if (mss) {
-               if (skb->protocol == ntohs(ETH_P_IP)) {
-                       proto_hdr_len = ((skb->h.raw - skb->data) +
-                                        (skb->h.th->doff << 2));
+               if (skb->protocol == htons(ETH_P_IP)) {
+                       proto_hdr_len = (skb_transport_offset(skb) +
+                                        tcp_hdrlen(skb));
                        if (unlikely(proto_hdr_len > len)) {
                                dev_kfree_skb_any(skb);
                                return NETDEV_TX_OK;
@@ -2320,6 +2318,16 @@ static void __devexit atl1_remove(struct pci_dev *pdev)
                return;
 
        adapter = netdev_priv(netdev);
+
+       /* Some atl1 boards lack persistent storage for their MAC, and get it
+        * from the BIOS during POST.  If we've been messing with the MAC
+        * address, we need to save the permanent one.
+        */
+       if (memcmp(adapter->hw.mac_addr, adapter->hw.perm_mac_addr, ETH_ALEN)) {
+               memcpy(adapter->hw.mac_addr, adapter->hw.perm_mac_addr, ETH_ALEN);
+               atl1_set_mac_addr(&adapter->hw);
+       }
+
        iowrite16(0, adapter->hw.hw_addr + REG_GPHY_ENABLE);
        unregister_netdev(netdev);
        pci_iounmap(pdev, adapter->hw.hw_addr);