Skip to content

Commit

Permalink
ath6kl: Add support for uAPSD
Browse files Browse the repository at this point in the history
* A new APSD power save queue is added in the station structure.
* When a station has APSD capability and goes to power save, the frame
  designated to the station will be buffered in APSD queue.
* When the host receives a frame which the firmware marked as trigger,
  host delivers the buffered frame from the APSD power save queue.
  Number of frames to deliver is decided by MAX SP length.
* When a station moves from sleep to awake state, all frames buffered
  in APSD power save queue are sent to the firmware.
* When a station is disconnected, all frames bufferes in APSD power save
  queue are dropped.
* When the host queues the first frame to the APSD queue or removes the
  last frame from the APSD queue, it is indicated to the firmware using
  WMI_AP_APSD_BUFFERED_TRAFFIC_CMD.

kvalo: fix buggy handling of sks queues, made it more obvious
the user priority when wmm is disabled, remove unneed else block and
combined some variable declarations

Signed-off-by: Thirumalai Pachamuthu <tpachamu@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
  • Loading branch information
Thirumalai Pachamuthu authored and Kalle Valo committed Jan 13, 2012
1 parent 8232736 commit c1762a3
Show file tree
Hide file tree
Showing 6 changed files with 324 additions and 53 deletions.
6 changes: 6 additions & 0 deletions drivers/net/wireless/ath/ath6kl/cfg80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -2253,6 +2253,11 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
p.dot11_auth_mode = vif->dot11_auth_mode;
p.ch = cpu_to_le16(vif->next_chan);

/* Enable uAPSD support by default */
res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true);
if (res < 0)
return res;

if (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
p.nw_subtype = SUBTYPE_P2PGO;
} else {
Expand Down Expand Up @@ -2740,6 +2745,7 @@ struct ath6kl *ath6kl_core_alloc(struct device *dev)
for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
spin_lock_init(&ar->sta_list[ctr].psq_lock);
skb_queue_head_init(&ar->sta_list[ctr].psq);
skb_queue_head_init(&ar->sta_list[ctr].apsdq);
}

skb_queue_head_init(&ar->mcastpsq);
Expand Down
10 changes: 9 additions & 1 deletion drivers/net/wireless/ath/ath6kl/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@
#define ATH6KL_MAX_ENDPOINTS 4
#define MAX_NODE_NUM 15

#define ATH6KL_APSD_ALL_FRAME 0xFFFF
#define ATH6KL_APSD_NUM_OF_AC 0x4
#define ATH6KL_APSD_FRAME_MASK 0xF

/* Extra bytes for htc header alignment */
#define ATH6KL_HTC_ALIGN_BYTES 3

Expand Down Expand Up @@ -146,6 +150,8 @@ struct ath6kl_fw_ie {
#define STA_PS_AWAKE BIT(0)
#define STA_PS_SLEEP BIT(1)
#define STA_PS_POLLED BIT(2)
#define STA_PS_APSD_TRIGGER BIT(3)
#define STA_PS_APSD_EOSP BIT(4)

/* HTC TX packet tagging definitions */
#define ATH6KL_CONTROL_PKT_TAG HTC_TX_PACKET_TAG_USER_DEFINED
Expand Down Expand Up @@ -282,6 +288,8 @@ struct ath6kl_sta {
u8 wpa_ie[ATH6KL_MAX_IE];
struct sk_buff_head psq;
spinlock_t psq_lock;
u8 apsd_info;
struct sk_buff_head apsdq;
};

struct ath6kl_version {
Expand Down Expand Up @@ -714,7 +722,7 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel,
void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel);
void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr,
u8 keymgmt, u8 ucipher, u8 auth,
u8 assoc_req_len, u8 *assoc_info);
u8 assoc_req_len, u8 *assoc_info, u8 apsd_info);
void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason,
u8 *bssid, u8 assoc_resp_len,
u8 *assoc_info, u16 prot_reason_status);
Expand Down
9 changes: 6 additions & 3 deletions drivers/net/wireless/ath/ath6kl/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid)
}

static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie,
size_t ielen, u8 keymgmt, u8 ucipher, u8 auth)
size_t ielen, u8 keymgmt, u8 ucipher, u8 auth,
u8 apsd_info)
{
struct ath6kl_sta *sta;
u8 free_slot;
Expand All @@ -68,6 +69,7 @@ static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie,
sta->keymgmt = keymgmt;
sta->ucipher = ucipher;
sta->auth = auth;
sta->apsd_info = apsd_info;

ar->sta_list_index = ar->sta_list_index | (1 << free_slot);
ar->ap_stats.sta[free_slot].aid = cpu_to_le32(aid);
Expand All @@ -80,6 +82,7 @@ static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i)
/* empty the queued pkts in the PS queue if any */
spin_lock_bh(&sta->psq_lock);
skb_queue_purge(&sta->psq);
skb_queue_purge(&sta->apsdq);
spin_unlock_bh(&sta->psq_lock);

memset(&ar->ap_stats.sta[sta->aid - 1], 0,
Expand Down Expand Up @@ -425,7 +428,7 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel)

void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr,
u8 keymgmt, u8 ucipher, u8 auth,
u8 assoc_req_len, u8 *assoc_info)
u8 assoc_req_len, u8 *assoc_info, u8 apsd_info)
{
struct ath6kl *ar = vif->ar;
u8 *ies = NULL, *wpa_ie = NULL, *pos;
Expand Down Expand Up @@ -483,7 +486,7 @@ void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr,

ath6kl_add_new_sta(ar, mac_addr, aid, wpa_ie,
wpa_ie ? 2 + wpa_ie[1] : 0,
keymgmt, ucipher, auth);
keymgmt, ucipher, auth, apsd_info);

/* send event to application */
memset(&sinfo, 0, sizeof(sinfo));
Expand Down
Loading

0 comments on commit c1762a3

Please sign in to comment.