/*
* Copyright (c) 2004-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2012 Qualcomm Atheros, 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
*/
if (is_apsdq_empty) {
ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi,
- vif->fw_vif_idx,
- conn->aid, 1, 0);
+ vif->fw_vif_idx,
+ conn->aid, 1, 0);
}
*flags |= WMI_DATA_HDR_FLAGS_UAPSD;
int status = 0;
struct ath6kl_cookie *cookie = NULL;
+ if (WARN_ON_ONCE(ar->state == ATH6KL_STATE_WOW))
+ return -EACCES;
+
spin_lock_bh(&ar->lock);
ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
return 0;
}
+ if (WARN_ON_ONCE(ar->state != ATH6KL_STATE_ON)) {
+ dev_kfree_skb(skb);
+ return 0;
+ }
+
if (!test_bit(WMI_READY, &ar->flag))
goto fail_tx;
if (test_bit(WMI_ENABLED, &ar->flag)) {
if ((dev->features & NETIF_F_IP_CSUM) &&
- (csum == CHECKSUM_PARTIAL)) {
+ (csum == CHECKSUM_PARTIAL)) {
csum_start = skb->csum_start -
(skb_network_header(skb) - skb->head) +
sizeof(struct ath6kl_llc_snap_hdr);
}
if ((dev->features & NETIF_F_IP_CSUM) &&
- (csum == CHECKSUM_PARTIAL)) {
+ (csum == CHECKSUM_PARTIAL)) {
meta_v2.csum_start = csum_start;
meta_v2.csum_dest = csum_dest;
}
if ((vif->nw_type == ADHOC_NETWORK) &&
- ar->ibss_ps_enable && test_bit(CONNECTED, &vif->flags))
+ ar->ibss_ps_enable && test_bit(CONNECTED, &vif->flags))
chk_adhoc_ps_mapping = true;
else {
/* get the stream mapping */
*/
if (ar->ac_stream_pri_map[ar->ep2ac_map[endpoint]] <
ar->hiac_stream_active_pri &&
- ar->cookie_count <= MAX_HI_COOKIE_NUM)
+ ar->cookie_count <=
+ target->endpoint[endpoint].tx_drop_packet_threshold)
/*
* Give preference to the highest priority stream by
* dropping the packets which overflowed.
}
}
-void ath6kl_tx_complete(void *context, struct list_head *packet_queue)
+void ath6kl_tx_complete(struct htc_target *target,
+ struct list_head *packet_queue)
{
- struct ath6kl *ar = context;
+ struct ath6kl *ar = target->dev->ar;
struct sk_buff_head skb_queue;
struct htc_packet *packet;
struct sk_buff *skb;
if (!IS_ALIGNED((unsigned long) skb->data, 4))
skb->data = PTR_ALIGN(skb->data - 4, 4);
set_htc_rxpkt_info(packet, skb, skb->data,
- ATH6KL_BUFFER_SIZE, endpoint);
+ ATH6KL_BUFFER_SIZE, endpoint);
list_add_tail(&packet->list, &queue);
}
flags = 0;
ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi,
- vif->fw_vif_idx,
- conn->aid, 0, flags);
+ vif->fw_vif_idx,
+ conn->aid, 0, flags);
}
return;
skb_put(skb, packet->act_len + HTC_HDR_LENGTH);
skb_pull(skb, HTC_HDR_LENGTH);
+ ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, "rx ",
+ skb->data, skb->len);
+
if (ept == ar->ctrl_ep) {
+ if (test_bit(WMI_ENABLED, &ar->flag)) {
+ ath6kl_check_wow_status(ar);
+ ath6kl_wmi_control_rx(ar->wmi, skb);
+ return;
+ }
if_idx =
wmi_cmd_hdr_get_if_idx((struct wmi_cmd_hdr *) skb->data);
} else {
spin_unlock_bh(&vif->if_lock);
-
- ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, "rx ",
- skb->data, skb->len);
-
skb->dev = vif->ndev;
if (!test_bit(WMI_ENABLED, &ar->flag)) {
ath6kl_check_wow_status(ar);
- if (ept == ar->ctrl_ep) {
- ath6kl_wmi_control_rx(ar->wmi, skb);
- return;
- }
-
min_hdr_len = sizeof(struct ethhdr) + sizeof(struct wmi_data_hdr) +
sizeof(struct ath6kl_llc_snap_hdr);
if (!(conn->sta_flags & STA_PS_SLEEP)) {
struct sk_buff *skbuff = NULL;
bool is_apsdq_empty;
+ struct ath6kl_mgmt_buff *mgmt;
+ u8 idx;
spin_lock_bh(&conn->psq_lock);
+ while (conn->mgmt_psq_len > 0) {
+ mgmt = list_first_entry(
+ &conn->mgmt_psq,
+ struct ath6kl_mgmt_buff,
+ list);
+ list_del(&mgmt->list);
+ conn->mgmt_psq_len--;
+ spin_unlock_bh(&conn->psq_lock);
+ idx = vif->fw_vif_idx;
+
+ ath6kl_wmi_send_mgmt_cmd(ar->wmi,
+ idx,
+ mgmt->id,
+ mgmt->freq,
+ mgmt->wait,
+ mgmt->buf,
+ mgmt->len,
+ mgmt->no_cck);
+
+ kfree(mgmt);
+ spin_lock_bh(&conn->psq_lock);
+ }
+ conn->mgmt_psq_len = 0;
while ((skbuff = skb_dequeue(&conn->psq))) {
spin_unlock_bh(&conn->psq_lock);
ath6kl_data_tx(skbuff, vif->ndev);
aggr_conn = vif->aggr_cntxt->aggr_conn;
if (aggr_process_recv_frm(aggr_conn, tid, seq_no,
- is_amsdu, skb)) {
+ is_amsdu, skb)) {
/* aggregation code will handle the skb */
return;
}
rxtid->aggr = true;
}
-void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info_conn *aggr_conn)
+void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info *aggr_info,
+ struct aggr_info_conn *aggr_conn)
{
struct rxtid *rxtid;
u8 i;
init_timer(&aggr_conn->timer);
aggr_conn->timer.function = aggr_timeout;
aggr_conn->timer.data = (unsigned long) aggr_conn;
- aggr_conn->aggr_info = vif->aggr_cntxt;
+ aggr_conn->aggr_info = aggr_info;
aggr_conn->timer_scheduled = false;
return NULL;
}
- aggr_conn_init(vif, p_aggr->aggr_conn);
+ aggr_conn_init(vif, p_aggr, p_aggr->aggr_conn);
skb_queue_head_init(&p_aggr->rx_amsdu_freeq);
ath6kl_alloc_netbufs(&p_aggr->rx_amsdu_freeq, AGGR_NUM_OF_FREE_NETBUFS);