So it is something to do with the TCP checksum hardware not the switch. I have been blaming my failures on the switch code. I had noticed before that UDP worked and TCP failed.
I'm using the AsiaRF module which is very similar to the Hi-Link one but it is 25% smaller. It also brings out more pins. 32MB/8MB http://www.asiarf.com/Smallest-Tiny-Ralink-802-11n-Wireless-AP-Router-Module-Board-AWM002-product-view-375.html They just released a 64MB version. 64MB/8MB http://www.asiarf.com/BIG-Memory-Tiny-Ralink-802-11n-Wireless-AP-Router-Module-Board-AWM003-product-view-386.html Modules are around $8 in volume and you can get a dev board for $45. On Fri, Dec 27, 2013 at 11:55 AM, Darija Tadin-Đurović <[email protected]> wrote: > Hello, > same problem here, with RT5350 / HLK-RM04. > Got it working up to and including r39018 (with Jiapeng Li's patches from > https://github.com/JiapengLi/OpenWrt-HiLink-HLK-RM04 ). > On r39019 it breaks because of incorrect TCP checksum in packets outgoing > from HLK-RM04 (and the destination correctly disregards such packets). > > UDP gets through, as expected: ICMP ping, for example. > > Here follows a printout of a TCP SYN packet (all fields expanded) > originating from HLK-RM04 (192.168.2.11), you can see "Checksum: 0x858c > [incorrect, should be 0xacee (maybe caused by "TCP checksum offload"?)]" > further down in the printout. > > Regards > Darki > > > No. Time Source Destination > Protocol Length VLAN Info > 1 2013-12-23 14:58:15.281194000 192.168.2.11 192.168.2.2 > TCP 74 59173 > telnet [SYN] Seq=0 Win=14600 [TCP CHECKSUM > INCORRECT] Len=0 MSS=1460 SACK_PERM=1 TSval=591776 TSecr=0 WS=4 > > Frame 1: 74 bytes on wire (592 bits), 74 bytes captured (592 bits) on > interface 0 > Interface id: 0 > WTAP_ENCAP: 1 > Arrival Time: Dec 23, 2013 14:58:15.281194000 CET > [Time shift for this packet: 0.000000000 seconds] > Epoch Time: 1387807095.281194000 seconds > [Time delta from previous captured frame: 0.000000000 seconds] > [Time delta from previous displayed frame: 0.000000000 seconds] > [Time since reference or first frame: 0.000000000 seconds] > Frame Number: 1 > Frame Length: 74 bytes (592 bits) > Capture Length: 74 bytes (592 bits) > [Frame is marked: False] > [Frame is ignored: False] > [Protocols in frame: eth:ip:tcp] > [Coloring Rule Name: Checksum Errors] > [Coloring Rule String: cdp.checksum_bad==1 || edp.checksum_bad==1 || > ip.checksum_bad==1 || tcp.checksum_bad==1 || udp.checksum_bad==1 || > sctp.checksum_bad==1 || mstp.checksum_bad==1] > Ethernet II, Src: 66:51:7e:01:07:9f (66:51:7e:01:07:9f), Dst: > Fujitsu_18:1d:fa (50:26:90:18:1d:fa) > Destination: Fujitsu_18:1d:fa (50:26:90:18:1d:fa) > Address: Fujitsu_18:1d:fa (50:26:90:18:1d:fa) > .... ..0. .... .... .... .... = LG bit: Globally unique address > (factory default) > .... ...0 .... .... .... .... = IG bit: Individual address > (unicast) > Source: 66:51:7e:01:07:9f (66:51:7e:01:07:9f) > Address: 66:51:7e:01:07:9f (66:51:7e:01:07:9f) > .... ..1. .... .... .... .... = LG bit: Locally administered > address (this is NOT the factory default) > .... ...0 .... .... .... .... = IG bit: Individual address > (unicast) > Type: IP (0x0800) > Internet Protocol Version 4, Src: 192.168.2.11 (192.168.2.11), Dst: > 192.168.2.2 (192.168.2.2) > Version: 4 > Header length: 20 bytes > Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00: > Not-ECT (Not ECN-Capable Transport)) > 0000 00.. = Differentiated Services Codepoint: Default (0x00) > .... ..00 = Explicit Congestion Notification: Not-ECT (Not > ECN-Capable Transport) (0x00) > Total Length: 60 > Identification: 0xe3f1 (58353) > Flags: 0x02 (Don't Fragment) > 0... .... = Reserved bit: Not set > .1.. .... = Don't fragment: Set > ..0. .... = More fragments: Not set > Fragment offset: 0 > Time to live: 64 > Protocol: TCP (6) > Header checksum: 0xd16c [correct] > [Good: True] > [Bad: False] > Source: 192.168.2.11 (192.168.2.11) > Destination: 192.168.2.2 (192.168.2.2) > [Source GeoIP: Unknown] > [Destination GeoIP: Unknown] > Transmission Control Protocol, Src Port: 59173 (59173), Dst Port: telnet > (23), Seq: 0, Len: 0 > Source port: 59173 (59173) > Destination port: telnet (23) > [Stream index: 0] > Sequence number: 0 (relative sequence number) > Header length: 40 bytes > Flags: 0x002 (SYN) > 000. .... .... = Reserved: Not set > ...0 .... .... = Nonce: Not set > .... 0... .... = Congestion Window Reduced (CWR): Not set > .... .0.. .... = ECN-Echo: Not set > .... ..0. .... = Urgent: Not set > .... ...0 .... = Acknowledgment: Not set > .... .... 0... = Push: Not set > .... .... .0.. = Reset: Not set > .... .... ..1. = Syn: Set > [Expert Info (Chat/Sequence): Connection establish request > (SYN): server port telnet] > [Message: Connection establish request (SYN): server port > telnet] > [Severity level: Chat] > [Group: Sequence] > .... .... ...0 = Fin: Not set > Window size value: 14600 > [Calculated window size: 14600] > Checksum: 0x858c [incorrect, should be 0xacee (maybe caused by "TCP > checksum offload"?)] > [Good Checksum: False] > [Bad Checksum: True] > [Expert Info (Error/Checksum): Bad checksum] > [Message: Bad checksum] > [Severity level: Error] > [Group: Checksum] > Options: (20 bytes), Maximum segment size, SACK permitted, Timestamps, > No-Operation (NOP), Window scale > Maximum segment size: 1460 bytes > Kind: MSS size (2) > Length: 4 > MSS Value: 1460 > TCP SACK Permitted Option: True > Kind: SACK Permission (4) > Length: 2 > Timestamps: TSval 591776, TSecr 0 > Kind: Timestamp (8) > Length: 10 > Timestamp value: 591776 > Timestamp echo reply: 0 > No-Operation (NOP) > Type: 1 > 0... .... = Copy on fragmentation: No > .00. .... = Class: Control (0) > ...0 0001 = Number: No-Operation (NOP) (1) > Window scale: 2 (multiply by 4) > Kind: Window Scale (3) > Length: 3 > Shift count: 2 > [Multiplier: 4] > > > * [email protected] <[email protected]> [2013-12-26 21:23:44 -0500]: > > >> I had to revert this commit in order to get RT5350 working again. Any >> ideas why this change impacts Ethernet on the RT5350? >> >> commit b4fc4053d63294afbf77d1985b44a778d03af6c4 >> Author: blogic <blogic@3c298f89-4303-0410-b956-a3cf2f4a3e73> >> Date: Mon Dec 9 17:29:29 2013 +0000 >> >> ralink: add TSO >> >> Signed-off-by: John Crispin <[email protected]> >> >> git-svn-id: svn://svn.openwrt.org/openwrt/trunk@39019 >> 3c298f89-4303-0410-b956-a3cf2f4a3e73 >> >> >> >> -- >> Jon Smirl >> [email protected] > > >> --- a/drivers/net/ethernet/ralink/ralink_soc_eth.c >> +++ b/drivers/net/ethernet/ralink/ralink_soc_eth.c >> @@ -37,9 +37,8 @@ >> #include "esw_rt3052.h" >> #include "mdio.h" >> >> -#define TX_TIMEOUT (2 * HZ) >> +#define TX_TIMEOUT (20 * HZ / 100) >> #define MAX_RX_LENGTH 1536 >> -#define DMA_DUMMY_DESC 0xffffffff >> >> static const u32 fe_reg_table_default[FE_REG_COUNT] = { >> [FE_REG_PDMA_GLO_CFG] = FE_PDMA_GLO_CFG, >> @@ -240,41 +239,12 @@ static void fe_free_dma(struct fe_priv * >> netdev_reset_queue(priv->netdev); >> } >> >> -static void fe_start_tso(struct sk_buff *skb, struct net_device *dev, >> unsigned int nr_frags, int idx) >> -{ >> - struct fe_priv *priv = netdev_priv(dev); >> - struct skb_frag_struct *frag; >> - int i; >> - >> - for (i = 0; i < nr_frags; i++) { >> - dma_addr_t mapped_addr; >> - >> - frag = &skb_shinfo(skb)->frags[i]; >> - mapped_addr = skb_frag_dma_map(&dev->dev, frag, 0, >> skb_frag_size(frag), DMA_TO_DEVICE); >> - if (i % 2) { >> - idx = (idx + 1) % NUM_DMA_DESC; >> - priv->tx_dma[idx].txd1 = mapped_addr; >> - if (i == nr_frags - 1) >> - priv->tx_dma[idx].txd2 = TX_DMA_LSO | >> TX_DMA_PLEN0(frag->size); >> - else >> - priv->tx_dma[idx].txd2 = >> TX_DMA_PLEN0(frag->size); >> - } else { >> - priv->tx_dma[idx].txd3 = mapped_addr; >> - if (i == nr_frags - 1) >> - priv->tx_dma[idx].txd2 |= TX_DMA_LS1 | >> TX_DMA_PLEN1(frag->size); >> - else >> - priv->tx_dma[idx].txd2 |= >> TX_DMA_PLEN1(frag->size); >> - } >> - } >> -} >> - >> static int fe_start_xmit(struct sk_buff *skb, struct net_device *dev) >> { >> - unsigned int nr_frags = skb_shinfo(skb)->nr_frags; >> struct fe_priv *priv = netdev_priv(dev); >> dma_addr_t mapped_addr; >> - u32 tx_next, tx, tx_num = 1; >> - int i; >> + u32 tx_next; >> + u32 tx; >> >> if (priv->soc->min_pkt_len) { >> if (skb->len < priv->soc->min_pkt_len) { >> @@ -295,9 +265,8 @@ static int fe_start_xmit(struct sk_buff >> spin_lock(&priv->page_lock); >> >> tx = fe_reg_r32(FE_REG_TX_CTX_IDX0); >> - if (priv->soc->tso && nr_frags) >> - tx_num += nr_frags >> 1; >> - tx_next = (tx + tx_num) % NUM_DMA_DESC; >> + tx_next = (tx + 1) % NUM_DMA_DESC; >> + >> if ((priv->tx_skb[tx]) || (priv->tx_skb[tx_next]) || >> !(priv->tx_dma[tx].txd2 & TX_DMA_DONE) || >> !(priv->tx_dma[tx_next].txd2 & TX_DMA_DONE)) >> @@ -309,15 +278,7 @@ static int fe_start_xmit(struct sk_buff >> return NETDEV_TX_OK; >> } >> >> - if (priv->soc->tso) { >> - int t = tx_num; >> - >> - priv->tx_skb[(tx + t - 1) % NUM_DMA_DESC] = skb; >> - while (--t) >> - priv->tx_skb[(tx + t - 1) % NUM_DMA_DESC] = >> (struct sk_buff *) DMA_DUMMY_DESC; >> - } else { >> - priv->tx_skb[tx] = skb; >> - } >> + priv->tx_skb[tx] = skb; >> priv->tx_dma[tx].txd1 = (unsigned int) mapped_addr; >> wmb(); >> >> @@ -332,36 +293,9 @@ static int fe_start_xmit(struct sk_buff >> else >> priv->tx_dma[tx].txd4 &= ~TX_DMA_CHKSUM; >> >> - if (priv->soc->tso) >> - fe_start_tso(skb, dev, nr_frags, tx); >> - >> - if (skb_shinfo(skb)->gso_segs > 1) { >> - struct iphdr *iph = NULL; >> - struct tcphdr *th = NULL; >> - struct ipv6hdr *ip6h = NULL; >> - >> - ip6h = (struct ipv6hdr *) skb_network_header(skb); >> - iph = (struct iphdr *) skb_network_header(skb); >> - if ((iph->version == 4) && (iph->protocol == IPPROTO_TCP)) >> { >> - th = (struct tcphdr *)skb_transport_header(skb); >> - priv->tx_dma[tx].txd4 |= BIT(28); >> - th->check = htons(skb_shinfo(skb)->gso_size); >> - dma_cache_sync(NULL, th, sizeof(struct tcphdr), >> DMA_TO_DEVICE); >> - } else if ((ip6h->version == 6) && (ip6h->nexthdr == >> NEXTHDR_TCP)) { >> - th = (struct tcphdr *)skb_transport_header(skb); >> - priv->tx_dma[tx].txd4 |= BIT(28); >> - th->check = htons(skb_shinfo(skb)->gso_size); >> - dma_cache_sync(NULL, th, sizeof(struct tcphdr), >> DMA_TO_DEVICE); >> - } >> - } >> - >> - for (i = 0; i < tx_num; i++) >> - dma_cache_sync(NULL, &priv->tx_dma[tx + i], sizeof(struct >> fe_tx_dma), DMA_TO_DEVICE); >> - >> dev->stats.tx_packets++; >> dev->stats.tx_bytes += skb->len; >> >> - wmb(); >> fe_reg_w32(tx_next, FE_REG_TX_CTX_IDX0); >> netdev_sent_queue(dev, skb->len); >> >> @@ -459,11 +393,10 @@ static void fe_tx_housekeeping(unsigned >> if (!(txd->txd2 & TX_DMA_DONE) || >> !(priv->tx_skb[priv->tx_free_idx])) >> break; >> >> - if (priv->tx_skb[priv->tx_free_idx] != (struct sk_buff *) >> DMA_DUMMY_DESC) { >> - bytes_compl += >> priv->tx_skb[priv->tx_free_idx]->len; >> - >> dev_kfree_skb_irq(priv->tx_skb[priv->tx_free_idx]); >> - } >> + bytes_compl += priv->tx_skb[priv->tx_free_idx]->len; >> pkts_compl++; >> + >> + dev_kfree_skb_irq(priv->tx_skb[priv->tx_free_idx]); >> priv->tx_skb[priv->tx_free_idx] = NULL; >> priv->tx_free_idx++; >> if (priv->tx_free_idx >= NUM_DMA_DESC) >> @@ -712,9 +645,6 @@ static int fe_probe(struct platform_devi >> >> match = of_match_device(of_fe_match, &pdev->dev); >> soc = (struct fe_soc_data *) match->data; >> - >> - if (soc->init_data) >> - soc->init_data(soc); >> if (soc->reg_table) >> fe_reg_table = soc->reg_table; >> >> @@ -737,13 +667,6 @@ static int fe_probe(struct platform_devi >> if (fe_reg_table[FE_REG_FE_DMA_VID_BASE]) >> netdev->features |= NETIF_F_HW_VLAN_CTAG_TX; >> >> - if (soc->tso) { >> - dev_info(&pdev->dev, "Enabling TSO\n"); >> - netdev->features |= NETIF_F_SG | NETIF_F_TSO | >> NETIF_F_TSO6 | NETIF_F_IPV6_CSUM; >> - } >> - >> - netdev->hw_features = netdev->vlan_features = netdev->features; >> - >> netdev->irq = platform_get_irq(pdev, 0); >> if (netdev->irq < 0) { >> dev_err(&pdev->dev, "no IRQ resource found\n"); >> --- a/drivers/net/ethernet/ralink/ralink_soc_eth.h >> +++ b/drivers/net/ethernet/ralink/ralink_soc_eth.h >> @@ -279,8 +279,6 @@ struct fe_rx_dma { >> >> #define TX_DMA_PLEN0_MASK ((0x3fff) << 16) >> #define TX_DMA_PLEN0(_x) (((_x) & 0x3fff) << 16) >> -#define TX_DMA_PLEN1(_x) ((_x) & 0x3fff) >> -#define TX_DMA_LS1 BIT(14) >> #define TX_DMA_LSO BIT(30) >> #define TX_DMA_DONE BIT(31) >> #define TX_DMA_QN(_x) ((_x) << 16) >> @@ -319,7 +317,6 @@ struct fe_soc_data >> unsigned char mac[6]; >> const u32 *reg_table; >> >> - void (*init_data)(struct fe_soc_data *data); >> void (*reset_fe)(void); >> void (*set_mac)(struct fe_priv *priv, unsigned char *mac); >> void (*fwd_config)(struct fe_priv *priv); >> @@ -341,7 +338,6 @@ struct fe_soc_data >> u32 rx_dly_int; >> u32 tx_dly_int; >> u32 checksum_bit; >> - u32 tso; >> >> int min_pkt_len; >> }; >> --- a/drivers/net/ethernet/ralink/soc_mt7620.c >> +++ b/drivers/net/ethernet/ralink/soc_mt7620.c >> @@ -21,7 +21,6 @@ >> >> #include <asm/mach-ralink/ralink_regs.h> >> >> -#include <mt7620.h> >> #include "ralink_soc_eth.h" >> #include "gsw_mt7620a.h" >> >> @@ -79,20 +78,10 @@ static void mt7620_fwd_config(struct fe_ >> >> static void mt7620_tx_dma(struct fe_priv *priv, int idx, struct sk_buff >> *skb) >> { >> - unsigned int nr_frags = 0; >> - unsigned int len = 0; >> - >> - if (skb) { >> - nr_frags = skb_shinfo(skb)->nr_frags; >> - len = skb->len - skb->data_len; >> - } >> - >> - if (!skb) >> - priv->tx_dma[idx].txd2 = TX_DMA_LSO | TX_DMA_DONE; >> - else if (!nr_frags) >> - priv->tx_dma[idx].txd2 = TX_DMA_LSO | TX_DMA_PLEN0(len); >> + if (skb) >> + priv->tx_dma[idx].txd2 = TX_DMA_LSO | >> TX_DMA_PLEN0(skb->len); >> else >> - priv->tx_dma[idx].txd2 = TX_DMA_PLEN0(len); >> + priv->tx_dma[idx].txd2 = TX_DMA_LSO | TX_DMA_DONE; >> >> if(skb && vlan_tx_tag_present(skb)) >> priv->tx_dma[idx].txd4 = 0x80 | (vlan_tx_tag_get(skb) >> >> 13) << 4 | (vlan_tx_tag_get(skb) & 0xF); >> @@ -132,15 +121,8 @@ mt7620_get_skb_header(struct sk_buff *sk >> } >> #endif >> >> -static void mt7620_init_data(struct fe_soc_data *data) >> -{ >> - if (mt7620_get_eco() >= 5) >> - data->tso = 1; >> -} >> - >> static struct fe_soc_data mt7620_data = { >> .mac = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }, >> - .init_data = mt7620_init_data, >> .reset_fe = mt7620_fe_reset, >> .set_mac = mt7620_set_mac, >> .fwd_config = mt7620_fwd_config, > > >> _______________________________________________ >> openwrt-devel mailing list >> [email protected] >> https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel > > > > -- > Time is the quality of nature that keeps events from happening all at once. > Lately it doesn’t seem to be working. > —Anonymous > _______________________________________________ > openwrt-devel mailing list > [email protected] > https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel -- Jon Smirl [email protected] _______________________________________________ openwrt-devel mailing list [email protected] https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
