Messages in this thread | | | Date | Thu, 26 Aug 2010 08:57:58 -0700 | From | Stephen Hemminger <> | Subject | Re: [PATCH] Gigabit Ethernet driver of Topcliff PCH |
| |
On Thu, 26 Aug 2010 18:56:55 +0900 Masayuki Ohtake <masa-korg@dsn.okisemi.com> wrote:
> +static void pch_gbe_tx_queue(struct pch_gbe_adapter *adapter, > + struct pch_gbe_tx_ring *tx_ring, struct sk_buff *skb) > +{ > + struct pch_gbe_hw *hw = &adapter->hw; > + struct pch_gbe_tx_desc *tx_desc; > + struct pch_gbe_buffer *buffer_info; > + struct sk_buff *tmp_skb; > + unsigned int frame_ctrl; > + unsigned int ring_num; > + unsigned long flags; > + > + PCH_GBE_DEBUG("%s\n", __func__); > + > + > + /*-- Set frame control --*/ > + frame_ctrl = 0; > + if (unlikely(skb->len < PCH_GBE_SHORT_PKT)) > + frame_ctrl |= PCH_GBE_TXD_CTRL_APAD; > + if (unlikely(adapter->tx_csum == FALSE)) > + frame_ctrl |= PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF; > + > + /* Performs checksum processing */ > + /* > + * It is because the hardware accelerator does not support a checksum, > + * when the received data size is less than 64 bytes. > + */ > + if ((skb->len < PCH_GBE_SHORT_PKT) && (adapter->tx_csum == TRUE)) { > + frame_ctrl |= > + PCH_GBE_TXD_CTRL_APAD | PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF; > + if (skb->protocol == htons(ETH_P_IP)) { > + struct iphdr *iph = ip_hdr(skb); > + unsigned int offset; > + iph->check = 0; > + iph->check = ip_fast_csum((u8 *) iph, iph->ihl); > + offset = skb_transport_offset(skb); > + if (iph->protocol == IPPROTO_TCP) { > + skb->csum = 0; > + tcp_hdr(skb)->check = 0; > + skb->csum = > + skb_checksum(skb, offset, > + skb->len - offset, 0); > + tcp_hdr(skb)->check = > + csum_tcpudp_magic(iph->saddr, > + iph->daddr, > + skb->len - offset, > + IPPROTO_TCP, skb->csum); > + } else if (iph->protocol == IPPROTO_UDP) { > + skb->csum = 0; > + udp_hdr(skb)->check = 0; > + skb->csum = > + skb_checksum(skb, offset, > + skb->len - offset, 0); > + udp_hdr(skb)->check = > + csum_tcpudp_magic(iph->saddr, > + iph->daddr, > + skb->len - offset, > + IPPROTO_UDP, skb->csum); > + } > + } > + }
Why not something simpler using skb_checksum_help which is safer since it handles case of shared skb correctly.
if (skb->ip_summed = CHECKSUM_COMPLETE && skb->len < PCH_GBE_SHORT_PKT) { frame_ctrl |= PCH_GBE_TXD_CTRL_APAD | PCH_GBE_TXD_CTRL_TCPIP_ACC_OFF; skb->ip_summed = CHECKSUM_NONE; if (skb_checksum_help(skb)) goto drop; /* could not expand header to find space */ }
--
| |