diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath6kl/txrx.c')
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/txrx.c | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index f85353fd1792..67206aedea6c 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -15,8 +15,11 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include "core.h" #include "debug.h" +#include "htc-ops.h" /* * tid - tid_mux0..tid_mux3 @@ -322,6 +325,7 @@ int ath6kl_control_tx(void *devt, struct sk_buff *skb, cookie->map_no = 0; set_htc_pkt_info(&cookie->htc_pkt, cookie, skb->data, skb->len, eid, ATH6KL_CONTROL_PKT_TAG); + cookie->htc_pkt.skb = skb; /* * This interface is asynchronous, if there is an error, cleanup @@ -358,15 +362,11 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) skb, skb->data, skb->len); /* If target is not associated */ - if (!test_bit(CONNECTED, &vif->flags)) { - dev_kfree_skb(skb); - return 0; - } + if (!test_bit(CONNECTED, &vif->flags)) + goto fail_tx; - if (WARN_ON_ONCE(ar->state != ATH6KL_STATE_ON)) { - dev_kfree_skb(skb); - return 0; - } + if (WARN_ON_ONCE(ar->state != ATH6KL_STATE_ON)) + goto fail_tx; if (!test_bit(WMI_READY, &ar->flag)) goto fail_tx; @@ -490,6 +490,7 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) cookie->map_no = map_no; set_htc_pkt_info(&cookie->htc_pkt, cookie, skb->data, skb->len, eid, htc_tag); + cookie->htc_pkt.skb = skb; ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, "tx ", skb->data, skb->len); @@ -570,7 +571,7 @@ void ath6kl_indicate_tx_activity(void *devt, u8 traffic_class, bool active) notify_htc: /* notify HTC, this may cause credit distribution changes */ - ath6kl_htc_indicate_activity_change(ar->htc_target, eid, active); + ath6kl_htc_activity_changed(ar->htc_target, eid, active); } enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target, @@ -666,9 +667,10 @@ static void ath6kl_tx_clear_node_map(struct ath6kl_vif *vif, } } -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; @@ -887,6 +889,7 @@ void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint) skb->data = PTR_ALIGN(skb->data - 4, 4); set_htc_rxpkt_info(packet, skb, skb->data, ATH6KL_BUFFER_SIZE, endpoint); + packet->skb = skb; list_add_tail(&packet->list, &queue); } @@ -909,6 +912,8 @@ void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count) skb->data = PTR_ALIGN(skb->data - 4, 4); set_htc_rxpkt_info(packet, skb, skb->data, ATH6KL_AMSDU_BUFFER_SIZE, 0); + packet->skb = skb; + spin_lock_bh(&ar->lock); list_add_tail(&packet->list, &ar->amsdu_rx_buffer_queue); spin_unlock_bh(&ar->lock); @@ -1281,6 +1286,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) struct wmi_data_hdr *dhdr; int min_hdr_len; u8 meta_type, dot11_hdr = 0; + u8 pad_before_data_start; int status = packet->status; enum htc_endpoint_id ept = packet->endpoint; bool is_amsdu, prev_ps, ps_state = false; @@ -1492,6 +1498,10 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) seq_no = wmi_data_hdr_get_seqno(dhdr); meta_type = wmi_data_hdr_get_meta(dhdr); dot11_hdr = wmi_data_hdr_get_dot11(dhdr); + pad_before_data_start = + (le16_to_cpu(dhdr->info3) >> WMI_DATA_HDR_PAD_BEFORE_DATA_SHIFT) + & WMI_DATA_HDR_PAD_BEFORE_DATA_MASK; + skb_pull(skb, sizeof(struct wmi_data_hdr)); switch (meta_type) { @@ -1510,6 +1520,8 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) break; } + skb_pull(skb, pad_before_data_start); + if (dot11_hdr) status = ath6kl_wmi_dot11_hdr_remove(ar->wmi, skb); else if (!is_amsdu) @@ -1579,7 +1591,8 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) /* aggregation code will handle the skb */ return; } - } + } else if (!is_broadcast_ether_addr(datap->h_dest)) + vif->net_stats.multicast++; ath6kl_deliver_frames_to_nw_stack(vif->ndev, skb); } |