On Fri, Dec 27, 2013 at 3:33 PM, jonsm...@gmail.com <jonsm...@gmail.com> wrote: > On Fri, Dec 27, 2013 at 3:27 PM, Darija Tadin-Đurović <68da...@gmail.com> > wrote: >> Hi Jon, >> what do you mean by "TCP checksum hardware"? >> I had the same HW board working on (and before) r39018, but never after >> (well, "never" being too strong a term, actually it does not work - with the >> same TCP checksum error - on r39019, r39020, r39024, r39033, r39101).
Apply the patch in the first email and it will work again. >> >> Regards >> Darki >> >> PS Thanks for the tip on AsiaRF. However, HLK's operating temperature range >> is from -20°C to +70°C, which is really important right now > > That is impossible. RT5350 is only rated -10C to 55C. > > >> >> * jonsm...@gmail.com <jonsm...@gmail.com> [2013-12-27 14:43:27 -0500]: >> >> >>> 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ć >>> <68da...@gmail.com> 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] >>>> >>>> >>>> * jonsm...@gmail.com <jonsm...@gmail.com> [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 <blo...@openwrt.org> >>>>> >>>>> git-svn-id: svn://svn.openwrt.org/openwrt/trunk@39019 >>>>> 3c298f89-4303-0410-b956-a3cf2f4a3e73 >>>>> >>>>> >>>>> >>>>> -- >>>>> Jon Smirl >>>>> jonsm...@gmail.com >>>> >>>> >>>> >>>>> --- 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 >>>>> openwrt-devel@lists.openwrt.org >>>>> 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 >>>> openwrt-devel@lists.openwrt.org >>>> https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel >>> >>> >>> >>> >>> -- >>> Jon Smirl >>> jonsm...@gmail.com >> >> >> -- >> Time is the quality of nature that keeps events from happening all at once. >> Lately it doesn’t seem to be working. >> —Anonymous >> > > > > -- > Jon Smirl > jonsm...@gmail.com -- Jon Smirl jonsm...@gmail.com _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel