mt76: enable p2p support
authorLorenzo Bianconi <lorenzo@kernel.org>
Tue, 12 May 2020 20:02:49 +0000 (22:02 +0200)
committerFelix Fietkau <nbd@nbd.name>
Wed, 13 May 2020 18:01:11 +0000 (20:01 +0200)
Introduce p2p-go/p2p-client suppor to mt76 driver

Co-developed-by: Sean Wang <sean.wang@mediatek.com>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mac80211.c
drivers/net/wireless/mediatek/mt76/mt7603/init.c
drivers/net/wireless/mediatek/mt76/mt7615/init.c
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
drivers/net/wireless/mediatek/mt76/mt76x02_util.c

index 21407704f1b3d9e1d07e02c2752db048ac43fc5f..9070981018981f02ef65b4e76634203a1e93c694 100644 (file)
@@ -313,6 +313,8 @@ mt76_phy_init(struct mt76_dev *dev, struct ieee80211_hw *hw)
 #ifdef CONFIG_MAC80211_MESH
                BIT(NL80211_IFTYPE_MESH_POINT) |
 #endif
+               BIT(NL80211_IFTYPE_P2P_CLIENT) |
+               BIT(NL80211_IFTYPE_P2P_GO) |
                BIT(NL80211_IFTYPE_ADHOC);
 }
 
index f641a8b56b396cdc000ae0cb381f5964e1e3ad81..94196599797e4de0ed3f55b1076694d9fefaeea1 100644 (file)
@@ -342,6 +342,8 @@ static const struct ieee80211_iface_limit if_limits[] = {
 #ifdef CONFIG_MAC80211_MESH
                         BIT(NL80211_IFTYPE_MESH_POINT) |
 #endif
+                        BIT(NL80211_IFTYPE_P2P_CLIENT) |
+                        BIT(NL80211_IFTYPE_P2P_GO) |
                         BIT(NL80211_IFTYPE_AP)
         },
 };
index 6e1a17f08f5ef66f86a8cbf3e56554c55d50da91..b5bbe9f5f7dd739979d33fddf8aa37ba5fd30d6b 100644 (file)
@@ -140,7 +140,9 @@ void mt7615_check_offload_capability(struct mt7615_dev *dev)
                ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
 
                wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR |
-                                  NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR;
+                                  NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR |
+                                  NL80211_FEATURE_P2P_GO_CTWIN |
+                                  NL80211_FEATURE_P2P_GO_OPPPS;
        } else {
                dev->ops->hw_scan = NULL;
                dev->ops->cancel_hw_scan = NULL;
@@ -205,6 +207,8 @@ static const struct ieee80211_iface_limit if_limits[] = {
 #ifdef CONFIG_MAC80211_MESH
                         BIT(NL80211_IFTYPE_MESH_POINT) |
 #endif
+                        BIT(NL80211_IFTYPE_P2P_CLIENT) |
+                        BIT(NL80211_IFTYPE_P2P_GO) |
                         BIT(NL80211_IFTYPE_STATION)
        }
 };
