pr_err("phy(%d) write timeout : %d\n", phy, reg);
}
+static int
+jme_phyext_read(struct jme_adapter *jme, int reg)
+{
+ jme_mdio_write(jme->dev, jme->mii_if.phy_id,
+ JME_PHY_SPEC_ADDR_REG,
+ JME_PHY_SPEC_REG_READ | (reg & 0x3FFF));
+ return jme_mdio_read(jme->dev, jme->mii_if.phy_id,
+ JME_PHY_SPEC_DATA_REG);
+}
+
+static void
+jme_phyext_write(struct jme_adapter *jme, int reg, int val)
+{
+ jme_mdio_write(jme->dev, jme->mii_if.phy_id,
+ JME_PHY_SPEC_DATA_REG, val);
+ jme_mdio_write(jme->dev, jme->mii_if.phy_id,
+ JME_PHY_SPEC_ADDR_REG,
+ JME_PHY_SPEC_REG_WRITE | (reg & 0x3FFF));
+}
+
+static void
+jme_phyext_memcpy(struct jme_adapter *jme, u32 *p, int reg_nr)
+{
+ int i;
+ u16 *p16 = (u16 *)p;
+
+ for (i = 0 ; i < reg_nr ; ++i)
+ p16[i] = jme_phyext_read(jme, i);
+}
+
static inline void
jme_reset_phy_processor(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;
}
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)
p32 += 0x100 >> 2;
mdio_memcpy(jme, p32, JME_PHY_REG_NR);
+
+ p32 += 0x100 >> 2;
+ jme_phyext_memcpy(jme, p32, JME_PHY_SPEC_REG_NR);
}
static int