1*5113495bSYour Name /*
2*5113495bSYour Name * Copyright (c) 2014-2017, 2019 The Linux Foundation. All rights reserved.
3*5113495bSYour Name *
4*5113495bSYour Name * Permission to use, copy, modify, and/or distribute this software for
5*5113495bSYour Name * any purpose with or without fee is hereby granted, provided that the
6*5113495bSYour Name * above copyright notice and this permission notice appear in all
7*5113495bSYour Name * copies.
8*5113495bSYour Name *
9*5113495bSYour Name * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
10*5113495bSYour Name * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
11*5113495bSYour Name * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
12*5113495bSYour Name * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
13*5113495bSYour Name * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
14*5113495bSYour Name * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
15*5113495bSYour Name * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16*5113495bSYour Name * PERFORMANCE OF THIS SOFTWARE.
17*5113495bSYour Name */
18*5113495bSYour Name
19*5113495bSYour Name /*========================================================================
20*5113495bSYour Name
21*5113495bSYour Name \file epping_rx.c
22*5113495bSYour Name
23*5113495bSYour Name \brief WLAN End Point Ping test tool implementation
24*5113495bSYour Name
25*5113495bSYour Name ========================================================================*/
26*5113495bSYour Name
27*5113495bSYour Name /*--------------------------------------------------------------------------
28*5113495bSYour Name Include Files
29*5113495bSYour Name ------------------------------------------------------------------------*/
30*5113495bSYour Name #include <cds_api.h>
31*5113495bSYour Name #include <cds_sched.h>
32*5113495bSYour Name #include <linux/etherdevice.h>
33*5113495bSYour Name #include <linux/firmware.h>
34*5113495bSYour Name #include <wni_api.h>
35*5113495bSYour Name #include <wlan_ptt_sock_svc.h>
36*5113495bSYour Name #include <linux/wireless.h>
37*5113495bSYour Name #include <net/cfg80211.h>
38*5113495bSYour Name #include <linux/rtnetlink.h>
39*5113495bSYour Name #include <linux/semaphore.h>
40*5113495bSYour Name #include <linux/ctype.h>
41*5113495bSYour Name #include "epping_main.h"
42*5113495bSYour Name #include "epping_internal.h"
43*5113495bSYour Name #include "epping_test.h"
44*5113495bSYour Name #include <wlan_hdd_napi.h>
45*5113495bSYour Name
46*5113495bSYour Name #define AR6000_MAX_RX_BUFFERS 16
47*5113495bSYour Name #define AR6000_BUFFER_SIZE 1664
48*5113495bSYour Name #define AR6000_MIN_HEAD_ROOM 64
49*5113495bSYour Name
50*5113495bSYour Name static bool enb_rx_dump;
51*5113495bSYour Name
52*5113495bSYour Name #ifdef HIF_SDIO
epping_refill(void * ctx,HTC_ENDPOINT_ID Endpoint)53*5113495bSYour Name void epping_refill(void *ctx, HTC_ENDPOINT_ID Endpoint)
54*5113495bSYour Name {
55*5113495bSYour Name epping_context_t *pEpping_ctx = (epping_context_t *) ctx;
56*5113495bSYour Name void *osBuf;
57*5113495bSYour Name int RxBuffers;
58*5113495bSYour Name int buffersToRefill;
59*5113495bSYour Name HTC_PACKET *pPacket;
60*5113495bSYour Name HTC_PACKET_QUEUE queue;
61*5113495bSYour Name
62*5113495bSYour Name buffersToRefill = (int)AR6000_MAX_RX_BUFFERS -
63*5113495bSYour Name htc_get_num_recv_buffers(pEpping_ctx->HTCHandle, Endpoint);
64*5113495bSYour Name
65*5113495bSYour Name if (buffersToRefill <= 0) {
66*5113495bSYour Name /* fast return, nothing to fill */
67*5113495bSYour Name return;
68*5113495bSYour Name }
69*5113495bSYour Name
70*5113495bSYour Name INIT_HTC_PACKET_QUEUE(&queue);
71*5113495bSYour Name
72*5113495bSYour Name EPPING_LOG(QDF_TRACE_LEVEL_INFO,
73*5113495bSYour Name "%s: providing htc with %d buffers at eid=%d\n",
74*5113495bSYour Name __func__, buffersToRefill, Endpoint);
75*5113495bSYour Name
76*5113495bSYour Name for (RxBuffers = 0; RxBuffers < buffersToRefill; RxBuffers++) {
77*5113495bSYour Name osBuf = qdf_nbuf_alloc(NULL, AR6000_BUFFER_SIZE,
78*5113495bSYour Name AR6000_MIN_HEAD_ROOM, 4, false);
79*5113495bSYour Name if (!osBuf) {
80*5113495bSYour Name break;
81*5113495bSYour Name }
82*5113495bSYour Name /* the HTC packet wrapper is at the head of the reserved area
83*5113495bSYour Name * in the skb */
84*5113495bSYour Name pPacket = (HTC_PACKET *) (A_NETBUF_HEAD(osBuf));
85*5113495bSYour Name /* set re-fill info */
86*5113495bSYour Name SET_HTC_PACKET_INFO_RX_REFILL(pPacket, osBuf,
87*5113495bSYour Name qdf_nbuf_data(osBuf),
88*5113495bSYour Name AR6000_BUFFER_SIZE, Endpoint);
89*5113495bSYour Name SET_HTC_PACKET_NET_BUF_CONTEXT(pPacket, osBuf);
90*5113495bSYour Name /* add to queue */
91*5113495bSYour Name HTC_PACKET_ENQUEUE(&queue, pPacket);
92*5113495bSYour Name }
93*5113495bSYour Name
94*5113495bSYour Name if (!HTC_QUEUE_EMPTY(&queue)) {
95*5113495bSYour Name /* add packets */
96*5113495bSYour Name htc_add_receive_pkt_multiple(pEpping_ctx->HTCHandle, &queue);
97*5113495bSYour Name }
98*5113495bSYour Name }
99*5113495bSYour Name #endif /* HIF_SDIO */
100*5113495bSYour Name
epping_rx(void * ctx,HTC_PACKET * pPacket)101*5113495bSYour Name void epping_rx(void *ctx, HTC_PACKET *pPacket)
102*5113495bSYour Name {
103*5113495bSYour Name epping_context_t *pEpping_ctx = (epping_context_t *) ctx;
104*5113495bSYour Name epping_adapter_t *adapter = pEpping_ctx->epping_adapter;
105*5113495bSYour Name struct net_device *dev = adapter->dev;
106*5113495bSYour Name QDF_STATUS status = pPacket->Status;
107*5113495bSYour Name HTC_ENDPOINT_ID eid = pPacket->Endpoint;
108*5113495bSYour Name struct sk_buff *pktSkb = (struct sk_buff *)pPacket->pPktContext;
109*5113495bSYour Name
110*5113495bSYour Name EPPING_LOG(QDF_TRACE_LEVEL_INFO,
111*5113495bSYour Name "%s: adapter = 0x%pK eid=%d, skb=0x%pK, data=0x%pK, len=0x%x status:%d",
112*5113495bSYour Name __func__, adapter, eid, pktSkb, pPacket->pBuffer,
113*5113495bSYour Name pPacket->ActualLength, status);
114*5113495bSYour Name
115*5113495bSYour Name if (status != QDF_STATUS_SUCCESS) {
116*5113495bSYour Name if (status != QDF_STATUS_E_CANCELED) {
117*5113495bSYour Name EPPING_LOG(QDF_TRACE_LEVEL_ERROR, "%s: RX ERR (%d)",
118*5113495bSYour Name __func__, status);
119*5113495bSYour Name }
120*5113495bSYour Name qdf_nbuf_free(pktSkb);
121*5113495bSYour Name return;
122*5113495bSYour Name }
123*5113495bSYour Name
124*5113495bSYour Name /* deliver to up layer */
125*5113495bSYour Name if (pktSkb) {
126*5113495bSYour Name if (EPPING_ALIGNMENT_PAD > 0) {
127*5113495bSYour Name A_NETBUF_PULL(pktSkb, EPPING_ALIGNMENT_PAD);
128*5113495bSYour Name }
129*5113495bSYour Name if (enb_rx_dump)
130*5113495bSYour Name epping_hex_dump((void *)qdf_nbuf_data(pktSkb),
131*5113495bSYour Name pktSkb->len, __func__);
132*5113495bSYour Name pktSkb->dev = dev;
133*5113495bSYour Name if ((pktSkb->dev->flags & IFF_UP) == IFF_UP) {
134*5113495bSYour Name pktSkb->protocol = eth_type_trans(pktSkb, pktSkb->dev);
135*5113495bSYour Name ++adapter->stats.rx_packets;
136*5113495bSYour Name adapter->stats.rx_bytes += pktSkb->len;
137*5113495bSYour Name qdf_net_buf_debug_release_skb(pktSkb);
138*5113495bSYour Name if (hdd_napi_enabled(HDD_NAPI_ANY))
139*5113495bSYour Name netif_receive_skb(pktSkb);
140*5113495bSYour Name else
141*5113495bSYour Name netif_rx_ni(pktSkb);
142*5113495bSYour Name if ((adapter->stats.rx_packets %
143*5113495bSYour Name EPPING_STATS_LOG_COUNT) == 0) {
144*5113495bSYour Name EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
145*5113495bSYour Name "%s: total_rx_pkts = %lu",
146*5113495bSYour Name __func__,
147*5113495bSYour Name adapter->stats.rx_packets);
148*5113495bSYour Name }
149*5113495bSYour Name } else {
150*5113495bSYour Name ++adapter->stats.rx_dropped;
151*5113495bSYour Name qdf_nbuf_free(pktSkb);
152*5113495bSYour Name }
153*5113495bSYour Name }
154*5113495bSYour Name }
155