ChangeSet 1.1732, 2004/05/17 15:32:03-07:00, [EMAIL PROTECTED]

[PATCH] USB: RNDIS (and CDC) filter flag handling

This should fix the problem David Meggy found, where RNDIS was setting
the OID_GEN_CURRENT_PACKET_FILTER state incorrectly.  It's the same
issue Andrew Morton noticed a while back, for that matter, but with
more than just a "now compiles on 64 bit" fix.

Basically the code needs to interpret 32 bits provided in the request
from the (Windows) host, rather than 8 bits of other memory that's got
some irrelevant value.

The fix is just to save the 32 bits.  I did the same thing with the
CDC Ethernet filter, which should eventually be used the same way:  to
limit what packets get sent to the host.  Also defined a couple more
of the CDC requests.


 drivers/usb/gadget/ether.c |   29 +++++++++++++++++++---
 drivers/usb/gadget/rndis.c |   57 ++++++++++-----------------------------------
 drivers/usb/gadget/rndis.h |    1 
 3 files changed, 39 insertions(+), 48 deletions(-)


diff -Nru a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
--- a/drivers/usb/gadget/ether.c        Mon May 17 16:37:33 2004
+++ b/drivers/usb/gadget/ether.c        Mon May 17 16:37:33 2004
@@ -117,6 +117,7 @@
        unsigned                zlp:1;
        unsigned                cdc:1;
        unsigned                rndis:1;
+       u16                     cdc_filter;
        unsigned long           todo;
 #define        WORK_RX_MEMORY          0
        int                     rndis_config;
@@ -1139,6 +1140,9 @@
        }
        eth_reset_config (dev);
 
+       /* default:  pass all packets, no multicast filtering */
+       dev->cdc_filter = 0x000f;
+
        switch (number) {
        case DEV_CONFIG_VALUE:
                dev->rndis = 0;
@@ -1311,9 +1315,20 @@
  * section 3.6.2.1 table 4 has ACM requests; RNDIS requires the
  * encapsulated command mechanism.
  */
-#define CDC_SEND_ENCAPSULATED_COMMAND  0x00    /* optional */
-#define CDC_GET_ENCAPSULATED_RESPONSE  0x01    /* optional */
-#define CDC_SET_ETHERNET_PACKET_FILTER 0x43    /* required */
+#define CDC_SEND_ENCAPSULATED_COMMAND          0x00    /* optional */
+#define CDC_GET_ENCAPSULATED_RESPONSE          0x01    /* optional */
+#define CDC_SET_ETHERNET_MULTICAST_FILTERS     0x40    /* optional */
+#define CDC_SET_ETHERNET_PM_PATTERN_FILTER     0x41    /* optional */
+#define CDC_GET_ETHERNET_PM_PATTERN_FILTER     0x42    /* optional */
+#define CDC_SET_ETHERNET_PACKET_FILTER         0x43    /* required */
+#define CDC_GET_ETHERNET_STATISTIC             0x44    /* optional */
+
+/* table 62; bits in cdc_filter */
+#define        CDC_PACKET_TYPE_PROMISCUOUS             (1 << 0)
+#define        CDC_PACKET_TYPE_ALL_MULTICAST           (1 << 1) /* no filter */
+#define        CDC_PACKET_TYPE_DIRECTED                (1 << 2)
+#define        CDC_PACKET_TYPE_BROADCAST               (1 << 3)
+#define        CDC_PACKET_TYPE_MULTICAST               (1 << 4) /* filtered */
 
 #ifdef CONFIG_USB_ETH_RNDIS
 
@@ -1513,8 +1528,9 @@
                DEBUG (dev, "NOP packet filter %04x\n", ctrl->wValue);
                /* NOTE: table 62 has 5 filter bits to reduce traffic,
                 * and we "must" support multicast and promiscuous.
-                * this NOP implements a bad filter...
+                * this NOP implements a bad filter (always promisc)
                 */
+               dev->cdc_filter = ctrl->wValue;
                value = 0;
                break;
 #endif /* DEV_CONFIG_CDC */
@@ -1941,6 +1957,11 @@
        int                     retval;
        struct usb_request      *req = 0;
        unsigned long           flags;
+
+       /* FIXME check dev->cdc_filter to decide whether to send this,
+        * instead of acting as if CDC_PACKET_TYPE_PROMISCUOUS were
+        * always set.  RNDIS has the same kind of outgoing filter.
+        */
 
        spin_lock_irqsave (&dev->lock, flags);
        req = container_of (dev->tx_reqs.next, struct usb_request, list);
diff -Nru a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
--- a/drivers/usb/gadget/rndis.c        Mon May 17 16:37:33 2004
+++ b/drivers/usb/gadget/rndis.c        Mon May 17 16:37:33 2004
@@ -78,44 +78,6 @@
 
 static rndis_resp_t *rndis_add_response (int configNr, u32 length);
 
-/* helper functions */
-static u32 devFlags2currentFilter (struct net_device *dev)
-{
-       u32 filter = 0;
-       
-       if (!dev) return 0;
-       
-       if (dev->flags & IFF_MULTICAST) 
-           filter |= NDIS_PACKET_TYPE_MULTICAST;
-       if (dev->flags & IFF_BROADCAST)
-           filter |= NDIS_PACKET_TYPE_BROADCAST;
-       if (dev->flags & IFF_ALLMULTI)
-           filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
-       if (dev->flags & IFF_PROMISC)
-           filter |= NDIS_PACKET_TYPE_PROMISCUOUS;
-       
-       return filter;
-}
-
-static void currentFilter2devFlags (u32 currentFilter, struct net_device *dev)
-{
-       /* FIXME the filter is supposed to control what gets
-        * forwarded from gadget to host; but dev->flags controls
-        * reporting from host to gadget ...
-        */
-#if 0
-       if (!dev) return;
-       if (currentFilter & NDIS_PACKET_TYPE_MULTICAST)
-           dev->flags |= IFF_MULTICAST;
-       if (currentFilter & NDIS_PACKET_TYPE_BROADCAST)
-           dev->flags |= IFF_BROADCAST;
-       if (currentFilter & NDIS_PACKET_TYPE_ALL_MULTICAST)
-           dev->flags |= IFF_ALLMULTI;
-       if (currentFilter & NDIS_PACKET_TYPE_PROMISCUOUS)
-           dev->flags |= IFF_PROMISC;
-#endif
-}
-
 /* FIXME OMITTED OIDs, that RNDIS-on-USB "must" support, include
  *  - power management (OID_PNP_CAPABILITIES, ...)
  *  - network wakeup (OID_PNP_ENABLE_WAKE_UP, ...)
@@ -252,13 +214,12 @@
                        rndis_per_dev_params [configNr].vendorDescr, length);
                retval = 0;
                break;
-               
+
        /* mandatory */
        case OID_GEN_CURRENT_PACKET_FILTER:
                DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__);
                length = 4;
-               *((u32 *) resp + 6) = devFlags2currentFilter (
-                                       rndis_per_dev_params [configNr].dev);
+               *((u32 *) resp + 6) = rndis_per_dev_params[configNr].filter;
                retval = 0;
                break;
                
@@ -767,16 +728,24 @@
 
        switch (OID) {
        case OID_GEN_CURRENT_PACKET_FILTER:
-               DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __FUNCTION__);
                params = &rndis_per_dev_params [configNr];
-               currentFilter2devFlags(cp[28], params->dev);
                retval = 0;
 
+               /* FIXME use this NDIS_PACKET_TYPE_* bitflags to
+                * filter packets in hard_start_xmit()
+                * NDIS_PACKET_TYPE_x == CDC_PACKET_TYPE_x for x in:
+                *      PROMISCUOUS, DIRECTED,
+                *      MULTICAST, ALL_MULTICAST, BROADCAST
+                */
+               params->filter = *(u32 *)buf;
+               DEBUG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n",
+                       __FUNCTION__, params->filter);
+
                /* this call has a significant side effect:  it's
                 * what makes the packet flow start and stop, like
                 * activating the CDC Ethernet altsetting.
                 */
-               if (cp[28]) {
+               if (params->filter) {
                        params->state = RNDIS_DATA_INITIALIZED;
                        netif_carrier_on(params->dev);
                        if (netif_running(params->dev))
diff -Nru a/drivers/usb/gadget/rndis.h b/drivers/usb/gadget/rndis.h
--- a/drivers/usb/gadget/rndis.h        Mon May 17 16:37:33 2004
+++ b/drivers/usb/gadget/rndis.h        Mon May 17 16:37:33 2004
@@ -277,6 +277,7 @@
        u8                      confignr;
        int                     used;
        enum rndis_state        state;
+       u32                     filter;
        u32                     medium;
        u32                     speed;
        u32                     media_state;



-------------------------------------------------------
This SF.Net email is sponsored by: SourceForge.net Broadband
Sign-up now for SourceForge Broadband and get the fastest
6.0/768 connection for only $19.95/mo for the first 3 months!
http://ads.osdn.com/?ad_id%62&alloc_ida84&op=click
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to