* Re: [PATCH v3 2/2] ath10k: implement per-VDEV FW statistics
From: Kalle Valo @ 2013-09-03 7:13 UTC (permalink / raw)
To: Bartosz Markowski; +Cc: ath10k, linux-wireless
In-Reply-To: <1377778061-22331-3-git-send-email-bartosz.markowski@tieto.com>
Bartosz Markowski <bartosz.markowski@tieto.com> writes:
> The WMI_REQUEST_PEER_STAT command with latst (1.0.0.716) FW
> can return per-VDEV statistics. Using debugfs we can fetch this info now.
>
> This is a backward compatible change. In case of older FW the VDEV
> statistics are simply not returned.
>
> Signed-off-by: Bartosz Markowski <bartosz.markowski@tieto.com>
[...]
> if (num_peer_stats) {
> - struct wmi_peer_stats *peer_stats;
> struct ath10k_peer_stat *s;
> + struct wmi_peer_stats_1 *peer_stats_1;
> + struct wmi_peer_stats_2 *peer_stats_2;
>
> stats->peers = num_peer_stats;
>
> for (i = 0; i < num_peer_stats; i++) {
> - peer_stats = (struct wmi_peer_stats *)tmp;
> + peer_stats_1 = (struct wmi_peer_stats_1 *)tmp;
You still have this evil cast here which assumes struct wmi_peer_stats_1
starts with the same content as _2. It's better to spell that out in the
code, for example like this:
if (test_bit(ATH10K_FW_FEATURE_VDEV_STATS, ar->fw_features)) {
peer_v2 = (struct wmi_peer_stats_v2 *)tmp;
peer_stats = &peer_v2->common;
tmp += sizeof(*peer_v2);
} else {
peer_v1 = (struct wmi_peer_stats_v1 *)tmp;
peer_stats = &peer_v1->common;
tmp += sizeof(*peer_v1);
}
> +struct wmi_peer_stats_1 {
struct wmi_peer_stats_v1
> +struct wmi_peer_stats_2 {
struct wmi_peer_stats_v2
--
Kalle Valo
^ permalink raw reply
* Re: [PATCH v2 net-next 0/9] set addr_assign_type when inheriting a dev_addr
From: Bjørn Mork @ 2013-09-03 7:38 UTC (permalink / raw)
To: David Miller
Cc: netdev, kaber, jiri, linville, linux-wireless, j, libertas-dev,
gregkh, devel, forest, stephen, dan.carpenter
In-Reply-To: <20130831.225057.1874268263797742541.davem@davemloft.net>
David Miller <davem@davemloft.net> writes:
> From: Bjørn Mork <bjorn@mork.no>
> Date: Fri, 30 Aug 2013 18:08:43 +0200
>
>> Copying the dev_addr from a parent device is an operation
>> common to a number of drivers. The addr_assign_type should
>> be updated accordingly, either by reusing the value from
>> the source device or explicitly indicating that the address
>> is stolen by setting addr_assign_type to NET_ADDR_STOLEN.
>>
>> This patch set adds a helper copying both the dev_addr and
>> the addr_assign_type, and use this helper in drivers which
>> don't currently set the addr_assign_type. Using NET_ADDR_STOLEN
>> might be more appropriate in some of these cases. Please
>> let me know, and I'll update the patch accordingly.
>>
>> Changes in v2:
>> - assuming addr_len == ETH_ALEN to allow optimized memcpy
>> - dropped the vt6656 patch due to addr_len being unset in that driver
>
> Looks good, series applied, thanks.
Thanks. But it doesn't look like it ended up in net-next? Or am I
missing something (again)?
Bjørn
^ permalink raw reply
* Pull request: ath 20130930
From: Kalle Valo @ 2013-09-03 8:14 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, ath10k, ath6kl-devel
Hi John,
here are latest ath10k changes, I hope it's still time to get these to
3.12. The changelog for the pull request:
Bartosz dropped support for qca98xx hw1.0 hardware from ath10k, it's
just too much to support it. Michal added support for the new firmware
interface. Marek fixed WEP in AP and IBSS mode. Rest of the changes are
minor fixes or cleanups.
The following changes since commit 9d0e2f0772d394060bf3b17cd1f3a35574365103:
ath6kl: Fix invalid pointer access on fuzz testing with AP mode (2013-08-07 10:58:59 +0300)
are available in the git repository at:
git://github.com/kvalo/ath.git for-linville
for you to fetch changes up to 763b8cd31493f452094fd0eaeedb8cad37c756a2:
ath10k: add chip_id file to debugfs (2013-09-03 09:59:53 +0300)
----------------------------------------------------------------
Bartosz Markowski (2):
ath10k: Remove qca98xx hw1.0 support
ath10k: update supported FW build version
Janusz Dziedzic (2):
ath10k: setup peer UAPSD flag correctly
ath10k: check allocation errors in CE
Kalle Valo (10):
ath10k: remove un ar_pci->cacheline_sz field
ath10k: pci: make host_ce_config_wlan[] more readable
ath10k: make target_ce_config_wlan more readable
ath10k: remove void pointer from struct ath10k_pci_compl
ath10k: convert ath10k_pci_reg_read/write32() to take struct ath10k
ath10k: clean up ath10k_ce_completed_send_next_nolock()
ath10k: convert ath10k_pci_wake() to return
ath10k: simplify ath10k_ce_init() wake up handling
ath10k: check chip id from the soc register during probe
ath10k: add chip_id file to debugfs
Marek Puzyniak (1):
ath10k: fix WEP in AP and IBSS mode
Michal Kazior (15):
ath10k: clean up monitor start code
ath10k: use sizeof(*var) in kmalloc
ath10k: clean up PCI completion states
ath10k: print errcode when CE ring setup fails
ath10k: fix HTT service setup
ath10k: implement 802.3 SNAP rx decap type A-MSDU handling
ath10k: plug possible memory leak in WMI
ath10k: add support for firmware newer than 636
ath10k: add support for HTT 3.0
ath10k: use inline ce_state structure
ath10k: remove ce_op_state
ath10k: remove unused ce_attr parameters
ath10k: rename hif_ce_pipe_info to ath10k_pci_pipe
ath10k: rename ce_state to ath10k_ce_pipe
ath10k: rename ce_ring_state to ath10k_ce_ring
Mohammed Shafi Shajakhan (1):
ath10k: Fix mutex unlock balance
drivers/net/wireless/ath/ath10k/ce.c | 291 +++++++++++++-------------
drivers/net/wireless/ath/ath10k/ce.h | 74 +++----
drivers/net/wireless/ath/ath10k/core.c | 46 +++--
drivers/net/wireless/ath/ath10k/core.h | 13 +-
drivers/net/wireless/ath/ath10k/debug.c | 23 ++-
drivers/net/wireless/ath/ath10k/htc.c | 8 +-
drivers/net/wireless/ath/ath10k/htt.c | 19 +-
drivers/net/wireless/ath/ath10k/htt.h | 6 +-
drivers/net/wireless/ath/ath10k/htt_rx.c | 12 +-
drivers/net/wireless/ath/ath10k/htt_tx.c | 74 +++++--
drivers/net/wireless/ath/ath10k/hw.h | 19 +-
drivers/net/wireless/ath/ath10k/mac.c | 22 +-
drivers/net/wireless/ath/ath10k/pci.c | 325 ++++++++++++++++++++----------
drivers/net/wireless/ath/ath10k/pci.h | 73 +++----
drivers/net/wireless/ath/ath10k/wmi.c | 33 ++-
drivers/net/wireless/ath/ath10k/wmi.h | 16 +-
16 files changed, 626 insertions(+), 428 deletions(-)
--
Kalle Valo
^ permalink raw reply
* [PATCH v4 0/2] add per-VDEV FW statistics
From: Bartosz Markowski @ 2013-09-03 8:21 UTC (permalink / raw)
To: ath10k; +Cc: linux-wireless, Bartosz Markowski
FW 1.0.0.716 brings per-VDEV statistics. This patch-set implements
debugfs mechanism to fetch them. There's still few more fileds we
can read from the FW stats event, which are not covered here.
Let's bring them in the future.
Changes:
V2:
* introduce wmi_peer_stats_common struct
* fetch and print peer RX rates
* break up wmi_peer_stats_common update into separate patch
V3:
* rebase
* fix sparse endianness warnings
V4:
* rebase
* document the wal_dbg_tx_stats changes
* refactor wmi_peer_stats_common/v1/v2 handling
Bartosz Markowski (2):
ath10k: update wal_dbg_tx_stats structure with missing parameter.
ath10k: implement per-VDEV FW statistics
drivers/net/wireless/ath/ath10k/core.h | 27 ++++++++++
drivers/net/wireless/ath/ath10k/debug.c | 70 +++++++++++++++++++++---
drivers/net/wireless/ath/ath10k/wmi.c | 4 +-
drivers/net/wireless/ath/ath10k/wmi.h | 90 ++++++++++++++++++++++++++-----
4 files changed, 170 insertions(+), 21 deletions(-)
--
1.7.10
^ permalink raw reply
* [PATCH v4 1/2] ath10k: update wal_dbg_tx_stats structure with missing parameter.
From: Bartosz Markowski @ 2013-09-03 8:21 UTC (permalink / raw)
To: ath10k; +Cc: linux-wireless, Bartosz Markowski
In-Reply-To: <1378196481-13983-1-git-send-email-bartosz.markowski@tieto.com>
The filed has been missing (missmatched with FW ABI)
since 1.0.0.629 firmware release.
It's very imporatant to keep these structs up to date with FW,
due to the arithmetic we use while read the fw_stats.
Signed-off-by: Bartosz Markowski <bartosz.markowski@tieto.com>
---
drivers/net/wireless/ath/ath10k/wmi.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 08860c4..5b94707 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -1767,6 +1767,9 @@ struct wal_dbg_tx_stats {
/* wal pdev resets */
__le32 pdev_resets;
+ /* frames dropped due to non-availability of stateless TIDs */
+ __le32 stateless_tid_alloc_failure;
+
__le32 phy_underrun;
/* MPDU is more than txop limit */
--
1.7.10
^ permalink raw reply related
* [PATCH v4 2/2] ath10k: implement per-VDEV FW statistics
From: Bartosz Markowski @ 2013-09-03 8:21 UTC (permalink / raw)
To: ath10k; +Cc: linux-wireless, Bartosz Markowski
In-Reply-To: <1378196481-13983-1-git-send-email-bartosz.markowski@tieto.com>
The WMI_REQUEST_PEER_STAT command with latst (1.0.0.716) FW
can return per-VDEV statistics. Using debugfs we can fetch this info now.
This is a backward compatible change. In case of older FW the VDEV
statistics are simply not returned.
Signed-off-by: Bartosz Markowski <bartosz.markowski@tieto.com>
---
drivers/net/wireless/ath/ath10k/core.h | 27 ++++++++++
drivers/net/wireless/ath/ath10k/debug.c | 70 ++++++++++++++++++++++---
drivers/net/wireless/ath/ath10k/wmi.c | 4 +-
drivers/net/wireless/ath/ath10k/wmi.h | 87 ++++++++++++++++++++++++++-----
4 files changed, 167 insertions(+), 21 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 174c4b4..1a327a9 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -119,10 +119,32 @@ struct ath10k_wmi {
struct work_struct wmi_event_work;
};
+struct ath10k_snr_info {
+ s32 beacon_snr;
+ s32 data_snr;
+};
+
+struct ath10k_vdev_stat {
+ u32 vdev_id;
+ struct ath10k_snr_info vdev_snr;
+ u32 tx_frames_count[MAX_AC];
+ u32 rx_frames_count;
+ u32 multiple_retry_cnt[MAX_AC];
+ u32 fail_count[MAX_AC];
+ u32 rts_fail_count;
+ u32 rts_success_count;
+ u32 rts_err_count;
+ u32 rx_discard_count;
+ u32 ack_fail_count;
+ u32 tx_rate_history[MAX_TX_RATE_VALUES];
+ u32 bcn_rssi_history[MAX_RSSI_VALUES];
+};
+
struct ath10k_peer_stat {
u8 peer_macaddr[ETH_ALEN];
u32 peer_rssi;
u32 peer_tx_rate;
+ u32 peer_rx_rate;
};
struct ath10k_target_stats {
@@ -176,6 +198,8 @@ struct ath10k_target_stats {
s32 mpdu_errs;
/* VDEV STATS */
+ struct ath10k_vdev_stat vdev_stat[TARGET_NUM_VDEVS];
+ u8 vdevs;
/* PEER STATS */
u8 peers;
@@ -274,6 +298,9 @@ enum ath10k_fw_features {
/* wmi_mgmt_rx_hdr contains extra RSSI information */
ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX = 0,
+ /* firmware support per-VEDV statistics */
+ ATH10K_FW_FEATURE_VDEV_STATS = 1,
+
/* keep last */
ATH10K_FW_FEATURE_COUNT,
};
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index 09f535a..1582a97 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -228,25 +228,39 @@ void ath10k_debug_read_target_stats(struct ath10k *ar,
tmp += sizeof(struct wmi_pdev_stats);
}
- /* 0 or max vdevs */
- /* Currently firmware does not support VDEV stats */
if (num_vdev_stats) {
struct wmi_vdev_stats *vdev_stats;
+ struct ath10k_vdev_stat *s;
+
+ stats->vdevs = num_vdev_stats;
for (i = 0; i < num_vdev_stats; i++) {
vdev_stats = (struct wmi_vdev_stats *)tmp;
+ s = &stats->vdev_stat[i];
+
+ s->vdev_id = __le32_to_cpu(vdev_stats->vdev_id);
+ s->vdev_snr.beacon_snr =
+ __le32_to_cpu(vdev_stats->vdev_snr.beacon_snr);
+ s->vdev_snr.data_snr =
+ __le32_to_cpu(vdev_stats->vdev_snr.data_snr);
+
+ /* TODO:read remaining vdev stats */
+
tmp += sizeof(struct wmi_vdev_stats);
}
}
if (num_peer_stats) {
- struct wmi_peer_stats *peer_stats;
struct ath10k_peer_stat *s;
+ struct wmi_peer_stats_common *peer_stats;
+ struct wmi_peer_stats_v1 *peer_v1;
+ struct wmi_peer_stats_v2 *peer_v2;
stats->peers = num_peer_stats;
for (i = 0; i < num_peer_stats; i++) {
- peer_stats = (struct wmi_peer_stats *)tmp;
+ peer_stats = (struct wmi_peer_stats_common *)tmp;
+
s = &stats->peer_stat[i];
WMI_MAC_ADDR_TO_CHAR_ARRAY(&peer_stats->peer_macaddr,
@@ -255,7 +269,19 @@ void ath10k_debug_read_target_stats(struct ath10k *ar,
s->peer_tx_rate =
__le32_to_cpu(peer_stats->peer_tx_rate);
- tmp += sizeof(struct wmi_peer_stats);
+ if (test_bit(ATH10K_FW_FEATURE_VDEV_STATS,
+ ar->fw_features)) {
+ peer_v2 = (struct wmi_peer_stats_v2 *)tmp;
+ peer_stats = &peer_v2->common;
+ s->peer_rx_rate =
+ __le32_to_cpu(peer_v2->peer_rx_rate);
+
+ tmp += sizeof(*peer_v2);
+ } else {
+ peer_v1 = (struct wmi_peer_stats_v1 *)tmp;
+ peer_stats = &peer_v1->common;
+ tmp += sizeof(*peer_v1);
+ }
}
}
@@ -269,7 +295,7 @@ static ssize_t ath10k_read_fw_stats(struct file *file, char __user *user_buf,
struct ath10k *ar = file->private_data;
struct ath10k_target_stats *fw_stats;
char *buf = NULL;
- unsigned int len = 0, buf_len = 2500;
+ unsigned int len = 0, buf_len = 3000;
ssize_t ret_cnt = 0;
long left;
int i;
@@ -407,6 +433,27 @@ static ssize_t ath10k_read_fw_stats(struct file *file, char __user *user_buf,
len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
"MPDU errors (FCS, MIC, ENC)", fw_stats->mpdu_errs);
+ if (fw_stats->vdevs) {
+ len += scnprintf(buf + len, buf_len - len, "\n");
+ len += scnprintf(buf + len, buf_len - len, "%30s\n",
+ "ath10k VDEV stats");
+ len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
+ "=================");
+ }
+
+ for (i = 0; i < fw_stats->vdevs; i++) {
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
+ "VDEV ID", fw_stats->vdev_stat[i].vdev_id);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
+ "Beacon SNR",
+ fw_stats->vdev_stat[i].vdev_snr.beacon_snr);
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
+ "Data SNR",
+ fw_stats->vdev_stat[i].vdev_snr.data_snr);
+ len += scnprintf(buf + len, buf_len - len, "\n");
+ }
+
+
len += scnprintf(buf + len, buf_len - len, "\n");
len += scnprintf(buf + len, buf_len - len, "%30s\n",
"ath10k PEER stats");
@@ -417,11 +464,18 @@ static ssize_t ath10k_read_fw_stats(struct file *file, char __user *user_buf,
len += scnprintf(buf + len, buf_len - len, "%30s %pM\n",
"Peer MAC address",
fw_stats->peer_stat[i].peer_macaddr);
- len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
"Peer RSSI", fw_stats->peer_stat[i].peer_rssi);
- len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
"Peer TX rate",
fw_stats->peer_stat[i].peer_tx_rate);
+
+ if (test_bit(ATH10K_FW_FEATURE_VDEV_STATS, ar->fw_features))
+ len += scnprintf(buf + len, buf_len - len,
+ "%30s %10u\n",
+ "Peer RX rate",
+ fw_stats->peer_stat[i].peer_rx_rate);
+
len += scnprintf(buf + len, buf_len - len, "\n");
}
spin_unlock_bh(&ar->data_lock);
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
index 32fd5e7..3ebab3d 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -957,8 +957,10 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar,
ar->phy_capability = __le32_to_cpu(ev->phy_capability);
ar->num_rf_chains = __le32_to_cpu(ev->num_rf_chains);
- if (ar->fw_version_build > 636)
+ if (ar->fw_version_build > 636) {
set_bit(ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX, ar->fw_features);
+ set_bit(ATH10K_FW_FEATURE_VDEV_STATS, ar->fw_features);
+ }
if (ar->num_rf_chains > WMI_MAX_SPATIAL_STREAM) {
ath10k_warn("hardware advertises support for more spatial streams than it should (%d > %d)\n",
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 5b94707..2b429e4 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -60,6 +60,11 @@
*
*/
+#define MAX_AC 4 /* Maximum value of access category */
+
+#define MAX_TX_RATE_VALUES 10 /* Max Tx rates */
+#define MAX_RSSI_VALUES 10 /* Max RSSI values */
+
/* Control Path */
struct wmi_cmd_hdr {
__le32 cmd_id;
@@ -1828,11 +1833,10 @@ enum wmi_stats_id {
struct wmi_request_stats_cmd {
__le32 stats_id;
-
- /*
- * Space to add parameters like
- * peer mac addr
- */
+ /* unique id identifying the VDEV, generated by the caller */
+ __le32 vdev_id;
+ /* peer MAC address */
+ struct wmi_mac_addr peer_macaddr;
} __packed;
/* Suspend option */
@@ -1881,7 +1885,6 @@ struct wmi_stats_event {
/*
* PDEV statistics
- * TODO: add all PDEV stats here
*/
struct wmi_pdev_stats {
__le32 chan_nf; /* Channel noise floor */
@@ -1894,24 +1897,84 @@ struct wmi_pdev_stats {
struct wal_dbg_stats wal; /* WAL dbg stats */
} __packed;
-/*
- * VDEV statistics
- * TODO: add all VDEV stats here
- */
+struct wmi_snr_info {
+ __le32 beacon_snr;
+ __le32 data_snr;
+} __packed;
+
struct wmi_vdev_stats {
+ /* unique id identifying the VDEV, generated by the caller */
__le32 vdev_id;
+ struct wmi_snr_info vdev_snr;
+ /*
+ * Total number of packets(per AC) that were successfully transmitted
+ * (with and without retries, including multi-cast, broadcast)
+ */
+ __le32 tx_frm_cnt[MAX_AC];
+ /*
+ * Total number of packets that were successfully received
+ * (after appropriate filter rules including multi-cast, broadcast)
+ */
+ __le32 rx_frm_cnt;
+ /*
+ * The number of MSDU packets and MMPDU frames per AC that the 802.11
+ * station successfully transmitted after more than one retransmission
+ * attempt
+ */
+ __le32 multiple_retry_cnt[MAX_AC];
+ /* Total number packets(per AC) failed to transmit */
+ __le32 fail_cnt[MAX_AC];
+ /*
+ * Total number of RTS/CTS sequence failures for transmission of a
+ * packet
+ */
+ __le32 rts_fail_cnt;
+ /*
+ * Total number of RTS/CTS sequence success for transmission of a
+ * packet
+ */
+ __le32 rts_succ_cnt;
+ /*
+ * The receive error count.
+ * HAL will provide the RxP FCS error global
+ */
+ __le32 rx_err_cnt;
+ /*
+ * The sum of the receive error count and dropped-receive-buffer
+ * error count. (FCS error)
+ */
+ __le32 rx_discard_cnt;
+ /*
+ * Total number packets failed transmit because of no ACK
+ * from the remote entity
+ */
+ __le32 ack_fail_cnt;
+ /* History of last ten transmit rate, in units of 500 kbit/sec */
+ __le32 tx_rate_history[MAX_TX_RATE_VALUES];
+ /* History of last ten Beacon rssi of the connected Bss */
+ __le32 bcn_rssi_history[MAX_RSSI_VALUES];
} __packed;
/*
* peer statistics.
- * TODO: add more stats
*/
-struct wmi_peer_stats {
+struct wmi_peer_stats_common {
struct wmi_mac_addr peer_macaddr;
__le32 peer_rssi;
__le32 peer_tx_rate;
} __packed;
+struct wmi_peer_stats_v1 {
+ struct wmi_peer_stats_common common;
+} __packed;
+
+
+struct wmi_peer_stats_v2 {
+ struct wmi_peer_stats_common common;
+ __le32 peer_rx_rate;
+} __packed;
+
+
struct wmi_vdev_create_cmd {
__le32 vdev_id;
__le32 vdev_type;
--
1.7.10
^ permalink raw reply related
* Re: Pull request: ath 20130930
From: Kalle Valo @ 2013-09-03 8:27 UTC (permalink / raw)
To: John W. Linville; +Cc: ath6kl-devel, linux-wireless, ath10k
In-Reply-To: <87wqmyz5i9.fsf@kamboji.qca.qualcomm.com>
Kalle Valo <kvalo@qca.qualcomm.com> writes:
> Hi John,
>
> here are latest ath10k changes, I hope it's still time to get these to
> 3.12. The changelog for the pull request:
>
> Bartosz dropped support for qca98xx hw1.0 hardware from ath10k, it's
> just too much to support it. Michal added support for the new firmware
> interface. Marek fixed WEP in AP and IBSS mode. Rest of the changes are
> minor fixes or cleanups.
Oops, the date in the subject is wrong. Of course it should be 20130903.
--
Kalle Valo
^ permalink raw reply
* [PATCH 0/3] ath10k: HTT stats
From: Kalle Valo @ 2013-09-03 8:43 UTC (permalink / raw)
To: ath10k; +Cc: linux-wireless
Adds trace events and a debugfs interface to enable HTT stats
from firmware.
---
Kalle Valo (3):
ath10k: add trace event ath10k_htt_stats
ath10k: implement ath10k_debug_start/stop()
ath10k: add htt_stats_enable debugfs file
drivers/net/wireless/ath/ath10k/core.c | 6 +
drivers/net/wireless/ath/ath10k/core.h | 3 +
drivers/net/wireless/ath/ath10k/debug.c | 121 ++++++++++++++++++++++++++++++
drivers/net/wireless/ath/ath10k/debug.h | 11 +++
drivers/net/wireless/ath/ath10k/htt.h | 1
drivers/net/wireless/ath/ath10k/htt_rx.c | 5 +
drivers/net/wireless/ath/ath10k/htt_tx.c | 42 ++++++++++
drivers/net/wireless/ath/ath10k/trace.h | 21 +++++
8 files changed, 209 insertions(+), 1 deletion(-)
^ permalink raw reply
* [PATCH 1/3] ath10k: add trace event ath10k_htt_stats
From: Kalle Valo @ 2013-09-03 8:43 UTC (permalink / raw)
To: ath10k; +Cc: linux-wireless
In-Reply-To: <20130903084302.26199.3538.stgit@localhost6.localdomain6>
For analysing various data path statistics in user space.
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath10k/htt_rx.c | 5 ++++-
drivers/net/wireless/ath/ath10k/trace.h | 21 +++++++++++++++++++++
2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
index 9bb0ae89..af31d2f 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -20,6 +20,7 @@
#include "htt.h"
#include "txrx.h"
#include "debug.h"
+#include "trace.h"
#include <linux/log2.h>
@@ -1198,8 +1199,10 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
case HTT_T2H_MSG_TYPE_TEST:
/* FIX THIS */
break;
- case HTT_T2H_MSG_TYPE_TX_INSPECT_IND:
case HTT_T2H_MSG_TYPE_STATS_CONF:
+ trace_ath10k_htt_stats(skb->data, skb->len);
+ break;
+ case HTT_T2H_MSG_TYPE_TX_INSPECT_IND:
case HTT_T2H_MSG_TYPE_RX_ADDBA:
case HTT_T2H_MSG_TYPE_RX_DELBA:
case HTT_T2H_MSG_TYPE_RX_FLUSH:
diff --git a/drivers/net/wireless/ath/ath10k/trace.h b/drivers/net/wireless/ath/ath10k/trace.h
index 85e806b..bf1ceb8 100644
--- a/drivers/net/wireless/ath/ath10k/trace.h
+++ b/drivers/net/wireless/ath/ath10k/trace.h
@@ -158,6 +158,27 @@ TRACE_EVENT(ath10k_wmi_event,
)
);
+TRACE_EVENT(ath10k_htt_stats,
+ TP_PROTO(void *buf, size_t buf_len),
+
+ TP_ARGS(buf, buf_len),
+
+ TP_STRUCT__entry(
+ __field(size_t, buf_len)
+ __dynamic_array(u8, buf, buf_len)
+ ),
+
+ TP_fast_assign(
+ __entry->buf_len = buf_len;
+ memcpy(__get_dynamic_array(buf), buf, buf_len);
+ ),
+
+ TP_printk(
+ "len %zu",
+ __entry->buf_len
+ )
+);
+
#endif /* _TRACE_H_ || TRACE_HEADER_MULTI_READ*/
/* we don't want to use include/trace/events */
^ permalink raw reply related
* [PATCH 2/3] ath10k: implement ath10k_debug_start/stop()
From: Kalle Valo @ 2013-09-03 8:44 UTC (permalink / raw)
To: ath10k; +Cc: linux-wireless
In-Reply-To: <20130903084302.26199.3538.stgit@localhost6.localdomain6>
Needed for the HTT stats implementation.
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath10k/core.c | 6 ++++++
drivers/net/wireless/ath/ath10k/debug.c | 10 ++++++++++
drivers/net/wireless/ath/ath10k/debug.h | 11 +++++++++++
3 files changed, 27 insertions(+)
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 2dd39a8..4f2b0e7 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -630,6 +630,10 @@ int ath10k_core_start(struct ath10k *ar)
if (status)
goto err_disconnect_htc;
+ status = ath10k_debug_start(ar);
+ if (status)
+ goto err_disconnect_htc;
+
ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1;
return 0;
@@ -647,6 +651,7 @@ EXPORT_SYMBOL(ath10k_core_start);
void ath10k_core_stop(struct ath10k *ar)
{
+ ath10k_debug_stop(ar);
ath10k_htc_stop(&ar->htc);
ath10k_htt_detach(&ar->htt);
ath10k_wmi_detach(ar);
@@ -777,6 +782,7 @@ void ath10k_core_unregister(struct ath10k *ar)
* Otherwise we will fail to submit commands to FW and mac80211 will be
* unhappy about callback failures. */
ath10k_mac_unregister(ar);
+
ath10k_core_free_firmware_files(ar);
}
EXPORT_SYMBOL(ath10k_core_unregister);
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index 09f535a..219d469 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -517,6 +517,15 @@ static const struct file_operations fops_chip_id = {
.llseek = default_llseek,
};
+int ath10k_debug_start(struct ath10k *ar)
+{
+ return 0;
+}
+
+void ath10k_debug_stop(struct ath10k *ar)
+{
+}
+
int ath10k_debug_create(struct ath10k *ar)
{
ar->debug.debugfs_phy = debugfs_create_dir("ath10k",
@@ -541,6 +550,7 @@ int ath10k_debug_create(struct ath10k *ar)
return 0;
}
+
#endif /* CONFIG_ATH10K_DEBUGFS */
#ifdef CONFIG_ATH10K_DEBUG
diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h
index 168140c..9c442a8 100644
--- a/drivers/net/wireless/ath/ath10k/debug.h
+++ b/drivers/net/wireless/ath/ath10k/debug.h
@@ -42,6 +42,8 @@ extern __printf(1, 2) int ath10k_err(const char *fmt, ...);
extern __printf(1, 2) int ath10k_warn(const char *fmt, ...);
#ifdef CONFIG_ATH10K_DEBUGFS
+int ath10k_debug_start(struct ath10k *ar);
+void ath10k_debug_stop(struct ath10k *ar);
int ath10k_debug_create(struct ath10k *ar);
void ath10k_debug_read_service_map(struct ath10k *ar,
void *service_map,
@@ -50,6 +52,15 @@ void ath10k_debug_read_target_stats(struct ath10k *ar,
struct wmi_stats_event *ev);
#else
+int ath10k_debug_start(struct ath10k *ar)
+{
+ return 0;
+}
+
+void ath10k_debug_stop(struct ath10k *ar)
+{
+}
+
static inline int ath10k_debug_create(struct ath10k *ar)
{
return 0;
^ permalink raw reply related
* [PATCH 3/3] ath10k: add htt_stats_enable debugfs file
From: Kalle Valo @ 2013-09-03 8:44 UTC (permalink / raw)
To: ath10k; +Cc: linux-wireless
In-Reply-To: <20130903084302.26199.3538.stgit@localhost6.localdomain6>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath10k/core.h | 3 +
drivers/net/wireless/ath/ath10k/debug.c | 111 ++++++++++++++++++++++++++++++
drivers/net/wireless/ath/ath10k/htt.h | 1
drivers/net/wireless/ath/ath10k/htt_tx.c | 42 +++++++++++
4 files changed, 157 insertions(+)
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
index 174c4b4..22b17d6 100644
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -246,6 +246,9 @@ struct ath10k_debug {
u32 wmi_service_bitmap[WMI_SERVICE_BM_SIZE];
struct completion event_stats_compl;
+
+ unsigned long htt_stats_mask;
+ struct delayed_work htt_stats_dwork;
};
enum ath10k_state {
diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
index 219d469..59615c7 100644
--- a/drivers/net/wireless/ath/ath10k/debug.c
+++ b/drivers/net/wireless/ath/ath10k/debug.c
@@ -21,6 +21,9 @@
#include "core.h"
#include "debug.h"
+/* ms */
+#define ATH10K_DEBUG_HTT_STATS_INTERVAL 1000
+
static int ath10k_printk(const char *level, const char *fmt, ...)
{
struct va_format vaf;
@@ -517,13 +520,115 @@ static const struct file_operations fops_chip_id = {
.llseek = default_llseek,
};
+static int ath10k_debug_htt_stats_req(struct ath10k *ar)
+{
+ u64 cookie;
+ int ret;
+
+ lockdep_assert_held(&ar->conf_mutex);
+
+ if (ar->debug.htt_stats_mask == 0)
+ /* htt stats are disabled */
+ return 0;
+
+ if (ar->state != ATH10K_STATE_ON)
+ return 0;
+
+ cookie = get_jiffies_64();
+
+ ret = ath10k_htt_h2t_stats_req(&ar->htt, ar->debug.htt_stats_mask,
+ cookie);
+ if (ret) {
+ ath10k_warn("failed to send htt stats request: %d\n", ret);
+ return ret;
+ }
+
+ queue_delayed_work(ar->workqueue, &ar->debug.htt_stats_dwork,
+ msecs_to_jiffies(ATH10K_DEBUG_HTT_STATS_INTERVAL));
+
+ return 0;
+}
+
+static void ath10k_debug_htt_stats_dwork(struct work_struct *work)
+{
+ struct ath10k *ar = container_of(work, struct ath10k,
+ debug.htt_stats_dwork.work);
+
+ mutex_lock(&ar->conf_mutex);
+
+ ath10k_debug_htt_stats_req(ar);
+
+ mutex_unlock(&ar->conf_mutex);
+}
+
+static ssize_t ath10k_read_htt_stats_mask(struct file *file,
+ char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath10k *ar = file->private_data;
+ char buf[32];
+ unsigned int len;
+
+ len = scnprintf(buf, sizeof(buf), "%lu\n", ar->debug.htt_stats_mask);
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t ath10k_write_htt_stats_mask(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath10k *ar = file->private_data;
+ unsigned long mask;
+ int ret;
+
+ ret = kstrtoul_from_user(user_buf, count, 0, &mask);
+ if (ret)
+ return ret;
+
+ /* max 8 bit masks (for now) */
+ if (mask > 0xff)
+ return -E2BIG;
+
+ mutex_lock(&ar->conf_mutex);
+
+ ar->debug.htt_stats_mask = mask;
+
+ ret = ath10k_debug_htt_stats_req(ar);
+ if (ret)
+ goto out;
+
+ ret = count;
+
+out:
+ mutex_unlock(&ar->conf_mutex);
+
+ return ret;
+}
+
+static const struct file_operations fops_htt_stats_mask = {
+ .read = ath10k_read_htt_stats_mask,
+ .write = ath10k_write_htt_stats_mask,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
int ath10k_debug_start(struct ath10k *ar)
{
+ int ret;
+
+ ret = ath10k_debug_htt_stats_req(ar);
+ if (ret)
+ /* continue normally anyway, this isn't serious */
+ ath10k_warn("failed to start htt stats workqueue: %d\n", ret);
+
return 0;
}
void ath10k_debug_stop(struct ath10k *ar)
{
+ cancel_delayed_work_sync(&ar->debug.htt_stats_dwork);
}
int ath10k_debug_create(struct ath10k *ar)
@@ -534,6 +639,9 @@ int ath10k_debug_create(struct ath10k *ar)
if (!ar->debug.debugfs_phy)
return -ENOMEM;
+ INIT_DELAYED_WORK(&ar->debug.htt_stats_dwork,
+ ath10k_debug_htt_stats_dwork);
+
init_completion(&ar->debug.event_stats_compl);
debugfs_create_file("fw_stats", S_IRUSR, ar->debug.debugfs_phy, ar,
@@ -548,6 +656,9 @@ int ath10k_debug_create(struct ath10k *ar)
debugfs_create_file("chip_id", S_IRUSR, ar->debug.debugfs_phy,
ar, &fops_chip_id);
+ debugfs_create_file("htt_stats_mask", S_IRUSR, ar->debug.debugfs_phy,
+ ar, &fops_htt_stats_mask);
+
return 0;
}
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
index 26c78a9..e090902 100644
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -1327,6 +1327,7 @@ void ath10k_htt_rx_detach(struct ath10k_htt *htt);
void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb);
void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb);
int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt);
+int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie);
int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt);
void __ath10k_htt_tx_dec_pending(struct ath10k_htt *htt);
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
index d4fb387..b6b1420 100644
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
@@ -203,6 +203,48 @@ int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt)
return 0;
}
+int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie)
+{
+ struct htt_stats_req *req;
+ struct sk_buff *skb;
+ struct htt_cmd *cmd;
+ int len = 0, ret;
+
+ len += sizeof(cmd->hdr);
+ len += sizeof(cmd->stats_req);
+
+ skb = ath10k_htc_alloc_skb(len);
+ if (!skb)
+ return -ENOMEM;
+
+ skb_put(skb, len);
+ cmd = (struct htt_cmd *)skb->data;
+ cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_STATS_REQ;
+
+ req = &cmd->stats_req;
+
+ memset(req, 0, sizeof(*req));
+
+ /* currently we support only max 8 bit masks so no need to worry
+ * about endian support */
+ req->upload_types[0] = mask;
+ req->reset_types[0] = mask;
+ req->stat_type = HTT_STATS_REQ_CFG_STAT_TYPE_INVALID;
+ req->cookie_lsb = cpu_to_le32(cookie & 0xffffffff);
+ req->cookie_msb = cpu_to_le32((cookie & 0xffffffff00000000ULL) >> 32);
+
+ ATH10K_SKB_CB(skb)->htt.is_conf = true;
+
+ ret = ath10k_htc_send(&htt->ar->htc, htt->eid, skb);
+ if (ret) {
+ ath10k_warn("failed to send htt type stats request: %d", ret);
+ dev_kfree_skb_any(skb);
+ return ret;
+ }
+
+ return 0;
+}
+
int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt)
{
struct sk_buff *skb;
^ permalink raw reply related
* Re: WFD Development setup issues
From: Arend van Spriel @ 2013-09-03 11:29 UTC (permalink / raw)
To: HunTERminator Chief; +Cc: linux-wireless
In-Reply-To: <1378162958.1194.YahooMailBasic@web140906.mail.bf1.yahoo.com>
On 09/03/2013 01:02 AM, HunTERminator Chief wrote:
> I have attached the full output to this email.
>
> Can anyone tell me why this is happening? Or otherwise, how to get the ./wpa_supplicant to run properly?
You are trying this with NetworkManager handling wireless interfaces as
well?
> Thanks in advance
>
> -Brian
^ permalink raw reply
* Re: [PATCH 1/2] cw1200: Don't perform SPI transfers in interrupt context
From: Solomon Peachy @ 2013-09-03 11:58 UTC (permalink / raw)
To: linux-wireless
In-Reply-To: <1377649787-2817-1-git-send-email-pizza@shaftnet.org>
[-- Attachment #1: Type: text/plain, Size: 862 bytes --]
On Tue, Aug 27, 2013 at 08:29:46PM -0400, Solomon Peachy wrote:
> When we get an interrupt from the hardware, the first thing the driver does
> is tell the device to mask off the interrupt line. Unfortunately this
> involves a SPI transaction in interrupt context. Some (most?) SPI
> controllers perform the transfer asynchronously and try to sleep.
> This is bad, and triggers a BUG().
Did this patch series get dropped? I saw that the followup series
of minor cleanups were merged into wireless-next, but not these.
Since they didn't make it into 3.11, I intend to submit them to -stable,
but I need to make sure they at least make it into -next.
Thanks,
- Solomon
--
Solomon Peachy pizza at shaftnet dot org
Delray Beach, FL ^^ (email/xmpp) ^^
Quidquid latine dictum sit, altum viditur.
[-- Attachment #2: Type: application/pgp-signature, Size: 190 bytes --]
^ permalink raw reply
* [PATCH 1/2] ath10k: set the UART baud rate to 19200
From: Bartosz Markowski @ 2013-09-03 12:24 UTC (permalink / raw)
To: ath10k; +Cc: linux-wireless, Bartosz Markowski
When configuring the host_interests over BMI, set the UART
baud rate to 19200. This is valid for QCA988X_2.0 devices.
Signed-off-by: Bartosz Markowski <bartosz.markowski@tieto.com>
---
drivers/net/wireless/ath/ath10k/core.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
index 2dd39a8..2c1d2d7 100644
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -435,6 +435,13 @@ static int ath10k_init_uart(struct ath10k *ar)
return ret;
}
+ /* Set the UART baud rate to 19200. */
+ ret = ath10k_bmi_write32(ar, hi_desired_baud_rate, 19200);
+ if (ret) {
+ ath10k_warn("could not set the baud rate (%d)\n", ret);
+ return ret;
+ }
+
ath10k_info("UART prints enabled\n");
return 0;
}
--
1.7.10
^ permalink raw reply related
* [PATCH 2/2] ath10k: remove obsolete INIT STATUS definitions
From: Bartosz Markowski @ 2013-09-03 12:24 UTC (permalink / raw)
To: ath10k; +Cc: linux-wireless, Bartosz Markowski
In-Reply-To: <1378211043-20299-1-git-send-email-bartosz.markowski@tieto.com>
There's no functional changes. Just a small cleanup.
Signed-off-by: Bartosz Markowski <bartosz.markowski@tieto.com>
---
drivers/net/wireless/ath/ath10k/wmi.h | 8 --------
1 file changed, 8 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
index 08860c4..40fcf05 100644
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -763,14 +763,6 @@ struct wmi_service_ready_event {
struct wlan_host_mem_req mem_reqs[1];
} __packed;
-/*
- * status consists of upper 16 bits fo int status and lower 16 bits of
- * module ID that retuned status
- */
-#define WLAN_INIT_STATUS_SUCCESS 0x0
-#define WLAN_GET_INIT_STATUS_REASON(status) ((status) & 0xffff)
-#define WLAN_GET_INIT_STATUS_MODULE_ID(status) (((status) >> 16) & 0xffff)
-
#define WMI_SERVICE_READY_TIMEOUT_HZ (5*HZ)
#define WMI_UNIFIED_READY_TIMEOUT_HZ (5*HZ)
--
1.7.10
^ permalink raw reply related
* ACS compile to hostapd 2.0
From: Andrew Delamare @ 2013-09-03 12:33 UTC (permalink / raw)
To: linux-wireless@vger.kernel.org
Hey there,
So I want to get ACS working and I have looked at your ACS page at: http://wireless.kernel.org/en/users/Documentation/acs
I found there is a patchset that you can use with the ACS code that patches a standard hostapd. So I tried this patch and I am having issues getting ACS to patch into hostapd 2.0. What is the code strand that this patch works on?
Be great to get some help if possible.
Regards
--
Andrew Delamare
Director of Technology
Power Ethernet
07585956748
______________________________________________________________________
This email has been scanned by the Symantec Email Security.cloud service.
For more information please visit http://www.symanteccloud.com
______________________________________________________________________
^ permalink raw reply
* [PATCH] brcmfmac: fix bus interface selection in Kconfig
From: Arend van Spriel @ 2013-09-03 12:46 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, Arend van Spriel, Hauke Mehrtens
The kernel configuration for the driver could result in
compilation issues as reported by Randy Dunlap. His results
are show below:
"on x86_64:
when
CONFIG_MMC=m
CONFIG_BRCMUTIL=y
CONFIG_BRCMFMAC=y
CONFIG_BRCMFMAC_SDIO=y
This bool kconfig symbol:
config BRCMFMAC_SDIO
bool "SDIO bus interface support for FullMAC driver"
depends on MMC
allows BRCMFMAC_SDIO to be y even when MMC=m.
Is there a reasonable solution to this?
This causes many build errors:
drivers/built-in.o: In function `brcmf_sdio_assert_info':
dhd_sdio.c:(.text+0x39609b): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x3960d9): undefined reference to `sdio_release_host'
drivers/built-in.o: In function `brcmf_sdio_readframes':
dhd_sdio.c:(.text+0x396a62): undefined reference to `sdio_claim_host'
dhd_sdio.c:(.text+0x396a9b): undefined reference to `sdio_release_host'
..."
This patch adds the appropriate logic in Kconfig to resolve
these issues. The solution was provided by Hauke Mehrtens.
Reported-by: Randy Dunlap <rdunlap@infradead.org>
Cc: Hauke Mehrtens <hauke@hauke-m.de>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
Hi John,
Probably the merge window has already been started after the surpirse release
of 3.11, but this one was reported by Randy Dunlap on linux-next tree and
earlier today by Fenguang Wu. Maybe good to take it in the wireless-next tree.
Regards,
Arend
---
drivers/net/wireless/brcm80211/Kconfig | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
index fc8a0fa..b00a7e9 100644
--- a/drivers/net/wireless/brcm80211/Kconfig
+++ b/drivers/net/wireless/brcm80211/Kconfig
@@ -28,7 +28,7 @@ config BRCMFMAC
config BRCMFMAC_SDIO
bool "SDIO bus interface support for FullMAC driver"
- depends on MMC
+ depends on (MMC = y || MMC = BRCMFMAC)
depends on BRCMFMAC
select FW_LOADER
default y
@@ -39,7 +39,7 @@ config BRCMFMAC_SDIO
config BRCMFMAC_USB
bool "USB bus interface support for FullMAC driver"
- depends on USB
+ depends on (USB = y || USB = BRCMFMAC)
depends on BRCMFMAC
select FW_LOADER
---help---
--
1.7.10.4
^ permalink raw reply related
* [PATCH] rt2x00: Add WLI-UC-G300HP's Product ID
From: Masami Ichikawa @ 2013-09-03 12:51 UTC (permalink / raw)
To: kvalo, IvDoorn, gwingerde, helmut.schaa, linville
Cc: Masami Ichikawa, linux-wireless, users, netdev, linux-kernel
Support Bufallo WLI-UC-G300HP.
Signed-off-by: Masami Ichikawa <masami256@gmail.com>
---
drivers/net/wireless/rt2x00/rt2800usb.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 840833b..518277d 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -977,6 +977,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
{ USB_DEVICE(0x0411, 0x016f) },
{ USB_DEVICE(0x0411, 0x01a2) },
{ USB_DEVICE(0x0411, 0x01ee) },
+ { USB_DEVICE(0x0411, 0x01a8) },
/* Corega */
{ USB_DEVICE(0x07aa, 0x002f) },
{ USB_DEVICE(0x07aa, 0x003c) },
--
1.8.3.1
^ permalink raw reply related
* Re: ACS compile to hostapd 2.0
From: Michal Kazior @ 2013-09-03 12:53 UTC (permalink / raw)
To: Andrew Delamare; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <7f4ff1930bfc4f3b8160b1595950c5a1@THHSTE15D1BE3.hs20.net>
On 3 September 2013 14:33, Andrew Delamare
<andrew.delamare@powerethernet.com> wrote:
> Hey there,
>
> So I want to get ACS working and I have looked at your ACS page at: http://wireless.kernel.org/en/users/Documentation/acs
>
> I found there is a patchset that you can use with the ACS code that patches a standard hostapd. So I tried this patch and I am having issues getting ACS to patch into hostapd 2.0. What is the code strand that this patch works on?
Hi,
ACS has been merged into hostapd master branch 3 days ago so you can
try pulling that.
The patch on the aforementioned page probably doesn't apply on a 2.0
release as-is.
Michał.
^ permalink raw reply
* [PATCH] ath10k: prevent CE from looping indefinitely
From: Michal Kazior @ 2013-09-03 13:09 UTC (permalink / raw)
To: ath10k; +Cc: linux-wireless, Michal Kazior
The double while() could end up running forever.
Inner while() would complete very fast. However
the completion processing could take enough time
for more completions to flow in. In that case the
outer while() would not terminate and run again,
and again. This could happen especially on a slow
host system.
This could lead to a system freeze during heavy
traffic. Note: this doesn't solve all known
starvation issues yet.
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
---
drivers/net/wireless/ath/ath10k/ce.c | 57 ++++------------------
drivers/net/wireless/ath/ath10k/ce.h | 26 ++--------
drivers/net/wireless/ath/ath10k/pci.c | 84 +++++++++++++++------------------
3 files changed, 52 insertions(+), 115 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
index afe5df4..924b29e 100644
--- a/drivers/net/wireless/ath/ath10k/ce.c
+++ b/drivers/net/wireless/ath/ath10k/ce.c
@@ -742,11 +742,6 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id)
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
u32 ctrl_addr = ce_state->ctrl_addr;
- void *transfer_context;
- u32 buf;
- unsigned int nbytes;
- unsigned int id;
- unsigned int flags;
int ret;
ret = ath10k_pci_wake(ar);
@@ -759,38 +754,15 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id)
ath10k_ce_engine_int_status_clear(ar, ctrl_addr,
HOST_IS_COPY_COMPLETE_MASK);
- if (ce_state->recv_cb) {
- /*
- * Pop completed recv buffers and call the registered
- * recv callback for each
- */
- while (ath10k_ce_completed_recv_next_nolock(ce_state,
- &transfer_context,
- &buf, &nbytes,
- &id, &flags) == 0) {
- spin_unlock_bh(&ar_pci->ce_lock);
- ce_state->recv_cb(ce_state, transfer_context, buf,
- nbytes, id, flags);
- spin_lock_bh(&ar_pci->ce_lock);
- }
- }
+ spin_unlock_bh(&ar_pci->ce_lock);
- if (ce_state->send_cb) {
- /*
- * Pop completed send buffers and call the registered
- * send callback for each
- */
- while (ath10k_ce_completed_send_next_nolock(ce_state,
- &transfer_context,
- &buf,
- &nbytes,
- &id) == 0) {
- spin_unlock_bh(&ar_pci->ce_lock);
- ce_state->send_cb(ce_state, transfer_context,
- buf, nbytes, id);
- spin_lock_bh(&ar_pci->ce_lock);
- }
- }
+ if (ce_state->recv_cb)
+ ce_state->recv_cb(ce_state);
+
+ if (ce_state->send_cb)
+ ce_state->send_cb(ce_state);
+
+ spin_lock_bh(&ar_pci->ce_lock);
/*
* Misc CE interrupts are not being handled, but still need
@@ -881,11 +853,7 @@ void ath10k_ce_disable_interrupts(struct ath10k *ar)
}
void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state,
- void (*send_cb)(struct ath10k_ce_pipe *ce_state,
- void *transfer_context,
- u32 buffer,
- unsigned int nbytes,
- unsigned int transfer_id),
+ void (*send_cb)(struct ath10k_ce_pipe *),
int disable_interrupts)
{
struct ath10k *ar = ce_state->ar;
@@ -898,12 +866,7 @@ void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state,
}
void ath10k_ce_recv_cb_register(struct ath10k_ce_pipe *ce_state,
- void (*recv_cb)(struct ath10k_ce_pipe *ce_state,
- void *transfer_context,
- u32 buffer,
- unsigned int nbytes,
- unsigned int transfer_id,
- unsigned int flags))
+ void (*recv_cb)(struct ath10k_ce_pipe *))
{
struct ath10k *ar = ce_state->ar;
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
diff --git a/drivers/net/wireless/ath/ath10k/ce.h b/drivers/net/wireless/ath/ath10k/ce.h
index cfef7d0..fb22361 100644
--- a/drivers/net/wireless/ath/ath10k/ce.h
+++ b/drivers/net/wireless/ath/ath10k/ce.h
@@ -116,17 +116,8 @@ struct ath10k_ce_pipe {
u32 ctrl_addr;
- void (*send_cb) (struct ath10k_ce_pipe *ce_state,
- void *per_transfer_send_context,
- u32 buffer,
- unsigned int nbytes,
- unsigned int transfer_id);
- void (*recv_cb) (struct ath10k_ce_pipe *ce_state,
- void *per_transfer_recv_context,
- u32 buffer,
- unsigned int nbytes,
- unsigned int transfer_id,
- unsigned int flags);
+ void (*send_cb)(struct ath10k_ce_pipe *);
+ void (*recv_cb)(struct ath10k_ce_pipe *);
unsigned int src_sz_max;
struct ath10k_ce_ring *src_ring;
@@ -181,11 +172,7 @@ int ath10k_ce_send(struct ath10k_ce_pipe *ce_state,
unsigned int flags);
void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state,
- void (*send_cb)(struct ath10k_ce_pipe *ce_state,
- void *transfer_context,
- u32 buffer,
- unsigned int nbytes,
- unsigned int transfer_id),
+ void (*send_cb)(struct ath10k_ce_pipe *),
int disable_interrupts);
/* Append a simple buffer (address/length) to a sendlist. */
@@ -228,12 +215,7 @@ int ath10k_ce_recv_buf_enqueue(struct ath10k_ce_pipe *ce_state,
u32 buffer);
void ath10k_ce_recv_cb_register(struct ath10k_ce_pipe *ce_state,
- void (*recv_cb)(struct ath10k_ce_pipe *ce_state,
- void *transfer_context,
- u32 buffer,
- unsigned int nbytes,
- unsigned int transfer_id,
- unsigned int flags));
+ void (*recv_cb)(struct ath10k_ce_pipe *));
/* recv flags */
/* Data is byte-swapped */
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 622901d..d3c5d47 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -612,19 +612,20 @@ exit:
}
/* Called by lower (CE) layer when a send to Target completes. */
-static void ath10k_pci_ce_send_done(struct ath10k_ce_pipe *ce_state,
- void *transfer_context,
- u32 ce_data,
- unsigned int nbytes,
- unsigned int transfer_id)
+static void ath10k_pci_ce_send_done(struct ath10k_ce_pipe *ce_state)
{
struct ath10k *ar = ce_state->ar;
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
struct ath10k_pci_pipe *pipe_info = &ar_pci->pipe_info[ce_state->id];
struct ath10k_pci_compl *compl;
- bool process = false;
+ void *transfer_context;
+ u32 ce_data;
+ unsigned int nbytes;
+ unsigned int transfer_id;
- do {
+ while (ath10k_ce_completed_send_next(ce_state, &transfer_context,
+ &ce_data, &nbytes,
+ &transfer_id) == 0) {
/*
* For the send completion of an item in sendlist, just
* increment num_sends_allowed. The upper layer callback will
@@ -655,38 +656,28 @@ static void ath10k_pci_ce_send_done(struct ath10k_ce_pipe *ce_state,
spin_lock_bh(&ar_pci->compl_lock);
list_add_tail(&compl->list, &ar_pci->compl_process);
spin_unlock_bh(&ar_pci->compl_lock);
-
- process = true;
- } while (ath10k_ce_completed_send_next(ce_state,
- &transfer_context,
- &ce_data, &nbytes,
- &transfer_id) == 0);
-
- /*
- * If only some of the items within a sendlist have completed,
- * don't invoke completion processing until the entire sendlist
- * has been sent.
- */
- if (!process)
- return;
+ }
ath10k_pci_process_ce(ar);
}
/* Called by lower (CE) layer when data is received from the Target. */
-static void ath10k_pci_ce_recv_data(struct ath10k_ce_pipe *ce_state,
- void *transfer_context, u32 ce_data,
- unsigned int nbytes,
- unsigned int transfer_id,
- unsigned int flags)
+static void ath10k_pci_ce_recv_data(struct ath10k_ce_pipe *ce_state)
{
struct ath10k *ar = ce_state->ar;
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
struct ath10k_pci_pipe *pipe_info = &ar_pci->pipe_info[ce_state->id];
struct ath10k_pci_compl *compl;
struct sk_buff *skb;
+ void *transfer_context;
+ u32 ce_data;
+ unsigned int nbytes;
+ unsigned int transfer_id;
+ unsigned int flags;
- do {
+ while (ath10k_ce_completed_recv_next(ce_state, &transfer_context,
+ &ce_data, &nbytes, &transfer_id,
+ &flags) == 0) {
compl = get_free_compl(pipe_info);
if (!compl)
break;
@@ -709,12 +700,7 @@ static void ath10k_pci_ce_recv_data(struct ath10k_ce_pipe *ce_state,
spin_lock_bh(&ar_pci->compl_lock);
list_add_tail(&compl->list, &ar_pci->compl_process);
spin_unlock_bh(&ar_pci->compl_lock);
-
- } while (ath10k_ce_completed_recv_next(ce_state,
- &transfer_context,
- &ce_data, &nbytes,
- &transfer_id,
- &flags) == 0);
+ }
ath10k_pci_process_ce(ar);
}
@@ -1490,13 +1476,16 @@ err_dma:
return ret;
}
-static void ath10k_pci_bmi_send_done(struct ath10k_ce_pipe *ce_state,
- void *transfer_context,
- u32 data,
- unsigned int nbytes,
- unsigned int transfer_id)
+static void ath10k_pci_bmi_send_done(struct ath10k_ce_pipe *ce_state)
{
- struct bmi_xfer *xfer = transfer_context;
+ struct bmi_xfer *xfer;
+ u32 ce_data;
+ unsigned int nbytes;
+ unsigned int transfer_id;
+
+ if (ath10k_ce_completed_send_next(ce_state, (void **)&xfer, &ce_data,
+ &nbytes, &transfer_id))
+ return;
if (xfer->wait_for_resp)
return;
@@ -1504,14 +1493,17 @@ static void ath10k_pci_bmi_send_done(struct ath10k_ce_pipe *ce_state,
complete(&xfer->done);
}
-static void ath10k_pci_bmi_recv_data(struct ath10k_ce_pipe *ce_state,
- void *transfer_context,
- u32 data,
- unsigned int nbytes,
- unsigned int transfer_id,
- unsigned int flags)
+static void ath10k_pci_bmi_recv_data(struct ath10k_ce_pipe *ce_state)
{
- struct bmi_xfer *xfer = transfer_context;
+ struct bmi_xfer *xfer;
+ u32 ce_data;
+ unsigned int nbytes;
+ unsigned int transfer_id;
+ unsigned int flags;
+
+ if (ath10k_ce_completed_recv_next(ce_state, (void **)&xfer, &ce_data,
+ &nbytes, &transfer_id, &flags))
+ return;
if (!xfer->wait_for_resp) {
ath10k_warn("unexpected: BMI data received; ignoring\n");
--
1.7.9.5
^ permalink raw reply related
* RE: ACS compile to hostapd 2.0
From: Andrew Delamare @ 2013-09-03 14:26 UTC (permalink / raw)
To: Michal Kazior; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <CA+BoTQn7nhsDxedekMTZ9ZqFyo55zR3iGPuTYvVqELGYGh5njg@mail.gmail.com>
SGV5IE1pY2hhbCwKClRoYW5rcyBmb3IgdGhlIHN1cGVyIHNwZWVkeSByZXNwb25zZS4KCldoaWNo
IHJlcG9zaXRvcnkgaXMgdGhhdCBpbj8gCgpJZiB5b3UgY291bGQgcG9pbnQgbWUgdG8gdGhlIHJp
Z2h0IEdpdCByZXBvc2l0b3J5IG9yIGZ0cCBkb3dubG9hZCB0aGF0IHdvdWxkIGJlIGdyZWF0LgoK
ClJlZ2FyZHMKLS0KQW5kcmV3IERlbGFtYXJlCkRpcmVjdG9yIE9mIFRlY2hub2xvZ3kKUG93ZXIg
RXRoZXJuZXQgTHRkCjA3NTg1OTU2NzQ4CgoKCi0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0tCkZy
b206IE1pY2hhbCBLYXppb3IgW21haWx0bzptaWNoYWwua2F6aW9yQHRpZXRvLmNvbV0gClNlbnQ6
IFR1ZXNkYXksIFNlcHRlbWJlciAzLCAyMDEzIDE6NTMgUE0KVG86IEFuZHJldyBEZWxhbWFyZQpD
YzogbGludXgtd2lyZWxlc3NAdmdlci5rZXJuZWwub3JnClN1YmplY3Q6IFJlOiBBQ1MgY29tcGls
ZSB0byBob3N0YXBkIDIuMAoKT24gMyBTZXB0ZW1iZXIgMjAxMyAxNDozMywgQW5kcmV3IERlbGFt
YXJlIDxhbmRyZXcuZGVsYW1hcmVAcG93ZXJldGhlcm5ldC5jb20+IHdyb3RlOgo+IEhleSB0aGVy
ZSwKPgo+IFNvIEkgd2FudCB0byBnZXQgQUNTIHdvcmtpbmcgYW5kIEkgaGF2ZSBsb29rZWQgYXQg
eW91ciBBQ1MgcGFnZSBhdDogCj4gaHR0cDovL3dpcmVsZXNzLmtlcm5lbC5vcmcvZW4vdXNlcnMv
RG9jdW1lbnRhdGlvbi9hY3MKPgo+IEkgZm91bmQgdGhlcmUgaXMgYSBwYXRjaHNldCB0aGF0IHlv
dSBjYW4gdXNlIHdpdGggdGhlIEFDUyBjb2RlIHRoYXQgcGF0Y2hlcyBhIHN0YW5kYXJkIGhvc3Rh
cGQuIFNvIEkgdHJpZWQgdGhpcyBwYXRjaCBhbmQgSSBhbSBoYXZpbmcgaXNzdWVzIGdldHRpbmcg
QUNTIHRvIHBhdGNoIGludG8gaG9zdGFwZCAyLjAuIFdoYXQgaXMgdGhlIGNvZGUgc3RyYW5kIHRo
YXQgdGhpcyBwYXRjaCB3b3JrcyBvbj8KCkhpLAoKQUNTIGhhcyBiZWVuIG1lcmdlZCBpbnRvIGhv
c3RhcGQgbWFzdGVyIGJyYW5jaCAzIGRheXMgYWdvIHNvIHlvdSBjYW4gdHJ5IHB1bGxpbmcgdGhh
dC4KClRoZSBwYXRjaCBvbiB0aGUgYWZvcmVtZW50aW9uZWQgcGFnZSBwcm9iYWJseSBkb2Vzbid0
IGFwcGx5IG9uIGEgMi4wIHJlbGVhc2UgYXMtaXMuCgoKTWljaGHFgi4KCl9fX19fX19fX19fX19f
X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18K
VGhpcyBlbWFpbCBoYXMgYmVlbiBzY2FubmVkIGJ5IHRoZSBTeW1hbnRlYyBFbWFpbCBTZWN1cml0
eS5jbG91ZCBzZXJ2aWNlLgpGb3IgbW9yZSBpbmZvcm1hdGlvbiBwbGVhc2UgdmlzaXQgaHR0cDov
L3d3dy5zeW1hbnRlY2Nsb3VkLmNvbSBfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f
X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCgpfX19fX19fX19fX19fX19fX19f
X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fClRoaXMg
ZW1haWwgaGFzIGJlZW4gc2Nhbm5lZCBieSB0aGUgU3ltYW50ZWMgRW1haWwgU2VjdXJpdHkuY2xv
dWQgc2VydmljZS4KRm9yIG1vcmUgaW5mb3JtYXRpb24gcGxlYXNlIHZpc2l0IGh0dHA6Ly93d3cu
c3ltYW50ZWNjbG91ZC5jb20KX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f
X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwo=
^ permalink raw reply
* [PATCH 01/12] wlcore: ROC on AP channel before auth reply
From: Eliad Peller @ 2013-09-03 14:33 UTC (permalink / raw)
To: Luciano Coelho; +Cc: linux-wireless
From: Arik Nemtsov <arik@wizery.com>
Start a ROC on the AP channel beforing sending the authentication reply
to a connecting STA. This ROC is held up to 1 second via a timer. If the
station is authorized and added by mac80211, the ROC is extended until
the station is fully authorized.
We make sure not to ROC twice when several stations are connecting in
parallel and to only release the ROC when both the pending-reply timer
and the STA-state callbacks do not require it.
Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
drivers/net/wireless/ti/wlcore/main.c | 101 +++++++++++++++++++++++++-----
drivers/net/wireless/ti/wlcore/tx.c | 25 ++++++--
drivers/net/wireless/ti/wlcore/tx.h | 3 +
drivers/net/wireless/ti/wlcore/wlcore.h | 2 +
drivers/net/wireless/ti/wlcore/wlcore_i.h | 9 +++
5 files changed, 120 insertions(+), 20 deletions(-)
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 38995f9..b64b465 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -2008,6 +2008,47 @@ out:
mutex_unlock(&wl->mutex);
}
+static void wlcore_pending_auth_complete_work(struct work_struct *work)
+{
+ struct delayed_work *dwork;
+ struct wl1271 *wl;
+ struct wl12xx_vif *wlvif;
+ unsigned long time_spare;
+ int ret;
+
+ dwork = container_of(work, struct delayed_work, work);
+ wlvif = container_of(dwork, struct wl12xx_vif,
+ pending_auth_complete_work);
+ wl = wlvif->wl;
+
+ mutex_lock(&wl->mutex);
+
+ if (unlikely(wl->state != WLCORE_STATE_ON))
+ goto out;
+
+ /*
+ * Make sure a second really passed since the last auth reply. Maybe
+ * a second auth reply arrived while we were stuck on the mutex.
+ * Check for a little less than the timeout to protect from scheduler
+ * irregularities.
+ */
+ time_spare = jiffies +
+ msecs_to_jiffies(WLCORE_PEND_AUTH_ROC_TIMEOUT - 50);
+ if (!time_after(time_spare, wlvif->pending_auth_reply_time))
+ goto out;
+
+ ret = wl1271_ps_elp_wakeup(wl);
+ if (ret < 0)
+ goto out;
+
+ /* cancel the ROC if active */
+ wlcore_update_inconn_sta(wl, wlvif, NULL, false);
+
+ wl1271_ps_elp_sleep(wl);
+out:
+ mutex_unlock(&wl->mutex);
+}
+
static int wl12xx_allocate_rate_policy(struct wl1271 *wl, u8 *idx)
{
u8 policy = find_first_zero_bit(wl->rate_policies_map,
@@ -2159,6 +2200,8 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif)
wlcore_channel_switch_work);
INIT_DELAYED_WORK(&wlvif->connection_loss_work,
wlcore_connection_loss_work);
+ INIT_DELAYED_WORK(&wlvif->pending_auth_complete_work,
+ wlcore_pending_auth_complete_work);
INIT_LIST_HEAD(&wlvif->list);
setup_timer(&wlvif->rx_streaming_timer, wl1271_rx_streaming_timer,
@@ -2590,6 +2633,7 @@ unlock:
cancel_work_sync(&wlvif->rx_streaming_disable_work);
cancel_delayed_work_sync(&wlvif->connection_loss_work);
cancel_delayed_work_sync(&wlvif->channel_switch_work);
+ cancel_delayed_work_sync(&wlvif->pending_auth_complete_work);
mutex_lock(&wl->mutex);
}
@@ -3969,6 +4013,13 @@ static void wl1271_bss_info_changed_ap(struct wl1271 *wl,
}
} else {
if (test_bit(WLVIF_FLAG_AP_STARTED, &wlvif->flags)) {
+ /*
+ * AP might be in ROC in case we have just
+ * sent auth reply. handle it.
+ */
+ if (test_bit(wlvif->role_id, wl->roc_map))
+ wl12xx_croc(wl, wlvif->role_id);
+
ret = wl12xx_cmd_role_stop_ap(wl, wlvif);
if (ret < 0)
goto out;
@@ -4656,29 +4707,49 @@ static void wlcore_roc_if_possible(struct wl1271 *wl,
wl12xx_roc(wl, wlvif, wlvif->role_id, wlvif->band, wlvif->channel);
}
-static void wlcore_update_inconn_sta(struct wl1271 *wl,
- struct wl12xx_vif *wlvif,
- struct wl1271_station *wl_sta,
- bool in_connection)
+/*
+ * when wl_sta is NULL, we treat this call as if coming from a
+ * pending auth reply.
+ * wl->mutex must be taken and the FW must be awake when the call
+ * takes place.
+ */
+void wlcore_update_inconn_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+ struct wl1271_station *wl_sta, bool in_conn)
{
- if (in_connection) {
- if (WARN_ON(wl_sta->in_connection))
+ if (in_conn) {
+ if (WARN_ON(wl_sta && wl_sta->in_connection))
return;
- wl_sta->in_connection = true;
- if (!wlvif->inconn_count++)
+
+ if (!wlvif->ap_pending_auth_reply &&
+ !wlvif->inconn_count)
wlcore_roc_if_possible(wl, wlvif);
+
+ if (wl_sta) {
+ wl_sta->in_connection = true;
+ wlvif->inconn_count++;
+ } else {
+ wlvif->ap_pending_auth_reply = true;
+ }
} else {
- if (!wl_sta->in_connection)
+ if (wl_sta && !wl_sta->in_connection)
+ return;
+
+ if (WARN_ON(!wl_sta && !wlvif->ap_pending_auth_reply))
return;
- wl_sta->in_connection = false;
- wlvif->inconn_count--;
- if (WARN_ON(wlvif->inconn_count < 0))
+ if (WARN_ON(wl_sta && !wlvif->inconn_count))
return;
- if (!wlvif->inconn_count)
- if (test_bit(wlvif->role_id, wl->roc_map))
- wl12xx_croc(wl, wlvif->role_id);
+ if (wl_sta) {
+ wl_sta->in_connection = false;
+ wlvif->inconn_count--;
+ } else {
+ wlvif->ap_pending_auth_reply = false;
+ }
+
+ if (!wlvif->inconn_count && !wlvif->ap_pending_auth_reply &&
+ test_bit(wlvif->role_id, wl->roc_map))
+ wl12xx_croc(wl, wlvif->role_id);
}
}
diff --git a/drivers/net/wireless/ti/wlcore/tx.c b/drivers/net/wireless/ti/wlcore/tx.c
index 7e93fe6..03249da 100644
--- a/drivers/net/wireless/ti/wlcore/tx.c
+++ b/drivers/net/wireless/ti/wlcore/tx.c
@@ -86,19 +86,34 @@ void wl1271_free_tx_id(struct wl1271 *wl, int id)
EXPORT_SYMBOL(wl1271_free_tx_id);
static void wl1271_tx_ap_update_inconnection_sta(struct wl1271 *wl,
+ struct wl12xx_vif *wlvif,
struct sk_buff *skb)
{
struct ieee80211_hdr *hdr;
+ hdr = (struct ieee80211_hdr *)(skb->data +
+ sizeof(struct wl1271_tx_hw_descr));
+ if (!ieee80211_is_auth(hdr->frame_control))
+ return;
+
/*
* add the station to the known list before transmitting the
* authentication response. this way it won't get de-authed by FW
* when transmitting too soon.
*/
- hdr = (struct ieee80211_hdr *)(skb->data +
- sizeof(struct wl1271_tx_hw_descr));
- if (ieee80211_is_auth(hdr->frame_control))
- wl1271_acx_set_inconnection_sta(wl, hdr->addr1);
+ wl1271_acx_set_inconnection_sta(wl, hdr->addr1);
+
+ /*
+ * ROC for 1 second on the AP channel for completing the connection.
+ * Note the ROC will be continued by the update_sta_state callbacks
+ * once the station reaches the associated state.
+ */
+ wlcore_update_inconn_sta(wl, wlvif, NULL, true);
+ wlvif->pending_auth_reply_time = jiffies;
+ cancel_delayed_work(&wlvif->pending_auth_complete_work);
+ ieee80211_queue_delayed_work(wl->hw,
+ &wlvif->pending_auth_complete_work,
+ msecs_to_jiffies(WLCORE_PEND_AUTH_ROC_TIMEOUT));
}
static void wl1271_tx_regulate_link(struct wl1271 *wl,
@@ -404,7 +419,7 @@ static int wl1271_prepare_tx_frame(struct wl1271 *wl, struct wl12xx_vif *wlvif,
wl1271_tx_fill_hdr(wl, wlvif, skb, extra, info, hlid);
if (!is_dummy && wlvif && wlvif->bss_type == BSS_TYPE_AP_BSS) {
- wl1271_tx_ap_update_inconnection_sta(wl, skb);
+ wl1271_tx_ap_update_inconnection_sta(wl, wlvif, skb);
wl1271_tx_regulate_link(wl, wlvif, hlid);
}
diff --git a/drivers/net/wireless/ti/wlcore/tx.h b/drivers/net/wireless/ti/wlcore/tx.h
index 55aa4ac..35489c3 100644
--- a/drivers/net/wireless/ti/wlcore/tx.h
+++ b/drivers/net/wireless/ti/wlcore/tx.h
@@ -56,6 +56,9 @@
/* Used for management frames and dummy packets */
#define WL1271_TID_MGMT 7
+/* stop a ROC for pending authentication reply after this time (ms) */
+#define WLCORE_PEND_AUTH_ROC_TIMEOUT 1000
+
struct wl127x_tx_mem {
/*
* Number of extra memory blocks to allocate for this packet
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index 0034979..54ce5d5 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -481,6 +481,8 @@ int wlcore_set_key(struct wl1271 *wl, enum set_key_cmd cmd,
struct ieee80211_sta *sta,
struct ieee80211_key_conf *key_conf);
void wlcore_regdomain_config(struct wl1271 *wl);
+void wlcore_update_inconn_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+ struct wl1271_station *wl_sta, bool in_conn);
static inline void
wlcore_set_ht_cap(struct wl1271 *wl, enum ieee80211_band band,
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index e5e1464..14fd111 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -456,6 +456,15 @@ struct wl12xx_vif {
*/
int hw_queue_base;
+ /* do we have a pending auth reply? (and ROC) */
+ bool ap_pending_auth_reply;
+
+ /* time when we sent the pending auth reply */
+ unsigned long pending_auth_reply_time;
+
+ /* work for canceling ROC after pending auth reply */
+ struct delayed_work pending_auth_complete_work;
+
/*
* This struct must be last!
* data that has to be saved acrossed reconfigs (e.g. recovery)
--
1.8.3.rc1.35.g9b79519
^ permalink raw reply related
* [PATCH 02/12] wlcore: add new plt power-mode: CHIP_AWAKE
From: Eliad Peller @ 2013-09-03 14:33 UTC (permalink / raw)
To: Luciano Coelho; +Cc: linux-wireless
In-Reply-To: <1378218848-7853-1-git-send-email-eliad@wizery.com>
From: Yair Shapira <yair.shapira@ti.com>
Under this mode the chip is powered on including sdio
but no FW is downloaded and run, interrupts are not enabled, etc...
This mode is intended to allow RTTT to bridge sdio as a transport
to the chip.
Driver only provides sdio access using the dev_mem debugfs file.
Some fixes done to the code that ensures that PLT mode and normal
driver power mode (ifconfig/add_interface) are mutually excluded.
Signed-off-by: Yair Shapira <yair.shapira@ti.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
drivers/net/wireless/ti/wlcore/main.c | 16 ++++++++++++----
drivers/net/wireless/ti/wlcore/testmode.c | 13 +++++++++++--
drivers/net/wireless/ti/wlcore/wlcore_i.h | 1 +
3 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index b64b465..611e81d 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -1062,7 +1062,8 @@ int wl1271_plt_start(struct wl1271 *wl, const enum plt_mode plt_mode)
static const char* const PLT_MODE[] = {
"PLT_OFF",
"PLT_ON",
- "PLT_FEM_DETECT"
+ "PLT_FEM_DETECT",
+ "PLT_CHIP_AWAKE"
};
int ret;
@@ -1088,9 +1089,11 @@ int wl1271_plt_start(struct wl1271 *wl, const enum plt_mode plt_mode)
if (ret < 0)
goto power_off;
- ret = wl->ops->plt_init(wl);
- if (ret < 0)
- goto power_off;
+ if (plt_mode != PLT_CHIP_AWAKE) {
+ ret = wl->ops->plt_init(wl);
+ if (ret < 0)
+ goto power_off;
+ }
wl->state = WLCORE_STATE_ON;
wl1271_notice("firmware booted in PLT mode %s (%s)",
@@ -2419,6 +2422,11 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
int ret = 0;
u8 role_type;
+ if (wl->plt) {
+ wl1271_error("Adding Interface not allowed while in PLT mode");
+ return -EBUSY;
+ }
+
vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
IEEE80211_VIF_SUPPORTS_CQM_RSSI;
diff --git a/drivers/net/wireless/ti/wlcore/testmode.c b/drivers/net/wireless/ti/wlcore/testmode.c
index 527590f..a3b7d95 100644
--- a/drivers/net/wireless/ti/wlcore/testmode.c
+++ b/drivers/net/wireless/ti/wlcore/testmode.c
@@ -297,7 +297,8 @@ static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[])
ret = wl1271_plt_stop(wl);
break;
case PLT_ON:
- ret = wl1271_plt_start(wl, PLT_ON);
+ case PLT_CHIP_AWAKE:
+ ret = wl1271_plt_start(wl, val);
break;
case PLT_FEM_DETECT:
ret = wl1271_tm_detect_fem(wl, tb);
@@ -361,6 +362,7 @@ int wl1271_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
{
struct wl1271 *wl = hw->priv;
struct nlattr *tb[WL1271_TM_ATTR_MAX + 1];
+ u32 nla_cmd;
int err;
err = nla_parse(tb, WL1271_TM_ATTR_MAX, data, len, wl1271_tm_policy);
@@ -370,7 +372,14 @@ int wl1271_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
if (!tb[WL1271_TM_ATTR_CMD_ID])
return -EINVAL;
- switch (nla_get_u32(tb[WL1271_TM_ATTR_CMD_ID])) {
+ nla_cmd = nla_get_u32(tb[WL1271_TM_ATTR_CMD_ID]);
+
+ /* Only SET_PLT_MODE is allowed in case of mode PLT_CHIP_AWAKE */
+ if (wl->plt_mode == PLT_CHIP_AWAKE &&
+ nla_cmd != WL1271_TM_CMD_SET_PLT_MODE)
+ return -EOPNOTSUPP;
+
+ switch (nla_cmd) {
case WL1271_TM_CMD_TEST:
return wl1271_tm_cmd_test(wl, tb);
case WL1271_TM_CMD_INTERROGATE:
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index 14fd111..3f4f08b 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -307,6 +307,7 @@ enum plt_mode {
PLT_OFF = 0,
PLT_ON = 1,
PLT_FEM_DETECT = 2,
+ PLT_CHIP_AWAKE = 3
};
struct wl12xx_rx_filter_field {
--
1.8.3.rc1.35.g9b79519
^ permalink raw reply related
* [PATCH 03/12] wlcore: disable elp sleep while in plt mode
From: Eliad Peller @ 2013-09-03 14:33 UTC (permalink / raw)
To: Luciano Coelho; +Cc: linux-wireless
In-Reply-To: <1378218848-7853-1-git-send-email-eliad@wizery.com>
From: Yair Shapira <yair.shapira@ti.com>
We now disable elp sleep during plt mode to allow normal operation of
plt tools such as calibrator.
Having elp_sleep enabled during plt mode is actually not required and
in fact it disrupt plt operations such as rx statistics etc.
Signed-off-by: Yair Shapira <yair.shapira@ti.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
drivers/net/wireless/ti/wlcore/ps.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/wireless/ti/wlcore/ps.c b/drivers/net/wireless/ti/wlcore/ps.c
index 98066d4..26bfc36 100644
--- a/drivers/net/wireless/ti/wlcore/ps.c
+++ b/drivers/net/wireless/ti/wlcore/ps.c
@@ -83,6 +83,10 @@ void wl1271_ps_elp_sleep(struct wl1271 *wl)
struct wl12xx_vif *wlvif;
u32 timeout;
+ /* We do not enter elp sleep in PLT mode */
+ if (wl->plt)
+ return;
+
if (wl->sleep_auth != WL1271_PSM_ELP)
return;
--
1.8.3.rc1.35.g9b79519
^ permalink raw reply related
* [PATCH 04/12] wlcore: re-enable idle handling
From: Eliad Peller @ 2013-09-03 14:34 UTC (permalink / raw)
To: Luciano Coelho; +Cc: linux-wireless
In-Reply-To: <1378218848-7853-1-git-send-email-eliad@wizery.com>
From: Arik Nemtsov <arik@wizery.com>
We need some stuff done on idle change, most notably we have to stop
sched-scanning. Take care of this by reintroducing idle handling.
Signed-off-by: Arik Nemtsov <arik@wizery.com>
Signed-off-by: Eliad Peller <eliad@wizery.com>
---
drivers/net/wireless/ti/wlcore/main.c | 22 ++++++++++++++++++++++
drivers/net/wireless/ti/wlcore/wlcore_i.h | 1 +
2 files changed, 23 insertions(+)
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 611e81d..d952593 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -2927,6 +2927,25 @@ static void wl1271_set_band_rate(struct wl1271 *wl, struct wl12xx_vif *wlvif)
wlvif->rate_set = wlvif->basic_rate_set;
}
+static void wl1271_sta_handle_idle(struct wl1271 *wl, struct wl12xx_vif *wlvif,
+ bool idle)
+{
+ bool cur_idle = !test_bit(WLVIF_FLAG_ACTIVE, &wlvif->flags);
+
+ if (idle == cur_idle)
+ return;
+
+ if (idle) {
+ clear_bit(WLVIF_FLAG_ACTIVE, &wlvif->flags);
+ } else {
+ /* The current firmware only supports sched_scan in idle */
+ if (wl->sched_vif == wlvif)
+ wl->ops->sched_scan_stop(wl, wlvif);
+
+ set_bit(WLVIF_FLAG_ACTIVE, &wlvif->flags);
+ }
+}
+
static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif,
struct ieee80211_conf *conf, u32 changed)
{
@@ -4179,6 +4198,9 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
do_join = true;
}
+ if (changed & BSS_CHANGED_IDLE && !is_ibss)
+ wl1271_sta_handle_idle(wl, wlvif, bss_conf->idle);
+
if (changed & BSS_CHANGED_CQM) {
bool enable = false;
if (bss_conf->cqm_rssi_thold)
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index 3f4f08b..2a50e08 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -255,6 +255,7 @@ enum wl12xx_vif_flags {
WLVIF_FLAG_CS_PROGRESS,
WLVIF_FLAG_AP_PROBE_RESP_SET,
WLVIF_FLAG_IN_USE,
+ WLVIF_FLAG_ACTIVE,
};
struct wl12xx_vif;
--
1.8.3.rc1.35.g9b79519
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox