diff options
Diffstat (limited to 'drivers/net/wireless/quantenna/qtnfmac/cfg80211.c')
-rw-r--r-- | drivers/net/wireless/quantenna/qtnfmac/cfg80211.c | 259 |
1 files changed, 51 insertions, 208 deletions
diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c index a450bc6bc774..7d6dc76c930a 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c +++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c @@ -73,7 +73,10 @@ qtnf_mgmt_stypes[NUM_NL80211_IFTYPES] = { [NL80211_IFTYPE_AP] = { .tx = BIT(IEEE80211_STYPE_ACTION >> 4), .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | - BIT(IEEE80211_STYPE_PROBE_REQ >> 4), + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | + BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4), }, }; @@ -133,6 +136,7 @@ int qtnf_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev) vif->netdev = NULL; vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED; eth_zero_addr(vif->mac_addr); + eth_zero_addr(vif->bssid); return 0; } @@ -201,6 +205,8 @@ err_mac: qtnf_cmd_send_del_intf(vif); err_cmd: vif->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED; + eth_zero_addr(vif->mac_addr); + eth_zero_addr(vif->bssid); return ERR_PTR(-EFAULT); } @@ -211,10 +217,10 @@ static int qtnf_mgmt_set_appie(struct qtnf_vif *vif, int ret = 0; if (!info->beacon_ies || !info->beacon_ies_len) { - ret = qtnf_cmd_send_mgmt_set_appie(vif, QLINK_MGMT_FRAME_BEACON, + ret = qtnf_cmd_send_mgmt_set_appie(vif, QLINK_IE_SET_BEACON_IES, NULL, 0); } else { - ret = qtnf_cmd_send_mgmt_set_appie(vif, QLINK_MGMT_FRAME_BEACON, + ret = qtnf_cmd_send_mgmt_set_appie(vif, QLINK_IE_SET_BEACON_IES, info->beacon_ies, info->beacon_ies_len); } @@ -224,11 +230,11 @@ static int qtnf_mgmt_set_appie(struct qtnf_vif *vif, if (!info->proberesp_ies || !info->proberesp_ies_len) { ret = qtnf_cmd_send_mgmt_set_appie(vif, - QLINK_MGMT_FRAME_PROBE_RESP, + QLINK_IE_SET_PROBE_RESP_IES, NULL, 0); } else { ret = qtnf_cmd_send_mgmt_set_appie(vif, - QLINK_MGMT_FRAME_PROBE_RESP, + QLINK_IE_SET_PROBE_RESP_IES, info->proberesp_ies, info->proberesp_ies_len); } @@ -238,11 +244,11 @@ static int qtnf_mgmt_set_appie(struct qtnf_vif *vif, if (!info->assocresp_ies || !info->assocresp_ies_len) { ret = qtnf_cmd_send_mgmt_set_appie(vif, - QLINK_MGMT_FRAME_ASSOC_RESP, + QLINK_IE_SET_ASSOC_RESP, NULL, 0); } else { ret = qtnf_cmd_send_mgmt_set_appie(vif, - QLINK_MGMT_FRAME_ASSOC_RESP, + QLINK_IE_SET_ASSOC_RESP, info->assocresp_ies, info->assocresp_ies_len); } @@ -256,11 +262,6 @@ static int qtnf_change_beacon(struct wiphy *wiphy, struct net_device *dev, { struct qtnf_vif *vif = qtnf_netdev_get_priv(dev); - if (!(vif->bss_status & QTNF_STATE_AP_START)) { - pr_err("VIF%u.%u: not started\n", vif->mac->macid, vif->vifid); - return -EFAULT; - } - return qtnf_mgmt_set_appie(vif, info); } @@ -268,67 +269,13 @@ static int qtnf_start_ap(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ap_settings *settings) { struct qtnf_vif *vif = qtnf_netdev_get_priv(dev); - struct qtnf_wmac *mac = wiphy_priv(wiphy); - struct qtnf_bss_config *bss_cfg; int ret; - if (!cfg80211_chandef_identical(&mac->chandef, &settings->chandef)) { - memcpy(&mac->chandef, &settings->chandef, sizeof(mac->chandef)); - if (vif->vifid != 0) - pr_warn("%s: unexpected chan %u (%u MHz)\n", dev->name, - settings->chandef.chan->hw_value, - settings->chandef.chan->center_freq); - } - - bss_cfg = &vif->bss_cfg; - memset(bss_cfg, 0, sizeof(*bss_cfg)); - - bss_cfg->bcn_period = settings->beacon_interval; - bss_cfg->dtim = settings->dtim_period; - bss_cfg->auth_type = settings->auth_type; - bss_cfg->privacy = settings->privacy; - - bss_cfg->ssid_len = settings->ssid_len; - memcpy(&bss_cfg->ssid, settings->ssid, bss_cfg->ssid_len); - - memcpy(&bss_cfg->crypto, &settings->crypto, - sizeof(struct cfg80211_crypto_settings)); - - ret = qtnf_cmd_send_config_ap(vif); - if (ret) { - pr_err("VIF%u.%u: failed to push config to FW\n", - vif->mac->macid, vif->vifid); - goto out; - } - - if (!(vif->bss_status & QTNF_STATE_AP_CONFIG)) { - pr_err("VIF%u.%u: AP config failed in FW\n", vif->mac->macid, - vif->vifid); - ret = -EFAULT; - goto out; - } - - ret = qtnf_mgmt_set_appie(vif, &settings->beacon); - if (ret) { - pr_err("VIF%u.%u: failed to add IEs to beacon\n", - vif->mac->macid, vif->vifid); - goto out; - } - - ret = qtnf_cmd_send_start_ap(vif); - if (ret) { + ret = qtnf_cmd_send_start_ap(vif, settings); + if (ret) pr_err("VIF%u.%u: failed to start AP\n", vif->mac->macid, vif->vifid); - goto out; - } - if (!(vif->bss_status & QTNF_STATE_AP_START)) { - pr_err("VIF%u.%u: FW failed to start AP operation\n", - vif->mac->macid, vif->vifid); - ret = -EFAULT; - } - -out: return ret; } @@ -343,8 +290,6 @@ static int qtnf_stop_ap(struct wiphy *wiphy, struct net_device *dev) if (ret) { pr_err("VIF%u.%u: failed to stop AP operation in FW\n", vif->mac->macid, vif->vifid); - vif->bss_status &= ~QTNF_STATE_AP_START; - vif->bss_status &= ~QTNF_STATE_AP_CONFIG; netif_carrier_off(vif->netdev); } @@ -396,6 +341,13 @@ qtnf_mgmt_frame_register(struct wiphy *wiphy, struct wireless_dev *wdev, return; switch (frame_type & IEEE80211_FCTL_STYPE) { + case IEEE80211_STYPE_REASSOC_REQ: + case IEEE80211_STYPE_ASSOC_REQ: + qlink_frame_type = QLINK_MGMT_FRAME_ASSOC_REQ; + break; + case IEEE80211_STYPE_AUTH: + qlink_frame_type = QLINK_MGMT_FRAME_AUTH; + break; case IEEE80211_STYPE_PROBE_REQ: qlink_frame_type = QLINK_MGMT_FRAME_PROBE_REQ; break; @@ -581,9 +533,9 @@ qtnf_del_station(struct wiphy *wiphy, struct net_device *dev, return ret; } -static void qtnf_scan_timeout(unsigned long data) +static void qtnf_scan_timeout(struct timer_list *t) { - struct qtnf_wmac *mac = (struct qtnf_wmac *)data; + struct qtnf_wmac *mac = from_timer(mac, t, scan_timeout); pr_warn("mac%d scan timed out\n", mac->macid); qtnf_scan_done(mac, true); @@ -602,8 +554,7 @@ qtnf_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) return -EFAULT; } - mac->scan_timeout.data = (unsigned long)mac; - mac->scan_timeout.function = qtnf_scan_timeout; + mac->scan_timeout.function = (TIMER_FUNC_TYPE)qtnf_scan_timeout; mod_timer(&mac->scan_timeout, jiffies + QTNF_SCAN_TIMEOUT_SEC * HZ); @@ -615,9 +566,6 @@ qtnf_connect(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_connect_params *sme) { struct qtnf_vif *vif = qtnf_netdev_get_priv(dev); - struct qtnf_wmac *mac = wiphy_priv(wiphy); - struct cfg80211_chan_def chandef; - struct qtnf_bss_config *bss_cfg; int ret; if (vif->wdev.iftype != NL80211_IFTYPE_STATION) @@ -626,49 +574,10 @@ qtnf_connect(struct wiphy *wiphy, struct net_device *dev, if (vif->sta_state != QTNF_STA_DISCONNECTED) return -EBUSY; - bss_cfg = &vif->bss_cfg; - memset(bss_cfg, 0, sizeof(*bss_cfg)); - - if (sme->channel) { - /* FIXME: need to set proper nl80211_channel_type value */ - cfg80211_chandef_create(&chandef, sme->channel, - NL80211_CHAN_HT20); - /* fall-back to minimal safe chandef description */ - if (!cfg80211_chandef_valid(&chandef)) - cfg80211_chandef_create(&chandef, sme->channel, - NL80211_CHAN_HT20); - - memcpy(&mac->chandef, &chandef, sizeof(mac->chandef)); - } - - bss_cfg->ssid_len = sme->ssid_len; - memcpy(&bss_cfg->ssid, sme->ssid, bss_cfg->ssid_len); - bss_cfg->auth_type = sme->auth_type; - bss_cfg->privacy = sme->privacy; - bss_cfg->mfp = sme->mfp; - - if ((sme->bg_scan_period > 0) && - (sme->bg_scan_period <= QTNF_MAX_BG_SCAN_PERIOD)) - bss_cfg->bg_scan_period = sme->bg_scan_period; - else if (sme->bg_scan_period == -1) - bss_cfg->bg_scan_period = QTNF_DEFAULT_BG_SCAN_PERIOD; - else - bss_cfg->bg_scan_period = 0; /* disabled */ - - bss_cfg->connect_flags = 0; - - if (sme->flags & ASSOC_REQ_DISABLE_HT) - bss_cfg->connect_flags |= QLINK_STA_CONNECT_DISABLE_HT; - if (sme->flags & ASSOC_REQ_DISABLE_VHT) - bss_cfg->connect_flags |= QLINK_STA_CONNECT_DISABLE_VHT; - if (sme->flags & ASSOC_REQ_USE_RRM) - bss_cfg->connect_flags |= QLINK_STA_CONNECT_USE_RRM; - - memcpy(&bss_cfg->crypto, &sme->crypto, sizeof(bss_cfg->crypto)); if (sme->bssid) - ether_addr_copy(bss_cfg->bssid, sme->bssid); + ether_addr_copy(vif->bssid, sme->bssid); else - eth_zero_addr(bss_cfg->bssid); + eth_zero_addr(vif->bssid); ret = qtnf_cmd_send_connect(vif, sme); if (ret) { @@ -717,15 +626,15 @@ qtnf_dump_survey(struct wiphy *wiphy, struct net_device *dev, int idx, struct survey_info *survey) { struct qtnf_wmac *mac = wiphy_priv(wiphy); + struct wireless_dev *wdev = dev->ieee80211_ptr; struct ieee80211_supported_band *sband; - struct cfg80211_chan_def *chandef; + const struct cfg80211_chan_def *chandef = &wdev->chandef; struct ieee80211_channel *chan; struct qtnf_chan_stats stats; struct qtnf_vif *vif; int ret; vif = qtnf_netdev_get_priv(dev); - chandef = &mac->chandef; sband = wiphy->bands[NL80211_BAND_2GHZ]; if (sband && idx >= sband->n_channels) { @@ -792,46 +701,35 @@ static int qtnf_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev, struct cfg80211_chan_def *chandef) { - struct qtnf_wmac *mac = wiphy_priv(wiphy); struct net_device *ndev = wdev->netdev; struct qtnf_vif *vif; + int ret; if (!ndev) return -ENODEV; vif = qtnf_netdev_get_priv(wdev->netdev); - switch (vif->wdev.iftype) { - case NL80211_IFTYPE_STATION: - if (vif->sta_state == QTNF_STA_DISCONNECTED) { - pr_warn("%s: STA disconnected\n", ndev->name); - return -ENODATA; - } - break; - case NL80211_IFTYPE_AP: - if (!(vif->bss_status & QTNF_STATE_AP_START)) { - pr_warn("%s: AP not started\n", ndev->name); - return -ENODATA; - } - break; - default: - pr_err("unsupported vif type (%d)\n", vif->wdev.iftype); - return -ENODATA; + ret = qtnf_cmd_get_channel(vif, chandef); + if (ret) { + pr_err("%s: failed to get channel: %d\n", ndev->name, ret); + goto out; } - if (!cfg80211_chandef_valid(&mac->chandef)) { - pr_err("invalid channel settings on %s\n", ndev->name); - return -ENODATA; + if (!cfg80211_chandef_valid(chandef)) { + pr_err("%s: bad chan freq1=%u freq2=%u bw=%u\n", ndev->name, + chandef->center_freq1, chandef->center_freq2, + chandef->width); + ret = -ENODATA; } - memcpy(chandef, &mac->chandef, sizeof(*chandef)); - return 0; +out: + return ret; } static int qtnf_channel_switch(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_csa_settings *params) { - struct qtnf_wmac *mac = wiphy_priv(wiphy); struct qtnf_vif *vif = qtnf_netdev_get_priv(dev); int ret; @@ -839,41 +737,12 @@ static int qtnf_channel_switch(struct wiphy *wiphy, struct net_device *dev, params->chandef.chan->hw_value, params->count, params->radar_required, params->block_tx); - switch (vif->wdev.iftype) { - case NL80211_IFTYPE_AP: - if (!(vif->bss_status & QTNF_STATE_AP_START)) { - pr_warn("AP not started on %s\n", dev->name); - return -ENOTCONN; - } - break; - default: - pr_err("unsupported vif type (%d) on %s\n", - vif->wdev.iftype, dev->name); - return -EOPNOTSUPP; - } - - if (vif->vifid != 0) { - if (!(mac->status & QTNF_MAC_CSA_ACTIVE)) - return -EOPNOTSUPP; - - if (!cfg80211_chandef_identical(¶ms->chandef, - &mac->csa_chandef)) - return -EINVAL; - - return 0; - } - if (!cfg80211_chandef_valid(¶ms->chandef)) { pr_err("%s: invalid channel\n", dev->name); return -EINVAL; } - if (cfg80211_chandef_identical(¶ms->chandef, &mac->chandef)) { - pr_err("%s: switch request to the same channel\n", dev->name); - return -EALREADY; - } - - ret = qtnf_cmd_send_chan_switch(mac, params); + ret = qtnf_cmd_send_chan_switch(vif, params); if (ret) pr_warn("%s: failed to switch to channel (%u)\n", dev->name, params->chandef.chan->hw_value); @@ -939,8 +808,7 @@ static void qtnf_cfg80211_reg_notifier(struct wiphy *wiphy_in, if (!wiphy->bands[band]) continue; - ret = qtnf_cmd_get_mac_chan_info(mac, - wiphy->bands[band]); + ret = qtnf_cmd_band_info_get(mac, wiphy->bands[band]); if (ret) pr_err("failed to get chan info for mac %u band %u\n", mac_idx, band); @@ -948,33 +816,6 @@ static void qtnf_cfg80211_reg_notifier(struct wiphy *wiphy_in, } } -void qtnf_band_setup_htvht_caps(struct qtnf_mac_info *macinfo, - struct ieee80211_supported_band *band) -{ - struct ieee80211_sta_ht_cap *ht_cap; - struct ieee80211_sta_vht_cap *vht_cap; - - ht_cap = &band->ht_cap; - ht_cap->ht_supported = true; - memcpy(&ht_cap->cap, &macinfo->ht_cap.cap_info, - sizeof(u16)); - ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; - ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE; - memcpy(&ht_cap->mcs, &macinfo->ht_cap.mcs, - sizeof(ht_cap->mcs)); - - if (macinfo->phymode_cap & QLINK_PHYMODE_AC) { - vht_cap = &band->vht_cap; - vht_cap->vht_supported = true; - memcpy(&vht_cap->cap, - &macinfo->vht_cap.vht_cap_info, sizeof(u32)); - /* Update MCS support for VHT */ - memcpy(&vht_cap->vht_mcs, - &macinfo->vht_cap.supp_mcs, - sizeof(struct ieee80211_vht_mcs_info)); - } -} - struct wiphy *qtnf_wiphy_allocate(struct qtnf_bus *bus) { struct wiphy *wiphy; @@ -1035,9 +876,6 @@ int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac) if (ret) goto out; - pr_info("MAC%u: phymode=%#x radar=%#x\n", mac->macid, - mac->macinfo.phymode_cap, mac->macinfo.radar_detect_widths); - wiphy->frag_threshold = mac->macinfo.frag_thr; wiphy->rts_threshold = mac->macinfo.rts_thr; wiphy->retry_short = mac->macinfo.sretry_limit; @@ -1069,10 +907,15 @@ int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac) wiphy->available_antennas_rx = mac->macinfo.num_rx_chain; wiphy->max_ap_assoc_sta = mac->macinfo.max_ap_assoc_sta; + wiphy->ht_capa_mod_mask = &mac->macinfo.ht_cap_mod_mask; + wiphy->vht_capa_mod_mask = &mac->macinfo.vht_cap_mod_mask; ether_addr_copy(wiphy->perm_addr, mac->macaddr); - if (hw_info->hw_capab & QLINK_HW_SUPPORTS_REG_UPDATE) { + if (hw_info->hw_capab & QLINK_HW_CAPAB_STA_INACT_TIMEOUT) + wiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER; + + if (hw_info->hw_capab & QLINK_HW_CAPAB_REG_UPDATE) { wiphy->regulatory_flags |= REGULATORY_STRICT_REG | REGULATORY_CUSTOM_REG; wiphy->reg_notifier = qtnf_cfg80211_reg_notifier; @@ -1119,7 +962,7 @@ void qtnf_virtual_intf_cleanup(struct net_device *ndev) break; case QTNF_STA_CONNECTING: cfg80211_connect_result(vif->netdev, - vif->bss_cfg.bssid, NULL, 0, + vif->bssid, NULL, 0, NULL, 0, WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_KERNEL); @@ -1147,7 +990,7 @@ void qtnf_cfg80211_vif_reset(struct qtnf_vif *vif) switch (vif->sta_state) { case QTNF_STA_CONNECTING: cfg80211_connect_result(vif->netdev, - vif->bss_cfg.bssid, NULL, 0, + vif->bssid, NULL, 0, NULL, 0, WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_KERNEL); |