diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/quantenna/qtnfmac/cfg80211.c | 13 | ||||
-rw-r--r-- | drivers/net/wireless/quantenna/qtnfmac/commands.c | 186 | ||||
-rw-r--r-- | drivers/net/wireless/quantenna/qtnfmac/core.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/quantenna/qtnfmac/core.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/quantenna/qtnfmac/qlink.h | 42 | ||||
-rw-r--r-- | drivers/net/wireless/quantenna/qtnfmac/qlink_util.c | 62 | ||||
-rw-r--r-- | drivers/net/wireless/quantenna/qtnfmac/qlink_util.h | 2 |
7 files changed, 156 insertions, 156 deletions
diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c index 3131ced8801f..cea948466744 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c +++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c @@ -1145,17 +1145,16 @@ int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac) wiphy->wowlan = macinfo->wowlan; #endif - regdomain_is_known = isalpha(hw_info->rd->alpha2[0]) && - isalpha(hw_info->rd->alpha2[1]); + regdomain_is_known = isalpha(mac->rd->alpha2[0]) && + isalpha(mac->rd->alpha2[1]); if (hw_info->hw_capab & QLINK_HW_CAPAB_REG_UPDATE) { wiphy->reg_notifier = qtnf_cfg80211_reg_notifier; - if (hw_info->rd->alpha2[0] == '9' && - hw_info->rd->alpha2[1] == '9') { + if (mac->rd->alpha2[0] == '9' && mac->rd->alpha2[1] == '9') { wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG | REGULATORY_STRICT_REG; - wiphy_apply_custom_regulatory(wiphy, hw_info->rd); + wiphy_apply_custom_regulatory(wiphy, mac->rd); } else if (regdomain_is_known) { wiphy->regulatory_flags |= REGULATORY_STRICT_REG; } @@ -1181,9 +1180,9 @@ int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac) goto out; if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) - ret = regulatory_set_wiphy_regd(wiphy, hw_info->rd); + ret = regulatory_set_wiphy_regd(wiphy, mac->rd); else if (regdomain_is_known) - ret = regulatory_hint(wiphy, hw_info->rd->alpha2); + ret = regulatory_hint(wiphy, mac->rd->alpha2); out: return ret; diff --git a/drivers/net/wireless/quantenna/qtnfmac/commands.c b/drivers/net/wireless/quantenna/qtnfmac/commands.c index e61bec7c5d8a..1a248d9f2e4c 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/commands.c +++ b/drivers/net/wireless/quantenna/qtnfmac/commands.c @@ -831,55 +831,6 @@ out: return ret; } -static u32 qtnf_cmd_resp_reg_rule_flags_parse(u32 qflags) -{ - u32 flags = 0; - - if (qflags & QLINK_RRF_NO_OFDM) - flags |= NL80211_RRF_NO_OFDM; - - if (qflags & QLINK_RRF_NO_CCK) - flags |= NL80211_RRF_NO_CCK; - - if (qflags & QLINK_RRF_NO_INDOOR) - flags |= NL80211_RRF_NO_INDOOR; - - if (qflags & QLINK_RRF_NO_OUTDOOR) - flags |= NL80211_RRF_NO_OUTDOOR; - - if (qflags & QLINK_RRF_DFS) - flags |= NL80211_RRF_DFS; - - if (qflags & QLINK_RRF_PTP_ONLY) - flags |= NL80211_RRF_PTP_ONLY; - - if (qflags & QLINK_RRF_PTMP_ONLY) - flags |= NL80211_RRF_PTMP_ONLY; - - if (qflags & QLINK_RRF_NO_IR) - flags |= NL80211_RRF_NO_IR; - - if (qflags & QLINK_RRF_AUTO_BW) - flags |= NL80211_RRF_AUTO_BW; - - if (qflags & QLINK_RRF_IR_CONCURRENT) - flags |= NL80211_RRF_IR_CONCURRENT; - - if (qflags & QLINK_RRF_NO_HT40MINUS) - flags |= NL80211_RRF_NO_HT40MINUS; - - if (qflags & QLINK_RRF_NO_HT40PLUS) - flags |= NL80211_RRF_NO_HT40PLUS; - - if (qflags & QLINK_RRF_NO_80MHZ) - flags |= NL80211_RRF_NO_80MHZ; - - if (qflags & QLINK_RRF_NO_160MHZ) - flags |= NL80211_RRF_NO_160MHZ; - - return flags; -} - static int qtnf_cmd_resp_proc_hw_info(struct qtnf_bus *bus, const struct qlink_resp_get_hw_info *resp, @@ -887,7 +838,6 @@ qtnf_cmd_resp_proc_hw_info(struct qtnf_bus *bus, { struct qtnf_hw_info *hwinfo = &bus->hw_info; const struct qlink_tlv_hdr *tlv; - const struct qlink_tlv_reg_rule *tlv_rule; const char *bld_name = NULL; const char *bld_rev = NULL; const char *bld_type = NULL; @@ -898,19 +848,8 @@ qtnf_cmd_resp_proc_hw_info(struct qtnf_bus *bus, const char *calibration_ver = NULL; const char *uboot_ver = NULL; u32 hw_ver = 0; - struct ieee80211_reg_rule *rule; u16 tlv_type; u16 tlv_value_len; - unsigned int rule_idx = 0; - - if (WARN_ON(resp->n_reg_rules > NL80211_MAX_SUPP_REG_RULES)) - return -E2BIG; - - hwinfo->rd = kzalloc(struct_size(hwinfo->rd, reg_rules, - resp->n_reg_rules), GFP_KERNEL); - - if (!hwinfo->rd) - return -ENOMEM; hwinfo->num_mac = resp->num_mac; hwinfo->mac_bitmap = resp->mac_bitmap; @@ -919,30 +858,11 @@ qtnf_cmd_resp_proc_hw_info(struct qtnf_bus *bus, hwinfo->total_tx_chain = resp->total_tx_chain; hwinfo->total_rx_chain = resp->total_rx_chain; hwinfo->hw_capab = le32_to_cpu(resp->hw_capab); - hwinfo->rd->n_reg_rules = resp->n_reg_rules; - hwinfo->rd->alpha2[0] = resp->alpha2[0]; - hwinfo->rd->alpha2[1] = resp->alpha2[1]; bld_tmstamp = le32_to_cpu(resp->bld_tmstamp); plat_id = le32_to_cpu(resp->plat_id); hw_ver = le32_to_cpu(resp->hw_ver); - switch (resp->dfs_region) { - case QLINK_DFS_FCC: - hwinfo->rd->dfs_region = NL80211_DFS_FCC; - break; - case QLINK_DFS_ETSI: - hwinfo->rd->dfs_region = NL80211_DFS_ETSI; - break; - case QLINK_DFS_JP: - hwinfo->rd->dfs_region = NL80211_DFS_JP; - break; - case QLINK_DFS_UNSET: - default: - hwinfo->rd->dfs_region = NL80211_DFS_UNSET; - break; - } - tlv = (const struct qlink_tlv_hdr *)resp->info; while (info_len >= sizeof(*tlv)) { @@ -956,37 +876,6 @@ qtnf_cmd_resp_proc_hw_info(struct qtnf_bus *bus, } switch (tlv_type) { - case QTN_TLV_ID_REG_RULE: - if (rule_idx >= resp->n_reg_rules) { - pr_warn("unexpected number of rules: %u\n", - resp->n_reg_rules); - return -EINVAL; - } - - if (tlv_value_len != sizeof(*tlv_rule) - sizeof(*tlv)) { - pr_warn("malformed TLV 0x%.2X; LEN: %u\n", - tlv_type, tlv_value_len); - return -EINVAL; - } - - tlv_rule = (const struct qlink_tlv_reg_rule *)tlv; - rule = &hwinfo->rd->reg_rules[rule_idx++]; - - rule->freq_range.start_freq_khz = - le32_to_cpu(tlv_rule->start_freq_khz); - rule->freq_range.end_freq_khz = - le32_to_cpu(tlv_rule->end_freq_khz); - rule->freq_range.max_bandwidth_khz = - le32_to_cpu(tlv_rule->max_bandwidth_khz); - rule->power_rule.max_antenna_gain = - le32_to_cpu(tlv_rule->max_antenna_gain); - rule->power_rule.max_eirp = - le32_to_cpu(tlv_rule->max_eirp); - rule->dfs_cac_ms = - le32_to_cpu(tlv_rule->dfs_cac_ms); - rule->flags = qtnf_cmd_resp_reg_rule_flags_parse( - le32_to_cpu(tlv_rule->flags)); - break; case QTN_TLV_ID_BUILD_NAME: bld_name = (const void *)tlv->val; break; @@ -1019,17 +908,8 @@ qtnf_cmd_resp_proc_hw_info(struct qtnf_bus *bus, tlv = (struct qlink_tlv_hdr *)(tlv->val + tlv_value_len); } - if (rule_idx != resp->n_reg_rules) { - pr_warn("unexpected number of rules: expected %u got %u\n", - resp->n_reg_rules, rule_idx); - kfree(hwinfo->rd); - hwinfo->rd = NULL; - return -EINVAL; - } - - pr_info("fw_version=%d, MACs map %#x, alpha2=\"%c%c\", chains Tx=%u Rx=%u, capab=0x%x\n", + pr_info("fw_version=%d, MACs map %#x, chains Tx=%u Rx=%u, capab=0x%x\n", hwinfo->fw_ver, hwinfo->mac_bitmap, - hwinfo->rd->alpha2[0], hwinfo->rd->alpha2[1], hwinfo->total_tx_chain, hwinfo->total_rx_chain, hwinfo->hw_capab); @@ -1085,9 +965,12 @@ qtnf_parse_wowlan_info(struct qtnf_wmac *mac, } } -static int qtnf_parse_variable_mac_info(struct qtnf_wmac *mac, - const u8 *tlv_buf, size_t tlv_buf_size) +static int +qtnf_parse_variable_mac_info(struct qtnf_wmac *mac, + const struct qlink_resp_get_mac_info *resp, + size_t tlv_buf_size) { + const u8 *tlv_buf = resp->var_info; struct ieee80211_iface_combination *comb = NULL; size_t n_comb = 0; struct ieee80211_iface_limit *limits; @@ -1105,6 +988,38 @@ static int qtnf_parse_variable_mac_info(struct qtnf_wmac *mac, u8 ext_capa_len = 0; u8 ext_capa_mask_len = 0; int i = 0; + struct ieee80211_reg_rule *rule; + unsigned int rule_idx = 0; + const struct qlink_tlv_reg_rule *tlv_rule; + + if (WARN_ON(resp->n_reg_rules > NL80211_MAX_SUPP_REG_RULES)) + return -E2BIG; + + mac->rd = kzalloc(sizeof(*mac->rd) + + sizeof(struct ieee80211_reg_rule) * + resp->n_reg_rules, GFP_KERNEL); + if (!mac->rd) + return -ENOMEM; + + mac->rd->n_reg_rules = resp->n_reg_rules; + mac->rd->alpha2[0] = resp->alpha2[0]; + mac->rd->alpha2[1] = resp->alpha2[1]; + + switch (resp->dfs_region) { + case QLINK_DFS_FCC: + mac->rd->dfs_region = NL80211_DFS_FCC; + break; + case QLINK_DFS_ETSI: + mac->rd->dfs_region = NL80211_DFS_ETSI; + break; + case QLINK_DFS_JP: + mac->rd->dfs_region = NL80211_DFS_JP; + break; + case QLINK_DFS_UNSET: + default: + mac->rd->dfs_region = NL80211_DFS_UNSET; + break; + } tlv = (const struct qlink_tlv_hdr *)tlv_buf; while (tlv_buf_size >= sizeof(struct qlink_tlv_hdr)) { @@ -1225,6 +1140,23 @@ static int qtnf_parse_variable_mac_info(struct qtnf_wmac *mac, mac->macinfo.wowlan = NULL; qtnf_parse_wowlan_info(mac, wowlan); break; + case QTN_TLV_ID_REG_RULE: + if (rule_idx >= resp->n_reg_rules) { + pr_warn("unexpected number of rules: %u\n", + resp->n_reg_rules); + return -EINVAL; + } + + if (tlv_value_len != sizeof(*tlv_rule) - sizeof(*tlv)) { + pr_warn("malformed TLV 0x%.2X; LEN: %u\n", + tlv_type, tlv_value_len); + return -EINVAL; + } + + tlv_rule = (const struct qlink_tlv_reg_rule *)tlv; + rule = &mac->rd->reg_rules[rule_idx++]; + qlink_utils_regrule_q2nl(rule, tlv_rule); + break; default: pr_warn("MAC%u: unknown TLV type %u\n", mac->macid, tlv_type); @@ -1253,6 +1185,12 @@ static int qtnf_parse_variable_mac_info(struct qtnf_wmac *mac, return -EINVAL; } + if (rule_idx != resp->n_reg_rules) { + pr_warn("unexpected number of rules: expected %u got %u\n", + resp->n_reg_rules, rule_idx); + return -EINVAL; + } + if (ext_capa_len > 0) { ext_capa = kmemdup(ext_capa, ext_capa_len, GFP_KERNEL); if (!ext_capa) @@ -1663,7 +1601,7 @@ int qtnf_cmd_get_mac_info(struct qtnf_wmac *mac) resp = (const struct qlink_resp_get_mac_info *)resp_skb->data; qtnf_cmd_resp_proc_mac_info(mac, resp); - ret = qtnf_parse_variable_mac_info(mac, resp->var_info, var_data_len); + ret = qtnf_parse_variable_mac_info(mac, resp, var_data_len); out: qtnf_bus_unlock(mac->bus); diff --git a/drivers/net/wireless/quantenna/qtnfmac/core.c b/drivers/net/wireless/quantenna/qtnfmac/core.c index ee1b75fda1dd..f04f4e1f7d68 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/core.c +++ b/drivers/net/wireless/quantenna/qtnfmac/core.c @@ -499,6 +499,8 @@ static void qtnf_core_mac_detach(struct qtnf_bus *bus, unsigned int macid) qtnf_mac_iface_comb_free(mac); qtnf_mac_ext_caps_free(mac); kfree(mac->macinfo.wowlan); + kfree(mac->rd); + mac->rd = NULL; wiphy_free(wiphy); bus->mac[macid] = NULL; } @@ -665,9 +667,6 @@ void qtnf_core_detach(struct qtnf_bus *bus) destroy_workqueue(bus->workqueue); } - kfree(bus->hw_info.rd); - bus->hw_info.rd = NULL; - qtnf_trans_free(bus); } EXPORT_SYMBOL_GPL(qtnf_core_detach); diff --git a/drivers/net/wireless/quantenna/qtnfmac/core.h b/drivers/net/wireless/quantenna/qtnfmac/core.h index a31cff46e964..1b983ec9afcc 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/core.h +++ b/drivers/net/wireless/quantenna/qtnfmac/core.h @@ -112,6 +112,7 @@ struct qtnf_wmac { struct cfg80211_scan_request *scan_req; struct mutex mac_lock; /* lock during wmac speicific ops */ struct delayed_work scan_timeout; + struct ieee80211_regdomain *rd; }; struct qtnf_hw_info { @@ -120,7 +121,6 @@ struct qtnf_hw_info { u8 mac_bitmap; u32 fw_ver; u32 hw_capab; - struct ieee80211_regdomain *rd; u8 total_tx_chain; u8 total_rx_chain; char fw_version[ETHTOOL_FWVERS_LEN]; diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink.h b/drivers/net/wireless/quantenna/qtnfmac/qlink.h index ca84684a1a93..6951f6370985 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/qlink.h +++ b/drivers/net/wireless/quantenna/qtnfmac/qlink.h @@ -6,7 +6,7 @@ #include <linux/ieee80211.h> -#define QLINK_PROTO_VER 14 +#define QLINK_PROTO_VER 15 #define QLINK_MACID_RSVD 0xFF #define QLINK_VIFID_RSVD 0xFF @@ -771,6 +771,18 @@ struct qlink_resp { } __packed; /** + * enum qlink_dfs_regions - regulatory DFS regions + * + * Corresponds to &enum nl80211_dfs_regions. + */ +enum qlink_dfs_regions { + QLINK_DFS_UNSET = 0, + QLINK_DFS_FCC = 1, + QLINK_DFS_ETSI = 2, + QLINK_DFS_JP = 3, +}; + +/** * struct qlink_resp_get_mac_info - response for QLINK_CMD_MAC_INFO command * * Data describing specific physical device providing wireless MAC @@ -785,6 +797,10 @@ struct qlink_resp { * @bands_cap: wireless bands WMAC can operate in, bitmap of &enum qlink_band. * @max_ap_assoc_sta: Maximum number of associations supported by WMAC. * @radar_detect_widths: bitmask of channels BW for which WMAC can detect radar. + * @alpha2: country code ID firmware is configured to. + * @n_reg_rules: number of regulatory rules TLVs in variable portion of the + * message. + * @dfs_region: regulatory DFS region, one of @enum qlink_dfs_region. * @var_info: variable-length WMAC info data. */ struct qlink_resp_get_mac_info { @@ -798,23 +814,14 @@ struct qlink_resp_get_mac_info { __le16 radar_detect_widths; __le32 max_acl_mac_addrs; u8 bands_cap; + u8 alpha2[2]; + u8 n_reg_rules; + u8 dfs_region; u8 rsvd[1]; u8 var_info[0]; } __packed; /** - * enum qlink_dfs_regions - regulatory DFS regions - * - * Corresponds to &enum nl80211_dfs_regions. - */ -enum qlink_dfs_regions { - QLINK_DFS_UNSET = 0, - QLINK_DFS_FCC = 1, - QLINK_DFS_ETSI = 2, - QLINK_DFS_JP = 3, -}; - -/** * struct qlink_resp_get_hw_info - response for QLINK_CMD_GET_HW_INFO command * * Description of wireless hardware capabilities and features. @@ -826,11 +833,7 @@ enum qlink_dfs_regions { * @mac_bitmap: Bitmap of MAC IDs that are active and can be used in firmware. * @total_tx_chains: total number of transmit chains used by device. * @total_rx_chains: total number of receive chains. - * @alpha2: country code ID firmware is configured to. - * @n_reg_rules: number of regulatory rules TLVs in variable portion of the - * message. - * @dfs_region: regulatory DFS region, one of @enum qlink_dfs_region. - * @info: variable-length HW info, can contain QTN_TLV_ID_REG_RULE. + * @info: variable-length HW info. */ struct qlink_resp_get_hw_info { struct qlink_resp rhdr; @@ -844,9 +847,6 @@ struct qlink_resp_get_hw_info { u8 mac_bitmap; u8 total_tx_chain; u8 total_rx_chain; - u8 alpha2[2]; - u8 n_reg_rules; - u8 dfs_region; u8 info[0]; } __packed; diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink_util.c b/drivers/net/wireless/quantenna/qtnfmac/qlink_util.c index 8cae9d8d1ab6..1a972bce7b8b 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/qlink_util.c +++ b/drivers/net/wireless/quantenna/qtnfmac/qlink_util.c @@ -237,3 +237,65 @@ u32 qlink_utils_chflags_cfg2q(u32 cfgflags) return flags; } + +static u32 qtnf_reg_rule_flags_parse(u32 qflags) +{ + u32 flags = 0; + + if (qflags & QLINK_RRF_NO_OFDM) + flags |= NL80211_RRF_NO_OFDM; + + if (qflags & QLINK_RRF_NO_CCK) + flags |= NL80211_RRF_NO_CCK; + + if (qflags & QLINK_RRF_NO_INDOOR) + flags |= NL80211_RRF_NO_INDOOR; + + if (qflags & QLINK_RRF_NO_OUTDOOR) + flags |= NL80211_RRF_NO_OUTDOOR; + + if (qflags & QLINK_RRF_DFS) + flags |= NL80211_RRF_DFS; + + if (qflags & QLINK_RRF_PTP_ONLY) + flags |= NL80211_RRF_PTP_ONLY; + + if (qflags & QLINK_RRF_PTMP_ONLY) + flags |= NL80211_RRF_PTMP_ONLY; + + if (qflags & QLINK_RRF_NO_IR) + flags |= NL80211_RRF_NO_IR; + + if (qflags & QLINK_RRF_AUTO_BW) + flags |= NL80211_RRF_AUTO_BW; + + if (qflags & QLINK_RRF_IR_CONCURRENT) + flags |= NL80211_RRF_IR_CONCURRENT; + + if (qflags & QLINK_RRF_NO_HT40MINUS) + flags |= NL80211_RRF_NO_HT40MINUS; + + if (qflags & QLINK_RRF_NO_HT40PLUS) + flags |= NL80211_RRF_NO_HT40PLUS; + + if (qflags & QLINK_RRF_NO_80MHZ) + flags |= NL80211_RRF_NO_80MHZ; + + if (qflags & QLINK_RRF_NO_160MHZ) + flags |= NL80211_RRF_NO_160MHZ; + + return flags; +} + +void qlink_utils_regrule_q2nl(struct ieee80211_reg_rule *rule, + const struct qlink_tlv_reg_rule *tlv) +{ + rule->freq_range.start_freq_khz = le32_to_cpu(tlv->start_freq_khz); + rule->freq_range.end_freq_khz = le32_to_cpu(tlv->end_freq_khz); + rule->freq_range.max_bandwidth_khz = + le32_to_cpu(tlv->max_bandwidth_khz); + rule->power_rule.max_antenna_gain = le32_to_cpu(tlv->max_antenna_gain); + rule->power_rule.max_eirp = le32_to_cpu(tlv->max_eirp); + rule->dfs_cac_ms = le32_to_cpu(tlv->dfs_cac_ms); + rule->flags = qtnf_reg_rule_flags_parse(le32_to_cpu(tlv->flags)); +} diff --git a/drivers/net/wireless/quantenna/qtnfmac/qlink_util.h b/drivers/net/wireless/quantenna/qtnfmac/qlink_util.h index 9d10a2098ca7..f873beed2ae7 100644 --- a/drivers/net/wireless/quantenna/qtnfmac/qlink_util.h +++ b/drivers/net/wireless/quantenna/qtnfmac/qlink_util.h @@ -82,5 +82,7 @@ void qlink_acl_data_cfg2q(const struct cfg80211_acl_data *acl, enum qlink_band qlink_utils_band_cfg2q(enum nl80211_band band); enum qlink_dfs_state qlink_utils_dfs_state_cfg2q(enum nl80211_dfs_state state); u32 qlink_utils_chflags_cfg2q(u32 cfgflags); +void qlink_utils_regrule_q2nl(struct ieee80211_reg_rule *rule, + const struct qlink_tlv_reg_rule *tlv_rule); #endif /* _QTN_FMAC_QLINK_UTIL_H_ */ |