/*
* Setup Unicast Filter
*/
+ jme_set_unicastaddr(jme->dev);
jme_set_multi(jme->dev);
/*
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)
}
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;
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)
#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,
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
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;
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);
struct net_device *netdev;
struct jme_adapter *jme;
u16 bmcr, bmsr;
- u32 apmc;
+ u32 apmc, phy_gp2;
/*
* set up PCI device basics
}
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()
*/