From 48efd98e52b226c03b8833ebd34889676c58aa4d Mon Sep 17 00:00:00 2001 From: Yuseok Kim Date: Tue, 18 Jun 2019 20:00:19 +0900 Subject: [PATCH] [RAMEN9610-19423] wlbt : update packet filter for unwanted ARP packet Sometimes, Client send unicast ARP packet with different IP range. And, Wifi module processes it and wakes up the host. But, It is weakness from the point of view of power consumption. Since the desired ARP is offloaded from the FW, the other ARP packets that are not needed will be dropped. Change-Id: I34c0c7e29ca5deb1da7da899182e953db6bd7276 --- drivers/net/wireless/scsc/dev.h | 40 +++++++++++++++++---------------- drivers/net/wireless/scsc/mgt.c | 36 ++++++++++++++++++++++------- 2 files changed, 49 insertions(+), 27 deletions(-) diff --git a/drivers/net/wireless/scsc/dev.h b/drivers/net/wireless/scsc/dev.h index b31c107c0070..ea7172795893 100755 --- a/drivers/net/wireless/scsc/dev.h +++ b/drivers/net/wireless/scsc/dev.h @@ -458,38 +458,40 @@ struct slsi_wmm_parameter_element { #ifdef CONFIG_SCSC_WLAN_BLOCK_IPV6 enum slsi_filter_id { - SLSI_LOCAL_ARP_FILTER_ID = SLSI_MIN_FILTER_ID, /* 0x80 */ - SLSI_ALL_BC_MC_FILTER_ID, /* 0x81 */ - SLSI_PROXY_ARP_FILTER_ID, /* 0x82 */ - SLSI_ALL_IPV6_PKTS_FILTER_ID, /* 0x83 */ + SLSI_ALL_ARP_FILTER_ID = SLSI_MIN_FILTER_ID, /* 0x80 */ + SLSI_LOCAL_ARP_FILTER_ID, /* 0x81 */ + SLSI_ALL_BC_MC_FILTER_ID, /* 0x82 */ + SLSI_PROXY_ARP_FILTER_ID, /* 0x83 */ + SLSI_ALL_IPV6_PKTS_FILTER_ID, /* 0x84 */ #ifndef CONFIG_SCSC_WLAN_DISABLE_NAT_KA - SLSI_NAT_IPSEC_FILTER_ID, /* 0x84 */ + SLSI_NAT_IPSEC_FILTER_ID, /* 0x85 */ #endif #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 */ + 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, /* 0x88 */ + SLSI_REGD_MC_FILTER_ID, /* 0x89 */ }; #else /* for STA */ enum slsi_filter_id { - SLSI_LOCAL_ARP_FILTER_ID = SLSI_MIN_FILTER_ID, /* 0x80 */ - SLSI_ALL_BC_MC_FILTER_ID, /* 0x81 */ - SLSI_PROXY_ARP_FILTER_ID, /* 0x82 */ - SLSI_LOCAL_NS_FILTER_ID, /* 0x83 */ - SLSI_PROXY_ARP_NA_FILTER_ID, /* 0x84 */ + SLSI_ALL_ARP_FILTER_ID = SLSI_MIN_FILTER_ID, /* 0x80 */ + SLSI_LOCAL_ARP_FILTER_ID, /* 0x81 */ + SLSI_ALL_BC_MC_FILTER_ID, /* 0x82 */ + SLSI_PROXY_ARP_FILTER_ID, /* 0x83 */ + SLSI_LOCAL_NS_FILTER_ID, /* 0x84 */ + SLSI_PROXY_ARP_NA_FILTER_ID, /* 0x85 */ #ifndef CONFIG_SCSC_WLAN_DISABLE_NAT_KA - SLSI_NAT_IPSEC_FILTER_ID, /* 0x85 */ + SLSI_NAT_IPSEC_FILTER_ID, /* 0x86 */ #endif #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 */ + SLSI_OPT_OUT_ALL_FILTER_ID, /* 0x87 */ + SLSI_OPT_IN_TCP4_FILTER_ID, /* 0x88 */ + SLSI_OPT_IN_TCP6_FILTER_ID, /* 0x89 */ #endif - SLSI_REGD_MC_FILTER_ID, /* 0x89 */ + SLSI_REGD_MC_FILTER_ID, /* 0x8A */ }; #endif diff --git a/drivers/net/wireless/scsc/mgt.c b/drivers/net/wireless/scsc/mgt.c index 8fdb70100d85..d688fdb6190e 100755 --- a/drivers/net/wireless/scsc/mgt.c +++ b/drivers/net/wireless/scsc/mgt.c @@ -3233,7 +3233,7 @@ int slsi_set_arp_packet_filter(struct slsi_dev *sdev, struct net_device *dev) struct slsi_mlme_pattern_desc pattern_desc[SLSI_MAX_PATTERN_DESC]; int num_pattern_desc = 0; u8 pkt_filters_len = 0, num_filters = 0; - struct slsi_mlme_pkt_filter_elem pkt_filter_elem[2]; + struct slsi_mlme_pkt_filter_elem pkt_filter_elem[3]; int ret; struct netdev_vif *ndev_vif = netdev_priv(dev); struct slsi_peer *peer = slsi_get_peer_from_qs(sdev, dev, SLSI_STA_PEER_QUEUESET); @@ -3255,15 +3255,31 @@ int slsi_set_arp_packet_filter(struct slsi_dev *sdev, struct net_device *dev) SLSI_NET_DBG2(dev, SLSI_MLME, "Set ARP filter\n"); - /*Opt in the broadcast ARP packets for Local IP address*/ + /* Opt out all ARP requests*/ num_pattern_desc = 0; - pattern_desc[num_pattern_desc].offset = 0; /*filtering on MAC destination Address*/ - pattern_desc[num_pattern_desc].mask_length = ETH_ALEN; - SLSI_ETHER_COPY(pattern_desc[num_pattern_desc].mask, addr_mask); - SLSI_ETHER_COPY(pattern_desc[num_pattern_desc].pattern, addr_mask); + SET_ETHERTYPE_PATTERN_DESC(pattern_desc[num_pattern_desc], ETH_P_ARP); num_pattern_desc++; - /*filter on ethertype ARP*/ + /* ARP - Request */ + pattern_desc[num_pattern_desc].offset = 0x14; /*sizeof(struct ethhdr) + offsetof(ar_op)*/ + pattern_desc[num_pattern_desc].mask_length = 2; + pattern_desc[num_pattern_desc].mask[0] = 0xff; + pattern_desc[num_pattern_desc].mask[1] = 0xff; + pattern_desc[num_pattern_desc].pattern[0] = 0x00; + pattern_desc[num_pattern_desc].pattern[1] = 0x01; + num_pattern_desc++; + + slsi_create_packet_filter_element(SLSI_ALL_ARP_FILTER_ID, + FAPI_PACKETFILTERMODE_OPT_OUT | FAPI_PACKETFILTERMODE_OPT_OUT_SLEEP, + num_pattern_desc, pattern_desc, &pkt_filter_elem[num_filters], &pkt_filters_len); + num_filters++; + + ret = slsi_mlme_set_packet_filter(sdev, dev, pkt_filters_len, num_filters, pkt_filter_elem); + if (ret) + return ret; + + /*Opt-in arp pakcet for device IP address*/ + num_pattern_desc = 0; SET_ETHERTYPE_PATTERN_DESC(pattern_desc[num_pattern_desc], ETH_P_ARP); num_pattern_desc++; @@ -3273,7 +3289,8 @@ int slsi_set_arp_packet_filter(struct slsi_dev *sdev, struct net_device *dev) memcpy(pattern_desc[num_pattern_desc].pattern, &ndev_vif->ipaddress, pattern_desc[num_pattern_desc].mask_length); num_pattern_desc++; - slsi_create_packet_filter_element(SLSI_LOCAL_ARP_FILTER_ID, FAPI_PACKETFILTERMODE_OPT_IN, + slsi_create_packet_filter_element(SLSI_LOCAL_ARP_FILTER_ID, + FAPI_PACKETFILTERMODE_OPT_IN | FAPI_PACKETFILTERMODE_OPT_IN_SLEEP, num_pattern_desc, pattern_desc, &pkt_filter_elem[num_filters], &pkt_filters_len); num_filters++; @@ -3509,6 +3526,7 @@ int slsi_clear_packet_filters(struct slsi_dev *sdev, struct net_device *dev) num_filters = ndev_vif->sta.regd_mc_addr_count + SLSI_SCREEN_OFF_FILTERS_COUNT; if ((slsi_is_proxy_arp_supported_on_ap(peer->assoc_resp_ie)) == false) { num_filters++; + num_filters++; #ifndef CONFIG_SCSC_WLAN_BLOCK_IPV6 num_filters++; #endif @@ -3537,6 +3555,8 @@ int slsi_clear_packet_filters(struct slsi_dev *sdev, struct net_device *dev) if ((slsi_is_proxy_arp_supported_on_ap(peer->assoc_resp_ie)) == false) { slsi_create_packet_filter_element(SLSI_LOCAL_ARP_FILTER_ID, 0, 0, NULL, &pkt_filter_elem[num_filters], &pkt_filters_len); num_filters++; + slsi_create_packet_filter_element(SLSI_ALL_ARP_FILTER_ID, 0, 0, NULL, &pkt_filter_elem[num_filters], &pkt_filters_len); + num_filters++; #ifndef CONFIG_SCSC_WLAN_BLOCK_IPV6 slsi_create_packet_filter_element(SLSI_LOCAL_NS_FILTER_ID, 0, 0, NULL, &pkt_filter_elem[num_filters], &pkt_filters_len); num_filters++; -- 2.20.1