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). > > 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 _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel