net: wireless: bcm4329: Add packet filtering commands
authorDmitry Shmidt <dimitrysh@google.com>
Tue, 12 Jul 2011 00:17:23 +0000 (17:17 -0700)
committerDmitry Shmidt <dimitrysh@google.com>
Wed, 13 Jul 2011 22:59:59 +0000 (15:59 -0700)
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
drivers/net/wireless/bcm4329/dhd.h
drivers/net/wireless/bcm4329/dhd_common.c
drivers/net/wireless/bcm4329/dhd_linux.c
drivers/net/wireless/bcm4329/wl_iw.c
drivers/net/wireless/bcm4329/wl_iw.h

index 9aeca7e4f30ab34e60abae25fadefb5cf3c57fc3..95b334fd62f2702158ac9b6cb11dcb45c67d895b 100644 (file)
@@ -454,4 +454,11 @@ extern void dhd_arp_cleanup(dhd_pub_t *dhd);
 int dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen);
 void dhd_arp_offload_add_ip(dhd_pub_t *dhd, u32 ipaddr);
 
+#define DHD_UNICAST_FILTER_NUM         0
+#define DHD_BROADCAST_FILTER_NUM       1
+#define DHD_MULTICAST4_FILTER_NUM      2
+#define DHD_MULTICAST6_FILTER_NUM      3
+extern int net_os_set_packet_filter(struct net_device *dev, int val);
+extern int net_os_rxfilter_add_remove(struct net_device *dev, int val, int num);
+
 #endif /* _dhd_h_ */
