"Conor O'Gorman" <i...@conorogorman.net> writes: > On 08/10/14 11:00, John Crispin wrote: >> the e3267 that sami sent me works with this proto, but i am failing to >> get a DHCP addr. could someone with a ncm dongle please try this patch >> on top of latest trunk please and tell me if they are getting a dhcp addr ? > > I had a similar problem with a Huawei device. It worked after removing > some zero padding in the ncm driver. > > In cdc_ncm.c, cdc_ncm_fill_tx_frame(), towards the end there is > handling for Zero Length Packets (ZLP) and padding short packets. I > removed the padding, and it worked. Are you testing 3.10 or 3.14? It's > changed ever so slightly between them. > > I am somewhat confused by the comment. It won't pad out short packets, > but does make shortish packets long.
I don't have an fix for this bug, but I can try to add some background wrt the driver code... The NCM protocol assumes a powerful host and a much less powerful device (modem). It also assumes that devices can operate more efficiently if all (or most) packets have the same length, enabling the device DMA engine to operate on its own without involving the device CPU. These assumptions were true for all NCM devices and hosts implemented at the time the protocol was finalized. They are not necessarily true today. But we still have to deal with those assumptions somehow. One of the implications of this is that the device will operate more efficiently if the host pads packets the maximum length. On the other hand, this padding does of course cost extra bandwidth and buffer usage, so there is some cutoff point for really short packets. This is CDC_NCM_MIN_TX_PKT (512 bytes in the current NCM linux driver). So if a NCM packet exceeds 512 bytes then it is padded to max size. This maximum size is decided by the device (i.e. modem), but sanitized by the Linux driver. Most traditional NCM devices have buffers in the order of 4 or 8kB, which limits the overhead caused by the padding somewhat. But some Huawei devices have much larger buffers, causing an insane padding overhead given the fixed 512 bytes cutoff even if the driver sanitize the values somewhat. This is one of the issues I tried to fix in Linux v3.16. Whether it was successful remains to be seen, but at least v3.16 gives us (the users) a lot more control over the process by adding a few tunables. And some informational attributes as well. This is an example from v3.16+ (with an MBIM device, but the code and issues are both common): bjorn@nemi:~$ grep . /sys/class/net/wwan0/cdc_ncm/* /sys/class/net/wwan0/cdc_ncm/bmNtbFormatsSupported:0x0001 /sys/class/net/wwan0/cdc_ncm/dwNtbInMaxSize:15360 /sys/class/net/wwan0/cdc_ncm/dwNtbOutMaxSize:15360 /sys/class/net/wwan0/cdc_ncm/min_tx_pkt:13824 /sys/class/net/wwan0/cdc_ncm/rx_max:15360 /sys/class/net/wwan0/cdc_ncm/tx_max:15360 /sys/class/net/wwan0/cdc_ncm/tx_timer_usecs:400 /sys/class/net/wwan0/cdc_ncm/wNdpInAlignment:4 /sys/class/net/wwan0/cdc_ncm/wNdpInDivisor:1 /sys/class/net/wwan0/cdc_ncm/wNdpInPayloadRemainder:0 /sys/class/net/wwan0/cdc_ncm/wNdpOutAlignment:4 /sys/class/net/wwan0/cdc_ncm/wNdpOutDivisor:32 /sys/class/net/wwan0/cdc_ncm/wNdpOutPayloadRemainder:0 /sys/class/net/wwan0/cdc_ncm/wNtbOutMaxDatagrams:32 Here you can see the device specified TX and RX buffer sizes ("dwNtb*MaxSize") and also the buffers sizes currently in use by the driver ("rx_max"/"tx_max"). And finally the "min_tx_pkt" attribute, which has replaced the fixed CDC_NCM_MIN_TX_PKT. This is now dynamically calculated based on rx_max, and, as you can see from the values above, not causing that much overhead. Here's an example from a Huawei device (also MBIM), where the driver has sanitized the insane 128 kB buffer to 16 kB. bjorn@nemi:~$ grep . /sys/class/net/wwan1/cdc_ncm/* /sys/class/net/wwan1/cdc_ncm/bmNtbFormatsSupported:0x0003 /sys/class/net/wwan1/cdc_ncm/dwNtbInMaxSize:131072 /sys/class/net/wwan1/cdc_ncm/dwNtbOutMaxSize:32768 /sys/class/net/wwan1/cdc_ncm/min_tx_pkt:14849 /sys/class/net/wwan1/cdc_ncm/rx_max:16384 /sys/class/net/wwan1/cdc_ncm/tx_max:16385 /sys/class/net/wwan1/cdc_ncm/tx_timer_usecs:400 /sys/class/net/wwan1/cdc_ncm/wNdpInAlignment:4 /sys/class/net/wwan1/cdc_ncm/wNdpInDivisor:4 /sys/class/net/wwan1/cdc_ncm/wNdpInPayloadRemainder:0 /sys/class/net/wwan1/cdc_ncm/wNdpOutAlignment:4 /sys/class/net/wwan1/cdc_ncm/wNdpOutDivisor:4 /sys/class/net/wwan1/cdc_ncm/wNdpOutPayloadRemainder:0 /sys/class/net/wwan1/cdc_ncm/wNtbOutMaxDatagrams:0 And the last example from a device with extremely small buffers: bjorn@nemi:~$ grep . /sys/class/net/wwan2/cdc_ncm/* /sys/class/net/wwan2/cdc_ncm/bmNtbFormatsSupported:0x0001 /sys/class/net/wwan2/cdc_ncm/dwNtbInMaxSize:2048 /sys/class/net/wwan2/cdc_ncm/dwNtbOutMaxSize:2048 /sys/class/net/wwan2/cdc_ncm/min_tx_pkt:512 /sys/class/net/wwan2/cdc_ncm/rx_max:2048 /sys/class/net/wwan2/cdc_ncm/tx_max:2048 /sys/class/net/wwan2/cdc_ncm/tx_timer_usecs:400 /sys/class/net/wwan2/cdc_ncm/wNdpInAlignment:4 /sys/class/net/wwan2/cdc_ncm/wNdpInDivisor:4 /sys/class/net/wwan2/cdc_ncm/wNdpInPayloadRemainder:0 /sys/class/net/wwan2/cdc_ncm/wNdpOutAlignment:4 /sys/class/net/wwan2/cdc_ncm/wNdpOutDivisor:4 /sys/class/net/wwan2/cdc_ncm/wNdpOutPayloadRemainder:0 /sys/class/net/wwan2/cdc_ncm/wNtbOutMaxDatagrams:1 An interesting feature here is those 3 buffer size attributes are writeable, along with the aggregation timeout: bjorn@nemi:~$ ls -l /sys/class/net/wwan0/cdc_ncm/* -r--r--r-- 1 root root 4096 Oct 9 10:27 /sys/class/net/wwan0/cdc_ncm/bmNtbFormatsSupported -r--r--r-- 1 root root 4096 Oct 9 10:27 /sys/class/net/wwan0/cdc_ncm/dwNtbInMaxSize -r--r--r-- 1 root root 4096 Oct 9 10:27 /sys/class/net/wwan0/cdc_ncm/dwNtbOutMaxSize -rw-r--r-- 1 root root 4096 Oct 9 10:27 /sys/class/net/wwan0/cdc_ncm/min_tx_pkt -rw-r--r-- 1 root root 4096 Oct 9 10:27 /sys/class/net/wwan0/cdc_ncm/rx_max -rw-r--r-- 1 root root 4096 Oct 9 10:27 /sys/class/net/wwan0/cdc_ncm/tx_max -rw-r--r-- 1 root root 4096 Oct 9 10:27 /sys/class/net/wwan0/cdc_ncm/tx_timer_usecs -r--r--r-- 1 root root 4096 Oct 9 10:27 /sys/class/net/wwan0/cdc_ncm/wNdpInAlignment -r--r--r-- 1 root root 4096 Oct 9 10:27 /sys/class/net/wwan0/cdc_ncm/wNdpInDivisor -r--r--r-- 1 root root 4096 Oct 9 10:27 /sys/class/net/wwan0/cdc_ncm/wNdpInPayloadRemainder -r--r--r-- 1 root root 4096 Oct 9 10:27 /sys/class/net/wwan0/cdc_ncm/wNdpOutAlignment -r--r--r-- 1 root root 4096 Oct 9 10:27 /sys/class/net/wwan0/cdc_ncm/wNdpOutDivisor -r--r--r-- 1 root root 4096 Oct 9 10:27 /sys/class/net/wwan0/cdc_ncm/wNdpOutPayloadRemainder -r--r--r-- 1 root root 4096 Oct 9 10:27 /sys/class/net/wwan0/cdc_ncm/wNtbOutMaxDatagrams I know some OpenWRT hosts have had problems using NCM modems with really big buffers (typically Huawei modems), and am hoping that this feature will allow those issues to be resolved. Unfortunately not for anything based on v3.10 or v3.14, but at least in CC... Just one warning: I initially hoped to auto-configure the attributes to globally perfect values, but that turned out to be impossible due to device differences. Some buggy devices will fail if you change any of the buffer sizes from their defaults. So don't do that blindly, or on a wholesale basis. That's also one of the reasons why these settings are per-device. Hmm, I thought I had written some docs for this somewhere, but it doesn't seem so. Well, feel free to improve that now that I've posted everything I remember :-) Bjørn _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel