summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2011-07-11 17:17:23 -0700
committerDmitry Shmidt <dimitrysh@google.com>2011-07-13 15:59:59 -0700
commit7e26a6f63ad12130c0f3c10eb6515bc2afd099d4 (patch)
tree049e35273b7afc9c5942aa5a3b77613332b52275 /drivers/net
parentbb5b603036b99d80527b222dc98eba4ee8341020 (diff)
net: wireless: bcm4329: Add packet filtering commands
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/bcm4329/dhd.h7
-rw-r--r--drivers/net/wireless/bcm4329/dhd_common.c6
-rw-r--r--drivers/net/wireless/bcm4329/dhd_linux.c34
-rw-r--r--drivers/net/wireless/bcm4329/wl_iw.c22
-rw-r--r--drivers/net/wireless/bcm4329/wl_iw.h5
5 files changed, 67 insertions, 7 deletions
diff --git a/drivers/net/wireless/bcm4329/dhd.h b/drivers/net/wireless/bcm4329/dhd.h
index 9aeca7e4f30..95b334fd62f 100644
--- a/drivers/net/wireless/bcm4329/dhd.h
+++ b/drivers/net/wireless/bcm4329/dhd.h
@@ -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_ */
diff --git a/drivers/net/wireless/bcm4329/dhd_common.c b/drivers/net/wireless/bcm4329/dhd_common.c
index e50da1414c9..f7cd372d68c 100644
--- a/drivers/net/wireless/bcm4329/dhd_common.c
+++ b/drivers/net/wireless/bcm4329/dhd_common.c
@@ -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;
diff --git a/drivers/net/wireless/bcm4329/dhd_linux.c b/drivers/net/wireless/bcm4329/dhd_linux.c
index f1a25fe1e1d..c2d6587f30a 100644
--- a/drivers/net/wireless/bcm4329/dhd_linux.c
+++ b/drivers/net/wireless/bcm4329/dhd_linux.c
@@ -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);
diff --git a/drivers/net/wireless/bcm4329/wl_iw.c b/drivers/net/wireless/bcm4329/wl_iw.c
index 230619d901e..fe4afa9c6d3 100644
--- a/drivers/net/wireless/bcm4329/wl_iw.c
+++ b/drivers/net/wireless/bcm4329/wl_iw.c
@@ -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);
diff --git a/drivers/net/wireless/bcm4329/wl_iw.h b/drivers/net/wireless/bcm4329/wl_iw.h
index d94bdb43272..ee6c699936e 100644
--- a/drivers/net/wireless/bcm4329/wl_iw.h
+++ b/drivers/net/wireless/bcm4329/wl_iw.h
@@ -53,6 +53,10 @@
#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);