index e50da1414c9e7c4eedfe625af984e066ef1435cd..f7cd372d68c808d83db952ffaf0ffbb33cc4c5af 100644 (file)
@@ -992,6 +992,9 @@ dhd_pktfilter_offload_enable(dhd_pub_t * dhd, char *arg, int enable, int master_
        wl_pkt_filter_enable_t  enable_parm;
        wl_pkt_filter_enable_t  * pkt_filterp;
 
+       if (!arg)
+               return;
+
        if (!(arg_save = MALLOC(dhd->osh, strlen(arg) + 1))) {
                DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
                goto fail;
@@ -1065,6 +1068,9 @@ dhd_pktfilter_offload_set(dhd_pub_t * dhd, char *arg)
        char                            *arg_save = 0, *arg_org = 0;
 #define BUF_SIZE               2048
 
+       if (!arg)
+               return;
+
        if (!(arg_save = MALLOC(dhd->osh, strlen(arg) + 1))) {
                DHD_ERROR(("%s: kmalloc failed\n", __FUNCTION__));
                goto fail;
index f1a25fe1e1db46ef06d30ff96301d5f647d87db8..c2d6587f30a5707d95a29dd8e0de2ff229d6ebc5 100644 (file)
@@ -2301,9 +2301,12 @@ dhd_bus_start(dhd_pub_t *dhdp)
 /* enable dongle roaming event */
        setbit(dhdp->eventmask, WLC_E_ROAM);
 
-       dhdp->pktfilter_count = 1;
+       dhdp->pktfilter_count = 4;
        /* Setup filter to allow only unicast */
        dhdp->pktfilter[0] = "100 0 0 0 0x01 0x00";
+       dhdp->pktfilter[1] = NULL;
+       dhdp->pktfilter[2] = NULL;
+       dhdp->pktfilter[3] = NULL;
 #endif /* EMBEDDED_PLATFORM */
 
        /* Bus is ready, do any protocol initialization */
@@ -3074,6 +3077,35 @@ int net_os_set_dtim_skip(struct net_device *dev, int val)
        return 0;
 }
 
+int net_os_rxfilter_add_remove(struct net_device *dev, int add_remove, int num)
+{
+       dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
+       char *filterp = NULL;
+       int ret = 0;
+
+       if (!dhd || (num == DHD_UNICAST_FILTER_NUM))
+               return ret;
+       if (num >= dhd->pub.pktfilter_count)
+               return -EINVAL;
+       if (add_remove) {
+               switch (num) {
+               case DHD_BROADCAST_FILTER_NUM:
+                       filterp = "101 0 0 0 0xFFFFFFFFFFFF 0xFFFFFFFFFFFF";
+                       break;
+               case DHD_MULTICAST4_FILTER_NUM:
+                       filterp = "102 0 0 0 0xFFFFFF 0x01005E";
+                       break;
+               case DHD_MULTICAST6_FILTER_NUM:
+                       filterp = "103 0 0 0 0xFFFF 0x3333";
+                       break;
+               default:
+                       return -EINVAL;
+               }
+       }
+       dhd->pub.pktfilter[num] = filterp;
+       return ret;
+}
+
 int net_os_set_packet_filter(struct net_device *dev, int val)
 {
        dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
index 230619d901ec13187a13470a85350c0dfc259507..fe4afa9c6d3d09bc319464431d30d2fe4004b429 100644 (file)
@@ -7236,27 +7236,39 @@ static int wl_iw_set_priv(
                        ret = wl_iw_set_pno_enable(dev, info, (union iwreq_data *)dwrq, extra);
 #endif
 #if defined(CSCAN)
-           else if (strnicmp(extra, CSCAN_COMMAND, strlen(CSCAN_COMMAND)) == 0)
+               else if (strnicmp(extra, CSCAN_COMMAND, strlen(CSCAN_COMMAND)) == 0)
                        ret = wl_iw_set_cscan(dev, info, (union iwreq_data *)dwrq, extra);
-#endif 
+#endif
 #ifdef CUSTOMER_HW2
                else if (strnicmp(extra, "POWERMODE", strlen("POWERMODE")) == 0)
                        ret = wl_iw_set_power_mode(dev, info, (union iwreq_data *)dwrq, extra);
-           else if (strnicmp(extra, "BTCOEXMODE", strlen("BTCOEXMODE")) == 0) {
+               else if (strnicmp(extra, "BTCOEXMODE", strlen("BTCOEXMODE")) == 0) {
                        WL_TRACE_COEX(("%s:got Framwrork cmd: 'BTCOEXMODE'\n", __FUNCTION__));
                        ret = wl_iw_set_btcoex_dhcp(dev, info, (union iwreq_data *)dwrq, extra);
-           }
+               }
 #else
                else if (strnicmp(extra, "POWERMODE", strlen("POWERMODE")) == 0)
                        ret = wl_iw_set_btcoex_dhcp(dev, info, (union iwreq_data *)dwrq, extra);
 #endif
                else if (strnicmp(extra, "GETPOWER", strlen("GETPOWER")) == 0)
                        ret = wl_iw_get_power_mode(dev, info, (union iwreq_data *)dwrq, extra);
+               else if (strnicmp(extra, RXFILTER_START_CMD, strlen(RXFILTER_START_CMD)) == 0)
+                       ret = net_os_set_packet_filter(dev, 1);
+               else if (strnicmp(extra, RXFILTER_STOP_CMD, strlen(RXFILTER_STOP_CMD)) == 0)
+                       ret = net_os_set_packet_filter(dev, 0);
+               else if (strnicmp(extra, RXFILTER_ADD_CMD, strlen(RXFILTER_ADD_CMD)) == 0) {
+                       int filter_num = *(extra + strlen(RXFILTER_ADD_CMD) + 1) - '0';
+                       ret = net_os_rxfilter_add_remove(dev, TRUE, filter_num);
+               }
+               else if (strnicmp(extra, RXFILTER_REMOVE_CMD, strlen(RXFILTER_REMOVE_CMD)) == 0) {
+                       int filter_num = *(extra + strlen(RXFILTER_REMOVE_CMD) + 1) - '0';
+                       ret = net_os_rxfilter_add_remove(dev, FALSE, filter_num);
+               }
 #ifdef SOFTAP
 #ifdef SOFTAP_TLV_CFG
                else if (strnicmp(extra, SOFTAP_SET_CMD, strlen(SOFTAP_SET_CMD)) == 0) {
                    wl_iw_softap_cfg_tlv(dev, info, (union iwreq_data *)dwrq, extra);
-           }
+               }
 #endif
                else if (strnicmp(extra, "ASCII_CMD", strlen("ASCII_CMD")) == 0) {
                        wl_iw_process_private_ascii_cmd(dev, info, (union iwreq_data *)dwrq, extra);
index d94bdb4327233dcbc4ac76463336eddaff1c0728..ee6c699936ea0b7bd212e22159eb1ae2b3712ac7 100644 (file)
 #define PNOENABLE_SET_CMD                      "PNOFORCE"
 #define PNODEBUG_SET_CMD                       "PNODEBUG"
 #define TXPOWER_SET_CMD                                "TXPOWER"
+#define RXFILTER_START_CMD                     "RXFILTER-START"
+#define RXFILTER_STOP_CMD                      "RXFILTER-STOP"
+#define RXFILTER_ADD_CMD                       "RXFILTER-ADD"
+#define RXFILTER_REMOVE_CMD                    "RXFILTER-REMOVE"
 
 #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
 #define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
@@ -204,7 +208,6 @@ extern int net_os_wake_lock_timeout_enable(struct net_device *dev);
 extern int net_os_set_suspend_disable(struct net_device *dev, int val);
 extern int net_os_set_suspend(struct net_device *dev, int val);
 extern int net_os_set_dtim_skip(struct net_device *dev, int val);
-extern int net_os_set_packet_filter(struct net_device *dev, int val);
 extern void get_customized_country_code(char *country_iso_code, wl_country_t *cspec);
 extern char *dhd_bus_country_get(struct net_device *dev);
 extern int dhd_get_dtim_skip(dhd_pub_t *dhd);