index c8705f91bafcb4d49a64e2d3db1bdb951eb97545..e87a5843c7189a82304d9b20b7931cede6d8df17 100644 (file)
@@ -503,6 +503,9 @@ static void mt7615_bss_info_changed(struct ieee80211_hw *hw,
        if (changed & BSS_CHANGED_BEACON_ENABLED) {
                mt7615_mcu_add_bss_info(phy, vif, NULL, info->enable_beacon);
                mt7615_mcu_sta_add(dev, vif, NULL, info->enable_beacon);
+
+               if (vif->p2p && info->enable_beacon)
+                       mt7615_mcu_set_p2p_oppps(hw, vif);
        }
 
        if (changed & (BSS_CHANGED_BEACON |
index e9ae7e94d8fd333ce7e56a2f2746824c9a6db262..92ea9dc3c1c676d9cb1fac5920101970489b9a05 100644 (file)
@@ -695,9 +695,9 @@ mt7615_mcu_bss_basic_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
                         struct ieee80211_sta *sta, bool enable)
 {
        struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
+       u32 type = vif->p2p ? NETWORK_P2P : NETWORK_INFRA;
        struct bss_info_basic *bss;
        u8 wlan_idx = mvif->sta.wcid.idx;
-       u32 type = NETWORK_INFRA;
        struct tlv *tlv;
 
        tlv = mt7615_mcu_add_tlv(skb, BSS_INFO_BASIC, sizeof(*bss));
@@ -749,10 +749,16 @@ mt7615_mcu_bss_omac_tlv(struct sk_buff *skb, struct ieee80211_vif *vif)
        switch (vif->type) {
        case NL80211_IFTYPE_MESH_POINT:
        case NL80211_IFTYPE_AP:
-               type = CONNECTION_INFRA_AP;
+               if (vif->p2p)
+                       type = CONNECTION_P2P_GO;
+               else
+                       type = CONNECTION_INFRA_AP;
                break;
        case NL80211_IFTYPE_STATION:
-               type = CONNECTION_INFRA_STA;
+               if (vif->p2p)
+                       type = CONNECTION_P2P_GC;
+               else
+                       type = CONNECTION_INFRA_STA;
                break;
        case NL80211_IFTYPE_ADHOC:
                type = CONNECTION_IBSS_ADHOC;
@@ -815,6 +821,7 @@ mt7615_mcu_sta_basic_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
 {
        struct sta_rec_basic *basic;
        struct tlv *tlv;
+       int conn_type;
 
        tlv = mt7615_mcu_add_tlv(skb, STA_REC_BASIC, sizeof(*basic));
 
@@ -837,11 +844,19 @@ mt7615_mcu_sta_basic_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
        switch (vif->type) {
        case NL80211_IFTYPE_MESH_POINT:
        case NL80211_IFTYPE_AP:
-               basic->conn_type = cpu_to_le32(CONNECTION_INFRA_STA);
+               if (vif->p2p)
+                       conn_type = CONNECTION_P2P_GC;
+               else
+                       conn_type = CONNECTION_INFRA_STA;
+               basic->conn_type = cpu_to_le32(conn_type);
                basic->aid = cpu_to_le16(sta->aid);
                break;
        case NL80211_IFTYPE_STATION:
-               basic->conn_type = cpu_to_le32(CONNECTION_INFRA_AP);
+               if (vif->p2p)
+                       conn_type = CONNECTION_P2P_GO;
+               else
+                       conn_type = CONNECTION_INFRA_AP;
+               basic->conn_type = cpu_to_le32(conn_type);
                basic->aid = cpu_to_le16(vif->bss_conf.aid);
                break;
        case NL80211_IFTYPE_ADHOC:
@@ -1403,7 +1418,7 @@ mt7615_mcu_uni_add_bss(struct mt7615_phy *phy, struct ieee80211_vif *vif,
                        .short_st = true,
                },
        };
-       int err;
+       int err, conn_type;
        u8 idx;
 
        idx = mvif->omac_idx > EXT_BSSID_START ? HW_BSSID_0 : mvif->omac_idx;
@@ -1412,10 +1427,18 @@ mt7615_mcu_uni_add_bss(struct mt7615_phy *phy, struct ieee80211_vif *vif,
        switch (vif->type) {
        case NL80211_IFTYPE_MESH_POINT:
        case NL80211_IFTYPE_AP:
-               basic_req.basic.conn_type = cpu_to_le32(CONNECTION_INFRA_AP);
+               if (vif->p2p)
+                       conn_type = CONNECTION_P2P_GO;
+               else
+                       conn_type = CONNECTION_INFRA_AP;
+               basic_req.basic.conn_type = cpu_to_le32(conn_type);
                break;
        case NL80211_IFTYPE_STATION:
-               basic_req.basic.conn_type = cpu_to_le32(CONNECTION_INFRA_STA);
+               if (vif->p2p)
+                       conn_type = CONNECTION_P2P_GC;
+               else
+                       conn_type = CONNECTION_INFRA_STA;
+               basic_req.basic.conn_type = cpu_to_le32(conn_type);
                break;
        case NL80211_IFTYPE_ADHOC:
                basic_req.basic.conn_type = cpu_to_le32(CONNECTION_IBSS_ADHOC);
@@ -3550,3 +3573,25 @@ int mt7615_mcu_update_gtk_rekey(struct ieee80211_hw *hw,
                                       MCU_UNI_CMD_OFFLOAD, true);
 }
 #endif /* CONFIG_PM */
+
+int mt7615_mcu_set_p2p_oppps(struct ieee80211_hw *hw,
+                            struct ieee80211_vif *vif)
+{
+       struct mt7615_vif *mvif = (struct mt7615_vif *)vif->drv_priv;
+       int ct_window = vif->bss_conf.p2p_noa_attr.oppps_ctwindow;
+       struct mt7615_dev *dev = mt7615_hw_dev(hw);
+       struct {
+               __le32 ct_win;
+               u8 bss_idx;
+               u8 rsv[3];
+       } __packed req = {
+               .ct_win = cpu_to_le32(ct_window),
+               .bss_idx = mvif->idx,
+       };
+
+       if (!mt7615_firmware_offload(dev))
+               return -ENOTSUPP;
+
+       return __mt76_mcu_send_msg(&dev->mt76, MCU_CMD_SET_P2P_OPPPS,
+                                  &req, sizeof(req), false);
+}
index 0f12e6da89af72a3049ed89c1a35426775cc280d..338fd077f57584652b4cc1d09fd972c7e704d18d 100644 (file)
@@ -507,6 +507,7 @@ enum {
        MCU_CMD_SET_BSS_CONNECTED = MCU_CE_PREFIX | 0x16,
        MCU_CMD_SET_BSS_ABORT = MCU_CE_PREFIX | 0x17,
        MCU_CMD_CANCEL_HW_SCAN = MCU_CE_PREFIX | 0x1b,
+       MCU_CMD_SET_P2P_OPPPS = MCU_CE_PREFIX | 0x33,
        MCU_CMD_SCHED_SCAN_ENABLE = MCU_CE_PREFIX | 0x61,
        MCU_CMD_SCHED_SCAN_REQ = MCU_CE_PREFIX | 0x62,
 };
index dc60abb0a1301b2ec004d9f2c5b302b764e4356d..ebdfca64b0794ab82907a99d23c11b7c91e0d955 100644 (file)
@@ -530,6 +530,8 @@ int mt7615_mcu_apply_tx_dpd(struct mt7615_phy *phy);
 void m7615_mcu_set_ps_iter(void *priv, u8 *mac, struct ieee80211_vif *vif);
 int mt7615_dfs_init_radar_detector(struct mt7615_phy *phy);
 
+int mt7615_mcu_set_p2p_oppps(struct ieee80211_hw *hw,
+                            struct ieee80211_vif *vif);
 int mt7615_firmware_own(struct mt7615_dev *dev);
 int mt7615_driver_own(struct mt7615_dev *dev);
 
index b7a120b0856d95ba90463b03a0969aa3e3bf502d..9a2c9afa2fb5ec48d688b1731e1f8f176f194d87 100644 (file)
@@ -46,6 +46,8 @@ static const struct ieee80211_iface_limit mt76x02_if_limits[] = {
 #ifdef CONFIG_MAC80211_MESH
                         BIT(NL80211_IFTYPE_MESH_POINT) |
 #endif
+                        BIT(NL80211_IFTYPE_P2P_CLIENT) |
+                        BIT(NL80211_IFTYPE_P2P_GO) |
                         BIT(NL80211_IFTYPE_AP)
         },
 };
@@ -60,6 +62,8 @@ static const struct ieee80211_iface_limit mt76x02u_if_limits[] = {
 #ifdef CONFIG_MAC80211_MESH
                         BIT(NL80211_IFTYPE_MESH_POINT) |
 #endif
+                        BIT(NL80211_IFTYPE_P2P_CLIENT) |
+                        BIT(NL80211_IFTYPE_P2P_GO) |
                         BIT(NL80211_IFTYPE_AP)
        },
 };