From 1445327805bb20734f919703641f8038209f0758 Mon Sep 17 00:00:00 2001 From: dujeonglee Date: Thu, 28 Mar 2019 13:36:31 +0900 Subject: [PATCH] [NEUS7920-133][9610] wlbt: Enhanced packet filter This change filters all unicast except TCP packets in suspended mode SCSC-Bug-Id: SSB-51257 Change-Id: I3d8e651d8a4afc81c3f5b190a984a9bba9129d37 Signed-off-by: dujeonglee --- drivers/net/wireless/scsc/Kconfig | 7 ++ drivers/net/wireless/scsc/dev.h | 14 +++- drivers/net/wireless/scsc/mgt.c | 133 +++++++++++++++++++++++++++++- 3 files changed, 151 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/scsc/Kconfig b/drivers/net/wireless/scsc/Kconfig index fea095676678..675aa64314ab 100755 --- a/drivers/net/wireless/scsc/Kconfig +++ b/drivers/net/wireless/scsc/Kconfig @@ -189,3 +189,10 @@ config SCSC_WLAN_MHS_STATIC_INTERFACE ---help--- This option tells if AP interface has been created statically or dynamically. + +config SCSC_WLAN_ENHANCED_PKT_FILTER + bool "Enable enhanced packet filtering in suspend" + default n + ---help--- + This option tells if UDP packet filtering in suspend is + supported or not. diff --git a/drivers/net/wireless/scsc/dev.h b/drivers/net/wireless/scsc/dev.h index c63b43dbf369..f74715cae579 100755 --- a/drivers/net/wireless/scsc/dev.h +++ b/drivers/net/wireless/scsc/dev.h @@ -448,7 +448,12 @@ enum slsi_filter_id { #ifndef CONFIG_SCSC_WLAN_DISABLE_NAT_KA SLSI_NAT_IPSEC_FILTER_ID, /* 0x84 */ #endif - SLSI_REGD_MC_FILTER_ID = 0x85 +#ifdef CONFIG_SCSC_WLAN_ENHANCED_PKT_FILTER + SLSI_OPT_OUT_ALL_FILTER_ID, /* 0x85 */ + SLSI_OPT_IN_TCP4_FILTER_ID, /* 0x86 */ + SLSI_OPT_IN_TCP6_FILTER_ID, /* 0x87 */ +#endif + SLSI_REGD_MC_FILTER_ID, /* 0x88 */ }; #else @@ -462,7 +467,12 @@ enum slsi_filter_id { #ifndef CONFIG_SCSC_WLAN_DISABLE_NAT_KA SLSI_NAT_IPSEC_FILTER_ID, /* 0x85 */ #endif - SLSI_REGD_MC_FILTER_ID = 0x86 +#ifdef CONFIG_SCSC_WLAN_ENHANCED_PKT_FILTER + SLSI_OPT_OUT_ALL_FILTER_ID, /* 0x86 */ + SLSI_OPT_IN_TCP4_FILTER_ID, /* 0x87 */ + SLSI_OPT_IN_TCP6_FILTER_ID, /* 0x88 */ +#endif + SLSI_REGD_MC_FILTER_ID, /* 0x89 */ }; #endif diff --git a/drivers/net/wireless/scsc/mgt.c b/drivers/net/wireless/scsc/mgt.c index ab2657ac9cfe..4540ca997c3e 100755 --- a/drivers/net/wireless/scsc/mgt.c +++ b/drivers/net/wireless/scsc/mgt.c @@ -12,6 +12,11 @@ #include #endif +#ifdef CONFIG_SCSC_WLAN_ENHANCED_PKT_FILTER +#include +#include +#endif + #include #include "mgt.h" #include "debug.h" @@ -3023,6 +3028,96 @@ int slsi_set_arp_packet_filter(struct slsi_dev *sdev, struct net_device *dev) return ret; } +#ifdef CONFIG_SCSC_WLAN_ENHANCED_PKT_FILTER +static int slsi_set_opt_out_unicast_packet_filter(struct slsi_dev *sdev, struct net_device *dev) +{ + struct slsi_mlme_pattern_desc pattern_desc; + u8 pkt_filters_len = 0; + int ret = 0; + struct slsi_mlme_pkt_filter_elem pkt_filter_elem; + + /* IPv4 packet */ + pattern_desc.offset = 0; /* destination mac address*/ + pattern_desc.mask_length = ETH_ALEN; + memset(pattern_desc.mask, 0xff, ETH_ALEN); + memcpy(pattern_desc.pattern, sdev->hw_addr, ETH_ALEN); + + slsi_create_packet_filter_element(SLSI_OPT_OUT_ALL_FILTER_ID, + FAPI_PACKETFILTERMODE_OPT_OUT_SLEEP, + 1, &pattern_desc, + &pkt_filter_elem, &pkt_filters_len); + + ret = slsi_mlme_set_packet_filter(sdev, dev, pkt_filters_len, 1, &pkt_filter_elem); + + return ret; +} + +static int slsi_set_opt_in_tcp4_packet_filter(struct slsi_dev *sdev, struct net_device *dev) +{ + struct slsi_mlme_pattern_desc pattern_desc[2]; + u8 pkt_filters_len = 0; + int ret = 0; + struct slsi_mlme_pkt_filter_elem pkt_filter_elem; + + /* IPv4 packet */ + pattern_desc[0].offset = ETH_ALEN + ETH_ALEN; /* ethhdr->h_proto */ + pattern_desc[0].mask_length = 2; + pattern_desc[0].mask[0] = 0xff; /* Big endian 0xffff */ + pattern_desc[0].mask[1] = 0xff; + pattern_desc[0].pattern[0] = 0x08; /* Big endian 0x0800 */ + pattern_desc[0].pattern[1] = 0x00; + + /* dest.addr(6) + src.addr(6) + Protocol(2) = sizeof(struct ethhdr) = 14 */ + /* VER(1) + Svc(1) + TotalLen(2) + ID(2) + Flag&Fragmentation(2) + TTL(1) = 9 */ + pattern_desc[1].offset = 23; /* iphdr->protocol */ + pattern_desc[1].mask_length = 1; + pattern_desc[1].mask[0] = 0xff; + pattern_desc[1].pattern[0] = IPPROTO_TCP; /* 0x11 */ + slsi_create_packet_filter_element(SLSI_OPT_IN_TCP4_FILTER_ID, + FAPI_PACKETFILTERMODE_OPT_IN_SLEEP, + 2, + pattern_desc, + &pkt_filter_elem, + &pkt_filters_len); + + ret = slsi_mlme_set_packet_filter(sdev, dev, pkt_filters_len, 1, &pkt_filter_elem); + + return ret; +} + +static int slsi_set_opt_in_tcp6_packet_filter(struct slsi_dev *sdev, struct net_device *dev) +{ + struct slsi_mlme_pattern_desc pattern_desc[2]; + u8 pkt_filters_len = 0; + int ret = 0; + struct slsi_mlme_pkt_filter_elem pkt_filter_elem; + + /* IPv6 packet */ + pattern_desc[0].offset = ETH_ALEN + ETH_ALEN; /* ethhdr->h_proto */ + pattern_desc[0].mask_length = 2; + pattern_desc[0].mask[0] = 0xff; /* Big endian 0xffff */ + pattern_desc[0].mask[1] = 0xff; + pattern_desc[0].pattern[0] = 0x86; /* Big endian 0x86DD */ + pattern_desc[0].pattern[1] = 0xdd; + + pattern_desc[1].offset = sizeof(struct ethhdr) + 6; /*filtering on ipv6->next header*/ + pattern_desc[1].mask_length = 1; + pattern_desc[1].mask[0] = 0xff; + pattern_desc[1].pattern[0] = IPPROTO_TCP; + + slsi_create_packet_filter_element(SLSI_OPT_IN_TCP6_FILTER_ID, + FAPI_PACKETFILTERMODE_OPT_IN_SLEEP, + 2, + pattern_desc, + &pkt_filter_elem, + &pkt_filters_len); + + ret = slsi_mlme_set_packet_filter(sdev, dev, pkt_filters_len, 1, &pkt_filter_elem); + + return ret; +} +#endif + static int slsi_set_multicast_packet_filters(struct slsi_dev *sdev, struct net_device *dev) { struct slsi_mlme_pattern_desc pattern_desc; @@ -3052,10 +3147,15 @@ static int slsi_set_multicast_packet_filters(struct slsi_dev *sdev, struct net_ for (i = 0; i < mc_filter_count; i++) { SLSI_ETHER_COPY(pattern_desc.pattern, ndev_vif->sta.regd_mc_addr[i]); mc_filter_id = SLSI_REGD_MC_FILTER_ID + i; - +#ifdef CONFIG_SCSC_WLAN_ENHANCED_PKT_FILTER + slsi_create_packet_filter_element(mc_filter_id, + FAPI_PACKETFILTERMODE_OPT_IN, + 1, &pattern_desc, &pkt_filter_elem[num_filters], &pkt_filters_len); +#else slsi_create_packet_filter_element(mc_filter_id, FAPI_PACKETFILTERMODE_OPT_IN | FAPI_PACKETFILTERMODE_OPT_IN_SLEEP, 1, &pattern_desc, &pkt_filter_elem[num_filters], &pkt_filters_len); +#endif num_filters++; } @@ -3095,6 +3195,12 @@ int slsi_clear_packet_filters(struct slsi_dev *sdev, struct net_device *dev) #endif } +#ifdef CONFIG_SCSC_WLAN_ENHANCED_PKT_FILTER + num_filters++; /*All OPT OUT*/ + num_filters++; /*TCP IPv4 OPT IN*/ + num_filters++; /*TCP IPv6 OPT IN*/ +#endif + pkt_filter_elem = kmalloc((num_filters * sizeof(struct slsi_mlme_pkt_filter_elem)), GFP_KERNEL); if (!pkt_filter_elem) { SLSI_NET_ERR(dev, "ERROR Memory allocation failure"); @@ -3119,6 +3225,19 @@ int slsi_clear_packet_filters(struct slsi_dev *sdev, struct net_device *dev) slsi_create_packet_filter_element(SLSI_ALL_BC_MC_FILTER_ID, 0, 0, NULL, &pkt_filter_elem[num_filters], &pkt_filters_len); num_filters++; +#ifdef CONFIG_SCSC_WLAN_ENHANCED_PKT_FILTER + slsi_create_packet_filter_element(SLSI_OPT_OUT_ALL_FILTER_ID, 0, 0, NULL, + &pkt_filter_elem[num_filters], &pkt_filters_len); + num_filters++; + slsi_create_packet_filter_element(SLSI_OPT_IN_TCP4_FILTER_ID, 0, 0, NULL, + &pkt_filter_elem[num_filters], &pkt_filters_len); + num_filters++; + slsi_create_packet_filter_element(SLSI_OPT_IN_TCP6_FILTER_ID, 0, 0, NULL, + &pkt_filter_elem[num_filters], &pkt_filters_len); + num_filters++; + SLSI_INFO(sdev, "Enhanced packet filter is removed."); +#endif + ret = slsi_mlme_set_packet_filter(sdev, dev, pkt_filters_len, num_filters, pkt_filter_elem); kfree(pkt_filter_elem); return ret; @@ -3141,6 +3260,18 @@ int slsi_update_packet_filters(struct slsi_dev *sdev, struct net_device *dev) if (ret) return ret; +#ifdef CONFIG_SCSC_WLAN_ENHANCED_PKT_FILTER + ret = slsi_set_opt_out_unicast_packet_filter(sdev, dev); + if (ret) + return ret; + ret = slsi_set_opt_in_tcp4_packet_filter(sdev, dev); + if (ret) + return ret; + ret = slsi_set_opt_in_tcp6_packet_filter(sdev, dev); + if (ret) + return ret; + SLSI_INFO(sdev, "Enhanced packet filter is installed."); +#endif return slsi_set_common_packet_filters(sdev, dev); } -- 2.20.1