]> bbs.cooldavid.org Git - jme.git/blobdiff - jme.c
fixv6sum
[jme.git] / jme.c
diff --git a/jme.c b/jme.c
index b07d889573c9334b0278de46bbbf5d56135c490f..387434c5225ea16a3da18faae7f850075cc6529a 100644 (file)
--- a/jme.c
+++ b/jme.c
@@ -962,12 +962,48 @@ jme_disable_rx_engine(struct jme_adapter *jme)
        jme_mac_rxclk_off(jme);
 }
 
+static u16
+jme_udpsum(struct sk_buff *skb)
+{
+       u16 csum = 0xFFFFu;
+
+       if (skb->len < (ETH_HLEN + sizeof(struct iphdr)))
+               return csum;
+       if (skb->protocol != htons(ETH_P_IP))
+               return csum;
+       skb_set_network_header(skb, ETH_HLEN);
+       if ((ip_hdr(skb)->protocol != IPPROTO_UDP) ||
+           (skb->len < (ETH_HLEN +
+                       (ip_hdr(skb)->ihl << 2) +
+                       sizeof(struct udphdr)))) {
+               skb_reset_network_header(skb);
+               return csum;
+       }
+       skb_set_transport_header(skb,
+                       ETH_HLEN + (ip_hdr(skb)->ihl << 2));
+       csum = udp_hdr(skb)->check;
+       skb_reset_transport_header(skb);
+       skb_reset_network_header(skb);
+
+       return csum;
+}
+
 static int
-jme_rxsum_ok(struct jme_adapter *jme, u16 flags)
+jme_rxsum_ok(struct jme_adapter *jme, u16 flags, struct sk_buff *skb)
 {
        if (!(flags & (RXWBFLAG_TCPON | RXWBFLAG_UDPON | RXWBFLAG_IPV4)))
                return false;
 
+               /*              Hardware Workaround     , packet is IPv6 but checksum fail              */
+       if (flags & RXWBFLAG_IPV6) {
+       
+               printk("this is IPV6  packet : len=%d ", skb->len);
+               if ((flags & RXWBFLAG_TCPON) && (!(flags & RXWBFLAG_TCPCS)))
+                       return false;
+               if ((flags & RXWBFLAG_UDPON) && (!(flags & RXWBFLAG_UDPCS)))
+                       return false;
+       }
+       
        if (unlikely((flags & (RXWBFLAG_MF | RXWBFLAG_TCPON | RXWBFLAG_TCPCS))
                        == RXWBFLAG_TCPON)) {
                if (flags & RXWBFLAG_IPV4)
@@ -976,7 +1012,7 @@ jme_rxsum_ok(struct jme_adapter *jme, u16 flags)
        }
 
        if (unlikely((flags & (RXWBFLAG_MF | RXWBFLAG_UDPON | RXWBFLAG_UDPCS))
-                       == RXWBFLAG_UDPON)) {
+                       == RXWBFLAG_UDPON) && jme_udpsum(skb)) {
                if (flags & RXWBFLAG_IPV4)
                        netif_err(jme, rx_err, jme->dev, "UDP Checksum error\n");
                return false;
@@ -1024,7 +1060,7 @@ jme_alloc_and_feed_skb(struct jme_adapter *jme, int idx)
                skb_put(skb, framesize);
                skb->protocol = eth_type_trans(skb, jme->dev);
 
-               if (jme_rxsum_ok(jme, le16_to_cpu(rxdesc->descwb.flags)))
+               if (jme_rxsum_ok(jme, le16_to_cpu(rxdesc->descwb.flags), skb))
                        skb->ip_summed = CHECKSUM_UNNECESSARY;
                else
 #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
@@ -1032,7 +1068,8 @@ jme_alloc_and_feed_skb(struct jme_adapter *jme, int idx)
 #else
                        skb_checksum_none_assert(skb);
 #endif
-
+               printk("flag=%04x , skb->ip_summed =%d \n",le16_to_cpu(rxdesc->descwb.flags), skb->ip_summed);
+               
                if (rxdesc->descwb.flags & cpu_to_le16(RXWBFLAG_TAGON)) {
                        if (jme->vlgrp) {
                                jme->jme_vlan_rx(skb, jme->vlgrp,
@@ -1739,7 +1776,7 @@ jme_phy_off(struct jme_adapter *jme)
        jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_BMCR, bmcr);
 
        if (new_phy_power_ctrl(jme->chip_main_rev))
-               jme_new_phy_off(jme);
+               jme_new_phy_off(jme); 
 }
 
 static int
@@ -2422,6 +2459,8 @@ jme_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p)
        p32 += 0x100 >> 2;
        mmapio_memcpy(jme, p32, JME_MISC, JME_MISC_LEN);
 
+        printk("===jread32=%x===\n",jread32(jme, JME_EXGP2));
+
        p32 += 0x100 >> 2;
        mmapio_memcpy(jme, p32, JME_RSS, JME_RSS_LEN);
 
@@ -3006,7 +3045,7 @@ jme_init_one(struct pci_dev *pdev,
        struct net_device *netdev;
        struct jme_adapter *jme;
        u16 bmcr, bmsr;
-       u32 apmc;
+       u32 apmc, phy_gp2;
 
        /*
         * set up PCI device basics
@@ -3222,6 +3261,11 @@ jme_init_one(struct pci_dev *pdev,
        }
        jme_load_macaddr(netdev);
 
+       phy_gp2 = jread32(jme, JME_EXGP2)|FIX_IPV6_CHECKSUM;
+       jwrite32(jme, JME_EXGP2,phy_gp2);
+       wmb();
+       printk("==%x=====\n", jread32(jme, JME_EXGP2)); 
+
        /*
         * Tell stack that we are not ready to work until open()
         */