xref: /wlan-driver/qca-wifi-host-cmn/utils/epping/src/epping_txrx.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for
6*5113495bSYour Name  * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name  * above copyright notice and this permission notice appear in all
8*5113495bSYour Name  * copies.
9*5113495bSYour Name  *
10*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name  * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name  */
19*5113495bSYour Name 
20*5113495bSYour Name /*========================================================================
21*5113495bSYour Name 
22*5113495bSYour Name    \file  epping_txrx.c
23*5113495bSYour Name 
24*5113495bSYour Name    \brief WLAN End Point Ping test tool implementation
25*5113495bSYour Name 
26*5113495bSYour Name    ========================================================================*/
27*5113495bSYour Name 
28*5113495bSYour Name /*--------------------------------------------------------------------------
29*5113495bSYour Name    Include Files
30*5113495bSYour Name    ------------------------------------------------------------------------*/
31*5113495bSYour Name #include <cds_api.h>
32*5113495bSYour Name #include <cds_sched.h>
33*5113495bSYour Name #include <linux/etherdevice.h>
34*5113495bSYour Name #include <linux/firmware.h>
35*5113495bSYour Name #include <wni_api.h>
36*5113495bSYour Name #include <wlan_ptt_sock_svc.h>
37*5113495bSYour Name #include <linux/wireless.h>
38*5113495bSYour Name #include <net/cfg80211.h>
39*5113495bSYour Name #include <pld_common.h>
40*5113495bSYour Name #include <linux/rtnetlink.h>
41*5113495bSYour Name #include <linux/semaphore.h>
42*5113495bSYour Name #include <linux/ctype.h>
43*5113495bSYour Name #include "epping_main.h"
44*5113495bSYour Name #include "epping_internal.h"
45*5113495bSYour Name #include "qdf_net_if.h"
46*5113495bSYour Name 
47*5113495bSYour Name static int epping_start_adapter(epping_adapter_t *adapter);
48*5113495bSYour Name static void epping_stop_adapter(epping_adapter_t *adapter);
49*5113495bSYour Name 
epping_timer_expire(void * data)50*5113495bSYour Name static void epping_timer_expire(void *data)
51*5113495bSYour Name {
52*5113495bSYour Name 	struct net_device *dev = (struct net_device *)data;
53*5113495bSYour Name 	epping_adapter_t *adapter;
54*5113495bSYour Name 
55*5113495bSYour Name 	if (!dev) {
56*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
57*5113495bSYour Name 			   "%s: netdev = NULL", __func__);
58*5113495bSYour Name 		return;
59*5113495bSYour Name 	}
60*5113495bSYour Name 
61*5113495bSYour Name 	adapter = netdev_priv(dev);
62*5113495bSYour Name 	if (!adapter) {
63*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
64*5113495bSYour Name 			   "%s: adapter = NULL", __func__);
65*5113495bSYour Name 		return;
66*5113495bSYour Name 	}
67*5113495bSYour Name 	adapter->epping_timer_state = EPPING_TX_TIMER_STOPPED;
68*5113495bSYour Name 	epping_tx_timer_expire(adapter);
69*5113495bSYour Name }
70*5113495bSYour Name 
epping_ndev_open(struct net_device * dev)71*5113495bSYour Name static int epping_ndev_open(struct net_device *dev)
72*5113495bSYour Name {
73*5113495bSYour Name 	epping_adapter_t *adapter;
74*5113495bSYour Name 	int ret = 0;
75*5113495bSYour Name 
76*5113495bSYour Name 	adapter = netdev_priv(dev);
77*5113495bSYour Name 	epping_start_adapter(adapter);
78*5113495bSYour Name 	return ret;
79*5113495bSYour Name }
80*5113495bSYour Name 
epping_ndev_stop(struct net_device * dev)81*5113495bSYour Name static int epping_ndev_stop(struct net_device *dev)
82*5113495bSYour Name {
83*5113495bSYour Name 	epping_adapter_t *adapter;
84*5113495bSYour Name 	int ret = 0;
85*5113495bSYour Name 
86*5113495bSYour Name 	adapter = netdev_priv(dev);
87*5113495bSYour Name 	if (!adapter) {
88*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
89*5113495bSYour Name 			   "%s: EPPING adapter context is Null", __func__);
90*5113495bSYour Name 		ret = -ENODEV;
91*5113495bSYour Name 		goto end;
92*5113495bSYour Name 	}
93*5113495bSYour Name 	epping_stop_adapter(adapter);
94*5113495bSYour Name end:
95*5113495bSYour Name 	return ret;
96*5113495bSYour Name }
97*5113495bSYour Name 
epping_ndev_uninit(struct net_device * dev)98*5113495bSYour Name static void epping_ndev_uninit(struct net_device *dev)
99*5113495bSYour Name {
100*5113495bSYour Name 	epping_adapter_t *adapter;
101*5113495bSYour Name 
102*5113495bSYour Name 	adapter = netdev_priv(dev);
103*5113495bSYour Name 	if (!adapter) {
104*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
105*5113495bSYour Name 			   "%s: EPPING adapter context is Null", __func__);
106*5113495bSYour Name 		goto end;
107*5113495bSYour Name 	}
108*5113495bSYour Name 	epping_stop_adapter(adapter);
109*5113495bSYour Name end:
110*5113495bSYour Name 	return;
111*5113495bSYour Name }
112*5113495bSYour Name 
113*5113495bSYour Name #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 6, 0))
epping_tx_queue_timeout(struct net_device * dev,unsigned int txqueue)114*5113495bSYour Name static void epping_tx_queue_timeout(struct net_device *dev,
115*5113495bSYour Name 				    unsigned int txqueue)
116*5113495bSYour Name #else
117*5113495bSYour Name static void epping_tx_queue_timeout(struct net_device *dev)
118*5113495bSYour Name #endif
119*5113495bSYour Name {
120*5113495bSYour Name 	epping_adapter_t *adapter;
121*5113495bSYour Name 
122*5113495bSYour Name 	adapter = netdev_priv(dev);
123*5113495bSYour Name 	if (!adapter) {
124*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
125*5113495bSYour Name 			   "%s: EPPING adapter context is Null", __func__);
126*5113495bSYour Name 		goto end;
127*5113495bSYour Name 	}
128*5113495bSYour Name 
129*5113495bSYour Name 	EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
130*5113495bSYour Name 		   "%s: Transmission timeout occurred, adapter->started= %d",
131*5113495bSYour Name 		   __func__, adapter->started);
132*5113495bSYour Name 
133*5113495bSYour Name 	/* Getting here implies we disabled the TX queues
134*5113495bSYour Name 	 * for too long. Since this is epping
135*5113495bSYour Name 	 * (not because of disassociation or low resource scenarios),
136*5113495bSYour Name 	 * try to restart the queue
137*5113495bSYour Name 	 */
138*5113495bSYour Name 	if (adapter->started)
139*5113495bSYour Name 		netif_wake_queue(dev);
140*5113495bSYour Name end:
141*5113495bSYour Name 	return;
142*5113495bSYour Name 
143*5113495bSYour Name }
144*5113495bSYour Name 
epping_hard_start_xmit(struct sk_buff * skb,struct net_device * dev)145*5113495bSYour Name static netdev_tx_t epping_hard_start_xmit(struct sk_buff *skb,
146*5113495bSYour Name 					  struct net_device *dev)
147*5113495bSYour Name {
148*5113495bSYour Name 	epping_adapter_t *adapter;
149*5113495bSYour Name 	int ret = 0;
150*5113495bSYour Name 
151*5113495bSYour Name 	adapter = netdev_priv(dev);
152*5113495bSYour Name 	if (!adapter) {
153*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
154*5113495bSYour Name 			   "%s: EPPING adapter context is Null", __func__);
155*5113495bSYour Name 		kfree_skb(skb);
156*5113495bSYour Name 		ret = -ENODEV;
157*5113495bSYour Name 		goto end;
158*5113495bSYour Name 	}
159*5113495bSYour Name 	qdf_net_buf_debug_acquire_skb(skb, __FILE__, __LINE__);
160*5113495bSYour Name 	ret = epping_tx_send(skb, adapter);
161*5113495bSYour Name end:
162*5113495bSYour Name 	return NETDEV_TX_OK;
163*5113495bSYour Name }
164*5113495bSYour Name 
epping_get_stats(struct net_device * dev)165*5113495bSYour Name static struct net_device_stats *epping_get_stats(struct net_device *dev)
166*5113495bSYour Name {
167*5113495bSYour Name 	epping_adapter_t *adapter = netdev_priv(dev);
168*5113495bSYour Name 
169*5113495bSYour Name 	if (!adapter) {
170*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_ERROR, "%s: adapter = NULL",
171*5113495bSYour Name 			   __func__);
172*5113495bSYour Name 		return NULL;
173*5113495bSYour Name 	}
174*5113495bSYour Name 
175*5113495bSYour Name 	return &adapter->stats;
176*5113495bSYour Name }
177*5113495bSYour Name 
epping_ndev_ioctl(struct net_device * dev,struct ifreq * ifr,int cmd)178*5113495bSYour Name static int epping_ndev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
179*5113495bSYour Name {
180*5113495bSYour Name 	epping_adapter_t *adapter;
181*5113495bSYour Name 	int ret = 0;
182*5113495bSYour Name 
183*5113495bSYour Name 	adapter = netdev_priv(dev);
184*5113495bSYour Name 	if (!adapter) {
185*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
186*5113495bSYour Name 			   "%s: EPPING adapter context is Null", __func__);
187*5113495bSYour Name 		ret = -ENODEV;
188*5113495bSYour Name 		goto end;
189*5113495bSYour Name 	}
190*5113495bSYour Name 	if (dev != adapter->dev) {
191*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
192*5113495bSYour Name 			   "%s: HDD adapter/dev inconsistency", __func__);
193*5113495bSYour Name 		ret = -ENODEV;
194*5113495bSYour Name 		goto end;
195*5113495bSYour Name 	}
196*5113495bSYour Name 
197*5113495bSYour Name 	if ((!ifr) || (!ifr->ifr_data)) {
198*5113495bSYour Name 		ret = -EINVAL;
199*5113495bSYour Name 		goto end;
200*5113495bSYour Name 	}
201*5113495bSYour Name 
202*5113495bSYour Name 	switch (cmd) {
203*5113495bSYour Name 	case (SIOCDEVPRIVATE + 1):
204*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
205*5113495bSYour Name 			   "%s: do not support ioctl %d (SIOCDEVPRIVATE + 1)",
206*5113495bSYour Name 			   __func__, cmd);
207*5113495bSYour Name 		break;
208*5113495bSYour Name 	default:
209*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_ERROR, "%s: unknown ioctl %d",
210*5113495bSYour Name 			   __func__, cmd);
211*5113495bSYour Name 		ret = -EINVAL;
212*5113495bSYour Name 		break;
213*5113495bSYour Name 	}
214*5113495bSYour Name 
215*5113495bSYour Name end:
216*5113495bSYour Name 	return ret;
217*5113495bSYour Name }
218*5113495bSYour Name 
epping_set_mac_address(struct net_device * dev,void * addr)219*5113495bSYour Name static int epping_set_mac_address(struct net_device *dev, void *addr)
220*5113495bSYour Name {
221*5113495bSYour Name 	epping_adapter_t *adapter = netdev_priv(dev);
222*5113495bSYour Name 	struct sockaddr *psta_mac_addr = addr;
223*5113495bSYour Name 	qdf_mem_copy(&adapter->macAddressCurrent,
224*5113495bSYour Name 		     psta_mac_addr->sa_data, ETH_ALEN);
225*5113495bSYour Name 	qdf_net_update_net_device_dev_addr(dev, psta_mac_addr->sa_data,
226*5113495bSYour Name 					   ETH_ALEN);
227*5113495bSYour Name 	return 0;
228*5113495bSYour Name }
229*5113495bSYour Name 
epping_stop_adapter(epping_adapter_t * adapter)230*5113495bSYour Name static void epping_stop_adapter(epping_adapter_t *adapter)
231*5113495bSYour Name {
232*5113495bSYour Name 	qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
233*5113495bSYour Name 
234*5113495bSYour Name 	if (!qdf_ctx) {
235*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
236*5113495bSYour Name 			   "%s: qdf_ctx is NULL\n", __func__);
237*5113495bSYour Name 		return;
238*5113495bSYour Name 	}
239*5113495bSYour Name 
240*5113495bSYour Name 	if (adapter && adapter->started) {
241*5113495bSYour Name 		EPPING_LOG(LOG1, FL("Disabling queues"));
242*5113495bSYour Name 		netif_tx_disable(adapter->dev);
243*5113495bSYour Name 		netif_carrier_off(adapter->dev);
244*5113495bSYour Name 		adapter->started = false;
245*5113495bSYour Name 		pld_request_bus_bandwidth(qdf_ctx->dev,
246*5113495bSYour Name 					  PLD_BUS_WIDTH_LOW);
247*5113495bSYour Name 	}
248*5113495bSYour Name }
249*5113495bSYour Name 
epping_start_adapter(epping_adapter_t * adapter)250*5113495bSYour Name static int epping_start_adapter(epping_adapter_t *adapter)
251*5113495bSYour Name {
252*5113495bSYour Name 	qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
253*5113495bSYour Name 
254*5113495bSYour Name 	if (!qdf_ctx) {
255*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
256*5113495bSYour Name 			   "%s: qdf_ctx is NULL", __func__);
257*5113495bSYour Name 		return -EINVAL;
258*5113495bSYour Name 	}
259*5113495bSYour Name 
260*5113495bSYour Name 	if (!adapter) {
261*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
262*5113495bSYour Name 			   "%s: adapter= NULL\n", __func__);
263*5113495bSYour Name 		return -EINVAL;
264*5113495bSYour Name 	}
265*5113495bSYour Name 	if (!adapter->started) {
266*5113495bSYour Name 		pld_request_bus_bandwidth(qdf_ctx->dev,
267*5113495bSYour Name 					  PLD_BUS_WIDTH_HIGH);
268*5113495bSYour Name 		netif_carrier_on(adapter->dev);
269*5113495bSYour Name 		EPPING_LOG(LOG1, FL("Enabling queues"));
270*5113495bSYour Name 		netif_tx_start_all_queues(adapter->dev);
271*5113495bSYour Name 		adapter->started = true;
272*5113495bSYour Name 	} else {
273*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_WARN,
274*5113495bSYour Name 			   "%s: adapter %pK already started\n", __func__,
275*5113495bSYour Name 			   adapter);
276*5113495bSYour Name 	}
277*5113495bSYour Name 	return 0;
278*5113495bSYour Name }
279*5113495bSYour Name 
epping_register_adapter(epping_adapter_t * adapter,bool rtnl_held)280*5113495bSYour Name static int epping_register_adapter(epping_adapter_t *adapter, bool rtnl_held)
281*5113495bSYour Name {
282*5113495bSYour Name 	int ret = 0;
283*5113495bSYour Name 
284*5113495bSYour Name 	if (!rtnl_held)
285*5113495bSYour Name 		ret = register_netdev(adapter->dev);
286*5113495bSYour Name 	else
287*5113495bSYour Name 		ret = register_netdevice(adapter->dev);
288*5113495bSYour Name 	if (ret != 0) {
289*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
290*5113495bSYour Name 			   "%s: unable to register device\n",
291*5113495bSYour Name 			   adapter->dev->name);
292*5113495bSYour Name 	} else {
293*5113495bSYour Name 		adapter->registered = true;
294*5113495bSYour Name 	}
295*5113495bSYour Name 	return ret;
296*5113495bSYour Name }
297*5113495bSYour Name 
epping_unregister_adapter(epping_adapter_t * adapter)298*5113495bSYour Name static void epping_unregister_adapter(epping_adapter_t *adapter)
299*5113495bSYour Name {
300*5113495bSYour Name 	if (adapter) {
301*5113495bSYour Name 		epping_stop_adapter(adapter);
302*5113495bSYour Name 		if (adapter->registered) {
303*5113495bSYour Name 			unregister_netdev(adapter->dev);
304*5113495bSYour Name 			adapter->registered = false;
305*5113495bSYour Name 		}
306*5113495bSYour Name 	} else {
307*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
308*5113495bSYour Name 			   "%s: adapter = NULL, unable to unregister device\n",
309*5113495bSYour Name 			   __func__);
310*5113495bSYour Name 	}
311*5113495bSYour Name }
312*5113495bSYour Name 
epping_destroy_adapter(epping_adapter_t * adapter)313*5113495bSYour Name void epping_destroy_adapter(epping_adapter_t *adapter)
314*5113495bSYour Name {
315*5113495bSYour Name 	struct net_device *dev = NULL;
316*5113495bSYour Name 	epping_context_t *pEpping_ctx;
317*5113495bSYour Name 
318*5113495bSYour Name 	if (!adapter || !adapter->pEpping_ctx) {
319*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
320*5113495bSYour Name 			   "%s: adapter = NULL\n", __func__);
321*5113495bSYour Name 		return;
322*5113495bSYour Name 	}
323*5113495bSYour Name 
324*5113495bSYour Name 	dev = adapter->dev;
325*5113495bSYour Name 	pEpping_ctx = adapter->pEpping_ctx;
326*5113495bSYour Name 	epping_unregister_adapter(adapter);
327*5113495bSYour Name 
328*5113495bSYour Name 	qdf_spinlock_destroy(&adapter->data_lock);
329*5113495bSYour Name 	qdf_timer_free(&adapter->epping_timer);
330*5113495bSYour Name 	adapter->epping_timer_state = EPPING_TX_TIMER_STOPPED;
331*5113495bSYour Name 
332*5113495bSYour Name 	while (qdf_nbuf_queue_len(&adapter->nodrop_queue)) {
333*5113495bSYour Name 		qdf_nbuf_t tmp_nbuf = NULL;
334*5113495bSYour Name 		tmp_nbuf = qdf_nbuf_queue_remove(&adapter->nodrop_queue);
335*5113495bSYour Name 		if (tmp_nbuf)
336*5113495bSYour Name 			qdf_nbuf_free(tmp_nbuf);
337*5113495bSYour Name 	}
338*5113495bSYour Name 
339*5113495bSYour Name 	free_netdev(dev);
340*5113495bSYour Name 	if (!pEpping_ctx)
341*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
342*5113495bSYour Name 			   "%s: pEpping_ctx = NULL\n", __func__);
343*5113495bSYour Name 	else
344*5113495bSYour Name 		pEpping_ctx->epping_adapter = NULL;
345*5113495bSYour Name }
346*5113495bSYour Name 
347*5113495bSYour Name static struct net_device_ops epping_drv_ops = {
348*5113495bSYour Name 	.ndo_open = epping_ndev_open,
349*5113495bSYour Name 	.ndo_stop = epping_ndev_stop,
350*5113495bSYour Name 	.ndo_uninit = epping_ndev_uninit,
351*5113495bSYour Name 	.ndo_start_xmit = epping_hard_start_xmit,
352*5113495bSYour Name 	.ndo_tx_timeout = epping_tx_queue_timeout,
353*5113495bSYour Name 	.ndo_get_stats = epping_get_stats,
354*5113495bSYour Name 	.ndo_do_ioctl = epping_ndev_ioctl,
355*5113495bSYour Name 	.ndo_set_mac_address = epping_set_mac_address,
356*5113495bSYour Name 	.ndo_select_queue = NULL,
357*5113495bSYour Name };
358*5113495bSYour Name 
359*5113495bSYour Name #define EPPING_TX_QUEUE_MAX_LEN 128     /* need to be power of 2 */
360*5113495bSYour Name 
epping_add_adapter(epping_context_t * pEpping_ctx,tSirMacAddr macAddr,enum QDF_OPMODE device_mode,bool rtnl_held)361*5113495bSYour Name epping_adapter_t *epping_add_adapter(epping_context_t *pEpping_ctx,
362*5113495bSYour Name 				     tSirMacAddr macAddr,
363*5113495bSYour Name 				     enum QDF_OPMODE device_mode,
364*5113495bSYour Name 				     bool rtnl_held)
365*5113495bSYour Name {
366*5113495bSYour Name 	struct net_device *dev;
367*5113495bSYour Name 	epping_adapter_t *adapter;
368*5113495bSYour Name 
369*5113495bSYour Name 	dev = alloc_netdev(sizeof(epping_adapter_t), "wifi%d",
370*5113495bSYour Name #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0))
371*5113495bSYour Name 			   NET_NAME_UNKNOWN,
372*5113495bSYour Name #endif
373*5113495bSYour Name 			   ether_setup);
374*5113495bSYour Name 	if (!dev) {
375*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
376*5113495bSYour Name 			   "%s: Cannot allocate epping_adapter_t\n", __func__);
377*5113495bSYour Name 		return NULL;
378*5113495bSYour Name 	}
379*5113495bSYour Name 
380*5113495bSYour Name 	adapter = netdev_priv(dev);
381*5113495bSYour Name 	qdf_mem_zero(adapter, sizeof(*adapter));
382*5113495bSYour Name 	adapter->dev = dev;
383*5113495bSYour Name 	adapter->pEpping_ctx = pEpping_ctx;
384*5113495bSYour Name 	adapter->device_mode = device_mode;    /* station, SAP, etc */
385*5113495bSYour Name 	qdf_net_update_net_device_dev_addr(dev,
386*5113495bSYour Name 					   (void *)macAddr,
387*5113495bSYour Name 					   sizeof(tSirMacAddr));
388*5113495bSYour Name 	qdf_mem_copy(adapter->macAddressCurrent.bytes,
389*5113495bSYour Name 		     macAddr, sizeof(tSirMacAddr));
390*5113495bSYour Name 	qdf_spinlock_create(&adapter->data_lock);
391*5113495bSYour Name 	qdf_nbuf_queue_init(&adapter->nodrop_queue);
392*5113495bSYour Name 	adapter->epping_timer_state = EPPING_TX_TIMER_STOPPED;
393*5113495bSYour Name 	qdf_timer_init(epping_get_qdf_ctx(), &adapter->epping_timer,
394*5113495bSYour Name 		epping_timer_expire, dev, QDF_TIMER_TYPE_SW);
395*5113495bSYour Name 	dev->type = ARPHRD_IEEE80211;
396*5113495bSYour Name 	dev->needed_headroom += 24;
397*5113495bSYour Name 	dev->netdev_ops = &epping_drv_ops;
398*5113495bSYour Name 	dev->watchdog_timeo = 5 * HZ;   /* XXX */
399*5113495bSYour Name 	dev->tx_queue_len = EPPING_TXBUF - 1;      /* 1 for mgmt frame */
400*5113495bSYour Name 	if (epping_register_adapter(adapter, rtnl_held) == 0) {
401*5113495bSYour Name 		EPPING_LOG(LOG1, FL("Disabling queues"));
402*5113495bSYour Name 		netif_tx_disable(dev);
403*5113495bSYour Name 		netif_carrier_off(dev);
404*5113495bSYour Name 		return adapter;
405*5113495bSYour Name 	} else {
406*5113495bSYour Name 		epping_destroy_adapter(adapter);
407*5113495bSYour Name 		return NULL;
408*5113495bSYour Name 	}
409*5113495bSYour Name }
410*5113495bSYour Name 
epping_connect_service(epping_context_t * pEpping_ctx)411*5113495bSYour Name int epping_connect_service(epping_context_t *pEpping_ctx)
412*5113495bSYour Name {
413*5113495bSYour Name 	int status, i;
414*5113495bSYour Name 	struct htc_service_connect_req connect;
415*5113495bSYour Name 	struct htc_service_connect_resp response;
416*5113495bSYour Name 
417*5113495bSYour Name 	qdf_mem_zero(&connect, sizeof(connect));
418*5113495bSYour Name 	qdf_mem_zero(&response, sizeof(response));
419*5113495bSYour Name 
420*5113495bSYour Name 	/* these fields are the same for all service endpoints */
421*5113495bSYour Name 	connect.EpCallbacks.pContext = pEpping_ctx;
422*5113495bSYour Name 	connect.EpCallbacks.EpTxCompleteMultiple = NULL;
423*5113495bSYour Name 	connect.EpCallbacks.EpRecv = epping_rx;
424*5113495bSYour Name 	/* epping_tx_complete use Multiple version */
425*5113495bSYour Name 	connect.EpCallbacks.EpTxComplete  = epping_tx_complete;
426*5113495bSYour Name 	connect.MaxSendQueueDepth = 64;
427*5113495bSYour Name 
428*5113495bSYour Name #ifdef HIF_SDIO
429*5113495bSYour Name 	connect.EpCallbacks.EpRecvRefill = epping_refill;
430*5113495bSYour Name 	connect.EpCallbacks.EpSendFull =
431*5113495bSYour Name 		epping_tx_queue_full /* ar6000_tx_queue_full */;
432*5113495bSYour Name #elif defined(HIF_USB) || defined(HIF_PCI) || defined(HIF_SNOC) || \
433*5113495bSYour Name       defined(HIF_IPCI)
434*5113495bSYour Name 	connect.EpCallbacks.EpRecvRefill = NULL /* provided by HIF */;
435*5113495bSYour Name 	connect.EpCallbacks.EpSendFull = NULL /* provided by HIF */;
436*5113495bSYour Name 	/* disable flow control for hw flow control */
437*5113495bSYour Name 	connect.ConnectionFlags |= HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL;
438*5113495bSYour Name #endif
439*5113495bSYour Name 
440*5113495bSYour Name 	/* connect to service */
441*5113495bSYour Name 	connect.service_id = WMI_DATA_BE_SVC;
442*5113495bSYour Name 	status = htc_connect_service(pEpping_ctx->HTCHandle, &connect, &response);
443*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
444*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
445*5113495bSYour Name 			   "Failed to connect to Endpoint Ping BE service status:%d\n",
446*5113495bSYour Name 			   status);
447*5113495bSYour Name 		return status;
448*5113495bSYour Name 	} else {
449*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
450*5113495bSYour Name 			   "eppingtest BE endpoint:%d\n", response.Endpoint);
451*5113495bSYour Name 	}
452*5113495bSYour Name 	pEpping_ctx->EppingEndpoint[0] = response.Endpoint;
453*5113495bSYour Name 
454*5113495bSYour Name #if defined(HIF_PCI) || defined(HIF_USB) || defined(HIF_SNOC) || \
455*5113495bSYour Name     defined(HIF_IPCI)
456*5113495bSYour Name 	connect.service_id = WMI_DATA_BK_SVC;
457*5113495bSYour Name 	status = htc_connect_service(pEpping_ctx->HTCHandle, &connect, &response);
458*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
459*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
460*5113495bSYour Name 			   "Failed to connect to Endpoint Ping BK service status:%d\n",
461*5113495bSYour Name 			   status);
462*5113495bSYour Name 		return status;
463*5113495bSYour Name 	} else {
464*5113495bSYour Name 		EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
465*5113495bSYour Name 			   "eppingtest BK endpoint:%d\n", response.Endpoint);
466*5113495bSYour Name 	}
467*5113495bSYour Name 	pEpping_ctx->EppingEndpoint[1] = response.Endpoint;
468*5113495bSYour Name 	/* Since we do not create other two SVC use BK endpoint
469*5113495bSYour Name 	 * for rest ACs (2, 3) */
470*5113495bSYour Name 	for (i = 2; i < EPPING_MAX_NUM_EPIDS; i++) {
471*5113495bSYour Name 		pEpping_ctx->EppingEndpoint[i] = response.Endpoint;
472*5113495bSYour Name 	}
473*5113495bSYour Name #else
474*5113495bSYour Name 	/* we only use one endpoint for high latenance bus.
475*5113495bSYour Name 	 * Map all AC's EPIDs to the same endpoint ID returned by HTC */
476*5113495bSYour Name 	for (i = 0; i < EPPING_MAX_NUM_EPIDS; i++) {
477*5113495bSYour Name 		pEpping_ctx->EppingEndpoint[i] = response.Endpoint;
478*5113495bSYour Name 	}
479*5113495bSYour Name #endif
480*5113495bSYour Name 	return 0;
481*5113495bSYour Name }
482