return ret;
}
-static const struct wiphy_wowlan_support mt7921_wowlan_support = {
- .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT |
- WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | WIPHY_WOWLAN_NET_DETECT,
- .n_patterns = 1,
- .pattern_min_len = 1,
- .pattern_max_len = MT7921_WOW_PATTEN_MAX_LEN,
- .max_nd_match_sets = 10,
-};
-
static int mt7921_load_firmware(struct mt7921_dev *dev)
{
int ret;
mt76_queue_tx_cleanup(dev, dev->mt76.q_mcu[MT_MCUQ_FWDL], false);
#ifdef CONFIG_PM
- dev->mt76.hw->wiphy->wowlan = &mt7921_wowlan_support;
+ dev->mt76.hw->wiphy->wowlan = &mt76_connac_wowlan_support;
#endif /* CONFIG_PM */
dev_err(dev->mt76.dev, "Firmware init done\n");
return mt76_mcu_send_msg(&dev->mt76, MCU_CMD_SET_BSS_CONNECTED, &req,
sizeof(req), false);
}
-
-#ifdef CONFIG_PM
-int mt7921_mcu_set_hif_suspend(struct mt7921_dev *dev, bool suspend)
-{
- struct {
- struct {
- u8 hif_type; /* 0x0: HIF_SDIO
- * 0x1: HIF_USB
- * 0x2: HIF_PCIE
- */
- u8 pad[3];
- } __packed hdr;
- struct hif_suspend_tlv {
- __le16 tag;
- __le16 len;
- u8 suspend;
- } __packed hif_suspend;
- } req = {
- .hif_suspend = {
- .tag = cpu_to_le16(0), /* 0: UNI_HIF_CTRL_BASIC */
- .len = cpu_to_le16(sizeof(struct hif_suspend_tlv)),
- .suspend = suspend,
- },
- };
-
- if (mt76_is_mmio(&dev->mt76))
- req.hdr.hif_type = 2;
- else if (mt76_is_usb(&dev->mt76))
- req.hdr.hif_type = 1;
- else if (mt76_is_sdio(&dev->mt76))
- req.hdr.hif_type = 0;
-
- return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD_HIF_CTRL, &req,
- sizeof(req), true);
-}
-EXPORT_SYMBOL_GPL(mt7921_mcu_set_hif_suspend);
-
-static int
-mt7921_mcu_set_wow_ctrl(struct mt7921_phy *phy, struct ieee80211_vif *vif,
- bool suspend, struct cfg80211_wowlan *wowlan)
-{
- struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
- struct mt7921_dev *dev = phy->dev;
- struct {
- struct {
- u8 bss_idx;
- u8 pad[3];
- } __packed hdr;
- struct mt7921_wow_ctrl_tlv wow_ctrl_tlv;
- struct mt7921_wow_gpio_param_tlv gpio_tlv;
- } req = {
- .hdr = {
- .bss_idx = mvif->mt76.idx,
- },
- .wow_ctrl_tlv = {
- .tag = cpu_to_le16(UNI_SUSPEND_WOW_CTRL),
- .len = cpu_to_le16(sizeof(struct mt7921_wow_ctrl_tlv)),
- .cmd = suspend ? 1 : 2,
- },
- .gpio_tlv = {
- .tag = cpu_to_le16(UNI_SUSPEND_WOW_GPIO_PARAM),
- .len = cpu_to_le16(sizeof(struct mt7921_wow_gpio_param_tlv)),
- .gpio_pin = 0xff, /* follow fw about GPIO pin */
- },
- };
-
- if (wowlan->magic_pkt)
- req.wow_ctrl_tlv.trigger |= BIT(0);
- if (wowlan->disconnect)
- req.wow_ctrl_tlv.trigger |= BIT(2);
- if (wowlan->nd_config) {
- mt76_connac_mcu_sched_scan_req(&dev->mphy, vif,
- wowlan->nd_config);
- req.wow_ctrl_tlv.trigger |= BIT(5);
- mt76_connac_mcu_sched_scan_enable(&dev->mphy, vif, suspend);
- }
-
- if (mt76_is_mmio(&dev->mt76))
- req.wow_ctrl_tlv.wakeup_hif = WOW_PCIE;
- else if (mt76_is_usb(&dev->mt76))
- req.wow_ctrl_tlv.wakeup_hif = WOW_USB;
- else if (mt76_is_sdio(&dev->mt76))
- req.wow_ctrl_tlv.wakeup_hif = WOW_GPIO;
-
- return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD_SUSPEND, &req,
- sizeof(req), true);
-}
-
-static int
-mt7921_mcu_set_wow_pattern(struct mt7921_dev *dev,
- struct ieee80211_vif *vif,
- u8 index, bool enable,
- struct cfg80211_pkt_pattern *pattern)
-{
- struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
- struct mt7921_wow_pattern_tlv *ptlv;
- struct sk_buff *skb;
- struct req_hdr {
- u8 bss_idx;
- u8 pad[3];
- } __packed hdr = {
- .bss_idx = mvif->mt76.idx,
- };
-
- skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
- sizeof(hdr) + sizeof(*ptlv));
- if (!skb)
- return -ENOMEM;
-
- skb_put_data(skb, &hdr, sizeof(hdr));
- ptlv = (struct mt7921_wow_pattern_tlv *)skb_put(skb, sizeof(*ptlv));
- ptlv->tag = cpu_to_le16(UNI_SUSPEND_WOW_PATTERN);
- ptlv->len = cpu_to_le16(sizeof(*ptlv));
- ptlv->data_len = pattern->pattern_len;
- ptlv->enable = enable;
- ptlv->index = index;
-
- memcpy(ptlv->pattern, pattern->pattern, pattern->pattern_len);
- memcpy(ptlv->mask, pattern->mask, pattern->pattern_len / 8);
-
- return mt76_mcu_skb_send_msg(&dev->mt76, skb, MCU_UNI_CMD_SUSPEND,
- true);
-}
-
-static int
-mt7921_mcu_set_suspend_mode(struct mt7921_dev *dev,
- struct ieee80211_vif *vif,
- bool enable, u8 mdtim, bool wow_suspend)
-{
- struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
- struct {
- struct {
- u8 bss_idx;
- u8 pad[3];
- } __packed hdr;
- struct mt7921_suspend_tlv suspend_tlv;
- } req = {
- .hdr = {
- .bss_idx = mvif->mt76.idx,
- },
- .suspend_tlv = {
- .tag = cpu_to_le16(UNI_SUSPEND_MODE_SETTING),
- .len = cpu_to_le16(sizeof(struct mt7921_suspend_tlv)),
- .enable = enable,
- .mdtim = mdtim,
- .wow_suspend = wow_suspend,
- },
- };
-
- return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD_SUSPEND, &req,
- sizeof(req), true);
-}
-
-static int
-mt7921_mcu_set_gtk_rekey(struct mt7921_dev *dev,
- struct ieee80211_vif *vif,
- bool suspend)
-{
- struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
- struct {
- struct {
- u8 bss_idx;
- u8 pad[3];
- } __packed hdr;
- struct mt7921_gtk_rekey_tlv gtk_tlv;
- } __packed req = {
- .hdr = {
- .bss_idx = mvif->mt76.idx,
- },
- .gtk_tlv = {
- .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_GTK_REKEY),
- .len = cpu_to_le16(sizeof(struct mt7921_gtk_rekey_tlv)),
- .rekey_mode = !suspend,
- },
- };
-
- return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD_OFFLOAD, &req,
- sizeof(req), true);
-}
-
-static int
-mt7921_mcu_set_arp_filter(struct mt7921_dev *dev, struct ieee80211_vif *vif,
- bool suspend)
-{
- struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
- struct {
- struct {
- u8 bss_idx;
- u8 pad[3];
- } __packed hdr;
- struct mt7921_arpns_tlv arpns;
- } req = {
- .hdr = {
- .bss_idx = mvif->mt76.idx,
- },
- .arpns = {
- .tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_ARP),
- .len = cpu_to_le16(sizeof(struct mt7921_arpns_tlv)),
- .mode = suspend,
- },
- };
-
- return mt76_mcu_send_msg(&dev->mt76, MCU_UNI_CMD_OFFLOAD, &req,
- sizeof(req), true);
-}
-
-void mt7921_mcu_set_suspend_iter(void *priv, u8 *mac,
- struct ieee80211_vif *vif)
-{
- struct mt7921_phy *phy = priv;
- bool suspend = test_bit(MT76_STATE_SUSPEND, &phy->mt76->state);
- struct ieee80211_hw *hw = phy->mt76->hw;
- struct cfg80211_wowlan *wowlan = hw->wiphy->wowlan_config;
- int i;
-
- mt7921_mcu_set_gtk_rekey(phy->dev, vif, suspend);
- mt7921_mcu_set_arp_filter(phy->dev, vif, suspend);
-
- mt7921_mcu_set_suspend_mode(phy->dev, vif, suspend, 1, true);
-
- for (i = 0; i < wowlan->n_patterns; i++)
- mt7921_mcu_set_wow_pattern(phy->dev, vif, i, suspend,
- &wowlan->patterns[i]);
- mt7921_mcu_set_wow_ctrl(phy, vif, suspend, wowlan);
-}
-
-static void
-mt7921_mcu_key_iter(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- struct ieee80211_sta *sta, struct ieee80211_key_conf *key,
- void *data)
-{
- struct mt7921_gtk_rekey_tlv *gtk_tlv = data;
- u32 cipher;
-
- if (key->cipher != WLAN_CIPHER_SUITE_AES_CMAC &&
- key->cipher != WLAN_CIPHER_SUITE_CCMP &&
- key->cipher != WLAN_CIPHER_SUITE_TKIP)
- return;
-
- if (key->cipher == WLAN_CIPHER_SUITE_TKIP) {
- gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_1);
- cipher = BIT(3);
- } else {
- gtk_tlv->proto = cpu_to_le32(NL80211_WPA_VERSION_2);
- cipher = BIT(4);
- }
-
- /* we are assuming here to have a single pairwise key */
- if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
- gtk_tlv->pairwise_cipher = cpu_to_le32(cipher);
- gtk_tlv->group_cipher = cpu_to_le32(cipher);
- gtk_tlv->keyid = key->keyidx;
- }
-}
-
-int mt7921_mcu_update_gtk_rekey(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct cfg80211_gtk_rekey_data *key)
-{
- struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
- struct mt7921_dev *dev = mt7921_hw_dev(hw);
- struct mt7921_gtk_rekey_tlv *gtk_tlv;
- struct sk_buff *skb;
- struct {
- u8 bss_idx;
- u8 pad[3];
- } __packed hdr = {
- .bss_idx = mvif->mt76.idx,
- };
-
- skb = mt76_mcu_msg_alloc(&dev->mt76, NULL,
- sizeof(hdr) + sizeof(*gtk_tlv));
- if (!skb)
- return -ENOMEM;
-
- skb_put_data(skb, &hdr, sizeof(hdr));
- gtk_tlv = (struct mt7921_gtk_rekey_tlv *)skb_put(skb,
- sizeof(*gtk_tlv));
- gtk_tlv->tag = cpu_to_le16(UNI_OFFLOAD_OFFLOAD_GTK_REKEY);
- gtk_tlv->len = cpu_to_le16(sizeof(*gtk_tlv));
- gtk_tlv->rekey_mode = 2;
- gtk_tlv->option = 1;
-
- rcu_read_lock();
- ieee80211_iter_keys_rcu(hw, vif, mt7921_mcu_key_iter, gtk_tlv);
- rcu_read_unlock();
-
- memcpy(gtk_tlv->kek, key->kek, NL80211_KEK_LEN);
- memcpy(gtk_tlv->kck, key->kck, NL80211_KCK_LEN);
- memcpy(gtk_tlv->replay_ctr, key->replay_ctr, NL80211_REPLAY_CTR_LEN);
-
- return mt76_mcu_skb_send_msg(&dev->mt76, skb, MCU_UNI_CMD_OFFLOAD,
- true);
-}
-#endif /* CONFIG_PM */
__le32 status; /* 0: success, others: fail */
} __packed;
-struct mt7921_wow_ctrl_tlv {
- __le16 tag;
- __le16 len;
- u8 cmd; /* 0x1: PM_WOWLAN_REQ_START
- * 0x2: PM_WOWLAN_REQ_STOP
- * 0x3: PM_WOWLAN_PARAM_CLEAR
- */
- u8 trigger; /* 0: NONE
- * BIT(0): NL80211_WOWLAN_TRIG_MAGIC_PKT
- * BIT(1): NL80211_WOWLAN_TRIG_ANY
- * BIT(2): NL80211_WOWLAN_TRIG_DISCONNECT
- * BIT(3): NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE
- * BIT(4): BEACON_LOST
- * BIT(5): NL80211_WOWLAN_TRIG_NET_DETECT
- */
- u8 wakeup_hif; /* 0x0: HIF_SDIO
- * 0x1: HIF_USB
- * 0x2: HIF_PCIE
- * 0x3: HIF_GPIO
- */
- u8 pad;
- u8 rsv[4];
-} __packed;
-
-struct mt7921_wow_gpio_param_tlv {
- __le16 tag;
- __le16 len;
- u8 gpio_pin;
- u8 trigger_lvl;
- u8 pad[2];
- __le32 gpio_interval;
- u8 rsv[4];
-} __packed;
-
-#define MT7921_WOW_MASK_MAX_LEN 16
-#define MT7921_WOW_PATTEN_MAX_LEN 128
-struct mt7921_wow_pattern_tlv {
- __le16 tag;
- __le16 len;
- u8 index; /* pattern index */
- u8 enable; /* 0: disable
- * 1: enable
- */
- u8 data_len; /* pattern length */
- u8 pad;
- u8 mask[MT7921_WOW_MASK_MAX_LEN];
- u8 pattern[MT7921_WOW_PATTEN_MAX_LEN];
- u8 rsv[4];
-} __packed;
-
-struct mt7921_suspend_tlv {
- __le16 tag;
- __le16 len;
- u8 enable; /* 0: suspend mode disabled
- * 1: suspend mode enabled
- */
- u8 mdtim; /* LP parameter */
- u8 wow_suspend; /* 0: update by origin policy
- * 1: update by wow dtim
- */
- u8 pad[5];
-} __packed;
-
-struct mt7921_gtk_rekey_tlv {
- __le16 tag;
- __le16 len;
- u8 kek[NL80211_KEK_LEN];
- u8 kck[NL80211_KCK_LEN];
- u8 replay_ctr[NL80211_REPLAY_CTR_LEN];
- u8 rekey_mode; /* 0: rekey offload enable
- * 1: rekey offload disable
- * 2: rekey update
- */
- u8 keyid;
- u8 pad[2];
- __le32 proto; /* WPA-RSN-WAPI-OPSN */
- __le32 pairwise_cipher;
- __le32 group_cipher;
- __le32 key_mgmt; /* NONE-PSK-IEEE802.1X */
- __le32 mgmt_group_cipher;
- u8 option; /* 1: rekey data update without enabling offload */
- u8 reserverd[3];
-} __packed;
-
-struct mt7921_arpns_tlv {
- __le16 tag;
- __le16 len;
- u8 mode;
- u8 ips_num;
- u8 option;
- u8 pad[1];
-} __packed;
-
enum {
PATCH_NOT_DL_SEM_FAIL,
PATCH_IS_DL,