[RAMEN9610-19423] wlbt : update packet filter for unwanted ARP packet
authorYuseok Kim <yuseok21.kim@samsung.com>
Tue, 18 Jun 2019 11:00:19 +0000 (20:00 +0900)
committerKim Gunho <gunho.kim@samsung.com>
Fri, 30 Aug 2019 07:58:56 +0000 (16:58 +0900)
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
drivers/net/wireless/scsc/mgt.c

index b31c107c00700270f28964864f68d82a32f2c3b6..ea71727958932910f8104836ea35d5dfa7cecaaa 100755 (executable)
@@ -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
index 8fdb70100d8542501216defd83dc154d632b4888..d688fdb6190e6bc5ce9a9f54013b19d8f52a6951 100755 (executable)
@@ -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++;