From e32144bf9dbc25503dc7ad43f3d84c9632d40663 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Wed, 26 Aug 2015 22:57:29 +0000 Subject: mac80211: group last brcmfmac changes into (half) patchset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This prepares some place for backporting extra patches. Signed-off-by: Rafał Miłecki git-svn-id: svn://svn.openwrt.org/openwrt/branches/chaos_calmer@46735 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- ...1-brcmfmac-Check-if-firmware-supports-p2p.patch | 42 +++ ...ild-wiphy-mode-and-interface-combinations.patch | 198 +++++++++++++ ...003-brcmfmac-rework-.get_station-callback.patch | 326 +++++++++++++++++++++ ...ve-sdio-return-EIO-when-device-communicat.patch | 56 ++++ ...make-DMA-stop-related-messages-debug-only.patch | 74 +++++ ...9-brcmfmac-Check-if-firmware-supports-p2p.patch | 42 --- ...ild-wiphy-mode-and-interface-combinations.patch | 198 ------------- ...391-brcmfmac-rework-.get_station-callback.patch | 326 --------------------- ...ve-sdio-return-EIO-when-device-communicat.patch | 56 ---- ...make-DMA-stop-related-messages-debug-only.patch | 74 ----- 10 files changed, 696 insertions(+), 696 deletions(-) create mode 100644 package/kernel/mac80211/patches/389-0001-brcmfmac-Check-if-firmware-supports-p2p.patch create mode 100644 package/kernel/mac80211/patches/389-0002-brcmfmac-Build-wiphy-mode-and-interface-combinations.patch create mode 100644 package/kernel/mac80211/patches/389-0003-brcmfmac-rework-.get_station-callback.patch create mode 100644 package/kernel/mac80211/patches/389-0004-brcmfmac-have-sdio-return-EIO-when-device-communicat.patch create mode 100644 package/kernel/mac80211/patches/389-0005-ath9k-make-DMA-stop-related-messages-debug-only.patch delete mode 100644 package/kernel/mac80211/patches/389-brcmfmac-Check-if-firmware-supports-p2p.patch delete mode 100644 package/kernel/mac80211/patches/390-brcmfmac-Build-wiphy-mode-and-interface-combinations.patch delete mode 100644 package/kernel/mac80211/patches/391-brcmfmac-rework-.get_station-callback.patch delete mode 100644 package/kernel/mac80211/patches/392-brcmfmac-have-sdio-return-EIO-when-device-communicat.patch delete mode 100644 package/kernel/mac80211/patches/393-ath9k-make-DMA-stop-related-messages-debug-only.patch diff --git a/package/kernel/mac80211/patches/389-0001-brcmfmac-Check-if-firmware-supports-p2p.patch b/package/kernel/mac80211/patches/389-0001-brcmfmac-Check-if-firmware-supports-p2p.patch new file mode 100644 index 0000000000..ff24a4a06f --- /dev/null +++ b/package/kernel/mac80211/patches/389-0001-brcmfmac-Check-if-firmware-supports-p2p.patch @@ -0,0 +1,42 @@ +From: Pontus Fuchs +Date: Thu, 11 Jun 2015 00:12:17 +0200 +Subject: [PATCH] brcmfmac: Check if firmware supports p2p + +Add a feature flag to reflect the firmware's p2p capability. + +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Hante Meuleman +Reviewed-by: Arend Van Spriel +Signed-off-by: Pontus Fuchs +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/feature.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c +@@ -129,6 +129,7 @@ void brcmf_feat_attach(struct brcmf_pub + brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl"); + if (drvr->bus_if->chip != BRCM_CC_43362_CHIP_ID) + brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0); ++ brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_P2P, "p2p"); + + /* set chip related quirks */ + switch (drvr->bus_if->chip) { +--- a/drivers/net/wireless/brcm80211/brcmfmac/feature.h ++++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.h +@@ -23,12 +23,14 @@ + * MCHAN: multi-channel for concurrent P2P. + * PNO: preferred network offload. + * WOWL: Wake-On-WLAN. ++ * P2P: peer-to-peer + */ + #define BRCMF_FEAT_LIST \ + BRCMF_FEAT_DEF(MBSS) \ + BRCMF_FEAT_DEF(MCHAN) \ + BRCMF_FEAT_DEF(PNO) \ +- BRCMF_FEAT_DEF(WOWL) ++ BRCMF_FEAT_DEF(WOWL) \ ++ BRCMF_FEAT_DEF(P2P) + /* + * Quirks: + * diff --git a/package/kernel/mac80211/patches/389-0002-brcmfmac-Build-wiphy-mode-and-interface-combinations.patch b/package/kernel/mac80211/patches/389-0002-brcmfmac-Build-wiphy-mode-and-interface-combinations.patch new file mode 100644 index 0000000000..3876ba01da --- /dev/null +++ b/package/kernel/mac80211/patches/389-0002-brcmfmac-Build-wiphy-mode-and-interface-combinations.patch @@ -0,0 +1,198 @@ +From: Pontus Fuchs +Date: Thu, 11 Jun 2015 00:12:18 +0200 +Subject: [PATCH] brcmfmac: Build wiphy mode and interface combinations + dynamically + +Switch from using semi hard coded interface combinations. This makes +it easier to announce what the firmware actually supports. This fixes +the case where brcmfmac announces p2p but the firmware doesn't +support it. + +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Hante Meuleman +Reviewed-by: Arend Van Spriel +Signed-off-by: Pontus Fuchs +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +@@ -52,8 +52,6 @@ + #define BRCMF_PNO_SCAN_COMPLETE 1 + #define BRCMF_PNO_SCAN_INCOMPLETE 0 + +-#define BRCMF_IFACE_MAX_CNT 3 +- + #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */ + #define WPA_OUI_TYPE 1 + #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */ +@@ -5639,53 +5637,6 @@ static int brcmf_setup_wiphybands(struct + return 0; + } + +-static const struct ieee80211_iface_limit brcmf_iface_limits_mbss[] = { +- { +- .max = 1, +- .types = BIT(NL80211_IFTYPE_STATION) | +- BIT(NL80211_IFTYPE_ADHOC) +- }, +- { +- .max = 4, +- .types = BIT(NL80211_IFTYPE_AP) +- }, +- { +- .max = 1, +- .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | +- BIT(NL80211_IFTYPE_P2P_GO) +- }, +- { +- .max = 1, +- .types = BIT(NL80211_IFTYPE_P2P_DEVICE) +- } +-}; +- +-static const struct ieee80211_iface_limit brcmf_iface_limits_sbss[] = { +- { +- .max = 2, +- .types = BIT(NL80211_IFTYPE_STATION) | +- BIT(NL80211_IFTYPE_ADHOC) | +- BIT(NL80211_IFTYPE_AP) +- }, +- { +- .max = 1, +- .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | +- BIT(NL80211_IFTYPE_P2P_GO) +- }, +- { +- .max = 1, +- .types = BIT(NL80211_IFTYPE_P2P_DEVICE) +- } +-}; +-static struct ieee80211_iface_combination brcmf_iface_combos[] = { +- { +- .max_interfaces = BRCMF_IFACE_MAX_CNT, +- .num_different_channels = 1, +- .n_limits = ARRAY_SIZE(brcmf_iface_limits_sbss), +- .limits = brcmf_iface_limits_sbss, +- } +-}; +- + static const struct ieee80211_txrx_stypes + brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = { + [NL80211_IFTYPE_STATION] = { +@@ -5715,6 +5666,67 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = + } + }; + ++static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp) ++{ ++ struct ieee80211_iface_combination *combo = NULL; ++ struct ieee80211_iface_limit *limits = NULL; ++ int i = 0, max_iface_cnt; ++ ++ combo = kzalloc(sizeof(*combo), GFP_KERNEL); ++ if (!combo) ++ goto err; ++ ++ limits = kzalloc(sizeof(*limits) * 4, GFP_KERNEL); ++ if (!limits) ++ goto err; ++ ++ wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | ++ BIT(NL80211_IFTYPE_ADHOC) | ++ BIT(NL80211_IFTYPE_AP); ++ ++ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN)) ++ combo->num_different_channels = 2; ++ else ++ combo->num_different_channels = 1; ++ ++ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) { ++ limits[i].max = 1; ++ limits[i++].types = BIT(NL80211_IFTYPE_STATION); ++ limits[i].max = 4; ++ limits[i++].types = BIT(NL80211_IFTYPE_AP); ++ max_iface_cnt = 5; ++ } else { ++ limits[i].max = 2; ++ limits[i++].types = BIT(NL80211_IFTYPE_STATION) | ++ BIT(NL80211_IFTYPE_AP); ++ max_iface_cnt = 2; ++ } ++ ++ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P)) { ++ wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) | ++ BIT(NL80211_IFTYPE_P2P_GO) | ++ BIT(NL80211_IFTYPE_P2P_DEVICE); ++ limits[i].max = 1; ++ limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) | ++ BIT(NL80211_IFTYPE_P2P_GO); ++ limits[i].max = 1; ++ limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE); ++ max_iface_cnt += 2; ++ } ++ combo->max_interfaces = max_iface_cnt; ++ combo->limits = limits; ++ combo->n_limits = i; ++ ++ wiphy->iface_combinations = combo; ++ wiphy->n_iface_combinations = 1; ++ return 0; ++ ++err: ++ kfree(limits); ++ kfree(combo); ++ return -ENOMEM; ++} ++ + static void brcmf_wiphy_pno_params(struct wiphy *wiphy) + { + /* scheduled scan settings */ +@@ -5745,7 +5757,6 @@ static void brcmf_wiphy_wowl_params(stru + static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp) + { + struct ieee80211_supported_band *band; +- struct ieee80211_iface_combination ifc_combo; + __le32 bandlist[3]; + u32 n_bands; + int err, i; +@@ -5753,24 +5764,11 @@ static int brcmf_setup_wiphy(struct wiph + wiphy->max_scan_ssids = WL_NUM_SCAN_MAX; + wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX; + wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX; +- wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | +- BIT(NL80211_IFTYPE_ADHOC) | +- BIT(NL80211_IFTYPE_AP) | +- BIT(NL80211_IFTYPE_P2P_CLIENT) | +- BIT(NL80211_IFTYPE_P2P_GO) | +- BIT(NL80211_IFTYPE_P2P_DEVICE); +- /* need VSDB firmware feature for concurrent channels */ +- ifc_combo = brcmf_iface_combos[0]; +- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN)) +- ifc_combo.num_different_channels = 2; +- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) { +- ifc_combo.n_limits = ARRAY_SIZE(brcmf_iface_limits_mbss), +- ifc_combo.limits = brcmf_iface_limits_mbss; +- } +- wiphy->iface_combinations = kmemdup(&ifc_combo, +- sizeof(ifc_combo), +- GFP_KERNEL); +- wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos); ++ ++ err = brcmf_setup_ifmodes(wiphy, ifp); ++ if (err) ++ return err; ++ + wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; + wiphy->cipher_suites = __wl_cipher_suites; + wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); +@@ -6035,6 +6033,8 @@ static void brcmf_free_wiphy(struct wiph + if (!wiphy) + return; + ++ if (wiphy->iface_combinations) ++ kfree(wiphy->iface_combinations->limits); + kfree(wiphy->iface_combinations); + if (wiphy->bands[IEEE80211_BAND_2GHZ]) { + kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels); diff --git a/package/kernel/mac80211/patches/389-0003-brcmfmac-rework-.get_station-callback.patch b/package/kernel/mac80211/patches/389-0003-brcmfmac-rework-.get_station-callback.patch new file mode 100644 index 0000000000..7bd06869da --- /dev/null +++ b/package/kernel/mac80211/patches/389-0003-brcmfmac-rework-.get_station-callback.patch @@ -0,0 +1,326 @@ +From: Arend van Spriel +Date: Thu, 11 Jun 2015 00:12:19 +0200 +Subject: [PATCH] brcmfmac: rework .get_station() callback + +The .get_station() cfg80211 callback is used in several scenarios. In +managed mode it can obtain information about the access-point and its +BSS parameters. In managed mode it can also obtain information about +TDLS peers. In AP mode it can obtain information about connected +clients. + +Reviewed-by: Hante Meuleman +Reviewed-by: Daniel (Deognyoun) Kim +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c +@@ -2395,27 +2395,80 @@ brcmf_cfg80211_reconfigure_wep(struct br + brcmf_err("set wsec error (%d)\n", err); + } + ++static void brcmf_convert_sta_flags(u32 fw_sta_flags, struct station_info *si) ++{ ++ struct nl80211_sta_flag_update *sfu; ++ ++ brcmf_dbg(TRACE, "flags %08x\n", fw_sta_flags); ++ si->filled |= BIT(NL80211_STA_INFO_STA_FLAGS); ++ sfu = &si->sta_flags; ++ sfu->mask = BIT(NL80211_STA_FLAG_WME) | ++ BIT(NL80211_STA_FLAG_AUTHENTICATED) | ++ BIT(NL80211_STA_FLAG_ASSOCIATED) | ++ BIT(NL80211_STA_FLAG_AUTHORIZED); ++ if (fw_sta_flags & BRCMF_STA_WME) ++ sfu->set |= BIT(NL80211_STA_FLAG_WME); ++ if (fw_sta_flags & BRCMF_STA_AUTHE) ++ sfu->set |= BIT(NL80211_STA_FLAG_AUTHENTICATED); ++ if (fw_sta_flags & BRCMF_STA_ASSOC) ++ sfu->set |= BIT(NL80211_STA_FLAG_ASSOCIATED); ++ if (fw_sta_flags & BRCMF_STA_AUTHO) ++ sfu->set |= BIT(NL80211_STA_FLAG_AUTHORIZED); ++} ++ ++static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si) ++{ ++ struct { ++ __le32 len; ++ struct brcmf_bss_info_le bss_le; ++ } *buf; ++ u16 capability; ++ int err; ++ ++ buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); ++ if (!buf) ++ return; ++ ++ buf->len = cpu_to_le32(WL_BSS_INFO_MAX); ++ err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, buf, ++ WL_BSS_INFO_MAX); ++ if (err) { ++ brcmf_err("Failed to get bss info (%d)\n", err); ++ return; ++ } ++ si->filled |= BIT(NL80211_STA_INFO_BSS_PARAM); ++ si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period); ++ si->bss_param.dtim_period = buf->bss_le.dtim_period; ++ capability = le16_to_cpu(buf->bss_le.capability); ++ if (capability & IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT) ++ si->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT; ++ if (capability & WLAN_CAPABILITY_SHORT_PREAMBLE) ++ si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE; ++ if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) ++ si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; ++} ++ + static s32 + brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, + const u8 *mac, struct station_info *sinfo) + { + struct brcmf_if *ifp = netdev_priv(ndev); +- struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; +- struct brcmf_scb_val_le scb_val; +- int rssi; +- s32 rate; + s32 err = 0; +- u8 *bssid = profile->bssid; + struct brcmf_sta_info_le sta_info_le; +- u32 beacon_period; +- u32 dtim_period; ++ u32 sta_flags; ++ u32 is_tdls_peer; + + brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac); + if (!check_vif_up(ifp->vif)) + return -EIO; + +- if (brcmf_is_apmode(ifp->vif)) { +- memcpy(&sta_info_le, mac, ETH_ALEN); ++ memset(&sta_info_le, 0, sizeof(sta_info_le)); ++ memcpy(&sta_info_le, mac, ETH_ALEN); ++ err = brcmf_fil_iovar_data_get(ifp, "tdls_sta_info", ++ &sta_info_le, ++ sizeof(sta_info_le)); ++ is_tdls_peer = !err; ++ if (err) { + err = brcmf_fil_iovar_data_get(ifp, "sta_info", + &sta_info_le, + sizeof(sta_info_le)); +@@ -2423,73 +2476,48 @@ brcmf_cfg80211_get_station(struct wiphy + brcmf_err("GET STA INFO failed, %d\n", err); + goto done; + } +- sinfo->filled = BIT(NL80211_STA_INFO_INACTIVE_TIME); +- sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000; +- if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) { +- sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME); +- sinfo->connected_time = le32_to_cpu(sta_info_le.in); +- } +- brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n", +- sinfo->inactive_time, sinfo->connected_time); +- } else if (ifp->vif->wdev.iftype == NL80211_IFTYPE_STATION) { +- if (memcmp(mac, bssid, ETH_ALEN)) { +- brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n", +- mac, bssid); +- err = -ENOENT; +- goto done; +- } +- /* Report the current tx rate */ +- err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate); +- if (err) { +- brcmf_err("Could not get rate (%d)\n", err); +- goto done; +- } else { ++ } ++ brcmf_dbg(TRACE, "version %d\n", le16_to_cpu(sta_info_le.ver)); ++ sinfo->filled = BIT(NL80211_STA_INFO_INACTIVE_TIME); ++ sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000; ++ sta_flags = le32_to_cpu(sta_info_le.flags); ++ brcmf_convert_sta_flags(sta_flags, sinfo); ++ sinfo->sta_flags.mask |= BIT(NL80211_STA_FLAG_TDLS_PEER); ++ if (is_tdls_peer) ++ sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER); ++ else ++ sinfo->sta_flags.set &= ~BIT(NL80211_STA_FLAG_TDLS_PEER); ++ if (sta_flags & BRCMF_STA_ASSOC) { ++ sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME); ++ sinfo->connected_time = le32_to_cpu(sta_info_le.in); ++ brcmf_fill_bss_param(ifp, sinfo); ++ } ++ if (sta_flags & BRCMF_STA_SCBSTATS) { ++ sinfo->filled |= BIT(NL80211_STA_INFO_TX_FAILED); ++ sinfo->tx_failed = le32_to_cpu(sta_info_le.tx_failures); ++ sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS); ++ sinfo->tx_packets = le32_to_cpu(sta_info_le.tx_pkts); ++ sinfo->tx_packets += le32_to_cpu(sta_info_le.tx_mcast_pkts); ++ sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS); ++ sinfo->rx_packets = le32_to_cpu(sta_info_le.rx_ucast_pkts); ++ sinfo->rx_packets += le32_to_cpu(sta_info_le.rx_mcast_pkts); ++ if (sinfo->tx_packets) { + sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE); +- sinfo->txrate.legacy = rate * 5; +- brcmf_dbg(CONN, "Rate %d Mbps\n", rate / 2); ++ sinfo->txrate.legacy = le32_to_cpu(sta_info_le.tx_rate); ++ sinfo->txrate.legacy /= 100; + } +- +- if (test_bit(BRCMF_VIF_STATUS_CONNECTED, +- &ifp->vif->sme_state)) { +- memset(&scb_val, 0, sizeof(scb_val)); +- err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI, +- &scb_val, sizeof(scb_val)); +- if (err) { +- brcmf_err("Could not get rssi (%d)\n", err); +- goto done; +- } else { +- rssi = le32_to_cpu(scb_val.val); +- sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); +- sinfo->signal = rssi; +- brcmf_dbg(CONN, "RSSI %d dBm\n", rssi); +- } +- err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_BCNPRD, +- &beacon_period); +- if (err) { +- brcmf_err("Could not get beacon period (%d)\n", +- err); +- goto done; +- } else { +- sinfo->bss_param.beacon_interval = +- beacon_period; +- brcmf_dbg(CONN, "Beacon peroid %d\n", +- beacon_period); +- } +- err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_DTIMPRD, +- &dtim_period); +- if (err) { +- brcmf_err("Could not get DTIM period (%d)\n", +- err); +- goto done; +- } else { +- sinfo->bss_param.dtim_period = dtim_period; +- brcmf_dbg(CONN, "DTIM peroid %d\n", +- dtim_period); +- } +- sinfo->filled |= BIT(NL80211_STA_INFO_BSS_PARAM); ++ if (sinfo->rx_packets) { ++ sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE); ++ sinfo->rxrate.legacy = le32_to_cpu(sta_info_le.rx_rate); ++ sinfo->rxrate.legacy /= 100; ++ } ++ if (le16_to_cpu(sta_info_le.ver) >= 4) { ++ sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES); ++ sinfo->tx_bytes = le64_to_cpu(sta_info_le.tx_tot_bytes); ++ sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES); ++ sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes); + } +- } else +- err = -EPERM; ++ } + done: + brcmf_dbg(TRACE, "Exit\n"); + return err; +--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h ++++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h +@@ -32,7 +32,11 @@ + #define BRCMF_BSS_INFO_VERSION 109 /* curr ver of brcmf_bss_info_le struct */ + #define BRCMF_BSS_RSSI_ON_CHANNEL 0x0002 + +-#define BRCMF_STA_ASSOC 0x10 /* Associated */ ++#define BRCMF_STA_WME 0x00000002 /* WMM association */ ++#define BRCMF_STA_AUTHE 0x00000008 /* Authenticated */ ++#define BRCMF_STA_ASSOC 0x00000010 /* Associated */ ++#define BRCMF_STA_AUTHO 0x00000020 /* Authorized */ ++#define BRCMF_STA_SCBSTATS 0x00004000 /* Per STA debug stats */ + + /* size of brcmf_scan_params not including variable length array */ + #define BRCMF_SCAN_PARAMS_FIXED_SIZE 64 +@@ -113,6 +117,7 @@ + #define BRCMF_WOWL_MAXPATTERNSIZE 128 + + #define BRCMF_COUNTRY_BUF_SZ 4 ++#define BRCMF_ANT_MAX 4 + + /* join preference types for join_pref iovar */ + enum brcmf_join_pref_types { +@@ -456,25 +461,61 @@ struct brcmf_channel_info_le { + }; + + struct brcmf_sta_info_le { +- __le16 ver; /* version of this struct */ +- __le16 len; /* length in bytes of this structure */ +- __le16 cap; /* sta's advertised capabilities */ +- __le32 flags; /* flags defined below */ +- __le32 idle; /* time since data pkt rx'd from sta */ +- u8 ea[ETH_ALEN]; /* Station address */ +- __le32 count; /* # rates in this set */ +- u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units */ ++ __le16 ver; /* version of this struct */ ++ __le16 len; /* length in bytes of this structure */ ++ __le16 cap; /* sta's advertised capabilities */ ++ __le32 flags; /* flags defined below */ ++ __le32 idle; /* time since data pkt rx'd from sta */ ++ u8 ea[ETH_ALEN]; /* Station address */ ++ __le32 count; /* # rates in this set */ ++ u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units */ + /* w/hi bit set if basic */ +- __le32 in; /* seconds elapsed since associated */ +- __le32 listen_interval_inms; /* Min Listen interval in ms for STA */ +- __le32 tx_pkts; /* # of packets transmitted */ +- __le32 tx_failures; /* # of packets failed */ +- __le32 rx_ucast_pkts; /* # of unicast packets received */ +- __le32 rx_mcast_pkts; /* # of multicast packets received */ +- __le32 tx_rate; /* Rate of last successful tx frame */ +- __le32 rx_rate; /* Rate of last successful rx frame */ +- __le32 rx_decrypt_succeeds; /* # of packet decrypted successfully */ +- __le32 rx_decrypt_failures; /* # of packet decrypted failed */ ++ __le32 in; /* seconds elapsed since associated */ ++ __le32 listen_interval_inms; /* Min Listen interval in ms for STA */ ++ __le32 tx_pkts; /* # of packets transmitted */ ++ __le32 tx_failures; /* # of packets failed */ ++ __le32 rx_ucast_pkts; /* # of unicast packets received */ ++ __le32 rx_mcast_pkts; /* # of multicast packets received */ ++ __le32 tx_rate; /* Rate of last successful tx frame */ ++ __le32 rx_rate; /* Rate of last successful rx frame */ ++ __le32 rx_decrypt_succeeds; /* # of packet decrypted successfully */ ++ __le32 rx_decrypt_failures; /* # of packet decrypted failed */ ++ __le32 tx_tot_pkts; /* # of tx pkts (ucast + mcast) */ ++ __le32 rx_tot_pkts; /* # of data packets recvd (uni + mcast) */ ++ __le32 tx_mcast_pkts; /* # of mcast pkts txed */ ++ __le64 tx_tot_bytes; /* data bytes txed (ucast + mcast) */ ++ __le64 rx_tot_bytes; /* data bytes recvd (ucast + mcast) */ ++ __le64 tx_ucast_bytes; /* data bytes txed (ucast) */ ++ __le64 tx_mcast_bytes; /* # data bytes txed (mcast) */ ++ __le64 rx_ucast_bytes; /* data bytes recvd (ucast) */ ++ __le64 rx_mcast_bytes; /* data bytes recvd (mcast) */ ++ s8 rssi[BRCMF_ANT_MAX]; /* per antenna rssi */ ++ s8 nf[BRCMF_ANT_MAX]; /* per antenna noise floor */ ++ __le16 aid; /* association ID */ ++ __le16 ht_capabilities; /* advertised ht caps */ ++ __le16 vht_flags; /* converted vht flags */ ++ __le32 tx_pkts_retry_cnt; /* # of frames where a retry was ++ * exhausted. ++ */ ++ __le32 tx_pkts_retry_exhausted; /* # of user frames where a retry ++ * was exhausted ++ */ ++ s8 rx_lastpkt_rssi[BRCMF_ANT_MAX]; /* Per antenna RSSI of last ++ * received data frame. ++ */ ++ /* TX WLAN retry/failure statistics: ++ * Separated for host requested frames and locally generated frames. ++ * Include unicast frame only where the retries/failures can be counted. ++ */ ++ __le32 tx_pkts_total; /* # user frames sent successfully */ ++ __le32 tx_pkts_retries; /* # user frames retries */ ++ __le32 tx_pkts_fw_total; /* # FW generated sent successfully */ ++ __le32 tx_pkts_fw_retries; /* # retries for FW generated frames */ ++ __le32 tx_pkts_fw_retry_exhausted; /* # FW generated where a retry ++ * was exhausted ++ */ ++ __le32 rx_pkts_retried; /* # rx with retry bit set */ ++ __le32 tx_rate_fallback; /* lowest fallback TX rate */ + }; + + struct brcmf_chanspec_list { diff --git a/package/kernel/mac80211/patches/389-0004-brcmfmac-have-sdio-return-EIO-when-device-communicat.patch b/package/kernel/mac80211/patches/389-0004-brcmfmac-have-sdio-return-EIO-when-device-communicat.patch new file mode 100644 index 0000000000..302bc3ed15 --- /dev/null +++ b/package/kernel/mac80211/patches/389-0004-brcmfmac-have-sdio-return-EIO-when-device-communicat.patch @@ -0,0 +1,56 @@ +From: Arend van Spriel +Date: Thu, 11 Jun 2015 00:12:20 +0200 +Subject: [PATCH] brcmfmac: have sdio return -EIO when device communication + is not possible + +The bus interface functions txctl and rxctl may be used while the device +can not be accessed, eg. upon driver .remove() callback. This patch will +immediately return -EIO when this is the case which speeds up the module +unload. + +Reviewed-by: Hante Meuleman +Reviewed-by: Franky (Zhenhui) Lin +Reviewed-by: Pieter-Paul Giesberts +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + +--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +@@ -988,6 +988,7 @@ static void brcmf_sdiod_freezer_detach(s + + static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev) + { ++ sdiodev->state = BRCMF_SDIOD_DOWN; + if (sdiodev->bus) { + brcmf_sdio_remove(sdiodev->bus); + sdiodev->bus = NULL; +--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c +@@ -2820,6 +2820,8 @@ static int brcmf_sdio_bus_txdata(struct + struct brcmf_sdio *bus = sdiodev->bus; + + brcmf_dbg(TRACE, "Enter: pkt: data %p len %d\n", pkt->data, pkt->len); ++ if (sdiodev->state != BRCMF_SDIOD_DATA) ++ return -EIO; + + /* Add space for the header */ + skb_push(pkt, bus->tx_hdrlen); +@@ -2948,6 +2950,8 @@ brcmf_sdio_bus_txctl(struct device *dev, + int ret; + + brcmf_dbg(TRACE, "Enter\n"); ++ if (sdiodev->state != BRCMF_SDIOD_DATA) ++ return -EIO; + + /* Send from dpc */ + bus->ctrl_frame_buf = msg; +@@ -3238,6 +3242,8 @@ brcmf_sdio_bus_rxctl(struct device *dev, + struct brcmf_sdio *bus = sdiodev->bus; + + brcmf_dbg(TRACE, "Enter\n"); ++ if (sdiodev->state != BRCMF_SDIOD_DATA) ++ return -EIO; + + /* Wait until control frame is available */ + timeleft = brcmf_sdio_dcmd_resp_wait(bus, &bus->rxlen, &pending); diff --git a/package/kernel/mac80211/patches/389-0005-ath9k-make-DMA-stop-related-messages-debug-only.patch b/package/kernel/mac80211/patches/389-0005-ath9k-make-DMA-stop-related-messages-debug-only.patch new file mode 100644 index 0000000000..34af6d2acf --- /dev/null +++ b/package/kernel/mac80211/patches/389-0005-ath9k-make-DMA-stop-related-messages-debug-only.patch @@ -0,0 +1,74 @@ +From: Felix Fietkau +Date: Thu, 2 Jul 2015 13:35:05 +0200 +Subject: [PATCH] ath9k: make DMA stop related messages debug-only + +A long time ago, ath9k had issues during reset where the DMA engine +would stay active and could potentially corrupt memory. +To debug those issues, the driver would print warnings whenever they +occur. + +Nowadays, these issues are gone and the primary cause of these messages +is if the MAC is stuck during reset or busy processing a long +transmission. This is fairly harmless, yet these messages continue to +worry users. + +To reduce the number of bogus bug reports, turn these messages into +debug messages and count their occurence in the "reset" debugfs file. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -765,6 +765,8 @@ static int read_file_reset(struct seq_fi + [RESET_TYPE_BEACON_STUCK] = "Stuck Beacon", + [RESET_TYPE_MCI] = "MCI Reset", + [RESET_TYPE_CALIBRATION] = "Calibration error", ++ [RESET_TX_DMA_ERROR] = "Tx DMA stop error", ++ [RESET_RX_DMA_ERROR] = "Rx DMA stop error", + }; + int i; + +--- a/drivers/net/wireless/ath/ath9k/debug.h ++++ b/drivers/net/wireless/ath/ath9k/debug.h +@@ -50,6 +50,8 @@ enum ath_reset_type { + RESET_TYPE_BEACON_STUCK, + RESET_TYPE_MCI, + RESET_TYPE_CALIBRATION, ++ RESET_TX_DMA_ERROR, ++ RESET_RX_DMA_ERROR, + __RESET_TYPE_MAX + }; + +--- a/drivers/net/wireless/ath/ath9k/recv.c ++++ b/drivers/net/wireless/ath/ath9k/recv.c +@@ -496,10 +496,9 @@ bool ath_stoprecv(struct ath_softc *sc) + + if (!(ah->ah_flags & AH_UNPLUGGED) && + unlikely(!stopped)) { +- ath_err(ath9k_hw_common(sc->sc_ah), +- "Could not stop RX, we could be " +- "confusing the DMA engine when we start RX up\n"); +- ATH_DBG_WARN_ON_ONCE(!stopped); ++ ath_dbg(ath9k_hw_common(sc->sc_ah), RESET, ++ "Failed to stop Rx DMA\n"); ++ RESET_STAT_INC(sc, RESET_RX_DMA_ERROR); + } + return stopped && !reset; + } +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -1896,8 +1896,11 @@ bool ath_drain_all_txq(struct ath_softc + npend |= BIT(i); + } + +- if (npend) +- ath_err(common, "Failed to stop TX DMA, queues=0x%03x!\n", npend); ++ if (npend) { ++ RESET_STAT_INC(sc, RESET_TX_DMA_ERROR); ++ ath_dbg(common, RESET, ++ "Failed to stop TX DMA, queues=0x%03x!\n", npend); ++ } + + for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { + if (!ATH_TXQ_SETUP(sc, i)) diff --git a/package/kernel/mac80211/patches/389-brcmfmac-Check-if-firmware-supports-p2p.patch b/package/kernel/mac80211/patches/389-brcmfmac-Check-if-firmware-supports-p2p.patch deleted file mode 100644 index ff24a4a06f..0000000000 --- a/package/kernel/mac80211/patches/389-brcmfmac-Check-if-firmware-supports-p2p.patch +++ /dev/null @@ -1,42 +0,0 @@ -From: Pontus Fuchs -Date: Thu, 11 Jun 2015 00:12:17 +0200 -Subject: [PATCH] brcmfmac: Check if firmware supports p2p - -Add a feature flag to reflect the firmware's p2p capability. - -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Hante Meuleman -Reviewed-by: Arend Van Spriel -Signed-off-by: Pontus Fuchs -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/feature.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c -@@ -129,6 +129,7 @@ void brcmf_feat_attach(struct brcmf_pub - brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl"); - if (drvr->bus_if->chip != BRCM_CC_43362_CHIP_ID) - brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0); -+ brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_P2P, "p2p"); - - /* set chip related quirks */ - switch (drvr->bus_if->chip) { ---- a/drivers/net/wireless/brcm80211/brcmfmac/feature.h -+++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.h -@@ -23,12 +23,14 @@ - * MCHAN: multi-channel for concurrent P2P. - * PNO: preferred network offload. - * WOWL: Wake-On-WLAN. -+ * P2P: peer-to-peer - */ - #define BRCMF_FEAT_LIST \ - BRCMF_FEAT_DEF(MBSS) \ - BRCMF_FEAT_DEF(MCHAN) \ - BRCMF_FEAT_DEF(PNO) \ -- BRCMF_FEAT_DEF(WOWL) -+ BRCMF_FEAT_DEF(WOWL) \ -+ BRCMF_FEAT_DEF(P2P) - /* - * Quirks: - * diff --git a/package/kernel/mac80211/patches/390-brcmfmac-Build-wiphy-mode-and-interface-combinations.patch b/package/kernel/mac80211/patches/390-brcmfmac-Build-wiphy-mode-and-interface-combinations.patch deleted file mode 100644 index 3876ba01da..0000000000 --- a/package/kernel/mac80211/patches/390-brcmfmac-Build-wiphy-mode-and-interface-combinations.patch +++ /dev/null @@ -1,198 +0,0 @@ -From: Pontus Fuchs -Date: Thu, 11 Jun 2015 00:12:18 +0200 -Subject: [PATCH] brcmfmac: Build wiphy mode and interface combinations - dynamically - -Switch from using semi hard coded interface combinations. This makes -it easier to announce what the firmware actually supports. This fixes -the case where brcmfmac announces p2p but the firmware doesn't -support it. - -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Hante Meuleman -Reviewed-by: Arend Van Spriel -Signed-off-by: Pontus Fuchs -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -@@ -52,8 +52,6 @@ - #define BRCMF_PNO_SCAN_COMPLETE 1 - #define BRCMF_PNO_SCAN_INCOMPLETE 0 - --#define BRCMF_IFACE_MAX_CNT 3 -- - #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */ - #define WPA_OUI_TYPE 1 - #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */ -@@ -5639,53 +5637,6 @@ static int brcmf_setup_wiphybands(struct - return 0; - } - --static const struct ieee80211_iface_limit brcmf_iface_limits_mbss[] = { -- { -- .max = 1, -- .types = BIT(NL80211_IFTYPE_STATION) | -- BIT(NL80211_IFTYPE_ADHOC) -- }, -- { -- .max = 4, -- .types = BIT(NL80211_IFTYPE_AP) -- }, -- { -- .max = 1, -- .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | -- BIT(NL80211_IFTYPE_P2P_GO) -- }, -- { -- .max = 1, -- .types = BIT(NL80211_IFTYPE_P2P_DEVICE) -- } --}; -- --static const struct ieee80211_iface_limit brcmf_iface_limits_sbss[] = { -- { -- .max = 2, -- .types = BIT(NL80211_IFTYPE_STATION) | -- BIT(NL80211_IFTYPE_ADHOC) | -- BIT(NL80211_IFTYPE_AP) -- }, -- { -- .max = 1, -- .types = BIT(NL80211_IFTYPE_P2P_CLIENT) | -- BIT(NL80211_IFTYPE_P2P_GO) -- }, -- { -- .max = 1, -- .types = BIT(NL80211_IFTYPE_P2P_DEVICE) -- } --}; --static struct ieee80211_iface_combination brcmf_iface_combos[] = { -- { -- .max_interfaces = BRCMF_IFACE_MAX_CNT, -- .num_different_channels = 1, -- .n_limits = ARRAY_SIZE(brcmf_iface_limits_sbss), -- .limits = brcmf_iface_limits_sbss, -- } --}; -- - static const struct ieee80211_txrx_stypes - brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = { - [NL80211_IFTYPE_STATION] = { -@@ -5715,6 +5666,67 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = - } - }; - -+static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp) -+{ -+ struct ieee80211_iface_combination *combo = NULL; -+ struct ieee80211_iface_limit *limits = NULL; -+ int i = 0, max_iface_cnt; -+ -+ combo = kzalloc(sizeof(*combo), GFP_KERNEL); -+ if (!combo) -+ goto err; -+ -+ limits = kzalloc(sizeof(*limits) * 4, GFP_KERNEL); -+ if (!limits) -+ goto err; -+ -+ wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | -+ BIT(NL80211_IFTYPE_ADHOC) | -+ BIT(NL80211_IFTYPE_AP); -+ -+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN)) -+ combo->num_different_channels = 2; -+ else -+ combo->num_different_channels = 1; -+ -+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) { -+ limits[i].max = 1; -+ limits[i++].types = BIT(NL80211_IFTYPE_STATION); -+ limits[i].max = 4; -+ limits[i++].types = BIT(NL80211_IFTYPE_AP); -+ max_iface_cnt = 5; -+ } else { -+ limits[i].max = 2; -+ limits[i++].types = BIT(NL80211_IFTYPE_STATION) | -+ BIT(NL80211_IFTYPE_AP); -+ max_iface_cnt = 2; -+ } -+ -+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P)) { -+ wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) | -+ BIT(NL80211_IFTYPE_P2P_GO) | -+ BIT(NL80211_IFTYPE_P2P_DEVICE); -+ limits[i].max = 1; -+ limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) | -+ BIT(NL80211_IFTYPE_P2P_GO); -+ limits[i].max = 1; -+ limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE); -+ max_iface_cnt += 2; -+ } -+ combo->max_interfaces = max_iface_cnt; -+ combo->limits = limits; -+ combo->n_limits = i; -+ -+ wiphy->iface_combinations = combo; -+ wiphy->n_iface_combinations = 1; -+ return 0; -+ -+err: -+ kfree(limits); -+ kfree(combo); -+ return -ENOMEM; -+} -+ - static void brcmf_wiphy_pno_params(struct wiphy *wiphy) - { - /* scheduled scan settings */ -@@ -5745,7 +5757,6 @@ static void brcmf_wiphy_wowl_params(stru - static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp) - { - struct ieee80211_supported_band *band; -- struct ieee80211_iface_combination ifc_combo; - __le32 bandlist[3]; - u32 n_bands; - int err, i; -@@ -5753,24 +5764,11 @@ static int brcmf_setup_wiphy(struct wiph - wiphy->max_scan_ssids = WL_NUM_SCAN_MAX; - wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX; - wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX; -- wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | -- BIT(NL80211_IFTYPE_ADHOC) | -- BIT(NL80211_IFTYPE_AP) | -- BIT(NL80211_IFTYPE_P2P_CLIENT) | -- BIT(NL80211_IFTYPE_P2P_GO) | -- BIT(NL80211_IFTYPE_P2P_DEVICE); -- /* need VSDB firmware feature for concurrent channels */ -- ifc_combo = brcmf_iface_combos[0]; -- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN)) -- ifc_combo.num_different_channels = 2; -- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) { -- ifc_combo.n_limits = ARRAY_SIZE(brcmf_iface_limits_mbss), -- ifc_combo.limits = brcmf_iface_limits_mbss; -- } -- wiphy->iface_combinations = kmemdup(&ifc_combo, -- sizeof(ifc_combo), -- GFP_KERNEL); -- wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos); -+ -+ err = brcmf_setup_ifmodes(wiphy, ifp); -+ if (err) -+ return err; -+ - wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; - wiphy->cipher_suites = __wl_cipher_suites; - wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); -@@ -6035,6 +6033,8 @@ static void brcmf_free_wiphy(struct wiph - if (!wiphy) - return; - -+ if (wiphy->iface_combinations) -+ kfree(wiphy->iface_combinations->limits); - kfree(wiphy->iface_combinations); - if (wiphy->bands[IEEE80211_BAND_2GHZ]) { - kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels); diff --git a/package/kernel/mac80211/patches/391-brcmfmac-rework-.get_station-callback.patch b/package/kernel/mac80211/patches/391-brcmfmac-rework-.get_station-callback.patch deleted file mode 100644 index 7bd06869da..0000000000 --- a/package/kernel/mac80211/patches/391-brcmfmac-rework-.get_station-callback.patch +++ /dev/null @@ -1,326 +0,0 @@ -From: Arend van Spriel -Date: Thu, 11 Jun 2015 00:12:19 +0200 -Subject: [PATCH] brcmfmac: rework .get_station() callback - -The .get_station() cfg80211 callback is used in several scenarios. In -managed mode it can obtain information about the access-point and its -BSS parameters. In managed mode it can also obtain information about -TDLS peers. In AP mode it can obtain information about connected -clients. - -Reviewed-by: Hante Meuleman -Reviewed-by: Daniel (Deognyoun) Kim -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c -@@ -2395,27 +2395,80 @@ brcmf_cfg80211_reconfigure_wep(struct br - brcmf_err("set wsec error (%d)\n", err); - } - -+static void brcmf_convert_sta_flags(u32 fw_sta_flags, struct station_info *si) -+{ -+ struct nl80211_sta_flag_update *sfu; -+ -+ brcmf_dbg(TRACE, "flags %08x\n", fw_sta_flags); -+ si->filled |= BIT(NL80211_STA_INFO_STA_FLAGS); -+ sfu = &si->sta_flags; -+ sfu->mask = BIT(NL80211_STA_FLAG_WME) | -+ BIT(NL80211_STA_FLAG_AUTHENTICATED) | -+ BIT(NL80211_STA_FLAG_ASSOCIATED) | -+ BIT(NL80211_STA_FLAG_AUTHORIZED); -+ if (fw_sta_flags & BRCMF_STA_WME) -+ sfu->set |= BIT(NL80211_STA_FLAG_WME); -+ if (fw_sta_flags & BRCMF_STA_AUTHE) -+ sfu->set |= BIT(NL80211_STA_FLAG_AUTHENTICATED); -+ if (fw_sta_flags & BRCMF_STA_ASSOC) -+ sfu->set |= BIT(NL80211_STA_FLAG_ASSOCIATED); -+ if (fw_sta_flags & BRCMF_STA_AUTHO) -+ sfu->set |= BIT(NL80211_STA_FLAG_AUTHORIZED); -+} -+ -+static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si) -+{ -+ struct { -+ __le32 len; -+ struct brcmf_bss_info_le bss_le; -+ } *buf; -+ u16 capability; -+ int err; -+ -+ buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); -+ if (!buf) -+ return; -+ -+ buf->len = cpu_to_le32(WL_BSS_INFO_MAX); -+ err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, buf, -+ WL_BSS_INFO_MAX); -+ if (err) { -+ brcmf_err("Failed to get bss info (%d)\n", err); -+ return; -+ } -+ si->filled |= BIT(NL80211_STA_INFO_BSS_PARAM); -+ si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period); -+ si->bss_param.dtim_period = buf->bss_le.dtim_period; -+ capability = le16_to_cpu(buf->bss_le.capability); -+ if (capability & IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT) -+ si->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT; -+ if (capability & WLAN_CAPABILITY_SHORT_PREAMBLE) -+ si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE; -+ if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) -+ si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; -+} -+ - static s32 - brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, - const u8 *mac, struct station_info *sinfo) - { - struct brcmf_if *ifp = netdev_priv(ndev); -- struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; -- struct brcmf_scb_val_le scb_val; -- int rssi; -- s32 rate; - s32 err = 0; -- u8 *bssid = profile->bssid; - struct brcmf_sta_info_le sta_info_le; -- u32 beacon_period; -- u32 dtim_period; -+ u32 sta_flags; -+ u32 is_tdls_peer; - - brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac); - if (!check_vif_up(ifp->vif)) - return -EIO; - -- if (brcmf_is_apmode(ifp->vif)) { -- memcpy(&sta_info_le, mac, ETH_ALEN); -+ memset(&sta_info_le, 0, sizeof(sta_info_le)); -+ memcpy(&sta_info_le, mac, ETH_ALEN); -+ err = brcmf_fil_iovar_data_get(ifp, "tdls_sta_info", -+ &sta_info_le, -+ sizeof(sta_info_le)); -+ is_tdls_peer = !err; -+ if (err) { - err = brcmf_fil_iovar_data_get(ifp, "sta_info", - &sta_info_le, - sizeof(sta_info_le)); -@@ -2423,73 +2476,48 @@ brcmf_cfg80211_get_station(struct wiphy - brcmf_err("GET STA INFO failed, %d\n", err); - goto done; - } -- sinfo->filled = BIT(NL80211_STA_INFO_INACTIVE_TIME); -- sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000; -- if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) { -- sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME); -- sinfo->connected_time = le32_to_cpu(sta_info_le.in); -- } -- brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n", -- sinfo->inactive_time, sinfo->connected_time); -- } else if (ifp->vif->wdev.iftype == NL80211_IFTYPE_STATION) { -- if (memcmp(mac, bssid, ETH_ALEN)) { -- brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n", -- mac, bssid); -- err = -ENOENT; -- goto done; -- } -- /* Report the current tx rate */ -- err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate); -- if (err) { -- brcmf_err("Could not get rate (%d)\n", err); -- goto done; -- } else { -+ } -+ brcmf_dbg(TRACE, "version %d\n", le16_to_cpu(sta_info_le.ver)); -+ sinfo->filled = BIT(NL80211_STA_INFO_INACTIVE_TIME); -+ sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000; -+ sta_flags = le32_to_cpu(sta_info_le.flags); -+ brcmf_convert_sta_flags(sta_flags, sinfo); -+ sinfo->sta_flags.mask |= BIT(NL80211_STA_FLAG_TDLS_PEER); -+ if (is_tdls_peer) -+ sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER); -+ else -+ sinfo->sta_flags.set &= ~BIT(NL80211_STA_FLAG_TDLS_PEER); -+ if (sta_flags & BRCMF_STA_ASSOC) { -+ sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME); -+ sinfo->connected_time = le32_to_cpu(sta_info_le.in); -+ brcmf_fill_bss_param(ifp, sinfo); -+ } -+ if (sta_flags & BRCMF_STA_SCBSTATS) { -+ sinfo->filled |= BIT(NL80211_STA_INFO_TX_FAILED); -+ sinfo->tx_failed = le32_to_cpu(sta_info_le.tx_failures); -+ sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS); -+ sinfo->tx_packets = le32_to_cpu(sta_info_le.tx_pkts); -+ sinfo->tx_packets += le32_to_cpu(sta_info_le.tx_mcast_pkts); -+ sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS); -+ sinfo->rx_packets = le32_to_cpu(sta_info_le.rx_ucast_pkts); -+ sinfo->rx_packets += le32_to_cpu(sta_info_le.rx_mcast_pkts); -+ if (sinfo->tx_packets) { - sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE); -- sinfo->txrate.legacy = rate * 5; -- brcmf_dbg(CONN, "Rate %d Mbps\n", rate / 2); -+ sinfo->txrate.legacy = le32_to_cpu(sta_info_le.tx_rate); -+ sinfo->txrate.legacy /= 100; - } -- -- if (test_bit(BRCMF_VIF_STATUS_CONNECTED, -- &ifp->vif->sme_state)) { -- memset(&scb_val, 0, sizeof(scb_val)); -- err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI, -- &scb_val, sizeof(scb_val)); -- if (err) { -- brcmf_err("Could not get rssi (%d)\n", err); -- goto done; -- } else { -- rssi = le32_to_cpu(scb_val.val); -- sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL); -- sinfo->signal = rssi; -- brcmf_dbg(CONN, "RSSI %d dBm\n", rssi); -- } -- err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_BCNPRD, -- &beacon_period); -- if (err) { -- brcmf_err("Could not get beacon period (%d)\n", -- err); -- goto done; -- } else { -- sinfo->bss_param.beacon_interval = -- beacon_period; -- brcmf_dbg(CONN, "Beacon peroid %d\n", -- beacon_period); -- } -- err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_DTIMPRD, -- &dtim_period); -- if (err) { -- brcmf_err("Could not get DTIM period (%d)\n", -- err); -- goto done; -- } else { -- sinfo->bss_param.dtim_period = dtim_period; -- brcmf_dbg(CONN, "DTIM peroid %d\n", -- dtim_period); -- } -- sinfo->filled |= BIT(NL80211_STA_INFO_BSS_PARAM); -+ if (sinfo->rx_packets) { -+ sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE); -+ sinfo->rxrate.legacy = le32_to_cpu(sta_info_le.rx_rate); -+ sinfo->rxrate.legacy /= 100; -+ } -+ if (le16_to_cpu(sta_info_le.ver) >= 4) { -+ sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES); -+ sinfo->tx_bytes = le64_to_cpu(sta_info_le.tx_tot_bytes); -+ sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES); -+ sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes); - } -- } else -- err = -EPERM; -+ } - done: - brcmf_dbg(TRACE, "Exit\n"); - return err; ---- a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h -+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h -@@ -32,7 +32,11 @@ - #define BRCMF_BSS_INFO_VERSION 109 /* curr ver of brcmf_bss_info_le struct */ - #define BRCMF_BSS_RSSI_ON_CHANNEL 0x0002 - --#define BRCMF_STA_ASSOC 0x10 /* Associated */ -+#define BRCMF_STA_WME 0x00000002 /* WMM association */ -+#define BRCMF_STA_AUTHE 0x00000008 /* Authenticated */ -+#define BRCMF_STA_ASSOC 0x00000010 /* Associated */ -+#define BRCMF_STA_AUTHO 0x00000020 /* Authorized */ -+#define BRCMF_STA_SCBSTATS 0x00004000 /* Per STA debug stats */ - - /* size of brcmf_scan_params not including variable length array */ - #define BRCMF_SCAN_PARAMS_FIXED_SIZE 64 -@@ -113,6 +117,7 @@ - #define BRCMF_WOWL_MAXPATTERNSIZE 128 - - #define BRCMF_COUNTRY_BUF_SZ 4 -+#define BRCMF_ANT_MAX 4 - - /* join preference types for join_pref iovar */ - enum brcmf_join_pref_types { -@@ -456,25 +461,61 @@ struct brcmf_channel_info_le { - }; - - struct brcmf_sta_info_le { -- __le16 ver; /* version of this struct */ -- __le16 len; /* length in bytes of this structure */ -- __le16 cap; /* sta's advertised capabilities */ -- __le32 flags; /* flags defined below */ -- __le32 idle; /* time since data pkt rx'd from sta */ -- u8 ea[ETH_ALEN]; /* Station address */ -- __le32 count; /* # rates in this set */ -- u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units */ -+ __le16 ver; /* version of this struct */ -+ __le16 len; /* length in bytes of this structure */ -+ __le16 cap; /* sta's advertised capabilities */ -+ __le32 flags; /* flags defined below */ -+ __le32 idle; /* time since data pkt rx'd from sta */ -+ u8 ea[ETH_ALEN]; /* Station address */ -+ __le32 count; /* # rates in this set */ -+ u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units */ - /* w/hi bit set if basic */ -- __le32 in; /* seconds elapsed since associated */ -- __le32 listen_interval_inms; /* Min Listen interval in ms for STA */ -- __le32 tx_pkts; /* # of packets transmitted */ -- __le32 tx_failures; /* # of packets failed */ -- __le32 rx_ucast_pkts; /* # of unicast packets received */ -- __le32 rx_mcast_pkts; /* # of multicast packets received */ -- __le32 tx_rate; /* Rate of last successful tx frame */ -- __le32 rx_rate; /* Rate of last successful rx frame */ -- __le32 rx_decrypt_succeeds; /* # of packet decrypted successfully */ -- __le32 rx_decrypt_failures; /* # of packet decrypted failed */ -+ __le32 in; /* seconds elapsed since associated */ -+ __le32 listen_interval_inms; /* Min Listen interval in ms for STA */ -+ __le32 tx_pkts; /* # of packets transmitted */ -+ __le32 tx_failures; /* # of packets failed */ -+ __le32 rx_ucast_pkts; /* # of unicast packets received */ -+ __le32 rx_mcast_pkts; /* # of multicast packets received */ -+ __le32 tx_rate; /* Rate of last successful tx frame */ -+ __le32 rx_rate; /* Rate of last successful rx frame */ -+ __le32 rx_decrypt_succeeds; /* # of packet decrypted successfully */ -+ __le32 rx_decrypt_failures; /* # of packet decrypted failed */ -+ __le32 tx_tot_pkts; /* # of tx pkts (ucast + mcast) */ -+ __le32 rx_tot_pkts; /* # of data packets recvd (uni + mcast) */ -+ __le32 tx_mcast_pkts; /* # of mcast pkts txed */ -+ __le64 tx_tot_bytes; /* data bytes txed (ucast + mcast) */ -+ __le64 rx_tot_bytes; /* data bytes recvd (ucast + mcast) */ -+ __le64 tx_ucast_bytes; /* data bytes txed (ucast) */ -+ __le64 tx_mcast_bytes; /* # data bytes txed (mcast) */ -+ __le64 rx_ucast_bytes; /* data bytes recvd (ucast) */ -+ __le64 rx_mcast_bytes; /* data bytes recvd (mcast) */ -+ s8 rssi[BRCMF_ANT_MAX]; /* per antenna rssi */ -+ s8 nf[BRCMF_ANT_MAX]; /* per antenna noise floor */ -+ __le16 aid; /* association ID */ -+ __le16 ht_capabilities; /* advertised ht caps */ -+ __le16 vht_flags; /* converted vht flags */ -+ __le32 tx_pkts_retry_cnt; /* # of frames where a retry was -+ * exhausted. -+ */ -+ __le32 tx_pkts_retry_exhausted; /* # of user frames where a retry -+ * was exhausted -+ */ -+ s8 rx_lastpkt_rssi[BRCMF_ANT_MAX]; /* Per antenna RSSI of last -+ * received data frame. -+ */ -+ /* TX WLAN retry/failure statistics: -+ * Separated for host requested frames and locally generated frames. -+ * Include unicast frame only where the retries/failures can be counted. -+ */ -+ __le32 tx_pkts_total; /* # user frames sent successfully */ -+ __le32 tx_pkts_retries; /* # user frames retries */ -+ __le32 tx_pkts_fw_total; /* # FW generated sent successfully */ -+ __le32 tx_pkts_fw_retries; /* # retries for FW generated frames */ -+ __le32 tx_pkts_fw_retry_exhausted; /* # FW generated where a retry -+ * was exhausted -+ */ -+ __le32 rx_pkts_retried; /* # rx with retry bit set */ -+ __le32 tx_rate_fallback; /* lowest fallback TX rate */ - }; - - struct brcmf_chanspec_list { diff --git a/package/kernel/mac80211/patches/392-brcmfmac-have-sdio-return-EIO-when-device-communicat.patch b/package/kernel/mac80211/patches/392-brcmfmac-have-sdio-return-EIO-when-device-communicat.patch deleted file mode 100644 index 302bc3ed15..0000000000 --- a/package/kernel/mac80211/patches/392-brcmfmac-have-sdio-return-EIO-when-device-communicat.patch +++ /dev/null @@ -1,56 +0,0 @@ -From: Arend van Spriel -Date: Thu, 11 Jun 2015 00:12:20 +0200 -Subject: [PATCH] brcmfmac: have sdio return -EIO when device communication - is not possible - -The bus interface functions txctl and rxctl may be used while the device -can not be accessed, eg. upon driver .remove() callback. This patch will -immediately return -EIO when this is the case which speeds up the module -unload. - -Reviewed-by: Hante Meuleman -Reviewed-by: Franky (Zhenhui) Lin -Reviewed-by: Pieter-Paul Giesberts -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - ---- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c -@@ -988,6 +988,7 @@ static void brcmf_sdiod_freezer_detach(s - - static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev) - { -+ sdiodev->state = BRCMF_SDIOD_DOWN; - if (sdiodev->bus) { - brcmf_sdio_remove(sdiodev->bus); - sdiodev->bus = NULL; ---- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c -@@ -2820,6 +2820,8 @@ static int brcmf_sdio_bus_txdata(struct - struct brcmf_sdio *bus = sdiodev->bus; - - brcmf_dbg(TRACE, "Enter: pkt: data %p len %d\n", pkt->data, pkt->len); -+ if (sdiodev->state != BRCMF_SDIOD_DATA) -+ return -EIO; - - /* Add space for the header */ - skb_push(pkt, bus->tx_hdrlen); -@@ -2948,6 +2950,8 @@ brcmf_sdio_bus_txctl(struct device *dev, - int ret; - - brcmf_dbg(TRACE, "Enter\n"); -+ if (sdiodev->state != BRCMF_SDIOD_DATA) -+ return -EIO; - - /* Send from dpc */ - bus->ctrl_frame_buf = msg; -@@ -3238,6 +3242,8 @@ brcmf_sdio_bus_rxctl(struct device *dev, - struct brcmf_sdio *bus = sdiodev->bus; - - brcmf_dbg(TRACE, "Enter\n"); -+ if (sdiodev->state != BRCMF_SDIOD_DATA) -+ return -EIO; - - /* Wait until control frame is available */ - timeleft = brcmf_sdio_dcmd_resp_wait(bus, &bus->rxlen, &pending); diff --git a/package/kernel/mac80211/patches/393-ath9k-make-DMA-stop-related-messages-debug-only.patch b/package/kernel/mac80211/patches/393-ath9k-make-DMA-stop-related-messages-debug-only.patch deleted file mode 100644 index 34af6d2acf..0000000000 --- a/package/kernel/mac80211/patches/393-ath9k-make-DMA-stop-related-messages-debug-only.patch +++ /dev/null @@ -1,74 +0,0 @@ -From: Felix Fietkau -Date: Thu, 2 Jul 2015 13:35:05 +0200 -Subject: [PATCH] ath9k: make DMA stop related messages debug-only - -A long time ago, ath9k had issues during reset where the DMA engine -would stay active and could potentially corrupt memory. -To debug those issues, the driver would print warnings whenever they -occur. - -Nowadays, these issues are gone and the primary cause of these messages -is if the MAC is stuck during reset or busy processing a long -transmission. This is fairly harmless, yet these messages continue to -worry users. - -To reduce the number of bogus bug reports, turn these messages into -debug messages and count their occurence in the "reset" debugfs file. - -Signed-off-by: Felix Fietkau ---- - ---- a/drivers/net/wireless/ath/ath9k/debug.c -+++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -765,6 +765,8 @@ static int read_file_reset(struct seq_fi - [RESET_TYPE_BEACON_STUCK] = "Stuck Beacon", - [RESET_TYPE_MCI] = "MCI Reset", - [RESET_TYPE_CALIBRATION] = "Calibration error", -+ [RESET_TX_DMA_ERROR] = "Tx DMA stop error", -+ [RESET_RX_DMA_ERROR] = "Rx DMA stop error", - }; - int i; - ---- a/drivers/net/wireless/ath/ath9k/debug.h -+++ b/drivers/net/wireless/ath/ath9k/debug.h -@@ -50,6 +50,8 @@ enum ath_reset_type { - RESET_TYPE_BEACON_STUCK, - RESET_TYPE_MCI, - RESET_TYPE_CALIBRATION, -+ RESET_TX_DMA_ERROR, -+ RESET_RX_DMA_ERROR, - __RESET_TYPE_MAX - }; - ---- a/drivers/net/wireless/ath/ath9k/recv.c -+++ b/drivers/net/wireless/ath/ath9k/recv.c -@@ -496,10 +496,9 @@ bool ath_stoprecv(struct ath_softc *sc) - - if (!(ah->ah_flags & AH_UNPLUGGED) && - unlikely(!stopped)) { -- ath_err(ath9k_hw_common(sc->sc_ah), -- "Could not stop RX, we could be " -- "confusing the DMA engine when we start RX up\n"); -- ATH_DBG_WARN_ON_ONCE(!stopped); -+ ath_dbg(ath9k_hw_common(sc->sc_ah), RESET, -+ "Failed to stop Rx DMA\n"); -+ RESET_STAT_INC(sc, RESET_RX_DMA_ERROR); - } - return stopped && !reset; - } ---- a/drivers/net/wireless/ath/ath9k/xmit.c -+++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -1896,8 +1896,11 @@ bool ath_drain_all_txq(struct ath_softc - npend |= BIT(i); - } - -- if (npend) -- ath_err(common, "Failed to stop TX DMA, queues=0x%03x!\n", npend); -+ if (npend) { -+ RESET_STAT_INC(sc, RESET_TX_DMA_ERROR); -+ ath_dbg(common, RESET, -+ "Failed to stop TX DMA, queues=0x%03x!\n", npend); -+ } - - for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { - if (!ATH_TXQ_SETUP(sc, i)) -- cgit v1.2.3