You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'wireless-drivers-next-for-davem-2015-06-18' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next
Kalle Valo says: ==================== Major changes: mwifiex: * enhancements for AP mode: support verbose information in station dump command and also information about AP link. * enable power save by default brcmfmac: * fix module reload issue for PCIe * improving msgbuf protocol for PCIe devices * rework .get_station() cfg80211 callback operation * determine interface combinations upon device feature support ath9k: * ath9k_htc: add support of channel switch wil6210: * add modparam for bcast ring size * support hidden SSID * add per-MCS Rx stats ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
@@ -8169,8 +8169,6 @@ P: rt2x00 project
|
||||
M: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
M: Helmut Schaa <helmut.schaa@googlemail.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
L: users@rt2x00.serialmonkey.com (moderated for non-subscribers)
|
||||
W: http://rt2x00.serialmonkey.com/
|
||||
S: Maintained
|
||||
F: drivers/net/wireless/rt2x00/
|
||||
|
||||
|
||||
@@ -29,12 +29,6 @@ config BCMA_HOST_PCI
|
||||
select BCMA_DRIVER_PCI
|
||||
default y
|
||||
|
||||
config BCMA_DRIVER_PCI_HOSTMODE
|
||||
bool "Driver for PCI core working in hostmode"
|
||||
depends on BCMA && MIPS && BCMA_HOST_PCI
|
||||
help
|
||||
PCI core hostmode operation (external PCI bus).
|
||||
|
||||
config BCMA_HOST_SOC
|
||||
bool "Support for BCMA in a SoC"
|
||||
depends on BCMA
|
||||
@@ -61,6 +55,12 @@ config BCMA_DRIVER_PCI
|
||||
This driver is also prerequisite for a hostmode PCIe core
|
||||
support.
|
||||
|
||||
config BCMA_DRIVER_PCI_HOSTMODE
|
||||
bool "Driver for PCI core working in hostmode"
|
||||
depends on BCMA && MIPS && BCMA_DRIVER_PCI
|
||||
help
|
||||
PCI core hostmode operation (external PCI bus).
|
||||
|
||||
config BCMA_DRIVER_MIPS
|
||||
bool "BCMA Broadcom MIPS core driver"
|
||||
depends on BCMA && MIPS
|
||||
|
||||
@@ -48,6 +48,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
.name = "qca988x hw2.0",
|
||||
.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.has_shifted_cc_wraparound = true,
|
||||
.fw = {
|
||||
.dir = QCA988X_HW_2_0_FW_DIR,
|
||||
.fw = QCA988X_HW_2_0_FW_FILE,
|
||||
@@ -1084,6 +1085,22 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
|
||||
if (status)
|
||||
goto err;
|
||||
|
||||
/* Some of of qca988x solutions are having global reset issue
|
||||
* during target initialization. Bypassing PLL setting before
|
||||
* downloading firmware and letting the SoC run on REF_CLK is
|
||||
* fixing the problem. Corresponding firmware change is also needed
|
||||
* to set the clock source once the target is initialized.
|
||||
*/
|
||||
if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT,
|
||||
ar->fw_features)) {
|
||||
status = ath10k_bmi_write32(ar, hi_skip_clock_init, 1);
|
||||
if (status) {
|
||||
ath10k_err(ar, "could not write to skip_clock_init: %d\n",
|
||||
status);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
status = ath10k_download_fw(ar, mode);
|
||||
if (status)
|
||||
goto err;
|
||||
|
||||
@@ -284,15 +284,6 @@ struct ath10k_sta {
|
||||
#endif
|
||||
};
|
||||
|
||||
struct ath10k_chanctx {
|
||||
/* Used to story copy of chanctx_conf to avoid inconsistencies. Ideally
|
||||
* mac80211 should allow some sort of explicit locking to guarantee
|
||||
* that the publicly available chanctx_conf can be accessed safely at
|
||||
* all times.
|
||||
*/
|
||||
struct ieee80211_chanctx_conf conf;
|
||||
};
|
||||
|
||||
#define ATH10K_VDEV_SETUP_TIMEOUT_HZ (5*HZ)
|
||||
|
||||
enum ath10k_beacon_state {
|
||||
@@ -468,6 +459,9 @@ enum ath10k_fw_features {
|
||||
*/
|
||||
ATH10K_FW_FEATURE_NO_NWIFI_DECAP_4ADDR_PADDING,
|
||||
|
||||
/* Firmware supports bypassing PLL setting on init. */
|
||||
ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT = 9,
|
||||
|
||||
/* keep last */
|
||||
ATH10K_FW_FEATURE_COUNT,
|
||||
};
|
||||
@@ -577,6 +571,13 @@ struct ath10k {
|
||||
u32 patch_load_addr;
|
||||
int uart_pin;
|
||||
|
||||
/* This is true if given HW chip has a quirky Cycle Counter
|
||||
* wraparound which resets to 0x7fffffff instead of 0. All
|
||||
* other CC related counters (e.g. Rx Clear Count) are divided
|
||||
* by 2 so they never wraparound themselves.
|
||||
*/
|
||||
bool has_shifted_cc_wraparound;
|
||||
|
||||
struct ath10k_hw_params_fw {
|
||||
const char *dir;
|
||||
const char *fw;
|
||||
@@ -694,6 +695,14 @@ struct ath10k {
|
||||
u32 survey_last_cycle_count;
|
||||
struct survey_info survey[ATH10K_NUM_CHANS];
|
||||
|
||||
/* Channel info events are expected to come in pairs without and with
|
||||
* COMPLETE flag set respectively for each channel visit during scan.
|
||||
*
|
||||
* However there are deviations from this rule. This flag is used to
|
||||
* avoid reporting garbage data.
|
||||
*/
|
||||
bool ch_info_can_report_survey;
|
||||
|
||||
struct dfs_pattern_detector *dfs_detector;
|
||||
|
||||
unsigned long tx_paused; /* see ATH10K_TX_PAUSE_ */
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include "core.h"
|
||||
#include "hw.h"
|
||||
|
||||
const struct ath10k_hw_regs qca988x_regs = {
|
||||
@@ -56,3 +57,23 @@ const struct ath10k_hw_regs qca6174_regs = {
|
||||
.soc_chip_id_address = 0x000f0,
|
||||
.scratch_3_address = 0x0028,
|
||||
};
|
||||
|
||||
void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
|
||||
u32 cc, u32 rcc, u32 cc_prev, u32 rcc_prev)
|
||||
{
|
||||
u32 cc_fix = 0;
|
||||
|
||||
survey->filled |= SURVEY_INFO_TIME |
|
||||
SURVEY_INFO_TIME_BUSY;
|
||||
|
||||
if (ar->hw_params.has_shifted_cc_wraparound && cc < cc_prev) {
|
||||
cc_fix = 0x7fffffff;
|
||||
survey->filled &= ~SURVEY_INFO_TIME_BUSY;
|
||||
}
|
||||
|
||||
cc -= cc_prev - cc_fix;
|
||||
rcc -= rcc_prev;
|
||||
|
||||
survey->time = CCNT_TO_MSEC(cc);
|
||||
survey->time_busy = CCNT_TO_MSEC(rcc);
|
||||
}
|
||||
|
||||
@@ -169,6 +169,9 @@ struct ath10k_hw_regs {
|
||||
extern const struct ath10k_hw_regs qca988x_regs;
|
||||
extern const struct ath10k_hw_regs qca6174_regs;
|
||||
|
||||
void ath10k_hw_fill_survey_time(struct ath10k *ar, struct survey_info *survey,
|
||||
u32 cc, u32 rcc, u32 cc_prev, u32 rcc_prev);
|
||||
|
||||
#define QCA_REV_988X(ar) ((ar)->hw_rev == ATH10K_HW_QCA988X)
|
||||
#define QCA_REV_6174(ar) ((ar)->hw_rev == ATH10K_HW_QCA6174)
|
||||
|
||||
@@ -449,6 +452,9 @@ enum ath10k_hw_rate_cck {
|
||||
#define SCRATCH_3_ADDRESS ar->regs->scratch_3_address
|
||||
#define CPU_INTR_ADDRESS 0x0010
|
||||
|
||||
/* Cycle counters are running at 88MHz */
|
||||
#define CCNT_TO_MSEC(x) ((x) / 88000)
|
||||
|
||||
/* Firmware indications to the Host via SCRATCH_3 register. */
|
||||
#define FW_INDICATOR_ADDRESS (SOC_CORE_BASE_ADDRESS + SCRATCH_3_ADDRESS)
|
||||
#define FW_IND_EVENT_PENDING 1
|
||||
|
||||
@@ -3949,83 +3949,6 @@ static int ath10k_config_ps(struct ath10k *ar)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ath10k_mac_chan_reconfigure(struct ath10k *ar)
|
||||
{
|
||||
struct ath10k_vif *arvif;
|
||||
struct cfg80211_chan_def def;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC, "mac chan reconfigure\n");
|
||||
|
||||
/* First stop monitor interface. Some FW versions crash if there's a
|
||||
* lone monitor interface. */
|
||||
if (ar->monitor_started)
|
||||
ath10k_monitor_stop(ar);
|
||||
|
||||
list_for_each_entry(arvif, &ar->arvifs, list) {
|
||||
if (!arvif->is_started)
|
||||
continue;
|
||||
|
||||
if (!arvif->is_up)
|
||||
continue;
|
||||
|
||||
if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)
|
||||
continue;
|
||||
|
||||
ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to down vdev %d: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* all vdevs are downed now - attempt to restart and re-up them */
|
||||
|
||||
list_for_each_entry(arvif, &ar->arvifs, list) {
|
||||
if (!arvif->is_started)
|
||||
continue;
|
||||
|
||||
if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)
|
||||
continue;
|
||||
|
||||
ret = ath10k_mac_setup_bcn_tmpl(arvif);
|
||||
if (ret)
|
||||
ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
|
||||
ret);
|
||||
|
||||
ret = ath10k_mac_setup_prb_tmpl(arvif);
|
||||
if (ret)
|
||||
ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
|
||||
ret);
|
||||
|
||||
if (WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def)))
|
||||
continue;
|
||||
|
||||
ret = ath10k_vdev_restart(arvif, &def);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to restart vdev %d: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!arvif->is_up)
|
||||
continue;
|
||||
|
||||
ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
|
||||
arvif->bssid);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to bring vdev up %d: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
ath10k_monitor_recalc(ar);
|
||||
}
|
||||
|
||||
static int ath10k_mac_txpower_setup(struct ath10k *ar, int txpower)
|
||||
{
|
||||
int ret;
|
||||
@@ -6144,7 +6067,10 @@ static int ath10k_ampdu_action(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
static void
|
||||
ath10k_mac_update_rx_channel(struct ath10k *ar)
|
||||
ath10k_mac_update_rx_channel(struct ath10k *ar,
|
||||
struct ieee80211_chanctx_conf *ctx,
|
||||
struct ieee80211_vif_chanctx_switch *vifs,
|
||||
int n_vifs)
|
||||
{
|
||||
struct cfg80211_chan_def *def = NULL;
|
||||
|
||||
@@ -6154,6 +6080,9 @@ ath10k_mac_update_rx_channel(struct ath10k *ar)
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
lockdep_assert_held(&ar->data_lock);
|
||||
|
||||
WARN_ON(ctx && vifs);
|
||||
WARN_ON(vifs && n_vifs != 1);
|
||||
|
||||
/* FIXME: Sort of an optimization and a workaround. Peers and vifs are
|
||||
* on a linked list now. Doing a lookup peer -> vif -> chanctx for each
|
||||
* ppdu on Rx may reduce performance on low-end systems. It should be
|
||||
@@ -6165,36 +6094,28 @@ ath10k_mac_update_rx_channel(struct ath10k *ar)
|
||||
* affected much.
|
||||
*/
|
||||
rcu_read_lock();
|
||||
if (ath10k_mac_num_chanctxs(ar) == 1) {
|
||||
if (!ctx && ath10k_mac_num_chanctxs(ar) == 1) {
|
||||
ieee80211_iter_chan_contexts_atomic(ar->hw,
|
||||
ath10k_mac_get_any_chandef_iter,
|
||||
&def);
|
||||
|
||||
if (vifs)
|
||||
def = &vifs[0].new_ctx->def;
|
||||
|
||||
ar->rx_channel = def->chan;
|
||||
} else if (ctx && ath10k_mac_num_chanctxs(ar) == 0) {
|
||||
ar->rx_channel = ctx->def.chan;
|
||||
} else {
|
||||
ar->rx_channel = NULL;
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
static void
|
||||
ath10k_mac_chan_ctx_init(struct ath10k *ar,
|
||||
struct ath10k_chanctx *arctx,
|
||||
struct ieee80211_chanctx_conf *conf)
|
||||
{
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
lockdep_assert_held(&ar->data_lock);
|
||||
|
||||
memset(arctx, 0, sizeof(*arctx));
|
||||
|
||||
arctx->conf = *conf;
|
||||
}
|
||||
|
||||
static int
|
||||
ath10k_mac_op_add_chanctx(struct ieee80211_hw *hw,
|
||||
struct ieee80211_chanctx_conf *ctx)
|
||||
{
|
||||
struct ath10k *ar = hw->priv;
|
||||
struct ath10k_chanctx *arctx = (void *)ctx->drv_priv;
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC,
|
||||
"mac chanctx add freq %hu width %d ptr %p\n",
|
||||
@@ -6203,8 +6124,7 @@ ath10k_mac_op_add_chanctx(struct ieee80211_hw *hw,
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
ath10k_mac_chan_ctx_init(ar, arctx, ctx);
|
||||
ath10k_mac_update_rx_channel(ar);
|
||||
ath10k_mac_update_rx_channel(ar, ctx, NULL, 0);
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
ath10k_recalc_radar_detection(ar);
|
||||
@@ -6228,7 +6148,7 @@ ath10k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
ath10k_mac_update_rx_channel(ar);
|
||||
ath10k_mac_update_rx_channel(ar, NULL, NULL, 0);
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
ath10k_recalc_radar_detection(ar);
|
||||
@@ -6243,16 +6163,12 @@ ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,
|
||||
u32 changed)
|
||||
{
|
||||
struct ath10k *ar = hw->priv;
|
||||
struct ath10k_chanctx *arctx = (void *)ctx->drv_priv;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC,
|
||||
"mac chanctx change freq %hu->%hu width %d->%d ptr %p changed %x\n",
|
||||
arctx->conf.def.chan->center_freq,
|
||||
ctx->def.chan->center_freq,
|
||||
arctx->conf.def.width, ctx->def.width,
|
||||
ctx, changed);
|
||||
"mac chanctx change freq %hu width %d ptr %p changed %x\n",
|
||||
ctx->def.chan->center_freq, ctx->def.width, ctx, changed);
|
||||
|
||||
/* This shouldn't really happen because channel switching should use
|
||||
* switch_vif_chanctx().
|
||||
@@ -6260,10 +6176,6 @@ ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,
|
||||
if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL))
|
||||
goto unlock;
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
arctx->conf = *ctx;
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
ath10k_recalc_radar_detection(ar);
|
||||
|
||||
/* FIXME: How to configure Rx chains properly? */
|
||||
@@ -6283,7 +6195,6 @@ ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
|
||||
struct ieee80211_chanctx_conf *ctx)
|
||||
{
|
||||
struct ath10k *ar = hw->priv;
|
||||
struct ath10k_chanctx *arctx = (void *)ctx->drv_priv;
|
||||
struct ath10k_vif *arvif = (void *)vif->drv_priv;
|
||||
int ret;
|
||||
|
||||
@@ -6298,11 +6209,11 @@ ath10k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
ret = ath10k_vdev_start(arvif, &arctx->conf.def);
|
||||
ret = ath10k_vdev_start(arvif, &ctx->def);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to start vdev %i addr %pM on freq %d: %d\n",
|
||||
arvif->vdev_id, vif->addr,
|
||||
arctx->conf.def.chan->center_freq, ret);
|
||||
ctx->def.chan->center_freq, ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -6377,7 +6288,7 @@ ath10k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,
|
||||
{
|
||||
struct ath10k *ar = hw->priv;
|
||||
struct ath10k_vif *arvif;
|
||||
struct ath10k_chanctx *arctx_new, *arctx_old;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
@@ -6386,38 +6297,81 @@ ath10k_mac_op_switch_vif_chanctx(struct ieee80211_hw *hw,
|
||||
"mac chanctx switch n_vifs %d mode %d\n",
|
||||
n_vifs, mode);
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
/* First stop monitor interface. Some FW versions crash if there's a
|
||||
* lone monitor interface.
|
||||
*/
|
||||
if (ar->monitor_started)
|
||||
ath10k_monitor_stop(ar);
|
||||
|
||||
for (i = 0; i < n_vifs; i++) {
|
||||
arvif = ath10k_vif_to_arvif(vifs[i].vif);
|
||||
arctx_new = (void *)vifs[i].new_ctx->drv_priv;
|
||||
arctx_old = (void *)vifs[i].old_ctx->drv_priv;
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC,
|
||||
"mac chanctx switch vdev_id %i freq %hu->%hu width %d->%d ptr %p->%p\n",
|
||||
"mac chanctx switch vdev_id %i freq %hu->%hu width %d->%d\n",
|
||||
arvif->vdev_id,
|
||||
vifs[i].old_ctx->def.chan->center_freq,
|
||||
vifs[i].new_ctx->def.chan->center_freq,
|
||||
vifs[i].old_ctx->def.width,
|
||||
vifs[i].new_ctx->def.width,
|
||||
arctx_old, arctx_new);
|
||||
vifs[i].new_ctx->def.width);
|
||||
|
||||
if (mode == CHANCTX_SWMODE_SWAP_CONTEXTS) {
|
||||
ath10k_mac_chan_ctx_init(ar, arctx_new,
|
||||
vifs[i].new_ctx);
|
||||
if (WARN_ON(!arvif->is_started))
|
||||
continue;
|
||||
|
||||
if (WARN_ON(!arvif->is_up))
|
||||
continue;
|
||||
|
||||
ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to down vdev %d: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
arctx_new->conf = *vifs[i].new_ctx;
|
||||
|
||||
/* FIXME: ath10k_mac_chan_reconfigure() uses current, i.e. not
|
||||
* yet updated chanctx_conf pointer.
|
||||
*/
|
||||
arctx_old->conf = *vifs[i].new_ctx;
|
||||
}
|
||||
ath10k_mac_update_rx_channel(ar);
|
||||
|
||||
/* All relevant vdevs are downed and associated channel resources
|
||||
* should be available for the channel switch now.
|
||||
*/
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
ath10k_mac_update_rx_channel(ar, NULL, vifs, n_vifs);
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
/* FIXME: Reconfigure only affected vifs */
|
||||
ath10k_mac_chan_reconfigure(ar);
|
||||
for (i = 0; i < n_vifs; i++) {
|
||||
arvif = ath10k_vif_to_arvif(vifs[i].vif);
|
||||
|
||||
if (WARN_ON(!arvif->is_started))
|
||||
continue;
|
||||
|
||||
if (WARN_ON(!arvif->is_up))
|
||||
continue;
|
||||
|
||||
ret = ath10k_mac_setup_bcn_tmpl(arvif);
|
||||
if (ret)
|
||||
ath10k_warn(ar, "failed to update bcn tmpl during csa: %d\n",
|
||||
ret);
|
||||
|
||||
ret = ath10k_mac_setup_prb_tmpl(arvif);
|
||||
if (ret)
|
||||
ath10k_warn(ar, "failed to update prb tmpl during csa: %d\n",
|
||||
ret);
|
||||
|
||||
ret = ath10k_vdev_restart(arvif, &vifs[i].new_ctx->def);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to restart vdev %d: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
|
||||
arvif->bssid);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to bring vdev up %d: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
ath10k_monitor_recalc(ar);
|
||||
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
return 0;
|
||||
@@ -6914,7 +6868,6 @@ int ath10k_mac_register(struct ath10k *ar)
|
||||
|
||||
ar->hw->vif_data_size = sizeof(struct ath10k_vif);
|
||||
ar->hw->sta_data_size = sizeof(struct ath10k_sta);
|
||||
ar->hw->chanctx_data_size = sizeof(struct ath10k_chanctx);
|
||||
|
||||
ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL;
|
||||
|
||||
|
||||
@@ -1424,7 +1424,6 @@ static void ath10k_pci_tx_pipe_cleanup(struct ath10k_pci_pipe *pci_pipe)
|
||||
struct ath10k_ce_ring *ce_ring;
|
||||
struct ce_desc *ce_desc;
|
||||
struct sk_buff *skb;
|
||||
unsigned int id;
|
||||
int i;
|
||||
|
||||
ar = pci_pipe->hif_ce_state;
|
||||
@@ -1448,8 +1447,6 @@ static void ath10k_pci_tx_pipe_cleanup(struct ath10k_pci_pipe *pci_pipe)
|
||||
continue;
|
||||
|
||||
ce_ring->per_transfer_context[i] = NULL;
|
||||
id = MS(__le16_to_cpu(ce_desc[i].flags),
|
||||
CE_DESC_FLAGS_META_DATA);
|
||||
|
||||
ar_pci->msg_callbacks_current.tx_completion(ar, skb);
|
||||
}
|
||||
@@ -2850,6 +2847,7 @@ err_free_pipes:
|
||||
ath10k_pci_free_pipes(ar);
|
||||
|
||||
err_sleep:
|
||||
ath10k_pci_sleep_sync(ar);
|
||||
ath10k_pci_release(ar);
|
||||
|
||||
err_core_destroy:
|
||||
@@ -2927,8 +2925,10 @@ MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_BOARD_DATA_FILE);
|
||||
|
||||
/* QCA6174 2.1 firmware files */
|
||||
MODULE_FIRMWARE(QCA6174_HW_2_1_FW_DIR "/" ATH10K_FW_API4_FILE);
|
||||
MODULE_FIRMWARE(QCA6174_HW_2_1_FW_DIR "/" ATH10K_FW_API5_FILE);
|
||||
MODULE_FIRMWARE(QCA6174_HW_2_1_FW_DIR "/" QCA6174_HW_2_1_BOARD_DATA_FILE);
|
||||
|
||||
/* QCA6174 3.1 firmware files */
|
||||
MODULE_FIRMWARE(QCA6174_HW_3_0_FW_DIR "/" ATH10K_FW_API4_FILE);
|
||||
MODULE_FIRMWARE(QCA6174_HW_3_0_FW_DIR "/" ATH10K_FW_API5_FILE);
|
||||
MODULE_FIRMWARE(QCA6174_HW_3_0_FW_DIR "/" QCA6174_HW_3_0_BOARD_DATA_FILE);
|
||||
|
||||
@@ -402,7 +402,7 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb)
|
||||
id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
|
||||
|
||||
if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
|
||||
return;
|
||||
goto out;
|
||||
|
||||
trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
|
||||
|
||||
@@ -521,6 +521,7 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb)
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "testmode.h"
|
||||
#include "wmi-ops.h"
|
||||
#include "p2p.h"
|
||||
#include "hw.h"
|
||||
|
||||
/* MAIN WMI cmd track */
|
||||
static struct wmi_cmd_map wmi_cmd_map = {
|
||||
@@ -1450,6 +1451,7 @@ int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb)
|
||||
ret = ath10k_wmi_pull_mgmt_rx(ar, skb, &arg);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to parse mgmt rx event: %d\n", ret);
|
||||
dev_kfree_skb(skb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1636,20 +1638,22 @@ void ath10k_wmi_event_chan_info(struct ath10k *ar, struct sk_buff *skb)
|
||||
}
|
||||
|
||||
if (cmd_flags & WMI_CHAN_INFO_FLAG_COMPLETE) {
|
||||
/* During scanning chan info is reported twice for each
|
||||
* visited channel. The reported cycle count is global
|
||||
* and per-channel cycle count must be calculated */
|
||||
if (ar->ch_info_can_report_survey) {
|
||||
survey = &ar->survey[idx];
|
||||
survey->noise = noise_floor;
|
||||
survey->filled = SURVEY_INFO_NOISE_DBM;
|
||||
|
||||
cycle_count -= ar->survey_last_cycle_count;
|
||||
rx_clear_count -= ar->survey_last_rx_clear_count;
|
||||
ath10k_hw_fill_survey_time(ar,
|
||||
survey,
|
||||
cycle_count,
|
||||
rx_clear_count,
|
||||
ar->survey_last_cycle_count,
|
||||
ar->survey_last_rx_clear_count);
|
||||
}
|
||||
|
||||
survey = &ar->survey[idx];
|
||||
survey->time = WMI_CHAN_INFO_MSEC(cycle_count);
|
||||
survey->time_busy = WMI_CHAN_INFO_MSEC(rx_clear_count);
|
||||
survey->noise = noise_floor;
|
||||
survey->filled = SURVEY_INFO_TIME |
|
||||
SURVEY_INFO_TIME_BUSY |
|
||||
SURVEY_INFO_NOISE_DBM;
|
||||
ar->ch_info_can_report_survey = false;
|
||||
} else {
|
||||
ar->ch_info_can_report_survey = true;
|
||||
}
|
||||
|
||||
ar->survey_last_rx_clear_count = rx_clear_count;
|
||||
@@ -3219,7 +3223,7 @@ static void ath10k_wmi_op_rx(struct ath10k *ar, struct sk_buff *skb)
|
||||
id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
|
||||
|
||||
if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
|
||||
return;
|
||||
goto out;
|
||||
|
||||
trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
|
||||
|
||||
@@ -3323,6 +3327,7 @@ static void ath10k_wmi_op_rx(struct ath10k *ar, struct sk_buff *skb)
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
@@ -3336,7 +3341,7 @@ static void ath10k_wmi_10_1_op_rx(struct ath10k *ar, struct sk_buff *skb)
|
||||
id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
|
||||
|
||||
if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
|
||||
return;
|
||||
goto out;
|
||||
|
||||
trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
|
||||
|
||||
@@ -3459,7 +3464,7 @@ static void ath10k_wmi_10_2_op_rx(struct ath10k *ar, struct sk_buff *skb)
|
||||
id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
|
||||
|
||||
if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
|
||||
return;
|
||||
goto out;
|
||||
|
||||
trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
|
||||
|
||||
@@ -3567,6 +3572,7 @@ static void ath10k_wmi_10_2_op_rx(struct ath10k *ar, struct sk_buff *skb)
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
|
||||
@@ -4665,7 +4665,6 @@ struct wmi_peer_sta_kickout_event {
|
||||
} __packed;
|
||||
|
||||
#define WMI_CHAN_INFO_FLAG_COMPLETE BIT(0)
|
||||
#define WMI_CHAN_INFO_MSEC(x) ((x) / 88000)
|
||||
|
||||
/* Beacon filter wmi command info */
|
||||
#define BCN_FLT_MAX_SUPPORTED_IES 256
|
||||
|
||||
@@ -1527,8 +1527,8 @@ struct wmi_connect_event {
|
||||
__le32 nw_type;
|
||||
} sta;
|
||||
struct {
|
||||
u8 phymode;
|
||||
u8 aid;
|
||||
u8 phymode;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u8 auth;
|
||||
u8 keymgmt;
|
||||
|
||||
@@ -531,6 +531,7 @@ struct ath9k_htc_priv {
|
||||
struct ath9k_debug debug;
|
||||
#endif
|
||||
struct mutex mutex;
|
||||
struct ieee80211_vif *csa_vif;
|
||||
};
|
||||
|
||||
static inline void ath_read_cachesize(struct ath_common *common, int *csz)
|
||||
@@ -584,6 +585,7 @@ void ath9k_htc_tx_drain(struct ath9k_htc_priv *priv);
|
||||
void ath9k_htc_txstatus(struct ath9k_htc_priv *priv, void *wmi_event);
|
||||
void ath9k_tx_failed_tasklet(unsigned long data);
|
||||
void ath9k_htc_tx_cleanup_timer(unsigned long data);
|
||||
bool ath9k_htc_csa_is_finished(struct ath9k_htc_priv *priv);
|
||||
|
||||
int ath9k_rx_init(struct ath9k_htc_priv *priv);
|
||||
void ath9k_rx_cleanup(struct ath9k_htc_priv *priv);
|
||||
|
||||
@@ -257,6 +257,8 @@ static void ath9k_htc_send_beacon(struct ath9k_htc_priv *priv,
|
||||
}
|
||||
|
||||
spin_unlock_bh(&priv->beacon_lock);
|
||||
|
||||
ath9k_htc_csa_is_finished(priv);
|
||||
}
|
||||
|
||||
static int ath9k_htc_choose_bslot(struct ath9k_htc_priv *priv,
|
||||
@@ -503,3 +505,20 @@ void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool ath9k_htc_csa_is_finished(struct ath9k_htc_priv *priv)
|
||||
{
|
||||
struct ieee80211_vif *vif;
|
||||
|
||||
vif = priv->csa_vif;
|
||||
if (!vif || !vif->csa_active)
|
||||
return false;
|
||||
|
||||
if (!ieee80211_csa_is_complete(vif))
|
||||
return false;
|
||||
|
||||
ieee80211_csa_finish(vif);
|
||||
|
||||
priv->csa_vif = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -744,7 +744,8 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
|
||||
hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
||||
|
||||
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN |
|
||||
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
|
||||
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
|
||||
WIPHY_FLAG_HAS_CHANNEL_SWITCH;
|
||||
|
||||
hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
|
||||
|
||||
|
||||
@@ -1134,6 +1134,9 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
|
||||
priv->nvifs--;
|
||||
priv->vif_slot &= ~(1 << avp->index);
|
||||
|
||||
if (priv->csa_vif == vif)
|
||||
priv->csa_vif = NULL;
|
||||
|
||||
ath9k_htc_remove_station(priv, vif, NULL);
|
||||
|
||||
DEC_VIF(priv, vif->type);
|
||||
@@ -1841,6 +1844,19 @@ static int ath9k_htc_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ath9k_htc_channel_switch_beacon(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
struct ath9k_htc_priv *priv = hw->priv;
|
||||
|
||||
/* mac80211 does not support CSA in multi-if cases (yet) */
|
||||
if (WARN_ON(priv->csa_vif))
|
||||
return;
|
||||
|
||||
priv->csa_vif = vif;
|
||||
}
|
||||
|
||||
struct ieee80211_ops ath9k_htc_ops = {
|
||||
.tx = ath9k_htc_tx,
|
||||
.start = ath9k_htc_start,
|
||||
@@ -1867,6 +1883,7 @@ struct ieee80211_ops ath9k_htc_ops = {
|
||||
.set_bitrate_mask = ath9k_htc_set_bitrate_mask,
|
||||
.get_stats = ath9k_htc_get_stats,
|
||||
.get_antenna = ath9k_htc_get_antenna,
|
||||
.channel_switch_beacon = ath9k_htc_channel_switch_beacon,
|
||||
|
||||
#ifdef CONFIG_ATH9K_HTC_DEBUGFS
|
||||
.get_et_sset_count = ath9k_htc_get_et_sset_count,
|
||||
|
||||
@@ -216,11 +216,13 @@ static bool ath_prepare_reset(struct ath_softc *sc)
|
||||
ath_stop_ani(sc);
|
||||
ath9k_hw_disable_interrupts(ah);
|
||||
|
||||
if (!ath_drain_all_txq(sc))
|
||||
ret = false;
|
||||
|
||||
if (!ath_stoprecv(sc))
|
||||
ret = false;
|
||||
if (AR_SREV_9300_20_OR_LATER(ah)) {
|
||||
ret &= ath_stoprecv(sc);
|
||||
ret &= ath_drain_all_txq(sc);
|
||||
} else {
|
||||
ret &= ath_drain_all_txq(sc);
|
||||
ret &= ath_stoprecv(sc);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -289,6 +289,26 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
|
||||
}
|
||||
|
||||
wil_dbg_misc(wil, "Start scan_request 0x%p\n", request);
|
||||
wil_dbg_misc(wil, "SSID count: %d", request->n_ssids);
|
||||
|
||||
for (i = 0; i < request->n_ssids; i++) {
|
||||
wil_dbg_misc(wil, "SSID[%d]", i);
|
||||
print_hex_dump_bytes("SSID ", DUMP_PREFIX_OFFSET,
|
||||
request->ssids[i].ssid,
|
||||
request->ssids[i].ssid_len);
|
||||
}
|
||||
|
||||
if (request->n_ssids)
|
||||
rc = wmi_set_ssid(wil, request->ssids[0].ssid_len,
|
||||
request->ssids[0].ssid);
|
||||
else
|
||||
rc = wmi_set_ssid(wil, 0, NULL);
|
||||
|
||||
if (rc) {
|
||||
wil_err(wil, "set SSID for scan request failed: %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
wil->scan_request = request;
|
||||
mod_timer(&wil->scan_timer, jiffies + WIL6210_SCAN_TO);
|
||||
|
||||
@@ -778,6 +798,7 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
|
||||
size_t hlen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
|
||||
const u8 *pr_ies = NULL;
|
||||
size_t pr_ies_len = 0;
|
||||
u8 hidden_ssid;
|
||||
|
||||
wil_dbg_misc(wil, "%s()\n", __func__);
|
||||
|
||||
@@ -790,6 +811,8 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
|
||||
channel->center_freq, info->privacy ? "secure" : "open");
|
||||
wil_dbg_misc(wil, "Privacy: %d auth_type %d\n",
|
||||
info->privacy, info->auth_type);
|
||||
wil_dbg_misc(wil, "Hidden SSID mode: %d\n",
|
||||
info->hidden_ssid);
|
||||
wil_dbg_misc(wil, "BI %d DTIM %d\n", info->beacon_interval,
|
||||
info->dtim_period);
|
||||
print_hex_dump_bytes("SSID ", DUMP_PREFIX_OFFSET,
|
||||
@@ -835,10 +858,28 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
|
||||
|
||||
wil->privacy = info->privacy;
|
||||
|
||||
switch (info->hidden_ssid) {
|
||||
case NL80211_HIDDEN_SSID_NOT_IN_USE:
|
||||
hidden_ssid = WMI_HIDDEN_SSID_DISABLED;
|
||||
break;
|
||||
|
||||
case NL80211_HIDDEN_SSID_ZERO_LEN:
|
||||
hidden_ssid = WMI_HIDDEN_SSID_SEND_EMPTY;
|
||||
break;
|
||||
|
||||
case NL80211_HIDDEN_SSID_ZERO_CONTENTS:
|
||||
hidden_ssid = WMI_HIDDEN_SSID_CLEAR;
|
||||
break;
|
||||
|
||||
default:
|
||||
rc = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
netif_carrier_on(ndev);
|
||||
|
||||
rc = wmi_pcp_start(wil, info->beacon_interval, wmi_nettype,
|
||||
channel->hw_value);
|
||||
channel->hw_value, hidden_ssid);
|
||||
if (rc)
|
||||
goto err_pcp_start;
|
||||
|
||||
@@ -1023,8 +1064,7 @@ static struct cfg80211_ops wil_cfg80211_ops = {
|
||||
|
||||
static void wil_wiphy_init(struct wiphy *wiphy)
|
||||
{
|
||||
/* TODO: set real value */
|
||||
wiphy->max_scan_ssids = 10;
|
||||
wiphy->max_scan_ssids = 1;
|
||||
wiphy->max_scan_ie_len = WMI_MAX_IE_LEN;
|
||||
wiphy->max_num_pmkids = 0 /* TODO: */;
|
||||
wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||
|
||||
@@ -1360,7 +1360,7 @@ static int wil_sta_debugfs_show(struct seq_file *s, void *data)
|
||||
__acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock)
|
||||
{
|
||||
struct wil6210_priv *wil = s->private;
|
||||
int i, tid;
|
||||
int i, tid, mcs;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
|
||||
struct wil_sta_info *p = &wil->sta[i];
|
||||
@@ -1390,6 +1390,12 @@ __acquires(&p->tid_rx_lock) __releases(&p->tid_rx_lock)
|
||||
}
|
||||
}
|
||||
spin_unlock_bh(&p->tid_rx_lock);
|
||||
seq_puts(s, "Rx/MCS:");
|
||||
for (mcs = 0; mcs < ARRAY_SIZE(p->stats.rx_per_mcs);
|
||||
mcs++)
|
||||
seq_printf(s, " %lld",
|
||||
p->stats.rx_per_mcs[mcs]);
|
||||
seq_puts(s, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -100,6 +100,8 @@ module_param_cb(rx_ring_order, &ring_order_ops, &rx_ring_order, S_IRUGO);
|
||||
MODULE_PARM_DESC(rx_ring_order, " Rx ring order; size = 1 << order");
|
||||
module_param_cb(tx_ring_order, &ring_order_ops, &tx_ring_order, S_IRUGO);
|
||||
MODULE_PARM_DESC(tx_ring_order, " Tx ring order; size = 1 << order");
|
||||
module_param_cb(bcast_ring_order, &ring_order_ops, &bcast_ring_order, S_IRUGO);
|
||||
MODULE_PARM_DESC(bcast_ring_order, " Bcast ring order; size = 1 << order");
|
||||
|
||||
#define RST_DELAY (20) /* msec, for loop in @wil_target_reset */
|
||||
#define RST_COUNT (1 + 1000/RST_DELAY) /* round up to be above 1 sec total */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user