diff options
Diffstat (limited to 'drivers/net/usb')
-rw-r--r-- | drivers/net/usb/cdc_mbim.c | 57 | ||||
-rw-r--r-- | drivers/net/usb/cdc_ncm.c | 2 | ||||
-rw-r--r-- | drivers/net/usb/qmi_wwan.c | 28 |
3 files changed, 70 insertions, 17 deletions
diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c index c9f3281506af..2e025ddcef21 100644 --- a/drivers/net/usb/cdc_mbim.c +++ b/drivers/net/usb/cdc_mbim.c | |||
@@ -120,6 +120,16 @@ static void cdc_mbim_unbind(struct usbnet *dev, struct usb_interface *intf) | |||
120 | cdc_ncm_unbind(dev, intf); | 120 | cdc_ncm_unbind(dev, intf); |
121 | } | 121 | } |
122 | 122 | ||
123 | /* verify that the ethernet protocol is IPv4 or IPv6 */ | ||
124 | static bool is_ip_proto(__be16 proto) | ||
125 | { | ||
126 | switch (proto) { | ||
127 | case htons(ETH_P_IP): | ||
128 | case htons(ETH_P_IPV6): | ||
129 | return true; | ||
130 | } | ||
131 | return false; | ||
132 | } | ||
123 | 133 | ||
124 | static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) | 134 | static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) |
125 | { | 135 | { |
@@ -128,6 +138,7 @@ static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb | |||
128 | struct cdc_ncm_ctx *ctx = info->ctx; | 138 | struct cdc_ncm_ctx *ctx = info->ctx; |
129 | __le32 sign = cpu_to_le32(USB_CDC_MBIM_NDP16_IPS_SIGN); | 139 | __le32 sign = cpu_to_le32(USB_CDC_MBIM_NDP16_IPS_SIGN); |
130 | u16 tci = 0; | 140 | u16 tci = 0; |
141 | bool is_ip; | ||
131 | u8 *c; | 142 | u8 *c; |
132 | 143 | ||
133 | if (!ctx) | 144 | if (!ctx) |
@@ -137,25 +148,32 @@ static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb | |||
137 | if (skb->len <= ETH_HLEN) | 148 | if (skb->len <= ETH_HLEN) |
138 | goto error; | 149 | goto error; |
139 | 150 | ||
151 | /* Some applications using e.g. packet sockets will | ||
152 | * bypass the VLAN acceleration and create tagged | ||
153 | * ethernet frames directly. We primarily look for | ||
154 | * the accelerated out-of-band tag, but fall back if | ||
155 | * required | ||
156 | */ | ||
157 | skb_reset_mac_header(skb); | ||
158 | if (vlan_get_tag(skb, &tci) < 0 && skb->len > VLAN_ETH_HLEN && | ||
159 | __vlan_get_tag(skb, &tci) == 0) { | ||
160 | is_ip = is_ip_proto(vlan_eth_hdr(skb)->h_vlan_encapsulated_proto); | ||
161 | skb_pull(skb, VLAN_ETH_HLEN); | ||
162 | } else { | ||
163 | is_ip = is_ip_proto(eth_hdr(skb)->h_proto); | ||
164 | skb_pull(skb, ETH_HLEN); | ||
165 | } | ||
166 | |||
140 | /* mapping VLANs to MBIM sessions: | 167 | /* mapping VLANs to MBIM sessions: |
141 | * no tag => IPS session <0> | 168 | * no tag => IPS session <0> |
142 | * 1 - 255 => IPS session <vlanid> | 169 | * 1 - 255 => IPS session <vlanid> |
143 | * 256 - 511 => DSS session <vlanid - 256> | 170 | * 256 - 511 => DSS session <vlanid - 256> |
144 | * 512 - 4095 => unsupported, drop | 171 | * 512 - 4095 => unsupported, drop |
145 | */ | 172 | */ |
146 | vlan_get_tag(skb, &tci); | ||
147 | |||
148 | switch (tci & 0x0f00) { | 173 | switch (tci & 0x0f00) { |
149 | case 0x0000: /* VLAN ID 0 - 255 */ | 174 | case 0x0000: /* VLAN ID 0 - 255 */ |
150 | /* verify that datagram is IPv4 or IPv6 */ | 175 | if (!is_ip) |
151 | skb_reset_mac_header(skb); | ||
152 | switch (eth_hdr(skb)->h_proto) { | ||
153 | case htons(ETH_P_IP): | ||
154 | case htons(ETH_P_IPV6): | ||
155 | break; | ||
156 | default: | ||
157 | goto error; | 176 | goto error; |
158 | } | ||
159 | c = (u8 *)&sign; | 177 | c = (u8 *)&sign; |
160 | c[3] = tci; | 178 | c[3] = tci; |
161 | break; | 179 | break; |
@@ -169,7 +187,6 @@ static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb | |||
169 | "unsupported tci=0x%04x\n", tci); | 187 | "unsupported tci=0x%04x\n", tci); |
170 | goto error; | 188 | goto error; |
171 | } | 189 | } |
172 | skb_pull(skb, ETH_HLEN); | ||
173 | } | 190 | } |
174 | 191 | ||
175 | spin_lock_bh(&ctx->mtx); | 192 | spin_lock_bh(&ctx->mtx); |
@@ -204,17 +221,23 @@ static void do_neigh_solicit(struct usbnet *dev, u8 *buf, u16 tci) | |||
204 | return; | 221 | return; |
205 | 222 | ||
206 | /* need to send the NA on the VLAN dev, if any */ | 223 | /* need to send the NA on the VLAN dev, if any */ |
207 | if (tci) | 224 | rcu_read_lock(); |
225 | if (tci) { | ||
208 | netdev = __vlan_find_dev_deep(dev->net, htons(ETH_P_8021Q), | 226 | netdev = __vlan_find_dev_deep(dev->net, htons(ETH_P_8021Q), |
209 | tci); | 227 | tci); |
210 | else | 228 | if (!netdev) { |
229 | rcu_read_unlock(); | ||
230 | return; | ||
231 | } | ||
232 | } else { | ||
211 | netdev = dev->net; | 233 | netdev = dev->net; |
212 | if (!netdev) | 234 | } |
213 | return; | 235 | dev_hold(netdev); |
236 | rcu_read_unlock(); | ||
214 | 237 | ||
215 | in6_dev = in6_dev_get(netdev); | 238 | in6_dev = in6_dev_get(netdev); |
216 | if (!in6_dev) | 239 | if (!in6_dev) |
217 | return; | 240 | goto out; |
218 | is_router = !!in6_dev->cnf.forwarding; | 241 | is_router = !!in6_dev->cnf.forwarding; |
219 | in6_dev_put(in6_dev); | 242 | in6_dev_put(in6_dev); |
220 | 243 | ||
@@ -224,6 +247,8 @@ static void do_neigh_solicit(struct usbnet *dev, u8 *buf, u16 tci) | |||
224 | true /* solicited */, | 247 | true /* solicited */, |
225 | false /* override */, | 248 | false /* override */, |
226 | true /* inc_opt */); | 249 | true /* inc_opt */); |
250 | out: | ||
251 | dev_put(netdev); | ||
227 | } | 252 | } |
228 | 253 | ||
229 | static bool is_neigh_solicit(u8 *buf, size_t len) | 254 | static bool is_neigh_solicit(u8 *buf, size_t len) |
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 549dbac710ed..9a2bd11943eb 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c | |||
@@ -785,7 +785,7 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign) | |||
785 | skb_out->len > CDC_NCM_MIN_TX_PKT) | 785 | skb_out->len > CDC_NCM_MIN_TX_PKT) |
786 | memset(skb_put(skb_out, ctx->tx_max - skb_out->len), 0, | 786 | memset(skb_put(skb_out, ctx->tx_max - skb_out->len), 0, |
787 | ctx->tx_max - skb_out->len); | 787 | ctx->tx_max - skb_out->len); |
788 | else if ((skb_out->len % dev->maxpacket) == 0) | 788 | else if (skb_out->len < ctx->tx_max && (skb_out->len % dev->maxpacket) == 0) |
789 | *skb_put(skb_out, 1) = 0; /* force short packet */ | 789 | *skb_put(skb_out, 1) = 0; /* force short packet */ |
790 | 790 | ||
791 | /* set final frame length */ | 791 | /* set final frame length */ |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index e3458e3c44f1..83208d4fdc59 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
@@ -669,6 +669,22 @@ static const struct usb_device_id products[] = { | |||
669 | {QMI_FIXED_INTF(0x05c6, 0x920d, 5)}, | 669 | {QMI_FIXED_INTF(0x05c6, 0x920d, 5)}, |
670 | {QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */ | 670 | {QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */ |
671 | {QMI_FIXED_INTF(0x12d1, 0x14ac, 1)}, /* Huawei E1820 */ | 671 | {QMI_FIXED_INTF(0x12d1, 0x14ac, 1)}, /* Huawei E1820 */ |
672 | {QMI_FIXED_INTF(0x16d8, 0x6003, 0)}, /* CMOTech 6003 */ | ||
673 | {QMI_FIXED_INTF(0x16d8, 0x6007, 0)}, /* CMOTech CHE-628S */ | ||
674 | {QMI_FIXED_INTF(0x16d8, 0x6008, 0)}, /* CMOTech CMU-301 */ | ||
675 | {QMI_FIXED_INTF(0x16d8, 0x6280, 0)}, /* CMOTech CHU-628 */ | ||
676 | {QMI_FIXED_INTF(0x16d8, 0x7001, 0)}, /* CMOTech CHU-720S */ | ||
677 | {QMI_FIXED_INTF(0x16d8, 0x7002, 0)}, /* CMOTech 7002 */ | ||
678 | {QMI_FIXED_INTF(0x16d8, 0x7003, 4)}, /* CMOTech CHU-629K */ | ||
679 | {QMI_FIXED_INTF(0x16d8, 0x7004, 3)}, /* CMOTech 7004 */ | ||
680 | {QMI_FIXED_INTF(0x16d8, 0x7006, 5)}, /* CMOTech CGU-629 */ | ||
681 | {QMI_FIXED_INTF(0x16d8, 0x700a, 4)}, /* CMOTech CHU-629S */ | ||
682 | {QMI_FIXED_INTF(0x16d8, 0x7211, 0)}, /* CMOTech CHU-720I */ | ||
683 | {QMI_FIXED_INTF(0x16d8, 0x7212, 0)}, /* CMOTech 7212 */ | ||
684 | {QMI_FIXED_INTF(0x16d8, 0x7213, 0)}, /* CMOTech 7213 */ | ||
685 | {QMI_FIXED_INTF(0x16d8, 0x7251, 1)}, /* CMOTech 7251 */ | ||
686 | {QMI_FIXED_INTF(0x16d8, 0x7252, 1)}, /* CMOTech 7252 */ | ||
687 | {QMI_FIXED_INTF(0x16d8, 0x7253, 1)}, /* CMOTech 7253 */ | ||
672 | {QMI_FIXED_INTF(0x19d2, 0x0002, 1)}, | 688 | {QMI_FIXED_INTF(0x19d2, 0x0002, 1)}, |
673 | {QMI_FIXED_INTF(0x19d2, 0x0012, 1)}, | 689 | {QMI_FIXED_INTF(0x19d2, 0x0012, 1)}, |
674 | {QMI_FIXED_INTF(0x19d2, 0x0017, 3)}, | 690 | {QMI_FIXED_INTF(0x19d2, 0x0017, 3)}, |
@@ -730,16 +746,28 @@ static const struct usb_device_id products[] = { | |||
730 | {QMI_FIXED_INTF(0x114f, 0x68a2, 8)}, /* Sierra Wireless MC7750 */ | 746 | {QMI_FIXED_INTF(0x114f, 0x68a2, 8)}, /* Sierra Wireless MC7750 */ |
731 | {QMI_FIXED_INTF(0x1199, 0x68a2, 8)}, /* Sierra Wireless MC7710 in QMI mode */ | 747 | {QMI_FIXED_INTF(0x1199, 0x68a2, 8)}, /* Sierra Wireless MC7710 in QMI mode */ |
732 | {QMI_FIXED_INTF(0x1199, 0x68a2, 19)}, /* Sierra Wireless MC7710 in QMI mode */ | 748 | {QMI_FIXED_INTF(0x1199, 0x68a2, 19)}, /* Sierra Wireless MC7710 in QMI mode */ |
749 | {QMI_FIXED_INTF(0x1199, 0x68c0, 8)}, /* Sierra Wireless MC73xx */ | ||
750 | {QMI_FIXED_INTF(0x1199, 0x68c0, 10)}, /* Sierra Wireless MC73xx */ | ||
751 | {QMI_FIXED_INTF(0x1199, 0x68c0, 11)}, /* Sierra Wireless MC73xx */ | ||
733 | {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ | 752 | {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ |
753 | {QMI_FIXED_INTF(0x1199, 0x901f, 8)}, /* Sierra Wireless EM7355 */ | ||
754 | {QMI_FIXED_INTF(0x1199, 0x9041, 8)}, /* Sierra Wireless MC7305/MC7355 */ | ||
734 | {QMI_FIXED_INTF(0x1199, 0x9051, 8)}, /* Netgear AirCard 340U */ | 755 | {QMI_FIXED_INTF(0x1199, 0x9051, 8)}, /* Netgear AirCard 340U */ |
735 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ | 756 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ |
757 | {QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */ | ||
736 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ | 758 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ |
737 | {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ | 759 | {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ |
738 | {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ | 760 | {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ |
739 | {QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */ | 761 | {QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */ |
740 | {QMI_FIXED_INTF(0x0b3c, 0xc005, 6)}, /* Olivetti Olicard 200 */ | 762 | {QMI_FIXED_INTF(0x0b3c, 0xc005, 6)}, /* Olivetti Olicard 200 */ |
763 | {QMI_FIXED_INTF(0x0b3c, 0xc00b, 4)}, /* Olivetti Olicard 500 */ | ||
741 | {QMI_FIXED_INTF(0x1e2d, 0x0060, 4)}, /* Cinterion PLxx */ | 764 | {QMI_FIXED_INTF(0x1e2d, 0x0060, 4)}, /* Cinterion PLxx */ |
742 | {QMI_FIXED_INTF(0x1e2d, 0x0053, 4)}, /* Cinterion PHxx,PXxx */ | 765 | {QMI_FIXED_INTF(0x1e2d, 0x0053, 4)}, /* Cinterion PHxx,PXxx */ |
766 | {QMI_FIXED_INTF(0x413c, 0x81a2, 8)}, /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card */ | ||
767 | {QMI_FIXED_INTF(0x413c, 0x81a3, 8)}, /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card */ | ||
768 | {QMI_FIXED_INTF(0x413c, 0x81a4, 8)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */ | ||
769 | {QMI_FIXED_INTF(0x413c, 0x81a8, 8)}, /* Dell Wireless 5808 Gobi(TM) 4G LTE Mobile Broadband Card */ | ||
770 | {QMI_FIXED_INTF(0x413c, 0x81a9, 8)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */ | ||
743 | 771 | ||
744 | /* 4. Gobi 1000 devices */ | 772 | /* 4. Gobi 1000 devices */ |
745 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ | 773 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ |