aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-10-28 17:26:24 -0400
committerDavid S. Miller <davem@davemloft.net>2014-10-28 17:26:24 -0400
commit068301f2be36a5c1ee9a2521c94b98e343612a88 (patch)
tree4260ecf2fef1fb632e6d814323e420919b7d9a97
parent9ffa1fcaef222026a8e031830f8db29d3f2cfc47 (diff)
parentb77e26d191590c73b4a982ea3b3b87194069a56a (diff)
Merge branch 'cdc-ether'
Olivier Blin says: ==================== cdc-ether: handle promiscuous mode Since kernel 3.16, my Lenovo USB network adapters (RTL8153) using cdc-ether are not working anymore in a bridge. This is due to commit c472ab68ad67db23c9907a27649b7dc0899b61f9, which resets the packet filter when the device is bound. The default packet filter set by cdc-ether does not include promiscuous, while the adapter seemed to have promiscuous enabled by default. This patch series allows to support promiscuous mode for cdc-ether, by hooking into set_rx_mode. Incidentally, maybe this device should be handled by the r8152 driver, but this patch series is still nice for other adapters. ==================== Signed-off-by: David S. Miller <davem@davemloft.net> Acked-by: Oliver Neukum <oneukum@suse.de>
-rw-r--r--drivers/net/usb/cdc_ether.c47
-rw-r--r--drivers/net/usb/usbnet.c20
-rw-r--r--include/linux/usb/usbnet.h4
3 files changed, 57 insertions, 14 deletions
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 2a32d9167d3b..d3920b54a92c 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -67,6 +67,35 @@ static const u8 mbm_guid[16] = {
67 0xa6, 0x07, 0xc0, 0xff, 0xcb, 0x7e, 0x39, 0x2a, 67 0xa6, 0x07, 0xc0, 0xff, 0xcb, 0x7e, 0x39, 0x2a,
68}; 68};
69 69
70static void usbnet_cdc_update_filter(struct usbnet *dev)
71{
72 struct cdc_state *info = (void *) &dev->data;
73 struct usb_interface *intf = info->control;
74
75 u16 cdc_filter =
76 USB_CDC_PACKET_TYPE_ALL_MULTICAST | USB_CDC_PACKET_TYPE_DIRECTED |
77 USB_CDC_PACKET_TYPE_BROADCAST;
78
79 if (dev->net->flags & IFF_PROMISC)
80 cdc_filter |= USB_CDC_PACKET_TYPE_PROMISCUOUS;
81
82 /* FIXME cdc-ether has some multicast code too, though it complains
83 * in routine cases. info->ether describes the multicast support.
84 * Implement that here, manipulating the cdc filter as needed.
85 */
86
87 usb_control_msg(dev->udev,
88 usb_sndctrlpipe(dev->udev, 0),
89 USB_CDC_SET_ETHERNET_PACKET_FILTER,
90 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
91 cdc_filter,
92 intf->cur_altsetting->desc.bInterfaceNumber,
93 NULL,
94 0,
95 USB_CTRL_SET_TIMEOUT
96 );
97}
98
70/* probes control interface, claims data interface, collects the bulk 99/* probes control interface, claims data interface, collects the bulk
71 * endpoints, activates data interface (if needed), maybe sets MTU. 100 * endpoints, activates data interface (if needed), maybe sets MTU.
72 * all pure cdc, except for certain firmware workarounds, and knowing 101 * all pure cdc, except for certain firmware workarounds, and knowing
@@ -347,16 +376,8 @@ next_desc:
347 * don't do reset all the way. So the packet filter should 376 * don't do reset all the way. So the packet filter should
348 * be set to a sane initial value. 377 * be set to a sane initial value.
349 */ 378 */
350 usb_control_msg(dev->udev, 379 usbnet_cdc_update_filter(dev);
351 usb_sndctrlpipe(dev->udev, 0), 380
352 USB_CDC_SET_ETHERNET_PACKET_FILTER,
353 USB_TYPE_CLASS | USB_RECIP_INTERFACE,
354 USB_CDC_PACKET_TYPE_ALL_MULTICAST | USB_CDC_PACKET_TYPE_DIRECTED | USB_CDC_PACKET_TYPE_BROADCAST,
355 intf->cur_altsetting->desc.bInterfaceNumber,
356 NULL,
357 0,
358 USB_CTRL_SET_TIMEOUT
359 );
360 return 0; 381 return 0;
361 382
362bad_desc: 383bad_desc:
@@ -468,10 +489,6 @@ int usbnet_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
468 return status; 489 return status;
469 } 490 }
470 491
471 /* FIXME cdc-ether has some multicast code too, though it complains
472 * in routine cases. info->ether describes the multicast support.
473 * Implement that here, manipulating the cdc filter as needed.
474 */
475 return 0; 492 return 0;
476} 493}
477EXPORT_SYMBOL_GPL(usbnet_cdc_bind); 494EXPORT_SYMBOL_GPL(usbnet_cdc_bind);
@@ -482,6 +499,7 @@ static const struct driver_info cdc_info = {
482 .bind = usbnet_cdc_bind, 499 .bind = usbnet_cdc_bind,
483 .unbind = usbnet_cdc_unbind, 500 .unbind = usbnet_cdc_unbind,
484 .status = usbnet_cdc_status, 501 .status = usbnet_cdc_status,
502 .set_rx_mode = usbnet_cdc_update_filter,
485 .manage_power = usbnet_manage_power, 503 .manage_power = usbnet_manage_power,
486}; 504};
487 505
@@ -491,6 +509,7 @@ static const struct driver_info wwan_info = {
491 .bind = usbnet_cdc_bind, 509 .bind = usbnet_cdc_bind,
492 .unbind = usbnet_cdc_unbind, 510 .unbind = usbnet_cdc_unbind,
493 .status = usbnet_cdc_status, 511 .status = usbnet_cdc_status,
512 .set_rx_mode = usbnet_cdc_update_filter,
494 .manage_power = usbnet_manage_power, 513 .manage_power = usbnet_manage_power,
495}; 514};
496 515
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 20615bbd693b..3a6770a65d78 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1052,6 +1052,21 @@ static void __handle_link_change(struct usbnet *dev)
1052 clear_bit(EVENT_LINK_CHANGE, &dev->flags); 1052 clear_bit(EVENT_LINK_CHANGE, &dev->flags);
1053} 1053}
1054 1054
1055static void usbnet_set_rx_mode(struct net_device *net)
1056{
1057 struct usbnet *dev = netdev_priv(net);
1058
1059 usbnet_defer_kevent(dev, EVENT_SET_RX_MODE);
1060}
1061
1062static void __handle_set_rx_mode(struct usbnet *dev)
1063{
1064 if (dev->driver_info->set_rx_mode)
1065 (dev->driver_info->set_rx_mode)(dev);
1066
1067 clear_bit(EVENT_SET_RX_MODE, &dev->flags);
1068}
1069
1055/* work that cannot be done in interrupt context uses keventd. 1070/* work that cannot be done in interrupt context uses keventd.
1056 * 1071 *
1057 * NOTE: with 2.5 we could do more of this using completion callbacks, 1072 * NOTE: with 2.5 we could do more of this using completion callbacks,
@@ -1157,6 +1172,10 @@ skip_reset:
1157 if (test_bit (EVENT_LINK_CHANGE, &dev->flags)) 1172 if (test_bit (EVENT_LINK_CHANGE, &dev->flags))
1158 __handle_link_change(dev); 1173 __handle_link_change(dev);
1159 1174
1175 if (test_bit (EVENT_SET_RX_MODE, &dev->flags))
1176 __handle_set_rx_mode(dev);
1177
1178
1160 if (dev->flags) 1179 if (dev->flags)
1161 netdev_dbg(dev->net, "kevent done, flags = 0x%lx\n", dev->flags); 1180 netdev_dbg(dev->net, "kevent done, flags = 0x%lx\n", dev->flags);
1162} 1181}
@@ -1525,6 +1544,7 @@ static const struct net_device_ops usbnet_netdev_ops = {
1525 .ndo_stop = usbnet_stop, 1544 .ndo_stop = usbnet_stop,
1526 .ndo_start_xmit = usbnet_start_xmit, 1545 .ndo_start_xmit = usbnet_start_xmit,
1527 .ndo_tx_timeout = usbnet_tx_timeout, 1546 .ndo_tx_timeout = usbnet_tx_timeout,
1547 .ndo_set_rx_mode = usbnet_set_rx_mode,
1528 .ndo_change_mtu = usbnet_change_mtu, 1548 .ndo_change_mtu = usbnet_change_mtu,
1529 .ndo_set_mac_address = eth_mac_addr, 1549 .ndo_set_mac_address = eth_mac_addr,
1530 .ndo_validate_addr = eth_validate_addr, 1550 .ndo_validate_addr = eth_validate_addr,
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index 26088feb6608..d9a4905e01d0 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -78,6 +78,7 @@ struct usbnet {
78# define EVENT_NO_RUNTIME_PM 9 78# define EVENT_NO_RUNTIME_PM 9
79# define EVENT_RX_KILL 10 79# define EVENT_RX_KILL 10
80# define EVENT_LINK_CHANGE 11 80# define EVENT_LINK_CHANGE 11
81# define EVENT_SET_RX_MODE 12
81}; 82};
82 83
83static inline struct usb_driver *driver_of(struct usb_interface *intf) 84static inline struct usb_driver *driver_of(struct usb_interface *intf)
@@ -159,6 +160,9 @@ struct driver_info {
159 /* called by minidriver when receiving indication */ 160 /* called by minidriver when receiving indication */
160 void (*indication)(struct usbnet *dev, void *ind, int indlen); 161 void (*indication)(struct usbnet *dev, void *ind, int indlen);
161 162
163 /* rx mode change (device changes address list filtering) */
164 void (*set_rx_mode)(struct usbnet *dev);
165
162 /* for new devices, use the descriptor-reading code instead */ 166 /* for new devices, use the descriptor-reading code instead */
163 int in; /* rx endpoint */ 167 int in; /* rx endpoint */
164 int out; /* tx endpoint */ 168 int out; /* tx endpoint */