This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
playground:mission-log-template1 [2014-11-04 10:24] – removed chrono | playground:mission-log-template1 [2015-07-15 13:59] (current) – chrono | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== Fixing Kernel drivers for Huawei E3372s LTE/4G Stick====== | ||
+ | In order to mitigate the problem of having no internet at all, we got a SIM-Card for LTE/4Ǵ. At the same time the Telekom Speedstick V LTE (which is basically a rebranded Huawei 3372s) became available and not too expensive. A little research showed that it should be really easy to deploy this stick, when flashing a Non-HiLink Firmware (< | ||
+ | |||
+ | < | ||
+ | $ echo " | ||
+ | $ udhcpc wwan0 | ||
+ | </ | ||
+ | |||
+ | and should be done with it. In reality this became quite a quest but with combined efforts we managed to get it to work and created a patch for current kernels (tested 3.18.[11-18]. If you also have this stick and are unable to get an IP via dhcp, this patch might be for you. | ||
+ | |||
+ | < | ||
+ | $ make clean | ||
+ | $ make target/ | ||
+ | $ cd build_dir/ | ||
+ | $ patch -p1 -i / | ||
+ | </ | ||
+ | |||
+ | <sxh c> | ||
+ | diff -u a/ | ||
+ | --- a/ | ||
+ | +++ b/ | ||
+ | @@ -158,7 +158,7 @@ | ||
+ | if (!cdc_ncm_comm_intf_is_mbim(intf-> | ||
+ | | ||
+ | |||
+ | - ret = cdc_ncm_bind_common(dev, | ||
+ | + ret = cdc_ncm_bind_common(dev, | ||
+ | if (ret) | ||
+ | | ||
+ | |||
+ | diff -u a/ | ||
+ | --- a/ | ||
+ | +++ b/ | ||
+ | @@ -684,10 +684,11 @@ | ||
+ | | ||
+ | } | ||
+ | |||
+ | + kfree(ctx-> | ||
+ | | ||
+ | } | ||
+ | |||
+ | -int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting) | ||
+ | +int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting, | ||
+ | { | ||
+ | | ||
+ | | ||
+ | @@ -855,6 +856,17 @@ | ||
+ | /* finish setting up the device specific data */ | ||
+ | | ||
+ | |||
+ | + /* Device-specific flags */ | ||
+ | + ctx-> | ||
+ | + | ||
+ | + /* Allocate the delayed NDP if needed. */ | ||
+ | + if (ctx-> | ||
+ | + ctx-> | ||
+ | + if (!ctx-> | ||
+ | + goto error2; | ||
+ | + dev_info(& | ||
+ | + } | ||
+ | + | ||
+ | /* override ethtool_ops */ | ||
+ | | ||
+ | @@ -954,8 +966,11 @@ | ||
+ | if (cdc_ncm_select_altsetting(intf) != CDC_NCM_COMM_ALTSETTING_NCM) | ||
+ | | ||
+ | |||
+ | - /* The NCM data altsetting is fixed */ | ||
+ | - ret = cdc_ncm_bind_common(dev, | ||
+ | + /* The NCM data altsetting is fixed, so we hard-coded it. | ||
+ | + * Additionally, | ||
+ | + * placed NDP. | ||
+ | + */ | ||
+ | + ret = cdc_ncm_bind_common(dev, | ||
+ | |||
+ | /* | ||
+ | * We should get an event when network connection is " | ||
+ | @@ -986,6 +1001,14 @@ | ||
+ | | ||
+ | | ||
+ | |||
+ | + /* If NDP should be moved to the end of the NCM package, we can't follow the | ||
+ | + * NTH16 header as we would normally do. NDP isn't written to the SKB yet, and | ||
+ | + * the wNdpIndex field in the header is actually not consistent with reality. It will be later. | ||
+ | + */ | ||
+ | + if (ctx-> | ||
+ | + if (ctx-> | ||
+ | + return ctx-> | ||
+ | + | ||
+ | /* follow the chain of NDPs, looking for a match */ | ||
+ | | ||
+ | | ||
+ | @@ -995,7 +1018,8 @@ | ||
+ | } | ||
+ | |||
+ | /* align new NDP */ | ||
+ | - cdc_ncm_align_tail(skb, | ||
+ | + if (!(ctx-> | ||
+ | + cdc_ncm_align_tail(skb, | ||
+ | |||
+ | /* verify that there is room for the NDP and the datagram (reserve) */ | ||
+ | if ((ctx-> | ||
+ | @@ -1008,7 +1032,11 @@ | ||
+ | | ||
+ | |||
+ | /* push a new empty NDP */ | ||
+ | - ndp16 = (struct usb_cdc_ncm_ndp16 *)memset(skb_put(skb, | ||
+ | + if (!(ctx-> | ||
+ | + ndp16 = (struct usb_cdc_ncm_ndp16 *)memset(skb_put(skb, | ||
+ | + else | ||
+ | + ndp16 = ctx-> | ||
+ | + | ||
+ | | ||
+ | | ||
+ | | ||
+ | @@ -1023,6 +1051,15 @@ | ||
+ | | ||
+ | u16 n = 0, index, ndplen; | ||
+ | u8 ready2send = 0; | ||
+ | + u32 delayed_ndp_size; | ||
+ | + | ||
+ | + /* When our NDP gets written in cdc_ncm_ndp(), | ||
+ | + * accordingly. Otherwise, we should check here. | ||
+ | + */ | ||
+ | + if (ctx-> | ||
+ | + delayed_ndp_size = ctx-> | ||
+ | + else | ||
+ | + delayed_ndp_size = 0; | ||
+ | |||
+ | /* if there is a remaining skb, it gets priority */ | ||
+ | if (skb != NULL) { | ||
+ | @@ -1077,7 +1114,7 @@ | ||
+ | | ||
+ | |||
+ | /* check if we had enough room left for both NDP and frame */ | ||
+ | - if (!ndp16 || skb_out-> | ||
+ | + if (!ndp16 || skb_out-> | ||
+ | if (n == 0) { | ||
+ | | ||
+ | | ||
+ | |||
+ | @@ -1150,6 +1187,17 @@ | ||
+ | /* variables will be reset at next call */ | ||
+ | } | ||
+ | |||
+ | + /* If requested, put NDP at end of frame. */ | ||
+ | + if (ctx-> | ||
+ | + nth16 = (struct usb_cdc_ncm_nth16 *)skb_out-> | ||
+ | + cdc_ncm_align_tail(skb_out, | ||
+ | + nth16-> | ||
+ | + memcpy(skb_put(skb_out, | ||
+ | + | ||
+ | + /* Zero out delayed NDP - signature checking will naturally fail. */ | ||
+ | + ndp16 = memset(ctx-> | ||
+ | + } | ||
+ | + | ||
+ | /* If collected data size is less or equal ctx-> | ||
+ | * bytes, we send buffers as it is. If we get more data, it | ||
+ | * would be more efficient for USB HS mobile device with DMA | ||
+ | diff -u a/ | ||
+ | --- a/ | ||
+ | +++ b/ | ||
+ | @@ -73,11 +73,14 @@ | ||
+ | | ||
+ | int ret = -ENODEV; | ||
+ | | ||
+ | + int drvflags = 0; | ||
+ | |||
+ | /* altsetting should always be 1 for NCM devices - so we hard-coded | ||
+ | - * it here | ||
+ | + * it here. Some huawei devices will need the NDP part of the NCM package to | ||
+ | + * be at the end of the frame. | ||
+ | */ | ||
+ | - ret = cdc_ncm_bind_common(usbnet_dev, | ||
+ | + drvflags |= CDC_NCM_FLAG_NDP_TO_END; | ||
+ | + ret = cdc_ncm_bind_common(usbnet_dev, | ||
+ | if (ret) | ||
+ | | ||
+ | |||
+ | diff -u a/ | ||
+ | --- a/ | ||
+ | +++ b/ | ||
+ | @@ -80,6 +80,9 @@ | ||
+ | # | ||
+ | # | ||
+ | |||
+ | +/* Driver flags */ | ||
+ | +#define CDC_NCM_FLAG_NDP_TO_END 0x02 / | ||
+ | + | ||
+ | # | ||
+ | | ||
+ | # | ||
+ | @@ -103,9 +106,11 @@ | ||
+ | |||
+ | | ||
+ | | ||
+ | + int drvflags; | ||
+ | |||
+ | u32 timer_interval; | ||
+ | u32 max_ndp_size; | ||
+ | + struct usb_cdc_ncm_ndp16 *delayed_ndp16; | ||
+ | |||
+ | u32 tx_timer_pending; | ||
+ | u32 tx_curr_frame_num; | ||
+ | @@ -133,7 +138,7 @@ | ||
+ | }; | ||
+ | |||
+ | u8 cdc_ncm_select_altsetting(struct usb_interface *intf); | ||
+ | -int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting); | ||
+ | +int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting, | ||
+ | void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf); | ||
+ | | ||
+ | int cdc_ncm_rx_verify_nth16(struct cdc_ncm_ctx *ctx, struct sk_buff *skb_in); | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | {{tag> | ||
+ | |||
+ | ~~DISCUSSION~~ |