X-Git-Url: https://bbs.cooldavid.org/git/?p=jme.git;a=blobdiff_plain;f=jme.c;h=387434c5225ea16a3da18faae7f850075cc6529a;hp=d366e6a8a3e55e1b8912248882fa8ec82f3c4126;hb=refs%2Fheads%2Ffixv6csum;hpb=dc4185bdcf8f45d7cd1d09cd93b246d6a3a4e430 diff --git a/jme.c b/jme.c index d366e6a..387434c 100644 --- a/jme.c +++ b/jme.c @@ -904,6 +904,7 @@ jme_enable_rx_engine(struct jme_adapter *jme) /* * Setup Unicast Filter */ + jme_set_unicastaddr(jme->dev); jme_set_multi(jme->dev); /* @@ -961,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) @@ -975,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; @@ -1023,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) @@ -1031,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, @@ -1738,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 @@ -2169,27 +2207,34 @@ jme_start_xmit(struct sk_buff *skb, struct net_device *netdev) return NETDEV_TX_OK; } +static void +jme_set_unicastaddr(struct net_device *netdev) +{ + struct jme_adapter *jme = netdev_priv(netdev); + u32 val; + + val = (netdev->dev_addr[3] & 0xff) << 24 | + (netdev->dev_addr[2] & 0xff) << 16 | + (netdev->dev_addr[1] & 0xff) << 8 | + (netdev->dev_addr[0] & 0xff); + jwrite32(jme, JME_RXUMA_LO, val); + val = (netdev->dev_addr[5] & 0xff) << 8 | + (netdev->dev_addr[4] & 0xff); + jwrite32(jme, JME_RXUMA_HI, val); +} + static int jme_set_macaddr(struct net_device *netdev, void *p) { struct jme_adapter *jme = netdev_priv(netdev); struct sockaddr *addr = p; - u32 val; if (netif_running(netdev)) return -EBUSY; spin_lock_bh(&jme->macaddr_lock); memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); - - val = (addr->sa_data[3] & 0xff) << 24 | - (addr->sa_data[2] & 0xff) << 16 | - (addr->sa_data[1] & 0xff) << 8 | - (addr->sa_data[0] & 0xff); - jwrite32(jme, JME_RXUMA_LO, val); - val = (addr->sa_data[5] & 0xff) << 8 | - (addr->sa_data[4] & 0xff); - jwrite32(jme, JME_RXUMA_HI, val); + jme_set_unicastaddr(netdev); spin_unlock_bh(&jme->macaddr_lock); return 0; @@ -2414,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); @@ -2998,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 @@ -3214,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() */ @@ -3322,7 +3374,11 @@ jme_suspend(struct pci_dev *pdev, pm_message_t state) pci_save_state(pdev); jme_powersave_phy(jme); +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,27) pci_enable_wake(pdev, PCI_D3hot, true); +#else + pci_pme_active(pdev, true); +#endif pci_set_power_state(pdev, PCI_D3hot); return 0;