diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index beb725d7547f649f0acdc7482a015925a4ff543e..771c0217ea6a94b2b63a5c3aa596f714c1b69320 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h @@ -286,6 +286,10 @@ struct ar9170 { unsigned int tx_seq_table; } fw; + /* interface configuration combinations */ + struct ieee80211_iface_limit if_comb_limits[1]; + struct ieee80211_iface_combination if_combs[1]; + /* reset / stuck frames/queue detection */ struct work_struct restart_work; struct work_struct ping_work; diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c index 9517ede9e2dfdbb104042c3f520e9cb36a18c778..221957c5d37370830eef6c74ae3aacddcbb62f89 100644 --- a/drivers/net/wireless/ath/carl9170/fw.c +++ b/drivers/net/wireless/ath/carl9170/fw.c @@ -151,6 +151,7 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) const struct carl9170fw_chk_desc *chk_desc; const struct carl9170fw_last_desc *last_desc; const struct carl9170fw_txsq_desc *txsq_desc; + u16 if_comb_types; last_desc = carl9170_fw_find_desc(ar, LAST_MAGIC, sizeof(*last_desc), CARL9170FW_LAST_DESC_CUR_VER); @@ -268,6 +269,9 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) if (SUPP(CARL9170FW_WOL)) device_set_wakeup_enable(&ar->udev->dev, true); + if_comb_types = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_P2P_CLIENT); + ar->fw.vif_num = otus_desc->vif_num; ar->fw.cmd_bufs = otus_desc->cmd_bufs; ar->fw.address = le32_to_cpu(otus_desc->fw_address); @@ -294,12 +298,25 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC); if (SUPP(CARL9170FW_WLANTX_CAB)) { - ar->hw->wiphy->interface_modes |= + if_comb_types |= BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_P2P_GO); } } + ar->if_comb_limits[0].max = ar->fw.vif_num; + ar->if_comb_limits[0].types = if_comb_types; + + ar->if_combs[0].num_different_channels = 1; + ar->if_combs[0].max_interfaces = ar->fw.vif_num; + ar->if_combs[0].limits = ar->if_comb_limits; + ar->if_combs[0].n_limits = ARRAY_SIZE(ar->if_comb_limits); + + ar->hw->wiphy->iface_combinations = ar->if_combs; + ar->hw->wiphy->n_iface_combinations = ARRAY_SIZE(ar->if_combs); + + ar->hw->wiphy->interface_modes |= if_comb_types; + txsq_desc = carl9170_fw_find_desc(ar, TXSQ_MAGIC, sizeof(*txsq_desc), CARL9170FW_TXSQ_DESC_CUR_VER); diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 7d5c65ea94e6213723ecb7a98f8222d6fa727daf..54d093c2ab44f956b5988d73ae819ed9b398a58b 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -1570,14 +1570,8 @@ void *carl9170_alloc(size_t priv_size) INIT_LIST_HEAD(&ar->vif_list); init_completion(&ar->tx_flush); - /* - * Note: - * IBSS/ADHOC and AP mode are only enabled, if the firmware - * supports these modes. The code which will add the - * additional interface_modes is in fw.c. - */ - hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_P2P_CLIENT); + /* firmware decides which modes we support */ + hw->wiphy->interface_modes = 0; hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS | IEEE80211_HW_REPORTS_TX_ACK_STATUS |