Merge tag 'wireless-drivers-next-for-davem-2015-12-07' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next
Kalle Vallo says: ==================== brcfmac * support bcm4359 which can operate in two bands concurrently * disable runtime pm for USB avoiding issues * use generic pm callback in PCIe driver * support wowlan wake indication reporting * add beamforming support * unified handling of firmware files ath10k * support Manegement Frame Protection (MFP) * add thermal throttling support for 10.4 firmware * add support for pktlog in QCA99X0 * add debugfs file to enable Bluetooth coexistence feature * use firmware's native mesh interface type instead of raw mode iwlwifi * BT coex improvements * D3 operation bugfixes * rate control improvements * firmware debugging infra improvements * ground work for multi Rx * various security fixes ==================== Conflicts: drivers/net/wireless/ath/ath10k/pci.c The conflict resolution at: http://article.gmane.org/gmane.linux.kernel.next/37391 by Stephen Rothwell was used. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -90,7 +90,7 @@ static u8 ath10k_mac_bitrate_to_rate(int bitrate)
|
||||
}
|
||||
|
||||
u8 ath10k_mac_hw_rate_to_idx(const struct ieee80211_supported_band *sband,
|
||||
u8 hw_rate)
|
||||
u8 hw_rate, bool cck)
|
||||
{
|
||||
const struct ieee80211_rate *rate;
|
||||
int i;
|
||||
@@ -98,6 +98,9 @@ u8 ath10k_mac_hw_rate_to_idx(const struct ieee80211_supported_band *sband,
|
||||
for (i = 0; i < sband->n_bitrates; i++) {
|
||||
rate = &sband->bitrates[i];
|
||||
|
||||
if (ath10k_mac_bitrate_is_cck(rate->bitrate) != cck)
|
||||
continue;
|
||||
|
||||
if (rate->hw_value == hw_rate)
|
||||
return i;
|
||||
else if (rate->flags & IEEE80211_RATE_SHORT_PREAMBLE &&
|
||||
@@ -1960,7 +1963,7 @@ static void ath10k_peer_assoc_h_basic(struct ath10k *ar,
|
||||
ether_addr_copy(arg->addr, sta->addr);
|
||||
arg->vdev_id = arvif->vdev_id;
|
||||
arg->peer_aid = aid;
|
||||
arg->peer_flags |= WMI_PEER_AUTH;
|
||||
arg->peer_flags |= arvif->ar->wmi.peer_flags->auth;
|
||||
arg->peer_listen_intval = ath10k_peer_assoc_h_listen_intval(ar, vif);
|
||||
arg->peer_num_spatial_streams = 1;
|
||||
arg->peer_caps = vif->bss_conf.assoc_capability;
|
||||
@@ -1968,6 +1971,7 @@ static void ath10k_peer_assoc_h_basic(struct ath10k *ar,
|
||||
|
||||
static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct wmi_peer_assoc_complete_arg *arg)
|
||||
{
|
||||
struct ieee80211_bss_conf *info = &vif->bss_conf;
|
||||
@@ -2002,12 +2006,17 @@ static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
|
||||
/* FIXME: base on RSN IE/WPA IE is a correct idea? */
|
||||
if (rsnie || wpaie) {
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__);
|
||||
arg->peer_flags |= WMI_PEER_NEED_PTK_4_WAY;
|
||||
arg->peer_flags |= ar->wmi.peer_flags->need_ptk_4_way;
|
||||
}
|
||||
|
||||
if (wpaie) {
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__);
|
||||
arg->peer_flags |= WMI_PEER_NEED_GTK_2_WAY;
|
||||
arg->peer_flags |= ar->wmi.peer_flags->need_gtk_2_way;
|
||||
}
|
||||
|
||||
if (sta->mfp &&
|
||||
test_bit(ATH10K_FW_FEATURE_MFP_SUPPORT, ar->fw_features)) {
|
||||
arg->peer_flags |= ar->wmi.peer_flags->pmf;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2104,7 +2113,7 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
|
||||
ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
|
||||
return;
|
||||
|
||||
arg->peer_flags |= WMI_PEER_HT;
|
||||
arg->peer_flags |= ar->wmi.peer_flags->ht;
|
||||
arg->peer_max_mpdu = (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
|
||||
ht_cap->ampdu_factor)) - 1;
|
||||
|
||||
@@ -2115,10 +2124,10 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
|
||||
arg->peer_rate_caps |= WMI_RC_HT_FLAG;
|
||||
|
||||
if (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING)
|
||||
arg->peer_flags |= WMI_PEER_LDPC;
|
||||
arg->peer_flags |= ar->wmi.peer_flags->ldbc;
|
||||
|
||||
if (sta->bandwidth >= IEEE80211_STA_RX_BW_40) {
|
||||
arg->peer_flags |= WMI_PEER_40MHZ;
|
||||
arg->peer_flags |= ar->wmi.peer_flags->bw40;
|
||||
arg->peer_rate_caps |= WMI_RC_CW40_FLAG;
|
||||
}
|
||||
|
||||
@@ -2132,7 +2141,7 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
|
||||
|
||||
if (ht_cap->cap & IEEE80211_HT_CAP_TX_STBC) {
|
||||
arg->peer_rate_caps |= WMI_RC_TX_STBC_FLAG;
|
||||
arg->peer_flags |= WMI_PEER_STBC;
|
||||
arg->peer_flags |= ar->wmi.peer_flags->stbc;
|
||||
}
|
||||
|
||||
if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) {
|
||||
@@ -2140,7 +2149,7 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
|
||||
stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT;
|
||||
stbc = stbc << WMI_RC_RX_STBC_FLAG_S;
|
||||
arg->peer_rate_caps |= stbc;
|
||||
arg->peer_flags |= WMI_PEER_STBC;
|
||||
arg->peer_flags |= ar->wmi.peer_flags->stbc;
|
||||
}
|
||||
|
||||
if (ht_cap->mcs.rx_mask[1] && ht_cap->mcs.rx_mask[2])
|
||||
@@ -2321,10 +2330,10 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
|
||||
if (ath10k_peer_assoc_h_vht_masked(vht_mcs_mask))
|
||||
return;
|
||||
|
||||
arg->peer_flags |= WMI_PEER_VHT;
|
||||
arg->peer_flags |= ar->wmi.peer_flags->vht;
|
||||
|
||||
if (def.chan->band == IEEE80211_BAND_2GHZ)
|
||||
arg->peer_flags |= WMI_PEER_VHT_2G;
|
||||
arg->peer_flags |= ar->wmi.peer_flags->vht_2g;
|
||||
|
||||
arg->peer_vht_caps = vht_cap->cap;
|
||||
|
||||
@@ -2341,7 +2350,7 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
|
||||
ampdu_factor)) - 1);
|
||||
|
||||
if (sta->bandwidth == IEEE80211_STA_RX_BW_80)
|
||||
arg->peer_flags |= WMI_PEER_80MHZ;
|
||||
arg->peer_flags |= ar->wmi.peer_flags->bw80;
|
||||
|
||||
arg->peer_vht_rates.rx_max_rate =
|
||||
__le16_to_cpu(vht_cap->vht_mcs.rx_highest);
|
||||
@@ -2366,27 +2375,28 @@ static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
|
||||
switch (arvif->vdev_type) {
|
||||
case WMI_VDEV_TYPE_AP:
|
||||
if (sta->wme)
|
||||
arg->peer_flags |= WMI_PEER_QOS;
|
||||
arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
|
||||
|
||||
if (sta->wme && sta->uapsd_queues) {
|
||||
arg->peer_flags |= WMI_PEER_APSD;
|
||||
arg->peer_flags |= arvif->ar->wmi.peer_flags->apsd;
|
||||
arg->peer_rate_caps |= WMI_RC_UAPSD_FLAG;
|
||||
}
|
||||
break;
|
||||
case WMI_VDEV_TYPE_STA:
|
||||
if (vif->bss_conf.qos)
|
||||
arg->peer_flags |= WMI_PEER_QOS;
|
||||
arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
|
||||
break;
|
||||
case WMI_VDEV_TYPE_IBSS:
|
||||
if (sta->wme)
|
||||
arg->peer_flags |= WMI_PEER_QOS;
|
||||
arg->peer_flags |= arvif->ar->wmi.peer_flags->qos;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",
|
||||
sta->addr, !!(arg->peer_flags & WMI_PEER_QOS));
|
||||
sta->addr, !!(arg->peer_flags &
|
||||
arvif->ar->wmi.peer_flags->qos));
|
||||
}
|
||||
|
||||
static bool ath10k_mac_sta_has_ofdm_only(struct ieee80211_sta *sta)
|
||||
@@ -2479,7 +2489,7 @@ static int ath10k_peer_assoc_prepare(struct ath10k *ar,
|
||||
memset(arg, 0, sizeof(*arg));
|
||||
|
||||
ath10k_peer_assoc_h_basic(ar, vif, sta, arg);
|
||||
ath10k_peer_assoc_h_crypto(ar, vif, arg);
|
||||
ath10k_peer_assoc_h_crypto(ar, vif, sta, arg);
|
||||
ath10k_peer_assoc_h_rates(ar, vif, sta, arg);
|
||||
ath10k_peer_assoc_h_ht(ar, vif, sta, arg);
|
||||
ath10k_peer_assoc_h_vht(ar, vif, sta, arg);
|
||||
@@ -3112,35 +3122,11 @@ void ath10k_mac_handle_tx_pause_vdev(struct ath10k *ar, u32 vdev_id,
|
||||
spin_unlock_bh(&ar->htt.tx_lock);
|
||||
}
|
||||
|
||||
static u8 ath10k_tx_h_get_tid(struct ieee80211_hdr *hdr)
|
||||
{
|
||||
if (ieee80211_is_mgmt(hdr->frame_control))
|
||||
return HTT_DATA_TX_EXT_TID_MGMT;
|
||||
|
||||
if (!ieee80211_is_data_qos(hdr->frame_control))
|
||||
return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
|
||||
|
||||
if (!is_unicast_ether_addr(ieee80211_get_DA(hdr)))
|
||||
return HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
|
||||
|
||||
return ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
|
||||
}
|
||||
|
||||
static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, struct ieee80211_vif *vif)
|
||||
{
|
||||
if (vif)
|
||||
return ath10k_vif_to_arvif(vif)->vdev_id;
|
||||
|
||||
if (ar->monitor_started)
|
||||
return ar->monitor_vdev_id;
|
||||
|
||||
ath10k_warn(ar, "failed to resolve vdev id\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum ath10k_hw_txrx_mode
|
||||
ath10k_tx_h_get_txmode(struct ath10k *ar, struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta, struct sk_buff *skb)
|
||||
ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
const struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
__le16 fc = hdr->frame_control;
|
||||
@@ -3190,14 +3176,22 @@ ath10k_tx_h_get_txmode(struct ath10k *ar, struct ieee80211_vif *vif,
|
||||
}
|
||||
|
||||
static bool ath10k_tx_h_use_hwcrypto(struct ieee80211_vif *vif,
|
||||
struct sk_buff *skb) {
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
const struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
const struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
const u32 mask = IEEE80211_TX_INTFL_DONT_ENCRYPT |
|
||||
IEEE80211_TX_CTL_INJECTED;
|
||||
|
||||
if (!ieee80211_has_protected(hdr->frame_control))
|
||||
return false;
|
||||
|
||||
if ((info->flags & mask) == mask)
|
||||
return false;
|
||||
|
||||
if (vif)
|
||||
return !ath10k_vif_to_arvif(vif)->nohwcrypt;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3224,7 +3218,7 @@ static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
*/
|
||||
hdr = (void *)skb->data;
|
||||
if (ieee80211_is_qos_nullfunc(hdr->frame_control))
|
||||
cb->htt.tid = HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST;
|
||||
cb->flags &= ~ATH10K_SKB_F_QOS;
|
||||
|
||||
hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
|
||||
}
|
||||
@@ -3280,7 +3274,7 @@ static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar,
|
||||
}
|
||||
}
|
||||
|
||||
static bool ath10k_mac_need_offchan_tx_work(struct ath10k *ar)
|
||||
bool ath10k_mac_tx_frm_has_freq(struct ath10k *ar)
|
||||
{
|
||||
/* FIXME: Not really sure since when the behaviour changed. At some
|
||||
* point new firmware stopped requiring creation of peer entries for
|
||||
@@ -3288,8 +3282,9 @@ static bool ath10k_mac_need_offchan_tx_work(struct ath10k *ar)
|
||||
* tx credit replenishment and reliability). Assuming it's at least 3.4
|
||||
* because that's when the `freq` was introduced to TX_FRM HTT command.
|
||||
*/
|
||||
return !(ar->htt.target_version_major >= 3 &&
|
||||
ar->htt.target_version_minor >= 4);
|
||||
return (ar->htt.target_version_major >= 3 &&
|
||||
ar->htt.target_version_minor >= 4 &&
|
||||
ar->htt.op_version == ATH10K_FW_HTT_OP_VERSION_TLV);
|
||||
}
|
||||
|
||||
static int ath10k_mac_tx_wmi_mgmt(struct ath10k *ar, struct sk_buff *skb)
|
||||
@@ -3314,24 +3309,24 @@ unlock:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ath10k_mac_tx(struct ath10k *ar, struct sk_buff *skb)
|
||||
static void ath10k_mac_tx(struct ath10k *ar, enum ath10k_hw_txrx_mode txmode,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb);
|
||||
struct ath10k_htt *htt = &ar->htt;
|
||||
int ret = 0;
|
||||
|
||||
switch (cb->txmode) {
|
||||
switch (txmode) {
|
||||
case ATH10K_HW_TXRX_RAW:
|
||||
case ATH10K_HW_TXRX_NATIVE_WIFI:
|
||||
case ATH10K_HW_TXRX_ETHERNET:
|
||||
ret = ath10k_htt_tx(htt, skb);
|
||||
ret = ath10k_htt_tx(htt, txmode, skb);
|
||||
break;
|
||||
case ATH10K_HW_TXRX_MGMT:
|
||||
if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
|
||||
ar->fw_features))
|
||||
ret = ath10k_mac_tx_wmi_mgmt(ar, skb);
|
||||
else if (ar->htt.target_version_major >= 3)
|
||||
ret = ath10k_htt_tx(htt, skb);
|
||||
ret = ath10k_htt_tx(htt, txmode, skb);
|
||||
else
|
||||
ret = ath10k_htt_mgmt_tx(htt, skb);
|
||||
break;
|
||||
@@ -3361,9 +3356,13 @@ void ath10k_offchan_tx_work(struct work_struct *work)
|
||||
{
|
||||
struct ath10k *ar = container_of(work, struct ath10k, offchan_tx_work);
|
||||
struct ath10k_peer *peer;
|
||||
struct ath10k_vif *arvif;
|
||||
struct ieee80211_hdr *hdr;
|
||||
struct ieee80211_vif *vif;
|
||||
struct ieee80211_sta *sta;
|
||||
struct sk_buff *skb;
|
||||
const u8 *peer_addr;
|
||||
enum ath10k_hw_txrx_mode txmode;
|
||||
int vdev_id;
|
||||
int ret;
|
||||
unsigned long time_left;
|
||||
@@ -3388,9 +3387,9 @@ void ath10k_offchan_tx_work(struct work_struct *work)
|
||||
|
||||
hdr = (struct ieee80211_hdr *)skb->data;
|
||||
peer_addr = ieee80211_get_DA(hdr);
|
||||
vdev_id = ATH10K_SKB_CB(skb)->vdev_id;
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
vdev_id = ar->scan.vdev_id;
|
||||
peer = ath10k_peer_find(ar, vdev_id, peer_addr);
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
@@ -3413,7 +3412,22 @@ void ath10k_offchan_tx_work(struct work_struct *work)
|
||||
ar->offchan_tx_skb = skb;
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
ath10k_mac_tx(ar, skb);
|
||||
/* It's safe to access vif and sta - conf_mutex guarantees that
|
||||
* sta_state() and remove_interface() are locked exclusively
|
||||
* out wrt to this offchannel worker.
|
||||
*/
|
||||
arvif = ath10k_get_arvif(ar, vdev_id);
|
||||
if (arvif) {
|
||||
vif = arvif->vif;
|
||||
sta = ieee80211_find_sta(vif, peer_addr);
|
||||
} else {
|
||||
vif = NULL;
|
||||
sta = NULL;
|
||||
}
|
||||
|
||||
txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
|
||||
|
||||
ath10k_mac_tx(ar, txmode, skb);
|
||||
|
||||
time_left =
|
||||
wait_for_completion_timeout(&ar->offchan_tx_completed, 3 * HZ);
|
||||
@@ -3488,6 +3502,7 @@ void __ath10k_scan_finish(struct ath10k *ar)
|
||||
case ATH10K_SCAN_STARTING:
|
||||
ar->scan.state = ATH10K_SCAN_IDLE;
|
||||
ar->scan_channel = NULL;
|
||||
ar->scan.roc_freq = 0;
|
||||
ath10k_offchan_tx_purge(ar);
|
||||
cancel_delayed_work(&ar->scan.timeout);
|
||||
complete_all(&ar->scan.completed);
|
||||
@@ -3631,25 +3646,32 @@ static void ath10k_tx(struct ieee80211_hw *hw,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct ath10k *ar = hw->priv;
|
||||
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_vif *vif = info->control.vif;
|
||||
struct ieee80211_sta *sta = control->sta;
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
__le16 fc = hdr->frame_control;
|
||||
enum ath10k_hw_txrx_mode txmode;
|
||||
|
||||
/* We should disable CCK RATE due to P2P */
|
||||
if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE)
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n");
|
||||
|
||||
ATH10K_SKB_CB(skb)->htt.is_offchan = false;
|
||||
ATH10K_SKB_CB(skb)->htt.freq = 0;
|
||||
ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
|
||||
ATH10K_SKB_CB(skb)->htt.nohwcrypt = !ath10k_tx_h_use_hwcrypto(vif, skb);
|
||||
ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
|
||||
ATH10K_SKB_CB(skb)->txmode = ath10k_tx_h_get_txmode(ar, vif, sta, skb);
|
||||
ATH10K_SKB_CB(skb)->is_protected = ieee80211_has_protected(fc);
|
||||
txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
|
||||
|
||||
switch (ATH10K_SKB_CB(skb)->txmode) {
|
||||
skb_cb->flags = 0;
|
||||
if (!ath10k_tx_h_use_hwcrypto(vif, skb))
|
||||
skb_cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;
|
||||
|
||||
if (ieee80211_is_mgmt(hdr->frame_control))
|
||||
skb_cb->flags |= ATH10K_SKB_F_MGMT;
|
||||
|
||||
if (ieee80211_is_data_qos(hdr->frame_control))
|
||||
skb_cb->flags |= ATH10K_SKB_F_QOS;
|
||||
|
||||
skb_cb->vif = vif;
|
||||
|
||||
switch (txmode) {
|
||||
case ATH10K_HW_TXRX_MGMT:
|
||||
case ATH10K_HW_TXRX_NATIVE_WIFI:
|
||||
ath10k_tx_h_nwifi(hw, skb);
|
||||
@@ -3668,15 +3690,7 @@ static void ath10k_tx(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) {
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
ATH10K_SKB_CB(skb)->htt.freq = ar->scan.roc_freq;
|
||||
ATH10K_SKB_CB(skb)->vdev_id = ar->scan.vdev_id;
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
if (ath10k_mac_need_offchan_tx_work(ar)) {
|
||||
ATH10K_SKB_CB(skb)->htt.freq = 0;
|
||||
ATH10K_SKB_CB(skb)->htt.is_offchan = true;
|
||||
|
||||
if (!ath10k_mac_tx_frm_has_freq(ar)) {
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n",
|
||||
skb);
|
||||
|
||||
@@ -3686,7 +3700,7 @@ static void ath10k_tx(struct ieee80211_hw *hw,
|
||||
}
|
||||
}
|
||||
|
||||
ath10k_mac_tx(ar, skb);
|
||||
ath10k_mac_tx(ar, txmode, skb);
|
||||
}
|
||||
|
||||
/* Must not be called with conf_mutex held as workers can use that also. */
|
||||
@@ -4350,7 +4364,9 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
|
||||
arvif->vdev_type = WMI_VDEV_TYPE_IBSS;
|
||||
break;
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
|
||||
if (test_bit(WMI_SERVICE_MESH, ar->wmi.svc_map)) {
|
||||
arvif->vdev_subtype = WMI_VDEV_SUBTYPE_MESH;
|
||||
} else if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
|
||||
ret = -EINVAL;
|
||||
ath10k_warn(ar, "must load driver with rawmode=1 to add mesh interfaces\n");
|
||||
goto err;
|
||||
@@ -6907,35 +6923,39 @@ void ath10k_mac_destroy(struct ath10k *ar)
|
||||
|
||||
static const struct ieee80211_iface_limit ath10k_if_limits[] = {
|
||||
{
|
||||
.max = 8,
|
||||
.types = BIT(NL80211_IFTYPE_STATION)
|
||||
| BIT(NL80211_IFTYPE_P2P_CLIENT)
|
||||
.max = 8,
|
||||
.types = BIT(NL80211_IFTYPE_STATION)
|
||||
| BIT(NL80211_IFTYPE_P2P_CLIENT)
|
||||
},
|
||||
{
|
||||
.max = 3,
|
||||
.types = BIT(NL80211_IFTYPE_P2P_GO)
|
||||
.max = 3,
|
||||
.types = BIT(NL80211_IFTYPE_P2P_GO)
|
||||
},
|
||||
{
|
||||
.max = 1,
|
||||
.types = BIT(NL80211_IFTYPE_P2P_DEVICE)
|
||||
.max = 1,
|
||||
.types = BIT(NL80211_IFTYPE_P2P_DEVICE)
|
||||
},
|
||||
{
|
||||
.max = 7,
|
||||
.types = BIT(NL80211_IFTYPE_AP)
|
||||
.max = 7,
|
||||
.types = BIT(NL80211_IFTYPE_AP)
|
||||
#ifdef CONFIG_MAC80211_MESH
|
||||
| BIT(NL80211_IFTYPE_MESH_POINT)
|
||||
| BIT(NL80211_IFTYPE_MESH_POINT)
|
||||
#endif
|
||||
},
|
||||
};
|
||||
|
||||
static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
|
||||
{
|
||||
.max = 8,
|
||||
.types = BIT(NL80211_IFTYPE_AP)
|
||||
.max = 8,
|
||||
.types = BIT(NL80211_IFTYPE_AP)
|
||||
#ifdef CONFIG_MAC80211_MESH
|
||||
| BIT(NL80211_IFTYPE_MESH_POINT)
|
||||
| BIT(NL80211_IFTYPE_MESH_POINT)
|
||||
#endif
|
||||
},
|
||||
{
|
||||
.max = 1,
|
||||
.types = BIT(NL80211_IFTYPE_STATION)
|
||||
},
|
||||
};
|
||||
|
||||
static const struct ieee80211_iface_combination ath10k_if_comb[] = {
|
||||
|
Reference in New Issue
Block a user