diff options
Diffstat (limited to 'drivers/net/wireless/quantenna/qtnfmac/cfg80211.c')
-rw-r--r-- | drivers/net/wireless/quantenna/qtnfmac/cfg80211.c | 117 |
1 files changed, 61 insertions, 56 deletions
diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c index 8849faa5bc10..8be17106008d 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c +++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c @@ -60,7 +60,8 @@ qtnf_mgmt_stypes[NUM_NL80211_IFTYPES] = { BIT(IEEE80211_STYPE_AUTH >> 4), }, [NL80211_IFTYPE_AP] = { - .tx = BIT(IEEE80211_STYPE_ACTION >> 4), + .tx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_AUTH >> 4), .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | @@ -101,6 +102,21 @@ qtnf_validate_iface_combinations(struct wiphy *wiphy, ret = cfg80211_check_combinations(wiphy, ¶ms); + if (ret) + return ret; + + /* Check repeater interface combination: primary VIF should be STA only. + * STA (primary) + AP (secondary) is OK. + * AP (primary) + STA (secondary) is not supported. + */ + vif = qtnf_mac_get_base_vif(mac); + if (vif && vif->wdev.iftype == NL80211_IFTYPE_AP && + vif != change_vif && new_type == NL80211_IFTYPE_STATION) { + ret = -EINVAL; + pr_err("MAC%u invalid combination: AP as primary repeater interface is not supported\n", + mac->macid); + } + return ret; } @@ -248,7 +264,7 @@ static struct wireless_dev *qtnf_add_virtual_intf(struct wiphy *wiphy, goto error_del_vif; } - if (mac->bus->hw_info.hw_capab & QLINK_HW_CAPAB_HW_BRIDGE) { + if (qtnf_hwcap_is_set(&mac->bus->hw_info, QLINK_HW_CAPAB_HW_BRIDGE)) { ret = qtnf_cmd_netdev_changeupper(vif, vif->netdev->ifindex); if (ret) { unregister_netdevice(vif->netdev); @@ -679,10 +695,8 @@ qtnf_external_auth(struct wiphy *wiphy, struct net_device *dev, struct qtnf_vif *vif = qtnf_netdev_get_priv(dev); int ret; - if (vif->wdev.iftype != NL80211_IFTYPE_STATION) - return -EOPNOTSUPP; - - if (!ether_addr_equal(vif->bssid, auth->bssid)) + if (vif->wdev.iftype == NL80211_IFTYPE_STATION && + !ether_addr_equal(vif->bssid, auth->bssid)) pr_warn("unexpected bssid: %pM", auth->bssid); ret = qtnf_cmd_send_external_auth(vif, auth); @@ -739,7 +753,6 @@ qtnf_dump_survey(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_supported_band *sband; const struct cfg80211_chan_def *chandef = &wdev->chandef; struct ieee80211_channel *chan; - struct qtnf_chan_stats stats; int ret; sband = wiphy->bands[NL80211_BAND_2GHZ]; @@ -755,49 +768,16 @@ qtnf_dump_survey(struct wiphy *wiphy, struct net_device *dev, return -ENOENT; chan = &sband->channels[idx]; - memset(&stats, 0, sizeof(stats)); - survey->channel = chan; survey->filled = 0x0; - if (chandef->chan) { - if (chan->hw_value == chandef->chan->hw_value) - survey->filled = SURVEY_INFO_IN_USE; - } - - ret = qtnf_cmd_get_chan_stats(mac, chan->hw_value, &stats); - switch (ret) { - case 0: - if (unlikely(stats.chan_num != chan->hw_value)) { - pr_err("received stats for channel %d instead of %d\n", - stats.chan_num, chan->hw_value); - ret = -EINVAL; - break; - } + if (chan == chandef->chan) + survey->filled = SURVEY_INFO_IN_USE; - survey->filled |= SURVEY_INFO_TIME | - SURVEY_INFO_TIME_SCAN | - SURVEY_INFO_TIME_BUSY | - SURVEY_INFO_TIME_RX | - SURVEY_INFO_TIME_TX | - SURVEY_INFO_NOISE_DBM; - - survey->time_scan = stats.cca_try; - survey->time = stats.cca_try; - survey->time_tx = stats.cca_tx; - survey->time_rx = stats.cca_rx; - survey->time_busy = stats.cca_busy; - survey->noise = stats.chan_noise; - break; - case -ENOENT: - pr_debug("no stats for channel %u\n", chan->hw_value); - ret = 0; - break; - default: + ret = qtnf_cmd_get_chan_stats(mac, chan->center_freq, survey); + if (ret) pr_debug("failed to get chan(%d) stats from card\n", chan->hw_value); - break; - } return ret; } @@ -943,6 +923,26 @@ static int qtnf_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, return ret; } +static int qtnf_update_owe_info(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_update_owe_info *owe_info) +{ + struct qtnf_vif *vif = qtnf_netdev_get_priv(dev); + int ret; + + if (vif->wdev.iftype != NL80211_IFTYPE_AP) + return -EOPNOTSUPP; + + ret = qtnf_cmd_send_update_owe(vif, owe_info); + if (ret) { + pr_err("VIF%u.%u: failed to update owe info\n", + vif->mac->macid, vif->vifid); + goto out; + } + +out: + return ret; +} + #ifdef CONFIG_PM static int qtnf_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wowlan) { @@ -1039,6 +1039,7 @@ static struct cfg80211_ops qtn_cfg80211_ops = { .set_power_mgmt = qtnf_set_power_mgmt, .get_tx_power = qtnf_get_tx_power, .set_tx_power = qtnf_set_tx_power, + .update_owe_info = qtnf_update_owe_info, #ifdef CONFIG_PM .suspend = qtnf_suspend, .resume = qtnf_resume, @@ -1075,22 +1076,26 @@ static void qtnf_cfg80211_reg_notifier(struct wiphy *wiphy, } } -struct wiphy *qtnf_wiphy_allocate(struct qtnf_bus *bus) +struct wiphy *qtnf_wiphy_allocate(struct qtnf_bus *bus, + struct platform_device *pdev) { struct wiphy *wiphy; if (qtnf_dfs_offload_get() && - (bus->hw_info.hw_capab & QLINK_HW_CAPAB_DFS_OFFLOAD)) + qtnf_hwcap_is_set(&bus->hw_info, QLINK_HW_CAPAB_DFS_OFFLOAD)) qtn_cfg80211_ops.start_radar_detection = NULL; - if (!(bus->hw_info.hw_capab & QLINK_HW_CAPAB_PWR_MGMT)) + if (!qtnf_hwcap_is_set(&bus->hw_info, QLINK_HW_CAPAB_PWR_MGMT)) qtn_cfg80211_ops.set_power_mgmt = NULL; wiphy = wiphy_new(&qtn_cfg80211_ops, sizeof(struct qtnf_wmac)); if (!wiphy) return NULL; - set_wiphy_dev(wiphy, bus->dev); + if (pdev) + set_wiphy_dev(wiphy, &pdev->dev); + else + set_wiphy_dev(wiphy, bus->dev); return wiphy; } @@ -1142,7 +1147,7 @@ int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac) wiphy->coverage_class = macinfo->coverage_class; wiphy->max_scan_ssids = - (hw_info->max_scan_ssids) ? hw_info->max_scan_ssids : 1; + (macinfo->max_scan_ssids) ? macinfo->max_scan_ssids : 1; wiphy->max_scan_ie_len = QTNF_MAX_VSIE_LEN; wiphy->mgmt_stypes = qtnf_mgmt_stypes; wiphy->max_remain_on_channel_duration = 5000; @@ -1166,10 +1171,10 @@ int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac) wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; if (qtnf_dfs_offload_get() && - (hw_info->hw_capab & QLINK_HW_CAPAB_DFS_OFFLOAD)) + qtnf_hwcap_is_set(hw_info, QLINK_HW_CAPAB_DFS_OFFLOAD)) wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_DFS_OFFLOAD); - if (hw_info->hw_capab & QLINK_HW_CAPAB_SCAN_DWELL) + if (qtnf_hwcap_is_set(hw_info, QLINK_HW_CAPAB_SCAN_DWELL)) wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_SET_SCAN_DWELL); @@ -1185,16 +1190,16 @@ int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac) ether_addr_copy(wiphy->perm_addr, mac->macaddr); - if (hw_info->hw_capab & QLINK_HW_CAPAB_STA_INACT_TIMEOUT) + if (qtnf_hwcap_is_set(hw_info, QLINK_HW_CAPAB_STA_INACT_TIMEOUT)) wiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER; - if (hw_info->hw_capab & QLINK_HW_CAPAB_SCAN_RANDOM_MAC_ADDR) + if (qtnf_hwcap_is_set(hw_info, QLINK_HW_CAPAB_SCAN_RANDOM_MAC_ADDR)) wiphy->features |= NL80211_FEATURE_SCAN_RANDOM_MAC_ADDR; - if (!(hw_info->hw_capab & QLINK_HW_CAPAB_OBSS_SCAN)) + if (!qtnf_hwcap_is_set(hw_info, QLINK_HW_CAPAB_OBSS_SCAN)) wiphy->features |= NL80211_FEATURE_NEED_OBSS_SCAN; - if (hw_info->hw_capab & QLINK_HW_CAPAB_SAE) + if (qtnf_hwcap_is_set(hw_info, QLINK_HW_CAPAB_SAE)) wiphy->features |= NL80211_FEATURE_SAE; #ifdef CONFIG_PM @@ -1205,7 +1210,7 @@ int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac) regdomain_is_known = isalpha(mac->rd->alpha2[0]) && isalpha(mac->rd->alpha2[1]); - if (hw_info->hw_capab & QLINK_HW_CAPAB_REG_UPDATE) { + if (qtnf_hwcap_is_set(hw_info, QLINK_HW_CAPAB_REG_UPDATE)) { wiphy->reg_notifier = qtnf_cfg80211_reg_notifier; if (mac->rd->alpha2[0] == '9' && mac->rd->alpha2[1] == '9') { |