OSDN Git Service

mt76: mt7663: introduce ARP filter offload
authorSean Wang <sean.wang@mediatek.com>
Sun, 7 Jun 2020 09:34:40 +0000 (11:34 +0200)
committerFelix Fietkau <nbd@nbd.name>
Tue, 21 Jul 2020 17:01:14 +0000 (19:01 +0200)
Introduce ARP filter offload

Co-developed-by: Wan-Feng Jiang <Wan-Feng.Jiang@mediatek.com>
Signed-off-by: Wan-Feng Jiang <Wan-Feng.Jiang@mediatek.com>
Co-developed-by: Soul Huang <Soul.Huang@mediatek.com>
Signed-off-by: Soul Huang <Soul.Huang@mediatek.com>
Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt7615/main.c
drivers/net/wireless/mediatek/mt76/mt7615/mcu.c
drivers/net/wireless/mediatek/mt76/mt7615/mcu.h
drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h

index dfebf86..e6dbd70 100644 (file)
@@ -491,6 +491,9 @@ static void mt7615_bss_info_changed(struct ieee80211_hw *hw,
        if (changed & BSS_CHANGED_PS)
                mt7615_mcu_set_vif_ps(dev, vif);
 
+       if (changed & BSS_CHANGED_ARP_FILTER)
+               mt7615_mcu_update_arp_filter(hw, vif, info);
+
        mutex_unlock(&dev->mt76.mutex);
 }
 
index 6e869b8..b76ecc2 100644 (file)
@@ -3542,6 +3542,32 @@ mt7615_mcu_set_gtk_rekey(struct mt7615_dev *dev,
                                   &req, sizeof(req), true);
 }
 
+static int
+mt7615_mcu_set_arp_filter(struct mt7615_dev *dev, struct ieee80211_vif *vif,
+                         bool suspend)
+{
+       struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
+       struct {
+               struct {
+                       u8 bss_idx;
+                       u8 pad[3];
+               } __packed hdr;
+               struct mt7615_arpns_tlv arpns;
+       } req = {
+               .hdr = {
+                       .bss_idx = mvif->idx,
+               },
+               .arpns = {
+                       .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP),
+                       .len = cpu_to_le16(sizeof(struct mt7615_arpns_tlv)),
+                       .mode = suspend,
+               },
+       };
+
+       return __mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD_OFFLOAD,
+                                  &req, sizeof(req), true);
+}
+
 void mt7615_mcu_set_suspend_iter(void *priv, u8 *mac,
                                 struct ieee80211_vif *vif)
 {
@@ -3554,6 +3580,7 @@ void mt7615_mcu_set_suspend_iter(void *priv, u8 *mac,
        mt7615_mcu_set_bss_pm(phy->dev, vif, suspend);
 
        mt7615_mcu_set_gtk_rekey(phy->dev, vif, suspend);
+       mt7615_mcu_set_arp_filter(phy->dev, vif, suspend);
 
        mt7615_mcu_set_suspend_mode(phy->dev, vif, suspend, 1, true);
 
@@ -3653,6 +3680,53 @@ int mt7615_mcu_set_roc(struct mt7615_phy *phy, struct ieee80211_vif *vif,
                                   sizeof(req), false);
 }
 
+int mt7615_mcu_update_arp_filter(struct ieee80211_hw *hw,
+                                struct ieee80211_vif *vif,
+                                struct ieee80211_bss_conf *info)
+{
+       struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
+       struct mt7615_dev *dev = mt7615_hw_dev(hw);
+       struct sk_buff *skb;
+       int i, len = min_t(int, info->arp_addr_cnt,
+                          IEEE80211_BSS_ARP_ADDR_LIST_LEN);
+       struct {
+               struct {
+                       u8 bss_idx;
+                       u8 pad[3];
+               } __packed hdr;
+               struct mt7615_arpns_tlv arp;
+       } req_hdr = {
+               .hdr = {
+                       .bss_idx = mvif->idx,
+               },
+               .arp = {
+                       .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP),
+                       .len = cpu_to_le16(sizeof(struct mt7615_arpns_tlv)),
+                       .ips_num = len,
+                       .mode = 2,  /* update */
+                       .option = 1,
+               },
+       };
+
+       if (!mt7615_firmware_offload(dev))
+               return 0;
+
+       skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
+                                sizeof(req_hdr) + len * sizeof(__be32));
+       if (!skb)
+               return -ENOMEM;
+
+       skb_put_data(skb, &req_hdr, sizeof(req_hdr));
+       for (i = 0; i < len; i++) {
+               u8 *addr = (u8 *)skb_put(skb, sizeof(__be32));
+
+               memcpy(addr, &info->arp_addr_list[i], sizeof(__be32));
+       }
+
+       return __mt76_mcu_skb_send_msg(&dev->mt76, skb,
+                                      MCU_UNI_CMD_OFFLOAD, true);
+}
+
 int mt7615_mcu_set_p2p_oppps(struct ieee80211_hw *hw,
                             struct ieee80211_vif *vif)
 {
index 2314d0b..64f7471 100644 (file)
@@ -545,6 +545,15 @@ struct mt7615_roc_tlv {
        u8 rsv1[8];
 } __packed;
 
+struct mt7615_arpns_tlv {
+       __le16 tag;
+       __le16 len;
+       u8 mode;
+       u8 ips_num;
+       u8 option;
+       u8 pad[1];
+} __packed;
+
 /* offload mcu commands */
 enum {
        MCU_CMD_START_HW_SCAN = MCU_CE_PREFIX | 0x03,
@@ -580,8 +589,8 @@ enum {
 };
 
 enum {
-       UNI_OFFLOAD_OFFLOAD_ARPNS_IPV4,
-       UNI_OFFLOAD_OFFLOAD_ARPNS_IPV6,
+       UNI_OFFLOAD_OFFLOAD_ARP,
+       UNI_OFFLOAD_OFFLOAD_ND,
        UNI_OFFLOAD_OFFLOAD_GTK_REKEY,
        UNI_OFFLOAD_OFFLOAD_BMC_RPY_DETECT,
 };
index 640ff8b..913dac5 100644 (file)
@@ -586,7 +586,9 @@ void mt7615_mcu_set_suspend_iter(void *priv, u8 *mac,
 int mt7615_mcu_update_gtk_rekey(struct ieee80211_hw *hw,
                                struct ieee80211_vif *vif,
                                struct cfg80211_gtk_rekey_data *key);
-
+int mt7615_mcu_update_arp_filter(struct ieee80211_hw *hw,
+                                struct ieee80211_vif *vif,
+                                struct ieee80211_bss_conf *info);
 int __mt7663_load_firmware(struct mt7615_dev *dev);
 
 /* usb */