aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath6kl/wmi.c
diff options
context:
space:
mode:
authorThirumalai Pachamuthu <tpachamu@qca.qualcomm.com>2012-01-12 07:51:39 -0500
committerKalle Valo <kvalo@qca.qualcomm.com>2012-01-13 06:48:25 -0500
commitc1762a3fe196483981f91b926f5f6ee18af757f2 (patch)
tree39247fd547f84646ed137bdbac25851d73c58262 /drivers/net/wireless/ath/ath6kl/wmi.c
parent8232736dabd2a0310f76944fa7af0542fe3ded4f (diff)
ath6kl: Add support for uAPSD
* 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>
Diffstat (limited to 'drivers/net/wireless/ath/ath6kl/wmi.c')
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.c62
1 files changed, 54 insertions, 8 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 08fbd9a9be4b..c2420f886ed8 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -180,7 +180,7 @@ static int ath6kl_wmi_meta_add(struct wmi *wmi, struct sk_buff *skb,
180} 180}
181 181
182int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb, 182int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
183 u8 msg_type, bool more_data, 183 u8 msg_type, u32 flags,
184 enum wmi_data_hdr_data_type data_type, 184 enum wmi_data_hdr_data_type data_type,
185 u8 meta_ver, void *tx_meta_info, u8 if_idx) 185 u8 meta_ver, void *tx_meta_info, u8 if_idx)
186{ 186{
@@ -204,17 +204,19 @@ int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
204 data_hdr->info = msg_type << WMI_DATA_HDR_MSG_TYPE_SHIFT; 204 data_hdr->info = msg_type << WMI_DATA_HDR_MSG_TYPE_SHIFT;
205 data_hdr->info |= data_type << WMI_DATA_HDR_DATA_TYPE_SHIFT; 205 data_hdr->info |= data_type << WMI_DATA_HDR_DATA_TYPE_SHIFT;
206 206
207 if (more_data) 207 if (flags & WMI_DATA_HDR_FLAGS_MORE)
208 data_hdr->info |= 208 data_hdr->info |= WMI_DATA_HDR_MORE;
209 WMI_DATA_HDR_MORE_MASK << WMI_DATA_HDR_MORE_SHIFT;
210 209
211 data_hdr->info2 = cpu_to_le16(meta_ver << WMI_DATA_HDR_META_SHIFT); 210 if (flags & WMI_DATA_HDR_FLAGS_EOSP)
212 data_hdr->info3 = cpu_to_le16(if_idx & WMI_DATA_HDR_IF_IDX_MASK); 211 data_hdr->info3 |= cpu_to_le16(WMI_DATA_HDR_EOSP);
212
213 data_hdr->info2 |= cpu_to_le16(meta_ver << WMI_DATA_HDR_META_SHIFT);
214 data_hdr->info3 |= cpu_to_le16(if_idx & WMI_DATA_HDR_IF_IDX_MASK);
213 215
214 return 0; 216 return 0;
215} 217}
216 218
217static u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri) 219u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri)
218{ 220{
219 struct iphdr *ip_hdr = (struct iphdr *) pkt; 221 struct iphdr *ip_hdr = (struct iphdr *) pkt;
220 u8 ip_pri; 222 u8 ip_pri;
@@ -236,6 +238,11 @@ static u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri)
236 return ip_pri; 238 return ip_pri;
237} 239}
238 240
241u8 ath6kl_wmi_get_traffic_class(u8 user_priority)
242{
243 return up_to_ac[user_priority & 0x7];
244}
245
239int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, u8 if_idx, 246int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, u8 if_idx,
240 struct sk_buff *skb, 247 struct sk_buff *skb,
241 u32 layer2_priority, bool wmm_enabled, 248 u32 layer2_priority, bool wmm_enabled,
@@ -786,12 +793,14 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len,
786 ev->u.ap_sta.keymgmt, 793 ev->u.ap_sta.keymgmt,
787 le16_to_cpu(ev->u.ap_sta.cipher), 794 le16_to_cpu(ev->u.ap_sta.cipher),
788 ev->u.ap_sta.apsd_info); 795 ev->u.ap_sta.apsd_info);
796
789 ath6kl_connect_ap_mode_sta( 797 ath6kl_connect_ap_mode_sta(
790 vif, ev->u.ap_sta.aid, ev->u.ap_sta.mac_addr, 798 vif, ev->u.ap_sta.aid, ev->u.ap_sta.mac_addr,
791 ev->u.ap_sta.keymgmt, 799 ev->u.ap_sta.keymgmt,
792 le16_to_cpu(ev->u.ap_sta.cipher), 800 le16_to_cpu(ev->u.ap_sta.cipher),
793 ev->u.ap_sta.auth, ev->assoc_req_len, 801 ev->u.ap_sta.auth, ev->assoc_req_len,
794 ev->assoc_info + ev->beacon_ie_len); 802 ev->assoc_info + ev->beacon_ie_len,
803 ev->u.ap_sta.apsd_info);
795 } 804 }
796 return 0; 805 return 0;
797 } 806 }
@@ -2993,6 +3002,43 @@ int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 if_idx, u8 cmd, const u8 *mac,
2993 NO_SYNC_WMIFLAG); 3002 NO_SYNC_WMIFLAG);
2994} 3003}
2995 3004
3005/* This command will be used to enable/disable AP uAPSD feature */
3006int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable)
3007{
3008 struct wmi_ap_set_apsd_cmd *cmd;
3009 struct sk_buff *skb;
3010
3011 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
3012 if (!skb)
3013 return -ENOMEM;
3014
3015 cmd = (struct wmi_ap_set_apsd_cmd *)skb->data;
3016 cmd->enable = enable;
3017
3018 return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_AP_SET_APSD_CMDID,
3019 NO_SYNC_WMIFLAG);
3020}
3021
3022int ath6kl_wmi_set_apsd_bfrd_traf(struct wmi *wmi, u8 if_idx,
3023 u16 aid, u16 bitmap, u32 flags)
3024{
3025 struct wmi_ap_apsd_buffered_traffic_cmd *cmd;
3026 struct sk_buff *skb;
3027
3028 skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
3029 if (!skb)
3030 return -ENOMEM;
3031
3032 cmd = (struct wmi_ap_apsd_buffered_traffic_cmd *)skb->data;
3033 cmd->aid = cpu_to_le16(aid);
3034 cmd->bitmap = cpu_to_le16(bitmap);
3035 cmd->flags = cpu_to_le32(flags);
3036
3037 return ath6kl_wmi_cmd_send(wmi, if_idx, skb,
3038 WMI_AP_APSD_BUFFERED_TRAFFIC_CMDID,
3039 NO_SYNC_WMIFLAG);
3040}
3041
2996static int ath6kl_wmi_pspoll_event_rx(struct wmi *wmi, u8 *datap, int len, 3042static int ath6kl_wmi_pspoll_event_rx(struct wmi *wmi, u8 *datap, int len,
2997 struct ath6kl_vif *vif) 3043 struct ath6kl_vif *vif)
2998{ 3044{