diff options
author | Daniele Palmas <dnlplm@gmail.com> | 2018-12-21 07:07:23 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-12-21 13:58:45 -0500 |
commit | d667044f49513d55fcfefe4fa8f8d96091782901 (patch) | |
tree | 0ac86cd1b884e56eda7c2a38f5b68408d97fe10d | |
parent | 7c3db4105ce8d69bcb5c04bfa9acd1e9119af8d5 (diff) |
qmi_wwan: Fix qmap header retrieval in qmimux_rx_fixup
This patch fixes qmap header retrieval when modem is configured for
dl data aggregation.
Signed-off-by: Daniele Palmas <dnlplm@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/usb/qmi_wwan.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index f5bac5075386..774e1ff01c9a 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
@@ -151,17 +151,18 @@ static bool qmimux_has_slaves(struct usbnet *dev) | |||
151 | 151 | ||
152 | static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | 152 | static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb) |
153 | { | 153 | { |
154 | unsigned int len, offset = sizeof(struct qmimux_hdr); | 154 | unsigned int len, offset = 0; |
155 | struct qmimux_hdr *hdr; | 155 | struct qmimux_hdr *hdr; |
156 | struct net_device *net; | 156 | struct net_device *net; |
157 | struct sk_buff *skbn; | 157 | struct sk_buff *skbn; |
158 | u8 qmimux_hdr_sz = sizeof(*hdr); | ||
158 | 159 | ||
159 | while (offset < skb->len) { | 160 | while (offset + qmimux_hdr_sz < skb->len) { |
160 | hdr = (struct qmimux_hdr *)skb->data; | 161 | hdr = (struct qmimux_hdr *)(skb->data + offset); |
161 | len = be16_to_cpu(hdr->pkt_len); | 162 | len = be16_to_cpu(hdr->pkt_len); |
162 | 163 | ||
163 | /* drop the packet, bogus length */ | 164 | /* drop the packet, bogus length */ |
164 | if (offset + len > skb->len) | 165 | if (offset + len + qmimux_hdr_sz > skb->len) |
165 | return 0; | 166 | return 0; |
166 | 167 | ||
167 | /* control packet, we do not know what to do */ | 168 | /* control packet, we do not know what to do */ |
@@ -176,7 +177,7 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
176 | return 0; | 177 | return 0; |
177 | skbn->dev = net; | 178 | skbn->dev = net; |
178 | 179 | ||
179 | switch (skb->data[offset] & 0xf0) { | 180 | switch (skb->data[offset + qmimux_hdr_sz] & 0xf0) { |
180 | case 0x40: | 181 | case 0x40: |
181 | skbn->protocol = htons(ETH_P_IP); | 182 | skbn->protocol = htons(ETH_P_IP); |
182 | break; | 183 | break; |
@@ -188,12 +189,12 @@ static int qmimux_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
188 | goto skip; | 189 | goto skip; |
189 | } | 190 | } |
190 | 191 | ||
191 | skb_put_data(skbn, skb->data + offset, len); | 192 | skb_put_data(skbn, skb->data + offset + qmimux_hdr_sz, len); |
192 | if (netif_rx(skbn) != NET_RX_SUCCESS) | 193 | if (netif_rx(skbn) != NET_RX_SUCCESS) |
193 | return 0; | 194 | return 0; |
194 | 195 | ||
195 | skip: | 196 | skip: |
196 | offset += len + sizeof(struct qmimux_hdr); | 197 | offset += len + qmimux_hdr_sz; |
197 | } | 198 | } |
198 | return 1; | 199 | return 1; |
199 | } | 200 | } |