* [PATCH 3/4] ath6kl: Add uAPSD support in rx path.
@ 2012-01-09 7:45 Thirumalai
2012-01-11 12:55 ` Kalle Valo
2012-01-11 13:15 ` Kalle Valo
0 siblings, 2 replies; 3+ messages in thread
From: Thirumalai @ 2012-01-09 7:45 UTC (permalink / raw)
To: kvalo; +Cc: linux-wireless, Thirumalai
If uAPSD trigger is received, send out the packets in uAPSD
queue. Set more data bit if the queue is not empty else
update the uAPSD bitmap for the station.
Signed-off-by: Thirumalai <tpachamu@qca.qualcomm.com>
---
drivers/net/wireless/ath/ath6kl/txrx.c | 103 +++++++++++++++++++++++++++++++-
1 files changed, 101 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
index fcea824..bf6b102 100644
--- a/drivers/net/wireless/ath/ath6kl/txrx.c
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -1093,6 +1093,80 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid,
return is_queued;
}
+static void ath6kl_uapsd_trigger_frame_rx(struct ath6kl_vif *vif,
+ struct ath6kl_sta *conn)
+{
+ struct ath6kl *ar = vif->ar;
+ bool is_apsdq_empty;
+ bool is_apsdq_empty_at_start;
+ u32 num_frames_to_deliver;
+ struct sk_buff *skb = NULL;
+
+ /*
+ * If the APSD q for this STA is not empty, dequeue and
+ * send a pkt from the head of the q. Also update the
+ * More data bit in the WMI_DATA_HDR if there are
+ * more pkts for this STA in the APSD q.
+ * If there are no more pkts for this STA,
+ * update the APSD bitmap for this STA.
+ */
+
+ num_frames_to_deliver = (conn->apsd_info >> 4) & 0xF;
+
+ /*
+ * Number of frames to send in a service period is
+ * indicated by the station
+ * in the QOS_INFO of the association request
+ * If it is zero, send all frames
+ */
+ if (!num_frames_to_deliver)
+ num_frames_to_deliver = 0xFFFF;
+
+ spin_lock_bh(&conn->psq_lock);
+ is_apsdq_empty = skb_queue_empty(&conn->apsdq);
+ spin_unlock_bh(&conn->psq_lock);
+ is_apsdq_empty_at_start = is_apsdq_empty;
+
+ while ((!is_apsdq_empty) && (num_frames_to_deliver)) {
+
+ spin_lock_bh(&conn->psq_lock);
+ skb = skb_dequeue(&conn->apsdq);
+ is_apsdq_empty = skb_queue_empty(&conn->apsdq);
+ spin_unlock_bh(&conn->psq_lock);
+
+ /*
+ * Set the STA flag to Trigger delivery,
+ * so that the frame will go out
+ */
+ conn->sta_flags |= STA_PS_APSD_TRIGGER;
+ num_frames_to_deliver--;
+
+ /* Last frame in the service period, set EOSP or queue empty */
+ if ((is_apsdq_empty) || (!num_frames_to_deliver))
+ conn->sta_flags |= STA_PS_APSD_EOSP;
+
+ ath6kl_data_tx(skb, vif->ndev);
+ conn->sta_flags &= ~(STA_PS_APSD_TRIGGER);
+ conn->sta_flags &= ~(STA_PS_APSD_EOSP);
+ }
+
+ if (is_apsdq_empty) {
+ ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx, conn->aid, 0);
+ if (is_apsdq_empty_at_start) {
+ ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi,
+ vif->fw_vif_idx,
+ conn->aid, 0,
+ WMI_AP_APSD_NO_DELIVERY_FRAMES);
+ } else {
+ ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi,
+ vif->fw_vif_idx,
+ conn->aid, 0, 0);
+ }
+ }
+
+ return;
+}
+
void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
{
struct ath6kl *ar = target->dev->ar;
@@ -1104,6 +1178,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
int status = packet->status;
enum htc_endpoint_id ept = packet->endpoint;
bool is_amsdu, prev_ps, ps_state = false;
+ bool trigger_state = false;
struct ath6kl_sta *conn = NULL;
struct sk_buff *skb1 = NULL;
struct ethhdr *datap = NULL;
@@ -1197,6 +1272,8 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
WMI_DATA_HDR_PS_MASK);
offset = sizeof(struct wmi_data_hdr);
+ trigger_state = !!((dhdr->info3 >> WMI_DATA_HDR_TRIGGER_SHIFT) &
+ WMI_DATA_HDR_TRIGGER_MASK);
switch (meta_type) {
case 0:
@@ -1235,18 +1312,40 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
else
conn->sta_flags &= ~STA_PS_SLEEP;
+ /* Accept trigger only when the station is in sleep */
+ if ((conn->sta_flags & STA_PS_SLEEP) && trigger_state)
+ ath6kl_uapsd_trigger_frame_rx(vif, conn);
+
if (prev_ps ^ !!(conn->sta_flags & STA_PS_SLEEP)) {
if (!(conn->sta_flags & STA_PS_SLEEP)) {
struct sk_buff *skbuff = NULL;
+ bool is_apsdq_empty;
spin_lock_bh(&conn->psq_lock);
- while ((skbuff = skb_dequeue(&conn->psq))
- != NULL) {
+ skbuff = skb_dequeue(&conn->psq);
+ while (skbuff != NULL) {
+ spin_unlock_bh(&conn->psq_lock);
+ ath6kl_data_tx(skbuff, vif->ndev);
+ spin_lock_bh(&conn->psq_lock);
+ skbuff = skb_dequeue(&conn->psq);
+ }
+
+ is_apsdq_empty = skb_queue_empty(&conn->apsdq);
+ skbuff = skb_dequeue(&conn->apsdq);
+ while (skbuff != NULL) {
spin_unlock_bh(&conn->psq_lock);
ath6kl_data_tx(skbuff, vif->ndev);
spin_lock_bh(&conn->psq_lock);
+ skbuff = skb_dequeue(&conn->apsdq);
}
spin_unlock_bh(&conn->psq_lock);
+
+ if (!is_apsdq_empty)
+ ath6kl_wmi_set_apsd_bfrd_traf(
+ ar->wmi,
+ vif->fw_vif_idx,
+ conn->aid, 0, 0);
+
/* Clear the PVB for this STA */
ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx,
conn->aid, 0);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 3+ messages in thread* Re: [PATCH 3/4] ath6kl: Add uAPSD support in rx path.
2012-01-09 7:45 [PATCH 3/4] ath6kl: Add uAPSD support in rx path Thirumalai
@ 2012-01-11 12:55 ` Kalle Valo
2012-01-11 13:15 ` Kalle Valo
1 sibling, 0 replies; 3+ messages in thread
From: Kalle Valo @ 2012-01-11 12:55 UTC (permalink / raw)
To: Thirumalai; +Cc: linux-wireless, ath6kl-devel
On 01/09/2012 09:45 AM, Thirumalai wrote:
> If uAPSD trigger is received, send out the packets in uAPSD
> queue. Set more data bit if the queue is not empty else
> update the uAPSD bitmap for the station.
>
> Signed-off-by: Thirumalai <tpachamu@qca.qualcomm.com>
[...]
> + /*
> + * If the APSD q for this STA is not empty, dequeue and
> + * send a pkt from the head of the q. Also update the
> + * More data bit in the WMI_DATA_HDR if there are
> + * more pkts for this STA in the APSD q.
> + * If there are no more pkts for this STA,
> + * update the APSD bitmap for this STA.
> + */
> +
> + num_frames_to_deliver = (conn->apsd_info >> 4) & 0xF;
Defines would be nice for values 4 and 0xF.
> +
> + /*
> + * Number of frames to send in a service period is
> + * indicated by the station
> + * in the QOS_INFO of the association request
> + * If it is zero, send all frames
> + */
> + if (!num_frames_to_deliver)
> + num_frames_to_deliver = 0xFFFF;
And for 0xFFFF.
> +
> + spin_lock_bh(&conn->psq_lock);
> + is_apsdq_empty = skb_queue_empty(&conn->apsdq);
Extra space after is_apsdq_empty.
> - while ((skbuff = skb_dequeue(&conn->psq))
> - != NULL) {
> + skbuff = skb_dequeue(&conn->psq);
> + while (skbuff != NULL) {
> + spin_unlock_bh(&conn->psq_lock);
> + ath6kl_data_tx(skbuff, vif->ndev);
> + spin_lock_bh(&conn->psq_lock);
> + skbuff = skb_dequeue(&conn->psq);
> + }
I would say the original style is better:
while ((skbuff = skb_dequeue(&conn->psq))
> +
> + is_apsdq_empty = skb_queue_empty(&conn->apsdq);
> + skbuff = skb_dequeue(&conn->apsdq);
> + while (skbuff != NULL) {
> spin_unlock_bh(&conn->psq_lock);
> ath6kl_data_tx(skbuff, vif->ndev);
> spin_lock_bh(&conn->psq_lock);
> + skbuff = skb_dequeue(&conn->apsdq);
> }
Same here.
Kalle
^ permalink raw reply [flat|nested] 3+ messages in thread* Re: [PATCH 3/4] ath6kl: Add uAPSD support in rx path.
2012-01-09 7:45 [PATCH 3/4] ath6kl: Add uAPSD support in rx path Thirumalai
2012-01-11 12:55 ` Kalle Valo
@ 2012-01-11 13:15 ` Kalle Valo
1 sibling, 0 replies; 3+ messages in thread
From: Kalle Valo @ 2012-01-11 13:15 UTC (permalink / raw)
To: Thirumalai; +Cc: linux-wireless, ath6kl-devel
On 01/09/2012 09:45 AM, Thirumalai wrote:
> + ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx, conn->aid, 0);
> + if (is_apsdq_empty_at_start) {
> + ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi,
> + vif->fw_vif_idx,
> + conn->aid, 0,
> + WMI_AP_APSD_NO_DELIVERY_FRAMES);
> + } else {
> + ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi,
> + vif->fw_vif_idx,
> + conn->aid, 0, 0);
> + }
To have only one call to ath6kl_wmi_set_apsd_bfrd_traf() you could add a
variable like this:
u32 flags;
....
if (is_apsdq_empty_at_start)
flags = WMI_AP_APSD_NO_DELIVERY_FRAMES;
else
flags = 0;
ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx, conn->aid, 0);
ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi,
vif->fw_vif_idx,
conn->aid, 0, flags);
Kalle
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2012-01-11 13:16 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-01-09 7:45 [PATCH 3/4] ath6kl: Add uAPSD support in rx path Thirumalai
2012-01-11 12:55 ` Kalle Valo
2012-01-11 13:15 ` Kalle Valo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).