* [PATCH] mac80211_hwsim: Claim support for TDLS
From: Jouni Malinen @ 2011-10-23 19:45 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless
Signed-off-by: Jouni Malinen <j@w1.fi>
---
drivers/net/wireless/mac80211_hwsim.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
Note: Before even thinking of testing this, please take a look at the
RFC patch for handling supported rates configuration unless you want to
crash and burn your kernel.. Anyway, it is useful to get hwsim ready for
TDLS testing and the mac80211 issue is not specific to hwsim and people
who use hwsim are normally capable of patching kernel and familiar with
this mailing list in the first place.. ;-)
With the RFC "mac80211: Fix STA supported rate configuration with dummy
entry" patch in place, I was able to get the TDLS link running in
mac80211_hwsim environment between two WPA2 stations.
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 68455a2..477100d 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -1747,6 +1747,8 @@ static int __init init_mac80211_hwsim(void)
IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
IEEE80211_HW_AMPDU_AGGREGATION;
+ hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
+
/* ask mac80211 to reserve space for magic */
hw->vif_data_size = sizeof(struct hwsim_vif_priv);
hw->sta_data_size = sizeof(struct hwsim_sta_priv);
--
1.7.4.1
--
Jouni Malinen PGP id EFC895FA
^ permalink raw reply related
* Re: BUG: All network processes hang (brcmsmac/wpa_supplicant)
From: Nico Schottelius @ 2011-10-23 19:48 UTC (permalink / raw)
To: Nico Schottelius
Cc: Arend van Spriel, Eric Dumazet, linux-wireless@vger.kernel.org
In-Reply-To: <20111023105305.GA2489@schottelius.org>
[-- Attachment #1: Type: text/plain, Size: 1249 bytes --]
Update, just triggered it after a suspend/resume cycle:
ping: sendmsg: Network is unreachable
ping: sendmsg: Network is unreachable
ping: sendmsg: Network is unreachable
ping: sendmsg: Network is unreachable
64 bytes from 192.168.42.1: icmp_req=23 ttl=64 time=32.4 ms
64 bytes from 192.168.42.1: icmp_req=24 ttl=64 time=10.7 ms
64 bytes from 192.168.42.1: icmp_req=25 ttl=64 time=9.36 ms
64 bytes from 192.168.42.1: icmp_req=26 ttl=64 time=7.13 ms
64 bytes from 192.168.42.1: icmp_req=27 ttl=64 time=6.92 ms
ping: sendmsg: Network is unreachable
ping: sendmsg: Network is unreachable
ping: sendmsg: Network is unreachable
ping: sendmsg: Network is unreachable
ping: sendmsg: Network is unreachable
This changes every some seconds right now, because the connection
is established/shutdown and thus dhcpcd retries to get the ip address
every few seconds.
I've restarted the AP, but the situation stays the same.
The other devices in the network work fine, so it's really my system
that behaves "funny".
After that I've reloaded brcmsmac at 84262.797365, after which
the connection time lasted longer, but was also interrupted some
time later.
dmesg attached again.
Cheers,
Nico
--
PGP key: 7ED9 F7D3 6B10 81D7 0EC5 5C09 D7DC C8E4 3187 7DF0
[-- Attachment #2: dmesg.gz --]
[-- Type: application/octet-stream, Size: 60890 bytes --]
^ permalink raw reply
* Re: [PATCH] mac80211: Fix TDLS support validation in add_station handler
From: Arik Nemtsov @ 2011-10-23 21:00 UTC (permalink / raw)
To: Jouni Malinen; +Cc: John W. Linville, Johannes Berg, linux-wireless
In-Reply-To: <20111023193604.GA18257@jm.kir.nu>
On Sun, Oct 23, 2011 at 21:36, Jouni Malinen <j@w1.fi> wrote:
> We need to verify whether the command is successful before allocating
> the station entry to avoid extra processing. This also fixes a memory
> leak on the error path.
Thanks. I missed that one.
Arik
^ permalink raw reply
* Re: iwlagn is getting very shaky
From: David Rientjes @ 2011-10-23 21:26 UTC (permalink / raw)
To: Norbert Preining
Cc: wwguy, linux-kernel@vger.kernel.org,
ipw3945-devel@lists.sourceforge.net, ilw@linux.intel.com,
linux-wireless@vger.kernel.org, Pekka Enberg
In-Reply-To: <20111021012442.GB26758@gamma.logic.tuwien.ac.at>
On Fri, 21 Oct 2011, Norbert Preining wrote:
> > Great, this is just a test patch, we will figure out what is the correct
> > way to handle this and fix the issue for good :-)
>
> Thanks. If you need more testing just let me know.
>
It'd be interesting to see if this problem still exists in linux-next
since some wireless changes went into that recently. Please try the tree
at git://github.com/sfrothwell/linux-next.git
^ permalink raw reply
* Re: problem with intel 5300
From: Mikael Abrahamsson @ 2011-10-24 5:48 UTC (permalink / raw)
To: wwguy; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <alpine.DEB.2.00.1109201730450.13829@uplift.swm.pp.se>
On Tue, 20 Sep 2011, Mikael Abrahamsson wrote:
Hi,
just wanted to say that I have now upgraded to ubuntu 11.10 with its 3.0.x
kernel, and I'm now running it with .11n enabled and it's been ok for 20
hours. So whatever problem there was in 2.6.38, it seems to have been
fixed in 3.0.x, or at least it's working much better.
--
Mikael Abrahamsson email: swmike@swm.pp.se
^ permalink raw reply
* [PATCH 1/9] ath6kl: remove unused A_CACHE_LINE_PAD
From: Kalle Valo @ 2011-10-24 9:16 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath6kl/common.h | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h
index b92f0e5..d2efa19 100644
--- a/drivers/net/wireless/ath/ath6kl/common.h
+++ b/drivers/net/wireless/ath/ath6kl/common.h
@@ -23,8 +23,6 @@
extern int ath6kl_printk(const char *level, const char *fmt, ...);
-#define A_CACHE_LINE_PAD 128
-
/*
* Reflects the version of binary interface exposed by ATH6KL target
* firmware. Needs to be incremented by 1 for any change in the firmware
^ permalink raw reply related
* [PATCH 2/9] ath6kl: use ath6kl prefix in credit functions
From: Kalle Valo @ 2011-10-24 9:16 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless
In-Reply-To: <20111024091644.5004.2767.stgit@localhost6.localdomain6>
This is to follow the common style in the driver. Also add braces to
fix a style issue.
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath6kl/common.h | 20 +++++-----
drivers/net/wireless/ath/ath6kl/htc.c | 22 ++++++-----
drivers/net/wireless/ath/ath6kl/init.c | 2 +
drivers/net/wireless/ath/ath6kl/main.c | 60 +++++++++++++++---------------
4 files changed, 52 insertions(+), 52 deletions(-)
diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h
index d2efa19..fd239ea 100644
--- a/drivers/net/wireless/ath/ath6kl/common.h
+++ b/drivers/net/wireless/ath/ath6kl/common.h
@@ -78,16 +78,16 @@ struct ath6kl;
enum htc_credit_dist_reason;
struct htc_credit_state_info;
-int ath6k_setup_credit_dist(void *htc_handle,
- struct htc_credit_state_info *cred_info);
-void ath6k_credit_distribute(struct htc_credit_state_info *cred_inf,
- struct list_head *epdist_list,
- enum htc_credit_dist_reason reason);
-void ath6k_credit_init(struct htc_credit_state_info *cred_inf,
- struct list_head *ep_list,
- int tot_credits);
-void ath6k_seek_credits(struct htc_credit_state_info *cred_inf,
- struct htc_endpoint_credit_dist *ep_dist);
+int ath6kl_setup_credit_dist(void *htc_handle,
+ struct htc_credit_state_info *cred_info);
+void ath6kl_credit_distribute(struct htc_credit_state_info *cred_inf,
+ struct list_head *epdist_list,
+ enum htc_credit_dist_reason reason);
+void ath6kl_credit_init(struct htc_credit_state_info *cred_inf,
+ struct list_head *ep_list,
+ int tot_credits);
+void ath6kl_seek_credits(struct htc_credit_state_info *cred_inf,
+ struct htc_endpoint_credit_dist *ep_dist);
struct ath6kl *ath6kl_core_alloc(struct device *sdev);
int ath6kl_core_init(struct ath6kl *ar);
int ath6kl_unavail_ev(struct ath6kl *ar);
diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c
index 3cd3ef5..b861fa1 100644
--- a/drivers/net/wireless/ath/ath6kl/htc.c
+++ b/drivers/net/wireless/ath/ath6kl/htc.c
@@ -105,7 +105,7 @@ static void htc_tx_comp_update(struct htc_target *target,
ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx ctxt 0x%p dist 0x%p\n",
target->cred_dist_cntxt, &target->cred_dist_list);
- ath6k_credit_distribute(target->cred_dist_cntxt,
+ ath6kl_credit_distribute(target->cred_dist_cntxt,
&target->cred_dist_list,
HTC_CREDIT_DIST_SEND_COMPLETE);
@@ -237,7 +237,7 @@ static int htc_check_credits(struct htc_target *target,
ath6kl_dbg(ATH6KL_DBG_HTC, "htc creds ctxt 0x%p dist 0x%p\n",
target->cred_dist_cntxt, &ep->cred_dist);
- ath6k_seek_credits(target->cred_dist_cntxt, &ep->cred_dist);
+ ath6kl_seek_credits(target->cred_dist_cntxt, &ep->cred_dist);
ep->cred_dist.seek_cred = 0;
@@ -260,7 +260,7 @@ static int htc_check_credits(struct htc_target *target,
ath6kl_dbg(ATH6KL_DBG_HTC, "htc creds ctxt 0x%p dist 0x%p\n",
target->cred_dist_cntxt, &ep->cred_dist);
- ath6k_seek_credits(target->cred_dist_cntxt, &ep->cred_dist);
+ ath6kl_seek_credits(target->cred_dist_cntxt, &ep->cred_dist);
/* see if we were successful in getting more */
if (ep->cred_dist.credits < ep->cred_dist.cred_per_msg) {
@@ -842,9 +842,9 @@ void ath6kl_htc_indicate_activity_change(struct htc_target *target,
"htc tx activity ctxt 0x%p dist 0x%p\n",
target->cred_dist_cntxt, &target->cred_dist_list);
- ath6k_credit_distribute(target->cred_dist_cntxt,
- &target->cred_dist_list,
- HTC_CREDIT_DIST_ACTIVITY_CHANGE);
+ ath6kl_credit_distribute(target->cred_dist_cntxt,
+ &target->cred_dist_list,
+ HTC_CREDIT_DIST_ACTIVITY_CHANGE);
}
spin_unlock_bh(&target->tx_lock);
@@ -1272,9 +1272,9 @@ static void htc_proc_cred_rpt(struct htc_target *target,
ath6kl_dbg(ATH6KL_DBG_HTC, "htc creds ctxt 0x%p dist 0x%p\n",
target->cred_dist_cntxt, &target->cred_dist_list);
- ath6k_credit_distribute(target->cred_dist_cntxt,
- &target->cred_dist_list,
- HTC_CREDIT_DIST_SEND_COMPLETE);
+ ath6kl_credit_distribute(target->cred_dist_cntxt,
+ &target->cred_dist_list,
+ HTC_CREDIT_DIST_SEND_COMPLETE);
}
spin_unlock_bh(&target->tx_lock);
@@ -2338,8 +2338,8 @@ int ath6kl_htc_start(struct htc_target *target)
}
/* NOTE: the first entry in the distribution list is ENDPOINT_0 */
- ath6k_credit_init(target->cred_dist_cntxt, &target->cred_dist_list,
- target->tgt_creds);
+ ath6kl_credit_init(target->cred_dist_cntxt, &target->cred_dist_list,
+ target->tgt_creds);
dump_cred_dist_stats(target);
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 1700423..777ee2c 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -1516,7 +1516,7 @@ static int ath6kl_init(struct net_device *dev)
ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS);
/* setup credit distribution */
- ath6k_setup_credit_dist(ar->htc_target, &ar->credit_state_info);
+ ath6kl_setup_credit_dist(ar->htc_target, &ar->credit_state_info);
ath6kl_cookie_init(ar);
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index e693756..f35f763 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -623,9 +623,9 @@ void ath6kl_connect_ap_mode_sta(struct ath6kl *ar, u16 aid, u8 *mac_addr,
}
/* Functions for Tx credit handling */
-void ath6k_credit_init(struct htc_credit_state_info *cred_info,
- struct list_head *ep_list,
- int tot_credits)
+void ath6kl_credit_init(struct htc_credit_state_info *cred_info,
+ struct list_head *ep_list,
+ int tot_credits)
{
struct htc_endpoint_credit_dist *cur_ep_dist;
int count;
@@ -639,7 +639,7 @@ void ath6k_credit_init(struct htc_credit_state_info *cred_info,
cur_ep_dist->cred_min = cur_ep_dist->cred_per_msg;
- if (tot_credits > 4)
+ if (tot_credits > 4) {
if ((cur_ep_dist->svc_id == WMI_DATA_BK_SVC) ||
(cur_ep_dist->svc_id == WMI_DATA_BE_SVC)) {
ath6kl_deposit_credit_to_ep(cred_info,
@@ -647,6 +647,7 @@ void ath6k_credit_init(struct htc_credit_state_info *cred_info,
cur_ep_dist->cred_min);
cur_ep_dist->dist_flags |= HTC_EP_ACTIVE;
}
+ }
if (cur_ep_dist->svc_id == WMI_CONTROL_SVC) {
ath6kl_deposit_credit_to_ep(cred_info, cur_ep_dist,
@@ -701,8 +702,8 @@ void ath6k_credit_init(struct htc_credit_state_info *cred_info,
}
/* initialize and setup credit distribution */
-int ath6k_setup_credit_dist(void *htc_handle,
- struct htc_credit_state_info *cred_info)
+int ath6kl_setup_credit_dist(void *htc_handle,
+ struct htc_credit_state_info *cred_info)
{
u16 servicepriority[5];
@@ -721,9 +722,9 @@ int ath6k_setup_credit_dist(void *htc_handle,
}
/* reduce an ep's credits back to a set limit */
-static void ath6k_reduce_credits(struct htc_credit_state_info *cred_info,
- struct htc_endpoint_credit_dist *ep_dist,
- int limit)
+static void ath6kl_reduce_credits(struct htc_credit_state_info *cred_info,
+ struct htc_endpoint_credit_dist *ep_dist,
+ int limit)
{
int credits;
@@ -737,8 +738,8 @@ static void ath6k_reduce_credits(struct htc_credit_state_info *cred_info,
cred_info->cur_free_credits += credits;
}
-static void ath6k_credit_update(struct htc_credit_state_info *cred_info,
- struct list_head *epdist_list)
+static void ath6kl_credit_update(struct htc_credit_state_info *cred_info,
+ struct list_head *epdist_list)
{
struct htc_endpoint_credit_dist *cur_dist_list;
@@ -752,19 +753,19 @@ static void ath6k_credit_update(struct htc_credit_state_info *cred_info,
cur_dist_list->cred_to_dist = 0;
if (cur_dist_list->credits >
cur_dist_list->cred_assngd)
- ath6k_reduce_credits(cred_info,
+ ath6kl_reduce_credits(cred_info,
cur_dist_list,
cur_dist_list->cred_assngd);
if (cur_dist_list->credits >
cur_dist_list->cred_norm)
- ath6k_reduce_credits(cred_info, cur_dist_list,
- cur_dist_list->cred_norm);
+ ath6kl_reduce_credits(cred_info, cur_dist_list,
+ cur_dist_list->cred_norm);
if (!(cur_dist_list->dist_flags & HTC_EP_ACTIVE)) {
if (cur_dist_list->txq_depth == 0)
- ath6k_reduce_credits(cred_info,
- cur_dist_list, 0);
+ ath6kl_reduce_credits(cred_info,
+ cur_dist_list, 0);
}
}
}
@@ -774,8 +775,8 @@ static void ath6k_credit_update(struct htc_credit_state_info *cred_info,
* HTC has an endpoint that needs credits, ep_dist is the endpoint in
* question.
*/
-void ath6k_seek_credits(struct htc_credit_state_info *cred_info,
- struct htc_endpoint_credit_dist *ep_dist)
+void ath6kl_seek_credits(struct htc_credit_state_info *cred_info,
+ struct htc_endpoint_credit_dist *ep_dist)
{
struct htc_endpoint_credit_dist *curdist_list;
int credits = 0;
@@ -827,8 +828,8 @@ void ath6k_seek_credits(struct htc_credit_state_info *cred_info,
* above it's minimum to fulfill our need try to
* take away just enough to fulfill our need.
*/
- ath6k_reduce_credits(cred_info, curdist_list,
- curdist_list->cred_assngd - need);
+ ath6kl_reduce_credits(cred_info, curdist_list,
+ curdist_list->cred_assngd - need);
if (cred_info->cur_free_credits >=
ep_dist->seek_cred)
@@ -850,8 +851,8 @@ out:
}
/* redistribute credits based on activity change */
-static void ath6k_redistribute_credits(struct htc_credit_state_info *info,
- struct list_head *ep_dist_list)
+static void ath6kl_redistribute_credits(struct htc_credit_state_info *info,
+ struct list_head *ep_dist_list)
{
struct htc_endpoint_credit_dist *curdist_list;
@@ -866,10 +867,9 @@ static void ath6k_redistribute_credits(struct htc_credit_state_info *info,
if ((curdist_list->svc_id != WMI_CONTROL_SVC) &&
!(curdist_list->dist_flags & HTC_EP_ACTIVE)) {
if (curdist_list->txq_depth == 0)
- ath6k_reduce_credits(info,
- curdist_list, 0);
+ ath6kl_reduce_credits(info, curdist_list, 0);
else
- ath6k_reduce_credits(info,
+ ath6kl_reduce_credits(info,
curdist_list,
curdist_list->cred_min);
}
@@ -884,16 +884,16 @@ static void ath6k_redistribute_credits(struct htc_credit_state_info *info,
* structures in prioritized order as defined by the call to the
* htc_set_credit_dist() api.
*/
-void ath6k_credit_distribute(struct htc_credit_state_info *cred_info,
- struct list_head *ep_dist_list,
- enum htc_credit_dist_reason reason)
+void ath6kl_credit_distribute(struct htc_credit_state_info *cred_info,
+ struct list_head *ep_dist_list,
+ enum htc_credit_dist_reason reason)
{
switch (reason) {
case HTC_CREDIT_DIST_SEND_COMPLETE:
- ath6k_credit_update(cred_info, ep_dist_list);
+ ath6kl_credit_update(cred_info, ep_dist_list);
break;
case HTC_CREDIT_DIST_ACTIVITY_CHANGE:
- ath6k_redistribute_credits(cred_info, ep_dist_list);
+ ath6kl_redistribute_credits(cred_info, ep_dist_list);
break;
default:
break;
^ permalink raw reply related
* [PATCH 3/9] ath6kl: rename struct htc_endpoint_credit_dist.htc_rsvd to htc_ep
From: Kalle Valo @ 2011-10-24 9:17 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless
In-Reply-To: <20111024091644.5004.2767.stgit@localhost6.localdomain6>
No need to use void pointer here.
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath6kl/debug.c | 6 ++----
drivers/net/wireless/ath/ath6kl/htc.c | 4 ++--
drivers/net/wireless/ath/ath6kl/htc.h | 2 +-
3 files changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index e109f29..a6fda09 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -164,8 +164,7 @@ static void dump_cred_dist(struct htc_endpoint_credit_dist *ep_dist)
ath6kl_dbg(ATH6KL_DBG_ANY, " cred_to_dist : %d\n",
ep_dist->cred_to_dist);
ath6kl_dbg(ATH6KL_DBG_ANY, " txq_depth : %d\n",
- get_queue_depth(&((struct htc_endpoint *)
- ep_dist->htc_rsvd)->txq));
+ get_queue_depth(&ep_dist->htc_ep->txq));
ath6kl_dbg(ATH6KL_DBG_ANY,
"----------------------------------\n");
}
@@ -577,8 +576,7 @@ static ssize_t read_file_credit_dist_stats(struct file *file,
print_credit_info("%9d", cred_per_msg);
print_credit_info("%14d", cred_to_dist);
len += scnprintf(buf + len, buf_len - len, "%12d\n",
- get_queue_depth(&((struct htc_endpoint *)
- ep_list->htc_rsvd)->txq));
+ get_queue_depth(&ep_list->htc_ep->txq));
}
if (len > buf_len)
diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c
index b861fa1..4685a1b 100644
--- a/drivers/net/wireless/ath/ath6kl/htc.c
+++ b/drivers/net/wireless/ath/ath6kl/htc.c
@@ -619,7 +619,7 @@ static void htc_chk_ep_txq(struct htc_target *target)
* are not modifying any state.
*/
list_for_each_entry(cred_dist, &target->cred_dist_list, list) {
- endpoint = (struct htc_endpoint *)cred_dist->htc_rsvd;
+ endpoint = cred_dist->htc_ep;
spin_lock_bh(&target->tx_lock);
if (!list_empty(&endpoint->txq)) {
@@ -2119,7 +2119,7 @@ int ath6kl_htc_conn_service(struct htc_target *target,
endpoint->len_max = max_msg_sz;
endpoint->ep_cb = conn_req->ep_cb;
endpoint->cred_dist.svc_id = conn_req->svc_id;
- endpoint->cred_dist.htc_rsvd = endpoint;
+ endpoint->cred_dist.htc_ep = endpoint;
endpoint->cred_dist.endpoint = assigned_ep;
endpoint->cred_dist.cred_sz = target->tgt_cred_sz;
diff --git a/drivers/net/wireless/ath/ath6kl/htc.h b/drivers/net/wireless/ath/ath6kl/htc.h
index 69d44e3..5db4294 100644
--- a/drivers/net/wireless/ath/ath6kl/htc.h
+++ b/drivers/net/wireless/ath/ath6kl/htc.h
@@ -393,7 +393,7 @@ struct htc_endpoint_credit_dist {
int cred_per_msg;
/* reserved for HTC use */
- void *htc_rsvd;
+ struct htc_endpoint *htc_ep;
/*
* current depth of TX queue , i.e. messages waiting for credits
^ permalink raw reply related
* [PATCH 4/9] ath6kl: rename struct htc_credit_state_info to ath6kl_htc_credit_info
From: Kalle Valo @ 2011-10-24 9:17 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless
In-Reply-To: <20111024091644.5004.2767.stgit@localhost6.localdomain6>
Also rename cred_dist_cntxt to credit_info in struct htc_target.
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath6kl/common.h | 10 +++++-----
drivers/net/wireless/ath/ath6kl/core.h | 4 ++--
drivers/net/wireless/ath/ath6kl/debug.c | 10 +++++-----
drivers/net/wireless/ath/ath6kl/htc.c | 31 +++++++++++++++---------------
drivers/net/wireless/ath/ath6kl/htc.h | 11 ++++++++---
drivers/net/wireless/ath/ath6kl/main.c | 17 +++++++++-------
6 files changed, 45 insertions(+), 38 deletions(-)
diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h
index fd239ea..4fb2ccf 100644
--- a/drivers/net/wireless/ath/ath6kl/common.h
+++ b/drivers/net/wireless/ath/ath6kl/common.h
@@ -76,17 +76,17 @@ enum crypto_type {
struct htc_endpoint_credit_dist;
struct ath6kl;
enum htc_credit_dist_reason;
-struct htc_credit_state_info;
+struct ath6kl_htc_credit_info;
int ath6kl_setup_credit_dist(void *htc_handle,
- struct htc_credit_state_info *cred_info);
-void ath6kl_credit_distribute(struct htc_credit_state_info *cred_inf,
+ struct ath6kl_htc_credit_info *cred_info);
+void ath6kl_credit_distribute(struct ath6kl_htc_credit_info *cred_inf,
struct list_head *epdist_list,
enum htc_credit_dist_reason reason);
-void ath6kl_credit_init(struct htc_credit_state_info *cred_inf,
+void ath6kl_credit_init(struct ath6kl_htc_credit_info *cred_inf,
struct list_head *ep_list,
int tot_credits);
-void ath6kl_seek_credits(struct htc_credit_state_info *cred_inf,
+void ath6kl_seek_credits(struct ath6kl_htc_credit_info *cred_inf,
struct htc_endpoint_credit_dist *ep_dist);
struct ath6kl *ath6kl_core_alloc(struct device *sdev);
int ath6kl_core_init(struct ath6kl *ar);
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 31e5c7e..f8135a4 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -447,7 +447,7 @@ struct ath6kl {
u8 hiac_stream_active_pri;
u8 ep2ac_map[ENDPOINT_MAX];
enum htc_endpoint_id ctrl_ep;
- struct htc_credit_state_info credit_state_info;
+ struct ath6kl_htc_credit_info credit_state_info;
u32 connect_ctrl_flags;
u32 user_key_ctrl;
u8 usr_bss_filter;
@@ -545,7 +545,7 @@ static inline void *ath6kl_priv(struct net_device *dev)
return wdev_priv(dev->ieee80211_ptr);
}
-static inline void ath6kl_deposit_credit_to_ep(struct htc_credit_state_info
+static inline void ath6kl_deposit_credit_to_ep(struct ath6kl_htc_credit_info
*cred_info,
struct htc_endpoint_credit_dist
*ep_dist, int credits)
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index a6fda09..324fdb3 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -180,11 +180,11 @@ void dump_cred_dist_stats(struct htc_target *target)
dump_cred_dist(ep_list);
ath6kl_dbg(ATH6KL_DBG_HTC, "ctxt:%p dist:%p\n",
- target->cred_dist_cntxt, NULL);
+ target->credit_info, NULL);
ath6kl_dbg(ATH6KL_DBG_HTC,
"credit distribution, total : %d, free : %d\n",
- target->cred_dist_cntxt->total_avail_credits,
- target->cred_dist_cntxt->cur_free_credits);
+ target->credit_info->total_avail_credits,
+ target->credit_info->cur_free_credits);
}
static int ath6kl_debugfs_open(struct inode *inode, struct file *file)
@@ -554,10 +554,10 @@ static ssize_t read_file_credit_dist_stats(struct file *file,
len += scnprintf(buf + len, buf_len - len, "%25s%5d\n",
"Total Avail Credits: ",
- target->cred_dist_cntxt->total_avail_credits);
+ target->credit_info->total_avail_credits);
len += scnprintf(buf + len, buf_len - len, "%25s%5d\n",
"Free credits :",
- target->cred_dist_cntxt->cur_free_credits);
+ target->credit_info->cur_free_credits);
len += scnprintf(buf + len, buf_len - len,
" Epid Flags Cred_norm Cred_min Credits Cred_assngd"
diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c
index 4685a1b..24dfc02 100644
--- a/drivers/net/wireless/ath/ath6kl/htc.c
+++ b/drivers/net/wireless/ath/ath6kl/htc.c
@@ -103,11 +103,11 @@ static void htc_tx_comp_update(struct htc_target *target,
endpoint->cred_dist.txq_depth = get_queue_depth(&endpoint->txq);
ath6kl_dbg(ATH6KL_DBG_HTC, "htc tx ctxt 0x%p dist 0x%p\n",
- target->cred_dist_cntxt, &target->cred_dist_list);
+ target->credit_info, &target->cred_dist_list);
- ath6kl_credit_distribute(target->cred_dist_cntxt,
- &target->cred_dist_list,
- HTC_CREDIT_DIST_SEND_COMPLETE);
+ ath6kl_credit_distribute(target->credit_info,
+ &target->cred_dist_list,
+ HTC_CREDIT_DIST_SEND_COMPLETE);
spin_unlock_bh(&target->tx_lock);
}
@@ -235,9 +235,9 @@ static int htc_check_credits(struct htc_target *target,
ep->cred_dist.seek_cred = *req_cred - ep->cred_dist.credits;
ath6kl_dbg(ATH6KL_DBG_HTC, "htc creds ctxt 0x%p dist 0x%p\n",
- target->cred_dist_cntxt, &ep->cred_dist);
+ target->credit_info, &ep->cred_dist);
- ath6kl_seek_credits(target->cred_dist_cntxt, &ep->cred_dist);
+ ath6kl_seek_credits(target->credit_info, &ep->cred_dist);
ep->cred_dist.seek_cred = 0;
@@ -258,9 +258,9 @@ static int htc_check_credits(struct htc_target *target,
ep->cred_dist.cred_per_msg - ep->cred_dist.credits;
ath6kl_dbg(ATH6KL_DBG_HTC, "htc creds ctxt 0x%p dist 0x%p\n",
- target->cred_dist_cntxt, &ep->cred_dist);
+ target->credit_info, &ep->cred_dist);
- ath6kl_seek_credits(target->cred_dist_cntxt, &ep->cred_dist);
+ ath6kl_seek_credits(target->credit_info, &ep->cred_dist);
/* see if we were successful in getting more */
if (ep->cred_dist.credits < ep->cred_dist.cred_per_msg) {
@@ -698,13 +698,13 @@ static int htc_setup_tx_complete(struct htc_target *target)
}
void ath6kl_htc_set_credit_dist(struct htc_target *target,
- struct htc_credit_state_info *cred_dist_cntxt,
+ struct ath6kl_htc_credit_info *credit_info,
u16 srvc_pri_order[], int list_len)
{
struct htc_endpoint *endpoint;
int i, ep;
- target->cred_dist_cntxt = cred_dist_cntxt;
+ target->credit_info = credit_info;
list_add_tail(&target->endpoint[ENDPOINT_0].cred_dist.list,
&target->cred_dist_list);
@@ -840,9 +840,9 @@ void ath6kl_htc_indicate_activity_change(struct htc_target *target,
ath6kl_dbg(ATH6KL_DBG_HTC,
"htc tx activity ctxt 0x%p dist 0x%p\n",
- target->cred_dist_cntxt, &target->cred_dist_list);
+ target->credit_info, &target->cred_dist_list);
- ath6kl_credit_distribute(target->cred_dist_cntxt,
+ ath6kl_credit_distribute(target->credit_info,
&target->cred_dist_list,
HTC_CREDIT_DIST_ACTIVITY_CHANGE);
}
@@ -1270,9 +1270,9 @@ static void htc_proc_cred_rpt(struct htc_target *target,
* operations note, this is done with the lock held
*/
ath6kl_dbg(ATH6KL_DBG_HTC, "htc creds ctxt 0x%p dist 0x%p\n",
- target->cred_dist_cntxt, &target->cred_dist_list);
+ target->credit_info, &target->cred_dist_list);
- ath6kl_credit_distribute(target->cred_dist_cntxt,
+ ath6kl_credit_distribute(target->credit_info,
&target->cred_dist_list,
HTC_CREDIT_DIST_SEND_COMPLETE);
}
@@ -2176,6 +2176,7 @@ static void reset_ep_state(struct htc_target *target)
}
/* reset distribution list */
+ /* FIXME: free existing entries */
INIT_LIST_HEAD(&target->cred_dist_list);
}
@@ -2338,7 +2339,7 @@ int ath6kl_htc_start(struct htc_target *target)
}
/* NOTE: the first entry in the distribution list is ENDPOINT_0 */
- ath6kl_credit_init(target->cred_dist_cntxt, &target->cred_dist_list,
+ ath6kl_credit_init(target->credit_info, &target->cred_dist_list,
target->tgt_creds);
dump_cred_dist_stats(target);
diff --git a/drivers/net/wireless/ath/ath6kl/htc.h b/drivers/net/wireless/ath/ath6kl/htc.h
index 5db4294..47a588c 100644
--- a/drivers/net/wireless/ath/ath6kl/htc.h
+++ b/drivers/net/wireless/ath/ath6kl/htc.h
@@ -414,9 +414,11 @@ enum htc_credit_dist_reason {
HTC_CREDIT_DIST_SEEK_CREDITS,
};
-struct htc_credit_state_info {
+struct ath6kl_htc_credit_info {
int total_avail_credits;
int cur_free_credits;
+
+ /* list of lowest priority endpoints */
struct list_head lowestpri_ep_dist;
};
@@ -508,10 +510,13 @@ struct ath6kl_device;
/* our HTC target state */
struct htc_target {
struct htc_endpoint endpoint[ENDPOINT_MAX];
+
+ /* contains struct htc_endpoint_credit_dist */
struct list_head cred_dist_list;
+
struct list_head free_ctrl_txbuf;
struct list_head free_ctrl_rxbuf;
- struct htc_credit_state_info *cred_dist_cntxt;
+ struct ath6kl_htc_credit_info *credit_info;
int tgt_creds;
unsigned int tgt_cred_sz;
spinlock_t htc_lock;
@@ -542,7 +547,7 @@ struct htc_target {
void *ath6kl_htc_create(struct ath6kl *ar);
void ath6kl_htc_set_credit_dist(struct htc_target *target,
- struct htc_credit_state_info *cred_info,
+ struct ath6kl_htc_credit_info *cred_info,
u16 svc_pri_order[], int len);
int ath6kl_htc_wait_target(struct htc_target *target);
int ath6kl_htc_start(struct htc_target *target);
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index f35f763..bc9ec6c 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -623,7 +623,7 @@ void ath6kl_connect_ap_mode_sta(struct ath6kl *ar, u16 aid, u8 *mac_addr,
}
/* Functions for Tx credit handling */
-void ath6kl_credit_init(struct htc_credit_state_info *cred_info,
+void ath6kl_credit_init(struct ath6kl_htc_credit_info *cred_info,
struct list_head *ep_list,
int tot_credits)
{
@@ -659,6 +659,7 @@ void ath6kl_credit_init(struct htc_credit_state_info *cred_info,
cur_ep_dist->dist_flags |= HTC_EP_ACTIVE;
} else if (cur_ep_dist->svc_id == WMI_DATA_BK_SVC)
/* this is the lowest priority data endpoint */
+ /* FIXME: this looks fishy, check */
cred_info->lowestpri_ep_dist = cur_ep_dist->list;
/*
@@ -703,11 +704,11 @@ void ath6kl_credit_init(struct htc_credit_state_info *cred_info,
/* initialize and setup credit distribution */
int ath6kl_setup_credit_dist(void *htc_handle,
- struct htc_credit_state_info *cred_info)
+ struct ath6kl_htc_credit_info *cred_info)
{
u16 servicepriority[5];
- memset(cred_info, 0, sizeof(struct htc_credit_state_info));
+ memset(cred_info, 0, sizeof(struct ath6kl_htc_credit_info));
servicepriority[0] = WMI_CONTROL_SVC; /* highest */
servicepriority[1] = WMI_DATA_VO_SVC;
@@ -722,7 +723,7 @@ int ath6kl_setup_credit_dist(void *htc_handle,
}
/* reduce an ep's credits back to a set limit */
-static void ath6kl_reduce_credits(struct htc_credit_state_info *cred_info,
+static void ath6kl_reduce_credits(struct ath6kl_htc_credit_info *cred_info,
struct htc_endpoint_credit_dist *ep_dist,
int limit)
{
@@ -738,7 +739,7 @@ static void ath6kl_reduce_credits(struct htc_credit_state_info *cred_info,
cred_info->cur_free_credits += credits;
}
-static void ath6kl_credit_update(struct htc_credit_state_info *cred_info,
+static void ath6kl_credit_update(struct ath6kl_htc_credit_info *cred_info,
struct list_head *epdist_list)
{
struct htc_endpoint_credit_dist *cur_dist_list;
@@ -775,7 +776,7 @@ static void ath6kl_credit_update(struct htc_credit_state_info *cred_info,
* HTC has an endpoint that needs credits, ep_dist is the endpoint in
* question.
*/
-void ath6kl_seek_credits(struct htc_credit_state_info *cred_info,
+void ath6kl_seek_credits(struct ath6kl_htc_credit_info *cred_info,
struct htc_endpoint_credit_dist *ep_dist)
{
struct htc_endpoint_credit_dist *curdist_list;
@@ -851,7 +852,7 @@ out:
}
/* redistribute credits based on activity change */
-static void ath6kl_redistribute_credits(struct htc_credit_state_info *info,
+static void ath6kl_redistribute_credits(struct ath6kl_htc_credit_info *info,
struct list_head *ep_dist_list)
{
struct htc_endpoint_credit_dist *curdist_list;
@@ -884,7 +885,7 @@ static void ath6kl_redistribute_credits(struct htc_credit_state_info *info,
* structures in prioritized order as defined by the call to the
* htc_set_credit_dist() api.
*/
-void ath6kl_credit_distribute(struct htc_credit_state_info *cred_info,
+void ath6kl_credit_distribute(struct ath6kl_htc_credit_info *cred_info,
struct list_head *ep_dist_list,
enum htc_credit_dist_reason reason)
{
^ permalink raw reply related
* [PATCH 5/9] ath6kl: move all credit distribution code to htc.c
From: Kalle Valo @ 2011-10-24 9:17 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless
In-Reply-To: <20111024091644.5004.2767.stgit@localhost6.localdomain6>
As htc is the only user there's no reason to keep it in main.c.
No functional changes.
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath6kl/common.h | 10 -
drivers/net/wireless/ath/ath6kl/core.h | 10 -
drivers/net/wireless/ath/ath6kl/htc.c | 292 ++++++++++++++++++++++++++++++
drivers/net/wireless/ath/ath6kl/htc.h | 3
drivers/net/wireless/ath/ath6kl/main.c | 282 -----------------------------
5 files changed, 295 insertions(+), 302 deletions(-)
diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h
index 4fb2ccf..a9fa057 100644
--- a/drivers/net/wireless/ath/ath6kl/common.h
+++ b/drivers/net/wireless/ath/ath6kl/common.h
@@ -78,16 +78,6 @@ struct ath6kl;
enum htc_credit_dist_reason;
struct ath6kl_htc_credit_info;
-int ath6kl_setup_credit_dist(void *htc_handle,
- struct ath6kl_htc_credit_info *cred_info);
-void ath6kl_credit_distribute(struct ath6kl_htc_credit_info *cred_inf,
- struct list_head *epdist_list,
- enum htc_credit_dist_reason reason);
-void ath6kl_credit_init(struct ath6kl_htc_credit_info *cred_inf,
- struct list_head *ep_list,
- int tot_credits);
-void ath6kl_seek_credits(struct ath6kl_htc_credit_info *cred_inf,
- struct htc_endpoint_credit_dist *ep_dist);
struct ath6kl *ath6kl_core_alloc(struct device *sdev);
int ath6kl_core_init(struct ath6kl *ar);
int ath6kl_unavail_ev(struct ath6kl *ar);
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index f8135a4..ae731e0 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -545,16 +545,6 @@ static inline void *ath6kl_priv(struct net_device *dev)
return wdev_priv(dev->ieee80211_ptr);
}
-static inline void ath6kl_deposit_credit_to_ep(struct ath6kl_htc_credit_info
- *cred_info,
- struct htc_endpoint_credit_dist
- *ep_dist, int credits)
-{
- ep_dist->credits += credits;
- ep_dist->cred_assngd += credits;
- cred_info->cur_free_credits -= credits;
-}
-
static inline u32 ath6kl_get_hi_item_addr(struct ath6kl *ar,
u32 item_offset)
{
diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c
index 24dfc02..5cb0327 100644
--- a/drivers/net/wireless/ath/ath6kl/htc.c
+++ b/drivers/net/wireless/ath/ath6kl/htc.c
@@ -22,6 +22,298 @@
#define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask))
+/* Functions for Tx credit handling */
+static void ath6kl_deposit_credit_to_ep(struct ath6kl_htc_credit_info
+ *cred_info,
+ struct htc_endpoint_credit_dist
+ *ep_dist, int credits)
+{
+ ep_dist->credits += credits;
+ ep_dist->cred_assngd += credits;
+ cred_info->cur_free_credits -= credits;
+}
+
+static void ath6kl_credit_init(struct ath6kl_htc_credit_info *cred_info,
+ struct list_head *ep_list,
+ int tot_credits)
+{
+ struct htc_endpoint_credit_dist *cur_ep_dist;
+ int count;
+
+ cred_info->cur_free_credits = tot_credits;
+ cred_info->total_avail_credits = tot_credits;
+
+ list_for_each_entry(cur_ep_dist, ep_list, list) {
+ if (cur_ep_dist->endpoint == ENDPOINT_0)
+ continue;
+
+ cur_ep_dist->cred_min = cur_ep_dist->cred_per_msg;
+
+ if (tot_credits > 4) {
+ if ((cur_ep_dist->svc_id == WMI_DATA_BK_SVC) ||
+ (cur_ep_dist->svc_id == WMI_DATA_BE_SVC)) {
+ ath6kl_deposit_credit_to_ep(cred_info,
+ cur_ep_dist,
+ cur_ep_dist->cred_min);
+ cur_ep_dist->dist_flags |= HTC_EP_ACTIVE;
+ }
+ }
+
+ if (cur_ep_dist->svc_id == WMI_CONTROL_SVC) {
+ ath6kl_deposit_credit_to_ep(cred_info, cur_ep_dist,
+ cur_ep_dist->cred_min);
+ /*
+ * Control service is always marked active, it
+ * never goes inactive EVER.
+ */
+ cur_ep_dist->dist_flags |= HTC_EP_ACTIVE;
+ } else if (cur_ep_dist->svc_id == WMI_DATA_BK_SVC)
+ /* this is the lowest priority data endpoint */
+ /* FIXME: this looks fishy, check */
+ cred_info->lowestpri_ep_dist = cur_ep_dist->list;
+
+ /*
+ * Streams have to be created (explicit | implicit) for all
+ * kinds of traffic. BE endpoints are also inactive in the
+ * beginning. When BE traffic starts it creates implicit
+ * streams that redistributes credits.
+ *
+ * Note: all other endpoints have minimums set but are
+ * initially given NO credits. credits will be distributed
+ * as traffic activity demands
+ */
+ }
+
+ WARN_ON(cred_info->cur_free_credits <= 0);
+
+ list_for_each_entry(cur_ep_dist, ep_list, list) {
+ if (cur_ep_dist->endpoint == ENDPOINT_0)
+ continue;
+
+ if (cur_ep_dist->svc_id == WMI_CONTROL_SVC)
+ cur_ep_dist->cred_norm = cur_ep_dist->cred_per_msg;
+ else {
+ /*
+ * For the remaining data endpoints, we assume that
+ * each cred_per_msg are the same. We use a simple
+ * calculation here, we take the remaining credits
+ * and determine how many max messages this can
+ * cover and then set each endpoint's normal value
+ * equal to 3/4 this amount.
+ */
+ count = (cred_info->cur_free_credits /
+ cur_ep_dist->cred_per_msg)
+ * cur_ep_dist->cred_per_msg;
+ count = (count * 3) >> 2;
+ count = max(count, cur_ep_dist->cred_per_msg);
+ cur_ep_dist->cred_norm = count;
+
+ }
+ }
+}
+
+/* initialize and setup credit distribution */
+int ath6kl_setup_credit_dist(void *htc_handle,
+ struct ath6kl_htc_credit_info *cred_info)
+{
+ u16 servicepriority[5];
+
+ memset(cred_info, 0, sizeof(struct ath6kl_htc_credit_info));
+
+ servicepriority[0] = WMI_CONTROL_SVC; /* highest */
+ servicepriority[1] = WMI_DATA_VO_SVC;
+ servicepriority[2] = WMI_DATA_VI_SVC;
+ servicepriority[3] = WMI_DATA_BE_SVC;
+ servicepriority[4] = WMI_DATA_BK_SVC; /* lowest */
+
+ /* set priority list */
+ ath6kl_htc_set_credit_dist(htc_handle, cred_info, servicepriority, 5);
+
+ return 0;
+}
+
+/* reduce an ep's credits back to a set limit */
+static void ath6kl_reduce_credits(struct ath6kl_htc_credit_info *cred_info,
+ struct htc_endpoint_credit_dist *ep_dist,
+ int limit)
+{
+ int credits;
+
+ ep_dist->cred_assngd = limit;
+
+ if (ep_dist->credits <= limit)
+ return;
+
+ credits = ep_dist->credits - limit;
+ ep_dist->credits -= credits;
+ cred_info->cur_free_credits += credits;
+}
+
+static void ath6kl_credit_update(struct ath6kl_htc_credit_info *cred_info,
+ struct list_head *epdist_list)
+{
+ struct htc_endpoint_credit_dist *cur_dist_list;
+
+ list_for_each_entry(cur_dist_list, epdist_list, list) {
+ if (cur_dist_list->endpoint == ENDPOINT_0)
+ continue;
+
+ if (cur_dist_list->cred_to_dist > 0) {
+ cur_dist_list->credits +=
+ cur_dist_list->cred_to_dist;
+ cur_dist_list->cred_to_dist = 0;
+ if (cur_dist_list->credits >
+ cur_dist_list->cred_assngd)
+ ath6kl_reduce_credits(cred_info,
+ cur_dist_list,
+ cur_dist_list->cred_assngd);
+
+ if (cur_dist_list->credits >
+ cur_dist_list->cred_norm)
+ ath6kl_reduce_credits(cred_info, cur_dist_list,
+ cur_dist_list->cred_norm);
+
+ if (!(cur_dist_list->dist_flags & HTC_EP_ACTIVE)) {
+ if (cur_dist_list->txq_depth == 0)
+ ath6kl_reduce_credits(cred_info,
+ cur_dist_list, 0);
+ }
+ }
+ }
+}
+
+/*
+ * HTC has an endpoint that needs credits, ep_dist is the endpoint in
+ * question.
+ */
+static void ath6kl_seek_credits(struct ath6kl_htc_credit_info *cred_info,
+ struct htc_endpoint_credit_dist *ep_dist)
+{
+ struct htc_endpoint_credit_dist *curdist_list;
+ int credits = 0;
+ int need;
+
+ if (ep_dist->svc_id == WMI_CONTROL_SVC)
+ goto out;
+
+ if ((ep_dist->svc_id == WMI_DATA_VI_SVC) ||
+ (ep_dist->svc_id == WMI_DATA_VO_SVC))
+ if ((ep_dist->cred_assngd >= ep_dist->cred_norm))
+ goto out;
+
+ /*
+ * For all other services, we follow a simple algorithm of:
+ *
+ * 1. checking the free pool for credits
+ * 2. checking lower priority endpoints for credits to take
+ */
+
+ credits = min(cred_info->cur_free_credits, ep_dist->seek_cred);
+
+ if (credits >= ep_dist->seek_cred)
+ goto out;
+
+ /*
+ * We don't have enough in the free pool, try taking away from
+ * lower priority services The rule for taking away credits:
+ *
+ * 1. Only take from lower priority endpoints
+ * 2. Only take what is allocated above the minimum (never
+ * starve an endpoint completely)
+ * 3. Only take what you need.
+ */
+
+ list_for_each_entry_reverse(curdist_list,
+ &cred_info->lowestpri_ep_dist,
+ list) {
+ if (curdist_list == ep_dist)
+ break;
+
+ need = ep_dist->seek_cred - cred_info->cur_free_credits;
+
+ if ((curdist_list->cred_assngd - need) >=
+ curdist_list->cred_min) {
+ /*
+ * The current one has been allocated more than
+ * it's minimum and it has enough credits assigned
+ * above it's minimum to fulfill our need try to
+ * take away just enough to fulfill our need.
+ */
+ ath6kl_reduce_credits(cred_info, curdist_list,
+ curdist_list->cred_assngd - need);
+
+ if (cred_info->cur_free_credits >=
+ ep_dist->seek_cred)
+ break;
+ }
+
+ if (curdist_list->endpoint == ENDPOINT_0)
+ break;
+ }
+
+ credits = min(cred_info->cur_free_credits, ep_dist->seek_cred);
+
+out:
+ /* did we find some credits? */
+ if (credits)
+ ath6kl_deposit_credit_to_ep(cred_info, ep_dist, credits);
+
+ ep_dist->seek_cred = 0;
+}
+
+/* redistribute credits based on activity change */
+static void ath6kl_redistribute_credits(struct ath6kl_htc_credit_info *info,
+ struct list_head *ep_dist_list)
+{
+ struct htc_endpoint_credit_dist *curdist_list;
+
+ list_for_each_entry(curdist_list, ep_dist_list, list) {
+ if (curdist_list->endpoint == ENDPOINT_0)
+ continue;
+
+ if ((curdist_list->svc_id == WMI_DATA_BK_SVC) ||
+ (curdist_list->svc_id == WMI_DATA_BE_SVC))
+ curdist_list->dist_flags |= HTC_EP_ACTIVE;
+
+ if ((curdist_list->svc_id != WMI_CONTROL_SVC) &&
+ !(curdist_list->dist_flags & HTC_EP_ACTIVE)) {
+ if (curdist_list->txq_depth == 0)
+ ath6kl_reduce_credits(info, curdist_list, 0);
+ else
+ ath6kl_reduce_credits(info,
+ curdist_list,
+ curdist_list->cred_min);
+ }
+ }
+}
+
+/*
+ *
+ * This function is invoked whenever endpoints require credit
+ * distributions. A lock is held while this function is invoked, this
+ * function shall NOT block. The ep_dist_list is a list of distribution
+ * structures in prioritized order as defined by the call to the
+ * htc_set_credit_dist() api.
+ */
+static void ath6kl_credit_distribute(struct ath6kl_htc_credit_info *cred_info,
+ struct list_head *ep_dist_list,
+ enum htc_credit_dist_reason reason)
+{
+ switch (reason) {
+ case HTC_CREDIT_DIST_SEND_COMPLETE:
+ ath6kl_credit_update(cred_info, ep_dist_list);
+ break;
+ case HTC_CREDIT_DIST_ACTIVITY_CHANGE:
+ ath6kl_redistribute_credits(cred_info, ep_dist_list);
+ break;
+ default:
+ break;
+ }
+
+ WARN_ON(cred_info->cur_free_credits > cred_info->total_avail_credits);
+ WARN_ON(cred_info->cur_free_credits < 0);
+}
+
static void ath6kl_htc_tx_buf_align(u8 **buf, unsigned long len)
{
u8 *align_addr;
diff --git a/drivers/net/wireless/ath/ath6kl/htc.h b/drivers/net/wireless/ath/ath6kl/htc.h
index 47a588c..c68e834 100644
--- a/drivers/net/wireless/ath/ath6kl/htc.h
+++ b/drivers/net/wireless/ath/ath6kl/htc.h
@@ -570,6 +570,9 @@ int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target,
int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target,
u32 msg_look_ahead, int *n_pkts);
+int ath6kl_setup_credit_dist(void *htc_handle,
+ struct ath6kl_htc_credit_info *cred_info);
+
static inline void set_htc_pkt_info(struct htc_packet *packet, void *context,
u8 *buf, unsigned int len,
enum htc_endpoint_id eid, u16 tag)
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index bc9ec6c..8d9a8f3 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -622,288 +622,6 @@ void ath6kl_connect_ap_mode_sta(struct ath6kl *ar, u16 aid, u8 *mac_addr,
netif_wake_queue(ar->net_dev);
}
-/* Functions for Tx credit handling */
-void ath6kl_credit_init(struct ath6kl_htc_credit_info *cred_info,
- struct list_head *ep_list,
- int tot_credits)
-{
- struct htc_endpoint_credit_dist *cur_ep_dist;
- int count;
-
- cred_info->cur_free_credits = tot_credits;
- cred_info->total_avail_credits = tot_credits;
-
- list_for_each_entry(cur_ep_dist, ep_list, list) {
- if (cur_ep_dist->endpoint == ENDPOINT_0)
- continue;
-
- cur_ep_dist->cred_min = cur_ep_dist->cred_per_msg;
-
- if (tot_credits > 4) {
- if ((cur_ep_dist->svc_id == WMI_DATA_BK_SVC) ||
- (cur_ep_dist->svc_id == WMI_DATA_BE_SVC)) {
- ath6kl_deposit_credit_to_ep(cred_info,
- cur_ep_dist,
- cur_ep_dist->cred_min);
- cur_ep_dist->dist_flags |= HTC_EP_ACTIVE;
- }
- }
-
- if (cur_ep_dist->svc_id == WMI_CONTROL_SVC) {
- ath6kl_deposit_credit_to_ep(cred_info, cur_ep_dist,
- cur_ep_dist->cred_min);
- /*
- * Control service is always marked active, it
- * never goes inactive EVER.
- */
- cur_ep_dist->dist_flags |= HTC_EP_ACTIVE;
- } else if (cur_ep_dist->svc_id == WMI_DATA_BK_SVC)
- /* this is the lowest priority data endpoint */
- /* FIXME: this looks fishy, check */
- cred_info->lowestpri_ep_dist = cur_ep_dist->list;
-
- /*
- * Streams have to be created (explicit | implicit) for all
- * kinds of traffic. BE endpoints are also inactive in the
- * beginning. When BE traffic starts it creates implicit
- * streams that redistributes credits.
- *
- * Note: all other endpoints have minimums set but are
- * initially given NO credits. credits will be distributed
- * as traffic activity demands
- */
- }
-
- WARN_ON(cred_info->cur_free_credits <= 0);
-
- list_for_each_entry(cur_ep_dist, ep_list, list) {
- if (cur_ep_dist->endpoint == ENDPOINT_0)
- continue;
-
- if (cur_ep_dist->svc_id == WMI_CONTROL_SVC)
- cur_ep_dist->cred_norm = cur_ep_dist->cred_per_msg;
- else {
- /*
- * For the remaining data endpoints, we assume that
- * each cred_per_msg are the same. We use a simple
- * calculation here, we take the remaining credits
- * and determine how many max messages this can
- * cover and then set each endpoint's normal value
- * equal to 3/4 this amount.
- */
- count = (cred_info->cur_free_credits /
- cur_ep_dist->cred_per_msg)
- * cur_ep_dist->cred_per_msg;
- count = (count * 3) >> 2;
- count = max(count, cur_ep_dist->cred_per_msg);
- cur_ep_dist->cred_norm = count;
-
- }
- }
-}
-
-/* initialize and setup credit distribution */
-int ath6kl_setup_credit_dist(void *htc_handle,
- struct ath6kl_htc_credit_info *cred_info)
-{
- u16 servicepriority[5];
-
- memset(cred_info, 0, sizeof(struct ath6kl_htc_credit_info));
-
- servicepriority[0] = WMI_CONTROL_SVC; /* highest */
- servicepriority[1] = WMI_DATA_VO_SVC;
- servicepriority[2] = WMI_DATA_VI_SVC;
- servicepriority[3] = WMI_DATA_BE_SVC;
- servicepriority[4] = WMI_DATA_BK_SVC; /* lowest */
-
- /* set priority list */
- ath6kl_htc_set_credit_dist(htc_handle, cred_info, servicepriority, 5);
-
- return 0;
-}
-
-/* reduce an ep's credits back to a set limit */
-static void ath6kl_reduce_credits(struct ath6kl_htc_credit_info *cred_info,
- struct htc_endpoint_credit_dist *ep_dist,
- int limit)
-{
- int credits;
-
- ep_dist->cred_assngd = limit;
-
- if (ep_dist->credits <= limit)
- return;
-
- credits = ep_dist->credits - limit;
- ep_dist->credits -= credits;
- cred_info->cur_free_credits += credits;
-}
-
-static void ath6kl_credit_update(struct ath6kl_htc_credit_info *cred_info,
- struct list_head *epdist_list)
-{
- struct htc_endpoint_credit_dist *cur_dist_list;
-
- list_for_each_entry(cur_dist_list, epdist_list, list) {
- if (cur_dist_list->endpoint == ENDPOINT_0)
- continue;
-
- if (cur_dist_list->cred_to_dist > 0) {
- cur_dist_list->credits +=
- cur_dist_list->cred_to_dist;
- cur_dist_list->cred_to_dist = 0;
- if (cur_dist_list->credits >
- cur_dist_list->cred_assngd)
- ath6kl_reduce_credits(cred_info,
- cur_dist_list,
- cur_dist_list->cred_assngd);
-
- if (cur_dist_list->credits >
- cur_dist_list->cred_norm)
- ath6kl_reduce_credits(cred_info, cur_dist_list,
- cur_dist_list->cred_norm);
-
- if (!(cur_dist_list->dist_flags & HTC_EP_ACTIVE)) {
- if (cur_dist_list->txq_depth == 0)
- ath6kl_reduce_credits(cred_info,
- cur_dist_list, 0);
- }
- }
- }
-}
-
-/*
- * HTC has an endpoint that needs credits, ep_dist is the endpoint in
- * question.
- */
-void ath6kl_seek_credits(struct ath6kl_htc_credit_info *cred_info,
- struct htc_endpoint_credit_dist *ep_dist)
-{
- struct htc_endpoint_credit_dist *curdist_list;
- int credits = 0;
- int need;
-
- if (ep_dist->svc_id == WMI_CONTROL_SVC)
- goto out;
-
- if ((ep_dist->svc_id == WMI_DATA_VI_SVC) ||
- (ep_dist->svc_id == WMI_DATA_VO_SVC))
- if ((ep_dist->cred_assngd >= ep_dist->cred_norm))
- goto out;
-
- /*
- * For all other services, we follow a simple algorithm of:
- *
- * 1. checking the free pool for credits
- * 2. checking lower priority endpoints for credits to take
- */
-
- credits = min(cred_info->cur_free_credits, ep_dist->seek_cred);
-
- if (credits >= ep_dist->seek_cred)
- goto out;
-
- /*
- * We don't have enough in the free pool, try taking away from
- * lower priority services The rule for taking away credits:
- *
- * 1. Only take from lower priority endpoints
- * 2. Only take what is allocated above the minimum (never
- * starve an endpoint completely)
- * 3. Only take what you need.
- */
-
- list_for_each_entry_reverse(curdist_list,
- &cred_info->lowestpri_ep_dist,
- list) {
- if (curdist_list == ep_dist)
- break;
-
- need = ep_dist->seek_cred - cred_info->cur_free_credits;
-
- if ((curdist_list->cred_assngd - need) >=
- curdist_list->cred_min) {
- /*
- * The current one has been allocated more than
- * it's minimum and it has enough credits assigned
- * above it's minimum to fulfill our need try to
- * take away just enough to fulfill our need.
- */
- ath6kl_reduce_credits(cred_info, curdist_list,
- curdist_list->cred_assngd - need);
-
- if (cred_info->cur_free_credits >=
- ep_dist->seek_cred)
- break;
- }
-
- if (curdist_list->endpoint == ENDPOINT_0)
- break;
- }
-
- credits = min(cred_info->cur_free_credits, ep_dist->seek_cred);
-
-out:
- /* did we find some credits? */
- if (credits)
- ath6kl_deposit_credit_to_ep(cred_info, ep_dist, credits);
-
- ep_dist->seek_cred = 0;
-}
-
-/* redistribute credits based on activity change */
-static void ath6kl_redistribute_credits(struct ath6kl_htc_credit_info *info,
- struct list_head *ep_dist_list)
-{
- struct htc_endpoint_credit_dist *curdist_list;
-
- list_for_each_entry(curdist_list, ep_dist_list, list) {
- if (curdist_list->endpoint == ENDPOINT_0)
- continue;
-
- if ((curdist_list->svc_id == WMI_DATA_BK_SVC) ||
- (curdist_list->svc_id == WMI_DATA_BE_SVC))
- curdist_list->dist_flags |= HTC_EP_ACTIVE;
-
- if ((curdist_list->svc_id != WMI_CONTROL_SVC) &&
- !(curdist_list->dist_flags & HTC_EP_ACTIVE)) {
- if (curdist_list->txq_depth == 0)
- ath6kl_reduce_credits(info, curdist_list, 0);
- else
- ath6kl_reduce_credits(info,
- curdist_list,
- curdist_list->cred_min);
- }
- }
-}
-
-/*
- *
- * This function is invoked whenever endpoints require credit
- * distributions. A lock is held while this function is invoked, this
- * function shall NOT block. The ep_dist_list is a list of distribution
- * structures in prioritized order as defined by the call to the
- * htc_set_credit_dist() api.
- */
-void ath6kl_credit_distribute(struct ath6kl_htc_credit_info *cred_info,
- struct list_head *ep_dist_list,
- enum htc_credit_dist_reason reason)
-{
- switch (reason) {
- case HTC_CREDIT_DIST_SEND_COMPLETE:
- ath6kl_credit_update(cred_info, ep_dist_list);
- break;
- case HTC_CREDIT_DIST_ACTIVITY_CHANGE:
- ath6kl_redistribute_credits(cred_info, ep_dist_list);
- break;
- default:
- break;
- }
-
- WARN_ON(cred_info->cur_free_credits > cred_info->total_avail_credits);
- WARN_ON(cred_info->cur_free_credits < 0);
-}
-
void disconnect_timer_handler(unsigned long ptr)
{
struct net_device *dev = (struct net_device *)ptr;
^ permalink raw reply related
* [PATCH 6/9] ath6kl: use ath6kl_credit prefix consistently
From: Kalle Valo @ 2011-10-24 9:17 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless
In-Reply-To: <20111024091644.5004.2767.stgit@localhost6.localdomain6>
Not all credit functions used that prefix, fix that.
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath6kl/htc.c | 63 ++++++++++++++++----------------
drivers/net/wireless/ath/ath6kl/htc.h | 4 +-
drivers/net/wireless/ath/ath6kl/init.c | 2 +
3 files changed, 34 insertions(+), 35 deletions(-)
diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c
index 5cb0327..511eebd 100644
--- a/drivers/net/wireless/ath/ath6kl/htc.c
+++ b/drivers/net/wireless/ath/ath6kl/htc.c
@@ -23,10 +23,9 @@
#define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask))
/* Functions for Tx credit handling */
-static void ath6kl_deposit_credit_to_ep(struct ath6kl_htc_credit_info
- *cred_info,
- struct htc_endpoint_credit_dist
- *ep_dist, int credits)
+static void ath6kl_credit_deposit(struct ath6kl_htc_credit_info *cred_info,
+ struct htc_endpoint_credit_dist *ep_dist,
+ int credits)
{
ep_dist->credits += credits;
ep_dist->cred_assngd += credits;
@@ -52,16 +51,16 @@ static void ath6kl_credit_init(struct ath6kl_htc_credit_info *cred_info,
if (tot_credits > 4) {
if ((cur_ep_dist->svc_id == WMI_DATA_BK_SVC) ||
(cur_ep_dist->svc_id == WMI_DATA_BE_SVC)) {
- ath6kl_deposit_credit_to_ep(cred_info,
- cur_ep_dist,
- cur_ep_dist->cred_min);
+ ath6kl_credit_deposit(cred_info,
+ cur_ep_dist,
+ cur_ep_dist->cred_min);
cur_ep_dist->dist_flags |= HTC_EP_ACTIVE;
}
}
if (cur_ep_dist->svc_id == WMI_CONTROL_SVC) {
- ath6kl_deposit_credit_to_ep(cred_info, cur_ep_dist,
- cur_ep_dist->cred_min);
+ ath6kl_credit_deposit(cred_info, cur_ep_dist,
+ cur_ep_dist->cred_min);
/*
* Control service is always marked active, it
* never goes inactive EVER.
@@ -113,8 +112,8 @@ static void ath6kl_credit_init(struct ath6kl_htc_credit_info *cred_info,
}
/* initialize and setup credit distribution */
-int ath6kl_setup_credit_dist(void *htc_handle,
- struct ath6kl_htc_credit_info *cred_info)
+int ath6kl_credit_setup(void *htc_handle,
+ struct ath6kl_htc_credit_info *cred_info)
{
u16 servicepriority[5];
@@ -133,9 +132,9 @@ int ath6kl_setup_credit_dist(void *htc_handle,
}
/* reduce an ep's credits back to a set limit */
-static void ath6kl_reduce_credits(struct ath6kl_htc_credit_info *cred_info,
- struct htc_endpoint_credit_dist *ep_dist,
- int limit)
+static void ath6kl_credit_reduce(struct ath6kl_htc_credit_info *cred_info,
+ struct htc_endpoint_credit_dist *ep_dist,
+ int limit)
{
int credits;
@@ -164,19 +163,19 @@ static void ath6kl_credit_update(struct ath6kl_htc_credit_info *cred_info,
cur_dist_list->cred_to_dist = 0;
if (cur_dist_list->credits >
cur_dist_list->cred_assngd)
- ath6kl_reduce_credits(cred_info,
+ ath6kl_credit_reduce(cred_info,
cur_dist_list,
cur_dist_list->cred_assngd);
if (cur_dist_list->credits >
cur_dist_list->cred_norm)
- ath6kl_reduce_credits(cred_info, cur_dist_list,
- cur_dist_list->cred_norm);
+ ath6kl_credit_reduce(cred_info, cur_dist_list,
+ cur_dist_list->cred_norm);
if (!(cur_dist_list->dist_flags & HTC_EP_ACTIVE)) {
if (cur_dist_list->txq_depth == 0)
- ath6kl_reduce_credits(cred_info,
- cur_dist_list, 0);
+ ath6kl_credit_reduce(cred_info,
+ cur_dist_list, 0);
}
}
}
@@ -186,7 +185,7 @@ static void ath6kl_credit_update(struct ath6kl_htc_credit_info *cred_info,
* HTC has an endpoint that needs credits, ep_dist is the endpoint in
* question.
*/
-static void ath6kl_seek_credits(struct ath6kl_htc_credit_info *cred_info,
+static void ath6kl_credit_seek(struct ath6kl_htc_credit_info *cred_info,
struct htc_endpoint_credit_dist *ep_dist)
{
struct htc_endpoint_credit_dist *curdist_list;
@@ -239,8 +238,8 @@ static void ath6kl_seek_credits(struct ath6kl_htc_credit_info *cred_info,
* above it's minimum to fulfill our need try to
* take away just enough to fulfill our need.
*/
- ath6kl_reduce_credits(cred_info, curdist_list,
- curdist_list->cred_assngd - need);
+ ath6kl_credit_reduce(cred_info, curdist_list,
+ curdist_list->cred_assngd - need);
if (cred_info->cur_free_credits >=
ep_dist->seek_cred)
@@ -256,14 +255,14 @@ static void ath6kl_seek_credits(struct ath6kl_htc_credit_info *cred_info,
out:
/* did we find some credits? */
if (credits)
- ath6kl_deposit_credit_to_ep(cred_info, ep_dist, credits);
+ ath6kl_credit_deposit(cred_info, ep_dist, credits);
ep_dist->seek_cred = 0;
}
/* redistribute credits based on activity change */
-static void ath6kl_redistribute_credits(struct ath6kl_htc_credit_info *info,
- struct list_head *ep_dist_list)
+static void ath6kl_credit_redistribute(struct ath6kl_htc_credit_info *info,
+ struct list_head *ep_dist_list)
{
struct htc_endpoint_credit_dist *curdist_list;
@@ -278,11 +277,11 @@ static void ath6kl_redistribute_credits(struct ath6kl_htc_credit_info *info,
if ((curdist_list->svc_id != WMI_CONTROL_SVC) &&
!(curdist_list->dist_flags & HTC_EP_ACTIVE)) {
if (curdist_list->txq_depth == 0)
- ath6kl_reduce_credits(info, curdist_list, 0);
+ ath6kl_credit_reduce(info, curdist_list, 0);
else
- ath6kl_reduce_credits(info,
- curdist_list,
- curdist_list->cred_min);
+ ath6kl_credit_reduce(info,
+ curdist_list,
+ curdist_list->cred_min);
}
}
}
@@ -304,7 +303,7 @@ static void ath6kl_credit_distribute(struct ath6kl_htc_credit_info *cred_info,
ath6kl_credit_update(cred_info, ep_dist_list);
break;
case HTC_CREDIT_DIST_ACTIVITY_CHANGE:
- ath6kl_redistribute_credits(cred_info, ep_dist_list);
+ ath6kl_credit_redistribute(cred_info, ep_dist_list);
break;
default:
break;
@@ -529,7 +528,7 @@ static int htc_check_credits(struct htc_target *target,
ath6kl_dbg(ATH6KL_DBG_HTC, "htc creds ctxt 0x%p dist 0x%p\n",
target->credit_info, &ep->cred_dist);
- ath6kl_seek_credits(target->credit_info, &ep->cred_dist);
+ ath6kl_credit_seek(target->credit_info, &ep->cred_dist);
ep->cred_dist.seek_cred = 0;
@@ -552,7 +551,7 @@ static int htc_check_credits(struct htc_target *target,
ath6kl_dbg(ATH6KL_DBG_HTC, "htc creds ctxt 0x%p dist 0x%p\n",
target->credit_info, &ep->cred_dist);
- ath6kl_seek_credits(target->credit_info, &ep->cred_dist);
+ ath6kl_credit_seek(target->credit_info, &ep->cred_dist);
/* see if we were successful in getting more */
if (ep->cred_dist.credits < ep->cred_dist.cred_per_msg) {
diff --git a/drivers/net/wireless/ath/ath6kl/htc.h b/drivers/net/wireless/ath/ath6kl/htc.h
index c68e834..57672e1 100644
--- a/drivers/net/wireless/ath/ath6kl/htc.h
+++ b/drivers/net/wireless/ath/ath6kl/htc.h
@@ -570,8 +570,8 @@ int ath6kl_htc_add_rxbuf_multiple(struct htc_target *target,
int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target,
u32 msg_look_ahead, int *n_pkts);
-int ath6kl_setup_credit_dist(void *htc_handle,
- struct ath6kl_htc_credit_info *cred_info);
+int ath6kl_credit_setup(void *htc_handle,
+ struct ath6kl_htc_credit_info *cred_info);
static inline void set_htc_pkt_info(struct htc_packet *packet, void *context,
u8 *buf, unsigned int len,
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 777ee2c..d161862 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -1516,7 +1516,7 @@ static int ath6kl_init(struct net_device *dev)
ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS);
/* setup credit distribution */
- ath6kl_setup_credit_dist(ar->htc_target, &ar->credit_state_info);
+ ath6kl_credit_setup(ar->htc_target, &ar->credit_state_info);
ath6kl_cookie_init(ar);
^ permalink raw reply related
* [PATCH 7/9] ath6kl: remove unused debug levels
From: Kalle Valo @ 2011-10-24 9:17 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless
In-Reply-To: <20111024091644.5004.2767.stgit@localhost6.localdomain6>
Few levels had only one user so I changed them to use WLAN_CFG.
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath6kl/debug.h | 8 ++++----
drivers/net/wireless/ath/ath6kl/main.c | 5 ++---
2 files changed, 6 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h
index cbabc25..afb747b 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.h
+++ b/drivers/net/wireless/ath/ath6kl/debug.h
@@ -20,16 +20,16 @@
#include "hif.h"
enum ATH6K_DEBUG_MASK {
- ATH6KL_DBG_WLAN_CONNECT = BIT(0), /* wlan connect */
- ATH6KL_DBG_WLAN_SCAN = BIT(1), /* wlan scan */
+ /* hole */
+ /* hole */
ATH6KL_DBG_WLAN_TX = BIT(2), /* wlan tx */
ATH6KL_DBG_WLAN_RX = BIT(3), /* wlan rx */
ATH6KL_DBG_BMI = BIT(4), /* bmi tracing */
ATH6KL_DBG_HTC = BIT(5),
ATH6KL_DBG_HIF = BIT(6),
ATH6KL_DBG_IRQ = BIT(7), /* interrupt processing */
- ATH6KL_DBG_PM = BIT(8), /* power management */
- ATH6KL_DBG_WLAN_NODE = BIT(9), /* general wlan node tracing */
+ /* hole */
+ /* hole */
ATH6KL_DBG_WMI = BIT(10), /* wmi tracing */
ATH6KL_DBG_TRC = BIT(11), /* generic func tracing */
ATH6KL_DBG_SCATTER = BIT(12), /* hif scatter tracing */
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index 8d9a8f3..9db86e3 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -742,7 +742,7 @@ void ath6kl_scan_complete_evt(struct ath6kl *ar, int status)
ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
}
- ath6kl_dbg(ATH6KL_DBG_WLAN_SCAN, "scan complete: %d\n", status);
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "scan complete: %d\n", status);
}
void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,
@@ -1089,8 +1089,7 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
del_timer(&ar->disconnect_timer);
- ath6kl_dbg(ATH6KL_DBG_WLAN_CONNECT,
- "disconnect reason is %d\n", reason);
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "disconnect reason is %d\n", reason);
/*
* If the event is due to disconnect cmd from the host, only they
^ permalink raw reply related
* [PATCH 8/9] ath6kl: add debug messages for credit handling
From: Kalle Valo @ 2011-10-24 9:17 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless
In-Reply-To: <20111024091644.5004.2767.stgit@localhost6.localdomain6>
Also take few from htc debug level which are more suitable for credit.
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath6kl/debug.c | 33 +++++++++++-----------
drivers/net/wireless/ath/ath6kl/debug.h | 2 +
drivers/net/wireless/ath/ath6kl/htc.c | 46 ++++++++++++++++---------------
3 files changed, 41 insertions(+), 40 deletions(-)
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index 324fdb3..7bc2656 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -142,47 +142,46 @@ void ath6kl_dump_registers(struct ath6kl_device *dev,
static void dump_cred_dist(struct htc_endpoint_credit_dist *ep_dist)
{
- ath6kl_dbg(ATH6KL_DBG_ANY,
+ ath6kl_dbg(ATH6KL_DBG_CREDIT,
"--- endpoint: %d svc_id: 0x%X ---\n",
ep_dist->endpoint, ep_dist->svc_id);
- ath6kl_dbg(ATH6KL_DBG_ANY, " dist_flags : 0x%X\n",
+ ath6kl_dbg(ATH6KL_DBG_CREDIT, " dist_flags : 0x%X\n",
ep_dist->dist_flags);
- ath6kl_dbg(ATH6KL_DBG_ANY, " cred_norm : %d\n",
+ ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_norm : %d\n",
ep_dist->cred_norm);
- ath6kl_dbg(ATH6KL_DBG_ANY, " cred_min : %d\n",
+ ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_min : %d\n",
ep_dist->cred_min);
- ath6kl_dbg(ATH6KL_DBG_ANY, " credits : %d\n",
+ ath6kl_dbg(ATH6KL_DBG_CREDIT, " credits : %d\n",
ep_dist->credits);
- ath6kl_dbg(ATH6KL_DBG_ANY, " cred_assngd : %d\n",
+ ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_assngd : %d\n",
ep_dist->cred_assngd);
- ath6kl_dbg(ATH6KL_DBG_ANY, " seek_cred : %d\n",
+ ath6kl_dbg(ATH6KL_DBG_CREDIT, " seek_cred : %d\n",
ep_dist->seek_cred);
- ath6kl_dbg(ATH6KL_DBG_ANY, " cred_sz : %d\n",
+ ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_sz : %d\n",
ep_dist->cred_sz);
- ath6kl_dbg(ATH6KL_DBG_ANY, " cred_per_msg : %d\n",
+ ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_per_msg : %d\n",
ep_dist->cred_per_msg);
- ath6kl_dbg(ATH6KL_DBG_ANY, " cred_to_dist : %d\n",
+ ath6kl_dbg(ATH6KL_DBG_CREDIT, " cred_to_dist : %d\n",
ep_dist->cred_to_dist);
- ath6kl_dbg(ATH6KL_DBG_ANY, " txq_depth : %d\n",
+ ath6kl_dbg(ATH6KL_DBG_CREDIT, " txq_depth : %d\n",
get_queue_depth(&ep_dist->htc_ep->txq));
- ath6kl_dbg(ATH6KL_DBG_ANY,
+ ath6kl_dbg(ATH6KL_DBG_CREDIT,
"----------------------------------\n");
}
+/* FIXME: move to htc.c */
void dump_cred_dist_stats(struct htc_target *target)
{
struct htc_endpoint_credit_dist *ep_list;
- if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_TRC))
+ if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_CREDIT))
return;
list_for_each_entry(ep_list, &target->cred_dist_list, list)
dump_cred_dist(ep_list);
- ath6kl_dbg(ATH6KL_DBG_HTC, "ctxt:%p dist:%p\n",
- target->credit_info, NULL);
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "credit distribution, total : %d, free : %d\n",
+ ath6kl_dbg(ATH6KL_DBG_CREDIT,
+ "credit distribution total %d free %d\n",
target->credit_info->total_avail_credits,
target->credit_info->cur_free_credits);
}
diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h
index afb747b..491485e 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.h
+++ b/drivers/net/wireless/ath/ath6kl/debug.h
@@ -20,7 +20,7 @@
#include "hif.h"
enum ATH6K_DEBUG_MASK {
- /* hole */
+ ATH6KL_DBG_CREDIT = BIT(0),
/* hole */
ATH6KL_DBG_WLAN_TX = BIT(2), /* wlan tx */
ATH6KL_DBG_WLAN_RX = BIT(3), /* wlan rx */
diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c
index 511eebd..a971c2f 100644
--- a/drivers/net/wireless/ath/ath6kl/htc.c
+++ b/drivers/net/wireless/ath/ath6kl/htc.c
@@ -27,6 +27,9 @@ static void ath6kl_credit_deposit(struct ath6kl_htc_credit_info *cred_info,
struct htc_endpoint_credit_dist *ep_dist,
int credits)
{
+ ath6kl_dbg(ATH6KL_DBG_CREDIT, "credit deposit ep %d credits %d\n",
+ ep_dist->endpoint, credits);
+
ep_dist->credits += credits;
ep_dist->cred_assngd += credits;
cred_info->cur_free_credits -= credits;
@@ -39,6 +42,8 @@ static void ath6kl_credit_init(struct ath6kl_htc_credit_info *cred_info,
struct htc_endpoint_credit_dist *cur_ep_dist;
int count;
+ ath6kl_dbg(ATH6KL_DBG_CREDIT, "credit init total %d\n", tot_credits);
+
cred_info->cur_free_credits = tot_credits;
cred_info->total_avail_credits = tot_credits;
@@ -108,6 +113,15 @@ static void ath6kl_credit_init(struct ath6kl_htc_credit_info *cred_info,
cur_ep_dist->cred_norm = count;
}
+
+ ath6kl_dbg(ATH6KL_DBG_CREDIT,
+ "credit ep %d svc_id %d credits %d per_msg %d norm %d min %d\n",
+ cur_ep_dist->endpoint,
+ cur_ep_dist->svc_id,
+ cur_ep_dist->credits,
+ cur_ep_dist->cred_per_msg,
+ cur_ep_dist->cred_norm,
+ cur_ep_dist->cred_min);
}
}
@@ -138,6 +152,9 @@ static void ath6kl_credit_reduce(struct ath6kl_htc_credit_info *cred_info,
{
int credits;
+ ath6kl_dbg(ATH6KL_DBG_CREDIT, "credit reduce ep %d limit %d\n",
+ ep_dist->endpoint, limit);
+
ep_dist->cred_assngd = limit;
if (ep_dist->credits <= limit)
@@ -515,7 +532,7 @@ static int htc_check_credits(struct htc_target *target,
*req_cred = (len > target->tgt_cred_sz) ?
DIV_ROUND_UP(len, target->tgt_cred_sz) : 1;
- ath6kl_dbg(ATH6KL_DBG_HTC, "htc creds required %d got %d\n",
+ ath6kl_dbg(ATH6KL_DBG_CREDIT, "credit check need %d got %d\n",
*req_cred, ep->cred_dist.credits);
if (ep->cred_dist.credits < *req_cred) {
@@ -525,16 +542,13 @@ static int htc_check_credits(struct htc_target *target,
/* Seek more credits */
ep->cred_dist.seek_cred = *req_cred - ep->cred_dist.credits;
- ath6kl_dbg(ATH6KL_DBG_HTC, "htc creds ctxt 0x%p dist 0x%p\n",
- target->credit_info, &ep->cred_dist);
-
ath6kl_credit_seek(target->credit_info, &ep->cred_dist);
ep->cred_dist.seek_cred = 0;
if (ep->cred_dist.credits < *req_cred) {
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc creds not enough credits for ep %d\n",
+ ath6kl_dbg(ATH6KL_DBG_CREDIT,
+ "credit not found for ep %d\n",
eid);
return -EINVAL;
}
@@ -548,9 +562,6 @@ static int htc_check_credits(struct htc_target *target,
ep->cred_dist.seek_cred =
ep->cred_dist.cred_per_msg - ep->cred_dist.credits;
- ath6kl_dbg(ATH6KL_DBG_HTC, "htc creds ctxt 0x%p dist 0x%p\n",
- target->credit_info, &ep->cred_dist);
-
ath6kl_credit_seek(target->credit_info, &ep->cred_dist);
/* see if we were successful in getting more */
@@ -558,7 +569,8 @@ static int htc_check_credits(struct htc_target *target,
/* tell the target we need credits ASAP! */
*flags |= HTC_FLAGS_NEED_CREDIT_UPDATE;
ep->ep_st.cred_low_indicate += 1;
- ath6kl_dbg(ATH6KL_DBG_HTC, "htc creds host needs credits\n");
+ ath6kl_dbg(ATH6KL_DBG_CREDIT,
+ "credit we need credits asap\n");
}
}
@@ -1495,9 +1507,6 @@ static void htc_proc_cred_rpt(struct htc_target *target,
int tot_credits = 0, i;
bool dist = false;
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc creds report entries %d\n", n_entries);
-
spin_lock_bh(&target->tx_lock);
for (i = 0; i < n_entries; i++, rpt++) {
@@ -1509,8 +1518,8 @@ static void htc_proc_cred_rpt(struct htc_target *target,
endpoint = &target->endpoint[rpt->eid];
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc creds report ep %d credits %d\n",
+ ath6kl_dbg(ATH6KL_DBG_CREDIT,
+ "credit report ep %d credits %d\n",
rpt->eid, rpt->credits);
endpoint->ep_st.tx_cred_rpt += 1;
@@ -1551,18 +1560,11 @@ static void htc_proc_cred_rpt(struct htc_target *target,
tot_credits += rpt->credits;
}
- ath6kl_dbg(ATH6KL_DBG_HTC,
- "htc creds report tot_credits %d\n",
- tot_credits);
-
if (dist) {
/*
* This was a credit return based on a completed send
* operations note, this is done with the lock held
*/
- ath6kl_dbg(ATH6KL_DBG_HTC, "htc creds ctxt 0x%p dist 0x%p\n",
- target->credit_info, &target->cred_dist_list);
-
ath6kl_credit_distribute(target->credit_info,
&target->cred_dist_list,
HTC_CREDIT_DIST_SEND_COMPLETE);
^ permalink raw reply related
* [PATCH 9/9] ath6kl: add more boot debug messages
From: Kalle Valo @ 2011-10-24 9:18 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless
In-Reply-To: <20111024091644.5004.2767.stgit@localhost6.localdomain6>
Move some of the debug logs to boot level because they are more
interesting when debugging boot issues.
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath6kl/htc.c | 8 ++++----
drivers/net/wireless/ath/ath6kl/sdio.c | 22 +++++++++++++---------
2 files changed, 17 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c
index a971c2f..976e352 100644
--- a/drivers/net/wireless/ath/ath6kl/htc.c
+++ b/drivers/net/wireless/ath/ath6kl/htc.c
@@ -2499,7 +2499,7 @@ static void htc_setup_msg_bndl(struct htc_target *target)
target->msg_per_bndl_max = min(target->max_scat_entries,
target->msg_per_bndl_max);
- ath6kl_dbg(ATH6KL_DBG_HTC,
+ ath6kl_dbg(ATH6KL_DBG_BOOT,
"htc bundling allowed msg_per_bndl_max %d\n",
target->msg_per_bndl_max);
@@ -2509,7 +2509,7 @@ static void htc_setup_msg_bndl(struct htc_target *target)
target->max_tx_bndl_sz = min(HIF_MBOX0_EXT_WIDTH,
target->max_xfer_szper_scatreq);
- ath6kl_dbg(ATH6KL_DBG_HTC, "htc max_rx_bndl_sz %d max_tx_bndl_sz %d\n",
+ ath6kl_dbg(ATH6KL_DBG_BOOT, "htc max_rx_bndl_sz %d max_tx_bndl_sz %d\n",
target->max_rx_bndl_sz, target->max_tx_bndl_sz);
if (target->max_tx_bndl_sz)
@@ -2563,7 +2563,7 @@ int ath6kl_htc_wait_target(struct htc_target *target)
target->tgt_creds = le16_to_cpu(rdy_msg->ver2_0_info.cred_cnt);
target->tgt_cred_sz = le16_to_cpu(rdy_msg->ver2_0_info.cred_sz);
- ath6kl_dbg(ATH6KL_DBG_HTC,
+ ath6kl_dbg(ATH6KL_DBG_BOOT,
"htc target ready credits %d size %d\n",
target->tgt_creds, target->tgt_cred_sz);
@@ -2578,7 +2578,7 @@ int ath6kl_htc_wait_target(struct htc_target *target)
target->msg_per_bndl_max = 0;
}
- ath6kl_dbg(ATH6KL_DBG_HTC, "htc using protocol %s (%d)\n",
+ ath6kl_dbg(ATH6KL_DBG_BOOT, "htc using protocol %s (%d)\n",
(target->htc_tgt_ver == HTC_VERSION_2P0) ? "2.0" : ">= 2.1",
target->htc_tgt_ver);
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
index 58e31f6..b7bbe56 100644
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -471,6 +471,8 @@ static int ath6kl_sdio_power_on(struct ath6kl_sdio *ar_sdio)
if (!ar_sdio->is_disabled)
return 0;
+ ath6kl_dbg(ATH6KL_DBG_BOOT, "sdio power on\n");
+
sdio_claim_host(func);
ret = sdio_enable_func(func);
@@ -500,6 +502,8 @@ static int ath6kl_sdio_power_off(struct ath6kl_sdio *ar_sdio)
if (ar_sdio->is_disabled)
return 0;
+ ath6kl_dbg(ATH6KL_DBG_BOOT, "sdio power off\n");
+
/* Disable the card */
sdio_claim_host(ar_sdio->func);
ret = sdio_disable_func(ar_sdio->func);
@@ -678,8 +682,8 @@ static int ath6kl_sdio_enable_scatter(struct ath6kl *ar)
MAX_SCATTER_REQUESTS, virt_scat);
if (!ret) {
- ath6kl_dbg(ATH6KL_DBG_SCATTER,
- "hif-scatter enabled: max scatter req : %d entries: %d\n",
+ ath6kl_dbg(ATH6KL_DBG_BOOT,
+ "hif-scatter enabled requests %d entries %d\n",
MAX_SCATTER_REQUESTS,
MAX_SCATTER_ENTRIES_PER_REQ);
@@ -703,8 +707,8 @@ static int ath6kl_sdio_enable_scatter(struct ath6kl *ar)
return ret;
}
- ath6kl_dbg(ATH6KL_DBG_SCATTER,
- "Vitual scatter enabled, max_scat_req:%d, entries:%d\n",
+ ath6kl_dbg(ATH6KL_DBG_BOOT,
+ "virtual scatter enabled requests %d entries %d\n",
ATH6KL_SCATTER_REQS, ATH6KL_SCATTER_ENTRIES_PER_REQ);
target->max_scat_entries = ATH6KL_SCATTER_ENTRIES_PER_REQ;
@@ -778,8 +782,8 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
struct ath6kl *ar;
int count;
- ath6kl_dbg(ATH6KL_DBG_SDIO,
- "new func %d vendor 0x%x device 0x%x block 0x%x/0x%x\n",
+ ath6kl_dbg(ATH6KL_DBG_BOOT,
+ "sdio new func %d vendor 0x%x device 0x%x block 0x%x/0x%x\n",
func->num, func->vendor, func->device,
func->max_blksize, func->cur_blksize);
@@ -840,7 +844,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func,
goto err_cfg80211;
}
- ath6kl_dbg(ATH6KL_DBG_SDIO, "4-bit async irq mode enabled\n");
+ ath6kl_dbg(ATH6KL_DBG_BOOT, "4-bit async irq mode enabled\n");
}
/* give us some time to enable, in ms */
@@ -888,8 +892,8 @@ static void ath6kl_sdio_remove(struct sdio_func *func)
{
struct ath6kl_sdio *ar_sdio;
- ath6kl_dbg(ATH6KL_DBG_SDIO,
- "removed func %d vendor 0x%x device 0x%x\n",
+ ath6kl_dbg(ATH6KL_DBG_BOOT,
+ "sdio removed func %d vendor 0x%x device 0x%x\n",
func->num, func->vendor, func->device);
ar_sdio = sdio_get_drvdata(func);
^ permalink raw reply related
* [BUG] Invalid file descriptor.
From: Daniel Wagner @ 2011-10-24 9:49 UTC (permalink / raw)
To: linux-wireless
To whom it might concern,
if bluez is running without an agent and the remote device tries to
connect to bluez you are able to trigger the "Invalid file descriptor".
bluetoothd[30869]: src/event.c:btd_event_bonding_complete() status 0x00
bluetoothd[30869]: src/adapter.c:adapter_get_device() A0:4E:04:F6:F5:05
bluetoothd[30869]: src/device.c:device_bonding_complete() bonding (nil)
status 0x00
bluetoothd[30869]: audio/manager.c:hf_io_cb() Authorization denied!
(bluetoothd:30869): GLib-WARNING **: Invalid file descriptor.
bluetoothd[30869]: plugins/hciops.c:disconn_complete() handle 44 status 0x00
bluetoothd[30869]: src/event.c:btd_event_disconn_complete()
bluetoothd[30869]: src/adapter.c:adapter_remove_connection()
cheers,
daniel
ps: I was told to report all crashes and bugs I find. Be prepared. I am
a very capable finding bugs :)
^ permalink raw reply
* Re: [PATCH 1/2] mac80211: fix remain_off_channel regression
From: Stanislaw Gruszka @ 2011-10-24 11:27 UTC (permalink / raw)
To: Eliad Peller, John W. Linville; +Cc: Johannes Berg, linux-wireless
In-Reply-To: <1319130350-15514-1-git-send-email-eliad@wizery.com>
On Thu, Oct 20, 2011 at 07:05:49PM +0200, Eliad Peller wrote:
> The offchannel code is currently broken - we should
> remain_off_channel if the work was started, and
> the work's channel and channel_type are the same
> as local->tmp_channel and local->tmp_channel_type.
>
> However, if wk->chan_type and local->tmp_channel_type
> coexist (e.g. have the same channel type), we won't
> remain_off_channel.
>
> This behavior was introduced by commit da2fd1f
> ("mac80211: Allow work items to use existing
> channel type.")
>
> Tested-by: Ben Greear <greearb@candelatech.com>
> Signed-off-by: Eliad Peller <eliad@wizery.com>
Both patches fixes serious bugs, should be marked
Cc: stable@kernel.org # 2.6.39+
I believe there is no need to repost, once informed
John would take care of process patches properly.
Stanislaw
^ permalink raw reply
* Re: [RFC] mac80211: Fix STA supported rate configuration with dummy entry
From: Arik Nemtsov @ 2011-10-24 11:59 UTC (permalink / raw)
To: Jouni Malinen; +Cc: Johannes Berg, Felix Fietkau, linux-wireless
In-Reply-To: <20111023194059.GA18385@jm.kir.nu>
On Sun, Oct 23, 2011 at 21:40, Jouni Malinen <j@w1.fi> wrote:
>
> Are all rate control algorithms fine with the second
> rate_control_rate_init() call? That is needed in the TDLS use case where
> the supported rate set is known only after the STA entry has been
Note that the sta-rates are not really required before second addition
(which also sets them). Initially the STA is not authorized for direct
Tx (as determined by the WLAN_STA_TDLS_PEER_AUTH bit).
We don't expect direct frames during link setup.
> added. I guess it would be possible to delay addition of the STA entry
> for TDLS until the supported rates are known, but I did not look at the
> details on what exactly that would require.
The STA is added to let us know we should drop all non-setup packets
between TDLS peers currently in link setup. We could have used a
different indication, but the STA entry is make the most sense here
since it is automatically cleaned up when we are disconnected from the
AP (as all TDLS state should be).
How about this one instead (tested hwsim with it):
>From d8b7acc16073e50f4fda3365d98ad01b21e2c631 Mon Sep 17 00:00:00 2001
From: Arik Nemtsov <arik@wizery.com>
Date: Mon, 24 Oct 2011 13:44:07 +0200
Subject: [RFC] mac80211: init rate-control for TDLS sta when supp-rates are
known
Initialize rate control algorithms only when supported rates are known
for a TDLS peer sta. Direct Tx between peers is not allowed before the
link is enabled. In turn, this only occurs after a change_station()
call that sets supported rates.
---
net/mac80211/cfg.c | 10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 1309bb9..9f05416d 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -829,7 +829,12 @@ static int ieee80211_add_station(struct wiphy
*wiphy, struct net_device *dev,
sdata->vif.type == NL80211_IFTYPE_STATION))
return -ENOTSUPP;
- rate_control_rate_init(sta);
+ /*
+ * for TDLS, rate control should be initialized only when supported
+ * rates are known.
+ */
+ if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER))
+ rate_control_rate_init(sta);
layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
sdata->vif.type == NL80211_IFTYPE_AP;
@@ -913,6 +918,9 @@ static int ieee80211_change_station(struct wiphy *wiphy,
sta_apply_parameters(local, sta, params);
+ if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) && params->supported_rates)
+ rate_control_rate_init(sta);
+
rcu_read_unlock();
if (sdata->vif.type == NL80211_IFTYPE_STATION &&
--
1.7.5.4
^ permalink raw reply related
* Re: [RFC] mac80211: Fix STA supported rate configuration with dummy entry
From: Jouni Malinen @ 2011-10-24 12:15 UTC (permalink / raw)
To: Arik Nemtsov; +Cc: Johannes Berg, Felix Fietkau, linux-wireless
In-Reply-To: <CA+XVXfdP5VjMLaYxh6Saa+SM+cDUG+h18L0ixheQmaAo+yQX+Q@mail.gmail.com>
On Mon, Oct 24, 2011 at 01:59:45PM +0200, Arik Nemtsov wrote:
> Note that the sta-rates are not really required before second addition
> (which also sets them). Initially the STA is not authorized for direct
> Tx (as determined by the WLAN_STA_TDLS_PEER_AUTH bit).
> We don't expect direct frames during link setup.
OK.. Though, there can still be some direct frames like TDLS Discovery
Response.
> The STA is added to let us know we should drop all non-setup packets
> between TDLS peers currently in link setup. We could have used a
> different indication, but the STA entry is make the most sense here
> since it is automatically cleaned up when we are disconnected from the
> AP (as all TDLS state should be).
When you say "drop", I hope you mean "buffer for later delivery" and
when you say "non-setup packets", I hope you mean "non-setup Data
frames" ;-).
> How about this one instead (tested hwsim with it):
> Subject: [RFC] mac80211: init rate-control for TDLS sta when supp-rates are
> known
>
> Initialize rate control algorithms only when supported rates are known
> for a TDLS peer sta. Direct Tx between peers is not allowed before the
> link is enabled. In turn, this only occurs after a change_station()
> call that sets supported rates.
I guess this could be fine, too, assuming TDLS is the only use case for
this type of changing of STA supported rates.
--
Jouni Malinen PGP id EFC895FA
^ permalink raw reply
* Re: [RFC] mac80211: Fix STA supported rate configuration with dummy entry
From: Arik Nemtsov @ 2011-10-24 12:37 UTC (permalink / raw)
To: Jouni Malinen; +Cc: Johannes Berg, Felix Fietkau, linux-wireless
In-Reply-To: <20111024121559.GA4821@jm.kir.nu>
On Mon, Oct 24, 2011 at 14:15, Jouni Malinen <j@w1.fi> wrote:
> On Mon, Oct 24, 2011 at 01:59:45PM +0200, Arik Nemtsov wrote:
>> Note that the sta-rates are not really required before second addition
>> (which also sets them). Initially the STA is not authorized for direct
>> Tx (as determined by the WLAN_STA_TDLS_PEER_AUTH bit).
>> We don't expect direct frames during link setup.
>
> OK.. Though, there can still be some direct frames like TDLS Discovery
> Response.
You have a point there - this one is not related to link setup. At
this point we really have no idea about peer supported rates (and no
STA entry).
I just tested this with hwsim and it seems to work. The rate chosen is
the the smallest non-basic rate (haven't looked at why that happens).
With cards that use HW rate control (like wl12xx), this will of course
be implementation defined.
>
>> The STA is added to let us know we should drop all non-setup packets
>> between TDLS peers currently in link setup. We could have used a
>> different indication, but the STA entry is make the most sense here
>> since it is automatically cleaned up when we are disconnected from the
>> AP (as all TDLS state should be).
>
> When you say "drop", I hope you mean "buffer for later delivery" and
> when you say "non-setup packets", I hope you mean "non-setup Data
> frames" ;-).
No I mean "drop". Initially a buffer was planned, but in reality the
setup process is extremely fast. I setup iperf between two regular
stations (about 15mb/s) and proceeded to setup TDLS. I managed to lose
only about 3-4 frames each time.
Of course there may be anomalies (bad link quality etc.), but IMHO for
real-world situations the extra complexity of a buffering mechanism is
not warranted. Also higher level protocols (like TCP) will generally
make up for any loss.
I'll change the second one to "non-setup Data frames" :)
>
>> How about this one instead (tested hwsim with it):
>> Subject: [RFC] mac80211: init rate-control for TDLS sta when supp-rates are
>> known
>>
>> Initialize rate control algorithms only when supported rates are known
>> for a TDLS peer sta. Direct Tx between peers is not allowed before the
>> link is enabled. In turn, this only occurs after a change_station()
>> call that sets supported rates.
>
> I guess this could be fine, too, assuming TDLS is the only use case for
> this type of changing of STA supported rates.
Currently it is - we even check this explicitly higher up in
nl80211_set_station().
Arik
^ permalink raw reply
* [PATCH] ath9k_hw: Update AR9485 initvals to fix system hang issue
From: Rajkumar Manoharan @ 2011-10-24 12:43 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Rajkumar Manoharan, stable
This patch fixes system hang when resuming from S3 state
and lower rate sens failure issue.
Cc: stable@kernel.org
Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/ar9485_initvals.h | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
index 611ea6c..d16d029 100644
--- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
@@ -521,7 +521,7 @@ static const u32 ar9485_1_1_radio_postamble[][2] = {
{0x000160ac, 0x24611800},
{0x000160b0, 0x03284f3e},
{0x0001610c, 0x00170000},
- {0x00016140, 0x10804008},
+ {0x00016140, 0x50804008},
};
static const u32 ar9485_1_1_mac_postamble[][5] = {
@@ -603,7 +603,7 @@ static const u32 ar9485_1_1_radio_core[][2] = {
static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_enable_L1[][2] = {
/* Addr allmodes */
- {0x00018c00, 0x10052e5e},
+ {0x00018c00, 0x18052e5e},
{0x00018c04, 0x000801d8},
{0x00018c08, 0x0000080c},
};
@@ -776,7 +776,7 @@ static const u32 ar9485_modes_green_ob_db_tx_gain_1_1[][5] = {
static const u32 ar9485_1_1_pcie_phy_clkreq_disable_L1[][2] = {
/* Addr allmodes */
- {0x00018c00, 0x10013e5e},
+ {0x00018c00, 0x18013e5e},
{0x00018c04, 0x000801d8},
{0x00018c08, 0x0000080c},
};
@@ -882,7 +882,7 @@ static const u32 ar9485_fast_clock_1_1_baseband_postamble[][3] = {
static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1[][2] = {
/* Addr allmodes */
- {0x00018c00, 0x10012e5e},
+ {0x00018c00, 0x18012e5e},
{0x00018c04, 0x000801d8},
{0x00018c08, 0x0000080c},
};
@@ -1021,7 +1021,7 @@ static const u32 ar9485_common_rx_gain_1_1[][2] = {
static const u32 ar9485_1_1_pcie_phy_clkreq_enable_L1[][2] = {
/* Addr allmodes */
- {0x00018c00, 0x10053e5e},
+ {0x00018c00, 0x18053e5e},
{0x00018c04, 0x000801d8},
{0x00018c08, 0x0000080c},
};
--
1.7.7
^ permalink raw reply related
* [PATCH] ath9k_hw: Update CCK spur mitigation for AR9462
From: Rajkumar Manoharan @ 2011-10-24 12:44 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Rajkumar Manoharan
To improve CCK sensitivity for AR9462 chips, performing
spur mitigation at 2440, 2464 frequencies alone is sufficient.
Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath9k/ar9003_phy.c | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index fe96997..04b060a 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -198,12 +198,14 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
synth_freq = chan->channel;
}
} else {
- range = 10;
+ range = AR_SREV_9462(ah) ? 5 : 10;
max_spur_cnts = 4;
synth_freq = chan->channel;
}
for (i = 0; i < max_spur_cnts; i++) {
+ if (AR_SREV_9462(ah) && (i == 0 || i == 3))
+ continue;
negative = 0;
if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah))
cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i],
--
1.7.7
^ permalink raw reply related
* Re: BUG: All network processes hang (brcmsmac/wpa_supplicant)
From: Arend van Spriel @ 2011-10-24 12:50 UTC (permalink / raw)
To: Nico Schottelius; +Cc: Eric Dumazet, linux-wireless@vger.kernel.org
In-Reply-To: <20111023194823.GB2489@schottelius.org>
On 10/23/2011 09:48 PM, Nico Schottelius wrote:
> Update, just triggered it after a suspend/resume cycle:
>
> This changes every some seconds right now, because the connection
> is established/shutdown and thus dhcpcd retries to get the ip address
> every few seconds.
>
> I've restarted the AP, but the situation stays the same.
>
> The other devices in the network work fine, so it's really my system
> that behaves "funny".
>
> After that I've reloaded brcmsmac at 84262.797365, after which
> the connection time lasted longer, but was also interrupted some
> time later.
>
> dmesg attached again.
>
> Cheers,
>
> Nico
>
I tried to make sense of the dmesg log you sent me. Not sure what is
happening so could do the following:
1. Determine wpa_supplicant version using -v option.
2. Add '-ddt' option in DBus service file:
wpa_supplicant >= 0.7: fi.w1.wpa_supplicant1.service
wpa_supplicant < 0.7: fi.epitest.hostap.WPASupplicant.service
(located in /usr/share/dbus-1/system-services/).
3. Reproduce the problem and sent /var/log/syslog.
Thanks
AvS
^ permalink raw reply
* [PATCH] ath9k: Add btcoex profile management support for AR9462
From: Rajkumar Manoharan @ 2011-10-24 12:49 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, Rajkumar Manoharan
AR9462 chips have the capabilities to provoide bluetooth
profile information. For non-AR9462 btcoex chips, the BT
priority traffic was identified by periodically polling
the respective registers and updated dutycycle, stomptype,
etc. As AR9462 chip offers the BT profile informations,
let us make use of that to update aggregation limit,
dutycycle, stomptype and wieghtages.
Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath.h | 1 +
drivers/net/wireless/ath/ath9k/Makefile | 1 +
drivers/net/wireless/ath/ath9k/ath9k.h | 3 +
drivers/net/wireless/ath/ath9k/gpio.c | 7 +-
drivers/net/wireless/ath/ath9k/hw.c | 2 +-
drivers/net/wireless/ath/ath9k/hw.h | 11 ++
drivers/net/wireless/ath/ath9k/init.c | 2 +
drivers/net/wireless/ath/ath9k/main.c | 6 +-
drivers/net/wireless/ath/ath9k/mci.c | 254 +++++++++++++++++++++++++++++++
drivers/net/wireless/ath/ath9k/mci.h | 118 ++++++++++++++
drivers/net/wireless/ath/ath9k/xmit.c | 5 +-
11 files changed, 403 insertions(+), 7 deletions(-)
create mode 100644 drivers/net/wireless/ath/ath9k/mci.c
create mode 100644 drivers/net/wireless/ath/ath9k/mci.h
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 908fdbc..fe4bf4d 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -240,6 +240,7 @@ enum ATH_DEBUG {
ATH_DBG_BTCOEX = 0x00002000,
ATH_DBG_WMI = 0x00004000,
ATH_DBG_BSTUCK = 0x00008000,
+ ATH_DBG_MCI = 0x00010000,
ATH_DBG_ANY = 0xffffffff
};
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 36ed3c4..49d3f25 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -4,6 +4,7 @@ ath9k-y += beacon.o \
main.o \
recv.o \
xmit.o \
+ mci.o \
ath9k-$(CONFIG_ATH9K_RATE_CONTROL) += rc.o
ath9k-$(CONFIG_ATH9K_PCI) += pci.o
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 1c269f5..4415e89 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -25,6 +25,7 @@
#include "debug.h"
#include "common.h"
+#include "mci.h"
/*
* Header for the ath9k.ko driver core *only* -- hw code nor any other driver
@@ -443,7 +444,9 @@ struct ath_btcoex {
u32 btcoex_no_stomp; /* in usec */
u32 btcoex_period; /* in usec */
u32 btscan_no_stomp; /* in usec */
+ u32 duty_cycle;
struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */
+ struct ath_mci_profile mci;
};
int ath_init_btcoex_timer(struct ath_softc *sc);
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
index 655576c..2c279dc 100644
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -189,8 +189,8 @@ static void ath_btcoex_period_timer(unsigned long data)
bool is_btscan;
ath9k_ps_wakeup(sc);
- ath_detect_bt_priority(sc);
-
+ if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI))
+ ath_detect_bt_priority(sc);
is_btscan = sc->sc_flags & SC_OP_BT_SCAN;
spin_lock_bh(&btcoex->btcoex_lock);
@@ -212,8 +212,9 @@ static void ath_btcoex_period_timer(unsigned long data)
}
ath9k_ps_restore(sc);
+ timer_period = btcoex->btcoex_period / 1000;
mod_timer(&btcoex->period_timer, jiffies +
- msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD));
+ msecs_to_jiffies(timer_period));
}
/*
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index f16d203..8c36938 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2331,7 +2331,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
ah->enabled_cals |= TX_IQ_ON_AGC_CAL;
}
if (AR_SREV_9462(ah))
- pCap->hw_caps |= ATH9K_HW_CAP_RTT;
+ pCap->hw_caps |= ATH9K_HW_CAP_RTT | ATH9K_HW_CAP_MCI;
return 0;
}
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index f389b3c..33e8f2f 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -203,6 +203,7 @@ enum ath9k_hw_caps {
ATH9K_HW_CAP_5GHZ = BIT(14),
ATH9K_HW_CAP_APM = BIT(15),
ATH9K_HW_CAP_RTT = BIT(16),
+ ATH9K_HW_CAP_MCI = BIT(17),
};
struct ath9k_hw_capabilities {
@@ -419,6 +420,16 @@ enum ath9k_rx_qtype {
ATH9K_RX_QUEUE_MAX,
};
+enum ath_mci_gpm_coex_profile_type {
+ MCI_GPM_COEX_PROFILE_UNKNOWN,
+ MCI_GPM_COEX_PROFILE_RFCOMM,
+ MCI_GPM_COEX_PROFILE_A2DP,
+ MCI_GPM_COEX_PROFILE_HID,
+ MCI_GPM_COEX_PROFILE_BNEP,
+ MCI_GPM_COEX_PROFILE_VOICE,
+ MCI_GPM_COEX_PROFILE_MAX
+};
+
struct ath9k_beacon_state {
u32 bs_nexttbtt;
u32 bs_nextdtim;
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index af1b325..e8af582 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -423,6 +423,8 @@ static int ath9k_init_btcoex(struct ath_softc *sc)
txq = sc->tx.txq_map[WME_AC_BE];
ath9k_hw_init_btcoex_hw(sc->sc_ah, txq->axq_qnum);
sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
+ sc->btcoex.duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE;
+ INIT_LIST_HEAD(&sc->btcoex.mci.info);
break;
default:
WARN_ON(1);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 93fbe6f..e1e006d 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1133,8 +1133,9 @@ static int ath9k_start(struct ieee80211_hw *hw)
if ((ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE) &&
!ah->btcoex_hw.enabled) {
- ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
- AR_STOMP_LOW_WLAN_WGHT);
+ if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI))
+ ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+ AR_STOMP_LOW_WLAN_WGHT);
ath9k_hw_btcoex_enable(ah);
if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
@@ -1237,6 +1238,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
ath9k_hw_btcoex_disable(ah);
if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
ath9k_btcoex_timer_pause(sc);
+ ath_mci_flush_profile(&sc->btcoex.mci);
}
spin_lock_bh(&sc->sc_pcu_lock);
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c
new file mode 100644
index 0000000..0fbb141
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/mci.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "ath9k.h"
+#include "mci.h"
+
+u8 ath_mci_duty_cycle[] = { 0, 50, 60, 70, 80, 85, 90, 95, 98 };
+
+static struct ath_mci_profile_info*
+ath_mci_find_profile(struct ath_mci_profile *mci,
+ struct ath_mci_profile_info *info)
+{
+ struct ath_mci_profile_info *entry;
+
+ list_for_each_entry(entry, &mci->info, list) {
+ if (entry->conn_handle == info->conn_handle)
+ break;
+ }
+ return entry;
+}
+
+static bool ath_mci_add_profile(struct ath_common *common,
+ struct ath_mci_profile *mci,
+ struct ath_mci_profile_info *info)
+{
+ struct ath_mci_profile_info *entry;
+
+ if ((mci->num_sco == ATH_MCI_MAX_SCO_PROFILE) &&
+ (info->type == MCI_GPM_COEX_PROFILE_VOICE)) {
+ ath_dbg(common, ATH_DBG_MCI,
+ "Too many SCO profile, failed to add new profile\n");
+ return false;
+ }
+
+ if (((NUM_PROF(mci) - mci->num_sco) == ATH_MCI_MAX_ACL_PROFILE) &&
+ (info->type != MCI_GPM_COEX_PROFILE_VOICE)) {
+ ath_dbg(common, ATH_DBG_MCI,
+ "Too many ACL profile, failed to add new profile\n");
+ return false;
+ }
+
+ entry = ath_mci_find_profile(mci, info);
+
+ if (entry)
+ memcpy(entry, info, 10);
+ else {
+ entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry)
+ return false;
+
+ memcpy(entry, info, 10);
+ INC_PROF(mci, info);
+ list_add_tail(&info->list, &mci->info);
+ }
+ return true;
+}
+
+static void ath_mci_del_profile(struct ath_common *common,
+ struct ath_mci_profile *mci,
+ struct ath_mci_profile_info *info)
+{
+ struct ath_mci_profile_info *entry;
+
+ entry = ath_mci_find_profile(mci, info);
+
+ if (!entry) {
+ ath_dbg(common, ATH_DBG_MCI,
+ "Profile to be deleted not found\n");
+ return;
+ }
+ DEC_PROF(mci, entry);
+ list_del(&entry->list);
+ kfree(entry);
+}
+
+void ath_mci_flush_profile(struct ath_mci_profile *mci)
+{
+ struct ath_mci_profile_info *info, *tinfo;
+
+ list_for_each_entry_safe(info, tinfo, &mci->info, list) {
+ list_del(&info->list);
+ DEC_PROF(mci, info);
+ kfree(info);
+ }
+ mci->aggr_limit = 0;
+}
+
+static void ath_mci_adjust_aggr_limit(struct ath_btcoex *btcoex)
+{
+ struct ath_mci_profile *mci = &btcoex->mci;
+ u32 wlan_airtime = btcoex->btcoex_period *
+ (100 - btcoex->duty_cycle) / 100;
+
+ /*
+ * Scale: wlan_airtime is in ms, aggr_limit is in 0.25 ms.
+ * When wlan_airtime is less than 4ms, aggregation limit has to be
+ * adjusted half of wlan_airtime to ensure that the aggregation can fit
+ * without collision with BT traffic.
+ */
+ if ((wlan_airtime <= 4) &&
+ (!mci->aggr_limit || (mci->aggr_limit > (2 * wlan_airtime))))
+ mci->aggr_limit = 2 * wlan_airtime;
+}
+
+static void ath_mci_update_scheme(struct ath_softc *sc)
+{
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ struct ath_btcoex *btcoex = &sc->btcoex;
+ struct ath_mci_profile *mci = &btcoex->mci;
+ struct ath_mci_profile_info *info;
+ u32 num_profile = NUM_PROF(mci);
+
+ if (num_profile == 1) {
+ info = list_first_entry(&mci->info,
+ struct ath_mci_profile_info,
+ list);
+ if (mci->num_sco && info->T == 12) {
+ mci->aggr_limit = 8;
+ ath_dbg(common, ATH_DBG_MCI,
+ "Single SCO, aggregation limit 2 ms\n");
+ } else if ((info->type == MCI_GPM_COEX_PROFILE_BNEP) &&
+ !info->master) {
+ btcoex->btcoex_period = 60;
+ ath_dbg(common, ATH_DBG_MCI,
+ "Single slave PAN/FTP, bt period 60 ms\n");
+ } else if ((info->type == MCI_GPM_COEX_PROFILE_HID) &&
+ (info->T > 0 && info->T < 50) &&
+ (info->A > 1 || info->W > 1)) {
+ btcoex->duty_cycle = 30;
+ mci->aggr_limit = 8;
+ ath_dbg(common, ATH_DBG_MCI,
+ "Multiple attempt/timeout single HID "
+ "aggregation limit 2 ms dutycycle 30%%\n");
+ }
+ } else if ((num_profile == 2) && (mci->num_hid == 2)) {
+ btcoex->duty_cycle = 30;
+ mci->aggr_limit = 8;
+ ath_dbg(common, ATH_DBG_MCI,
+ "Two HIDs aggregation limit 2 ms dutycycle 30%%\n");
+ } else if (num_profile > 3) {
+ mci->aggr_limit = 6;
+ ath_dbg(common, ATH_DBG_MCI,
+ "Three or more profiles aggregation limit 1.5 ms\n");
+ }
+
+ if (IS_CHAN_2GHZ(sc->sc_ah->curchan)) {
+ if (IS_CHAN_HT(sc->sc_ah->curchan))
+ ath_mci_adjust_aggr_limit(btcoex);
+ else
+ btcoex->btcoex_period >>= 1;
+ }
+
+ ath9k_hw_btcoex_disable(sc->sc_ah);
+ ath9k_btcoex_timer_pause(sc);
+
+ if (IS_CHAN_5GHZ(sc->sc_ah->curchan))
+ return;
+
+ btcoex->duty_cycle += (mci->num_bdr ? ATH_MCI_MAX_DUTY_CYCLE : 0);
+ if (btcoex->duty_cycle > ATH_MCI_MAX_DUTY_CYCLE)
+ btcoex->duty_cycle = ATH_MCI_MAX_DUTY_CYCLE;
+
+ btcoex->btcoex_period *= 1000;
+ btcoex->btcoex_no_stomp = btcoex->btcoex_period *
+ (100 - btcoex->duty_cycle) / 100;
+
+ ath9k_hw_btcoex_enable(sc->sc_ah);
+ ath9k_btcoex_timer_resume(sc);
+}
+
+void ath_mci_process_profile(struct ath_softc *sc,
+ struct ath_mci_profile_info *info)
+{
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ struct ath_btcoex *btcoex = &sc->btcoex;
+ struct ath_mci_profile *mci = &btcoex->mci;
+
+ if (info->start) {
+ if (!ath_mci_add_profile(common, mci, info))
+ return;
+ } else
+ ath_mci_del_profile(common, mci, info);
+
+ btcoex->btcoex_period = ATH_MCI_DEF_BT_PERIOD;
+ mci->aggr_limit = mci->num_sco ? 6 : 0;
+ if (NUM_PROF(mci)) {
+ btcoex->bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
+ btcoex->duty_cycle = ath_mci_duty_cycle[NUM_PROF(mci)];
+ } else {
+ btcoex->bt_stomp_type = mci->num_mgmt ? ATH_BTCOEX_STOMP_ALL :
+ ATH_BTCOEX_STOMP_LOW;
+ btcoex->duty_cycle = ATH_BTCOEX_DEF_DUTY_CYCLE;
+ }
+
+ ath_mci_update_scheme(sc);
+}
+
+void ath_mci_process_status(struct ath_softc *sc,
+ struct ath_mci_profile_status *status)
+{
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ struct ath_btcoex *btcoex = &sc->btcoex;
+ struct ath_mci_profile *mci = &btcoex->mci;
+ struct ath_mci_profile_info info;
+ int i = 0, old_num_mgmt = mci->num_mgmt;
+
+ /* Link status type are not handled */
+ if (status->is_link) {
+ ath_dbg(common, ATH_DBG_MCI,
+ "Skip link type status update\n");
+ return;
+ }
+
+ memset(&info, 0, sizeof(struct ath_mci_profile_info));
+
+ info.conn_handle = status->conn_handle;
+ if (ath_mci_find_profile(mci, &info)) {
+ ath_dbg(common, ATH_DBG_MCI,
+ "Skip non link state update for existing profile %d\n",
+ status->conn_handle);
+ return;
+ }
+ if (status->conn_handle >= ATH_MCI_MAX_PROFILE) {
+ ath_dbg(common, ATH_DBG_MCI,
+ "Ignore too many non-link update\n");
+ return;
+ }
+ if (status->is_critical)
+ __set_bit(status->conn_handle, mci->status);
+ else
+ __clear_bit(status->conn_handle, mci->status);
+
+ mci->num_mgmt = 0;
+ do {
+ if (test_bit(i, mci->status))
+ mci->num_mgmt++;
+ } while (++i < ATH_MCI_MAX_PROFILE);
+
+ if (old_num_mgmt != mci->num_mgmt)
+ ath_mci_update_scheme(sc);
+}
diff --git a/drivers/net/wireless/ath/ath9k/mci.h b/drivers/net/wireless/ath/ath9k/mci.h
new file mode 100644
index 0000000..9590c61
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/mci.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef MCI_H
+#define MCI_H
+
+#define ATH_MCI_DEF_BT_PERIOD 40
+#define ATH_MCI_BDR_DUTY_CYCLE 20
+#define ATH_MCI_MAX_DUTY_CYCLE 90
+
+#define ATH_MCI_DEF_AGGR_LIMIT 6 /* in 0.24 ms */
+#define ATH_MCI_MAX_ACL_PROFILE 7
+#define ATH_MCI_MAX_SCO_PROFILE 1
+#define ATH_MCI_MAX_PROFILE (ATH_MCI_MAX_ACL_PROFILE +\
+ ATH_MCI_MAX_SCO_PROFILE)
+
+#define INC_PROF(_mci, _info) do { \
+ switch (_info->type) { \
+ case MCI_GPM_COEX_PROFILE_RFCOMM:\
+ _mci->num_other_acl++; \
+ break; \
+ case MCI_GPM_COEX_PROFILE_A2DP: \
+ _mci->num_a2dp++; \
+ if (!_info->edr) \
+ _mci->num_bdr++; \
+ break; \
+ case MCI_GPM_COEX_PROFILE_HID: \
+ _mci->num_hid++; \
+ break; \
+ case MCI_GPM_COEX_PROFILE_BNEP: \
+ _mci->num_pan++; \
+ break; \
+ case MCI_GPM_COEX_PROFILE_VOICE: \
+ _mci->num_sco++; \
+ break; \
+ default: \
+ break; \
+ } \
+ } while (0)
+
+#define DEC_PROF(_mci, _info) do { \
+ switch (_info->type) { \
+ case MCI_GPM_COEX_PROFILE_RFCOMM:\
+ _mci->num_other_acl--; \
+ break; \
+ case MCI_GPM_COEX_PROFILE_A2DP: \
+ _mci->num_a2dp--; \
+ if (!_info->edr) \
+ _mci->num_bdr--; \
+ break; \
+ case MCI_GPM_COEX_PROFILE_HID: \
+ _mci->num_hid--; \
+ break; \
+ case MCI_GPM_COEX_PROFILE_BNEP: \
+ _mci->num_pan--; \
+ break; \
+ case MCI_GPM_COEX_PROFILE_VOICE: \
+ _mci->num_sco--; \
+ break; \
+ default: \
+ break; \
+ } \
+ } while (0)
+
+#define NUM_PROF(_mci) (_mci->num_other_acl + _mci->num_a2dp + \
+ _mci->num_hid + _mci->num_pan + _mci->num_sco)
+
+struct ath_mci_profile_info {
+ u8 type;
+ u8 conn_handle;
+ bool start;
+ bool master;
+ bool edr;
+ u8 voice_type;
+ u16 T; /* Voice: Tvoice, HID: Tsniff, in slots */
+ u8 W; /* Voice: Wvoice, HID: Sniff timeout, in slots */
+ u8 A; /* HID: Sniff attempt, in slots */
+ struct list_head list;
+};
+
+struct ath_mci_profile_status {
+ bool is_critical;
+ bool is_link;
+ u8 conn_handle;
+};
+
+struct ath_mci_profile {
+ struct list_head info;
+ DECLARE_BITMAP(status, ATH_MCI_MAX_PROFILE);
+ u16 aggr_limit;
+ u8 num_mgmt;
+ u8 num_sco;
+ u8 num_a2dp;
+ u8 num_hid;
+ u8 num_pan;
+ u8 num_other_acl;
+ u8 num_bdr;
+};
+
+void ath_mci_flush_profile(struct ath_mci_profile *mci);
+void ath_mci_process_profile(struct ath_softc *sc,
+ struct ath_mci_profile_info *info);
+void ath_mci_process_status(struct ath_softc *sc,
+ struct ath_mci_profile_status *status);
+#endif
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 03b0a65..55d077e 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -601,6 +601,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
struct sk_buff *skb;
struct ieee80211_tx_info *tx_info;
struct ieee80211_tx_rate *rates;
+ struct ath_mci_profile *mci = &sc->btcoex.mci;
u32 max_4ms_framelen, frmlen;
u16 aggr_limit, legacy = 0;
int i;
@@ -645,7 +646,9 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy)
return 0;
- if (sc->sc_flags & SC_OP_BT_PRIORITY_DETECTED)
+ if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && mci->aggr_limit)
+ aggr_limit = (max_4ms_framelen * mci->aggr_limit) >> 4;
+ else if (sc->sc_flags & SC_OP_BT_PRIORITY_DETECTED)
aggr_limit = min((max_4ms_framelen * 3) / 8,
(u32)ATH_AMPDU_LIMIT_MAX);
else
--
1.7.7
^ permalink raw reply related
* Re: [BUG] Invalid file descriptor.
From: Daniel Wagner @ 2011-10-24 13:13 UTC (permalink / raw)
To: linux-wireless
In-Reply-To: <4EA53498.7030701@monom.org>
argh, sorry, wrong mailing list.
^ permalink raw reply
* Re: problem with intel 5300
From: Guy, Wey-Yi @ 2011-10-24 13:45 UTC (permalink / raw)
To: Mikael Abrahamsson; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <alpine.DEB.2.00.1110240746530.11931@uplift.swm.pp.se>
On Sun, 2011-10-23 at 22:48 -0700, Mikael Abrahamsson wrote:
> On Tue, 20 Sep 2011, Mikael Abrahamsson wrote:
>
> Hi,
>
> just wanted to say that I have now upgraded to ubuntu 11.10 with its 3.0.x
> kernel, and I'm now running it with .11n enabled and it's been ok for 20
> hours. So whatever problem there was in 2.6.38, it seems to have been
> fixed in 3.0.x, or at least it's working much better.
>
very happy to hear that, thank you very much for reporting
Wey
^ permalink raw reply
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