1a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/*
2a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * WlanDrvIf.c
3a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
4a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved.
5a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * All rights reserved.
6a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
7a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Redistribution and use in source and binary forms, with or without
8a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * modification, are permitted provided that the following conditions
9a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * are met:
10a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
11a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *  * Redistributions of source code must retain the above copyright
12a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *    notice, this list of conditions and the following disclaimer.
13a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *  * Redistributions in binary form must reproduce the above copyright
14a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *    notice, this list of conditions and the following disclaimer in
15a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *    the documentation and/or other materials provided with the
16a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *    distribution.
17a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *  * Neither the name Texas Instruments nor the names of its
18a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *    contributors may be used to endorse or promote products derived
19a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *    from this software without specific prior written permission.
20a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
21a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt */
33a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
34a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
35a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/*
36a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * src/esta_drv.c
37a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
38a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Kernel level portion of eSTA DK Linux module driver
39a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
40a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt */
41a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
42a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
43a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/** \file   WlanDrvIf.c
44a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *  \brief  The OS-Dependent interfaces of the WLAN driver with external applications:
45a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *          - Configuration utilities (including download, configuration and activation)
46a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *          - Network Stack (Tx and Rx)
47a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *          - Interrupts
48a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *          - Events to external applications
49a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
50a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *  \see    WlanDrvIf.h, Wext.c
51a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt */
52a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
53a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
54a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#include <net/sock.h>
55a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#include <linux/etherdevice.h>
56a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#include <linux/delay.h>
57a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#include <linux/netlink.h>
58a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
59a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#include "WlanDrvIf.h"
60a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#include "osApi.h"
61a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#include "host_platform.h"
62a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#include "context.h"
63a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#include "CmdHndlr.h"
64a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#include "WlanDrvWext.h"
65a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#include "DrvMain.h"
66a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#include "txDataQueue_Api.h"
67a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#include "txMgmtQueue_Api.h"
68a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#include "TWDriver.h"
69a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#include "Ethernet.h"
70a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#ifdef TI_DBG
71a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#include "tracebuf_api.h"
72a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#endif
73a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/* PM hooks */
74ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#ifdef TI_CONFIG_PM_HOOKS
75a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#include "SdioDrv.h"
76a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtstatic int wlanDrvIf_pm_resume(void);
77a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtstatic int wlanDrvIf_pm_suspend(void);
78a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#endif
79a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#include "bmtrace_api.h"
80ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#ifdef STACK_PROFILE
81ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#include "stack_profile.h"
82ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#endif
83a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
84a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/* save driver handle just for module cleanup */
85a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtstatic TWlanDrvIfObj *pDrvStaticHandle;
86a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
87a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#define OS_SPECIFIC_RAM_ALLOC_LIMIT			(0xFFFFFFFF)	/* assume OS never reach that limit */
88a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
89a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
90a615fb1650af6e111053506f1b764b28a5b4631dDmitry ShmidtMODULE_DESCRIPTION("TI WLAN Embedded Station Driver");
91a615fb1650af6e111053506f1b764b28a5b4631dDmitry ShmidtMODULE_LICENSE("GPL");
92a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
93a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
94ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31))
95ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidtstatic int wlanDrvIf_Xmit(struct sk_buff *skb, struct net_device *dev);
96ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidtstatic int wlanDrvIf_XmitDummy(struct sk_buff *skb, struct net_device *dev);
97ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidtstatic struct net_device_stats *wlanDrvIf_NetGetStat(struct net_device *dev);
98ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidtint wlanDrvIf_Open(struct net_device *dev);
99ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidtint wlanDrvIf_Release(struct net_device *dev);
100ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt
101ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidtstatic struct net_device_ops tiwlan_ops_pri = {
102ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	.ndo_open = wlanDrvIf_Open,
103ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	.ndo_stop = wlanDrvIf_Release,
104ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	.ndo_get_stats = wlanDrvIf_NetGetStat,
105ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	.ndo_do_ioctl = NULL,
106ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	.ndo_start_xmit = wlanDrvIf_Xmit,
107ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt};
108ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt
109ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidtstatic struct net_device_ops tiwlan_ops_dummy = {
110ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	.ndo_open = wlanDrvIf_Open,
111ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	.ndo_stop = wlanDrvIf_Release,
112ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	.ndo_get_stats = wlanDrvIf_NetGetStat,
113ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	.ndo_do_ioctl = NULL,
114ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	.ndo_start_xmit = wlanDrvIf_XmitDummy,
115ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt};
116ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#endif
117a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
118a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/**
119a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \fn     wlanDrvIf_Xmit
120a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \brief  Packets transmission
121a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
122a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * The network stack calls this function in order to transmit a packet
123a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *     through the WLAN interface.
124a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * The packet is inserted to the drver Tx queues and its handling is continued
125a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *     after switching to the driver context.
126a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
127a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \note
128a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  skb - The Linux packet buffer structure
129a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  dev - The driver network-interface handle
130a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \return 0 (= OK)
131a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \sa
132a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt */
133a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtstatic int wlanDrvIf_Xmit (struct sk_buff *skb, struct net_device *dev)
134a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
135ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev);
136ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	TTxCtrlBlk *  pPktCtrlBlk;
137ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	int status;
138a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
139ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	CL_TRACE_START_L1();
140a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
141ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	os_profile (drv, 0, 0);
142ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	drv->stats.tx_packets++;
143ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	drv->stats.tx_bytes += skb->len;
144a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
145ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* Allocate a TxCtrlBlk for the Tx packet and save timestamp, length and packet handle */
146ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	pPktCtrlBlk = TWD_txCtrlBlk_Alloc (drv->tCommon.hTWD);
147a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
148ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	pPktCtrlBlk->tTxDescriptor.startTime    = os_timeStampMs(drv); /* remove use of skb->tstamp.off_usec */
149ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	pPktCtrlBlk->tTxDescriptor.length       = skb->len;
150ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	pPktCtrlBlk->tTxPktParams.pInputPkt     = skb;
151a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
152ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* Point the first BDL buffer to the Ethernet header, and the second buffer to the rest of the packet */
153ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	pPktCtrlBlk->tTxnStruct.aBuf[0] = skb->data;
154ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	pPktCtrlBlk->tTxnStruct.aLen[0] = ETHERNET_HDR_LEN;
155ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	pPktCtrlBlk->tTxnStruct.aBuf[1] = skb->data + ETHERNET_HDR_LEN;
156ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	pPktCtrlBlk->tTxnStruct.aLen[1] = (TI_UINT16)skb->len - ETHERNET_HDR_LEN;
157ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	pPktCtrlBlk->tTxnStruct.aLen[2] = 0;
158a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
159ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* Send the packet to the driver for transmission. */
160ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	status = txDataQ_InsertPacket (drv->tCommon.hTxDataQ, pPktCtrlBlk,(TI_UINT8)skb->priority);
161a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
162ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* If failed (queue full or driver not running), drop the packet. */
163a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    if (status != TI_OK)
164a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    {
165a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        drv->stats.tx_errors++;
166a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    }
167ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	os_profile (drv, 1, 0);
168a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
169ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	CL_TRACE_END_L1("tiwlan_drv.ko", "OS", "TX", "");
170a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
171ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	return 0;
172a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt}
173a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/*--------------------------------------------------------------------------------------*/
174a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/**
175a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \fn     wlanDrvIf_FreeTxPacket
176a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \brief  Free the OS Tx packet
177a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
178a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Free the OS Tx packet after driver processing is finished.
179a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
180a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \note
181a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  hOs          - The OAL object handle
182a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  pPktCtrlBlk  - The packet CtrlBlk
183a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  eStatus      - The packet transmission status (OK/NOK)
184a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \return void
185a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \sa
186a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt */
187a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/*--------------------------------------------------------------------------------------*/
188a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
189a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtvoid wlanDrvIf_FreeTxPacket (TI_HANDLE hOs, TTxCtrlBlk *pPktCtrlBlk, TI_STATUS eStatus)
190a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
191a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt	dev_kfree_skb((struct sk_buff *)pPktCtrlBlk->tTxPktParams.pInputPkt);
192a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt}
193a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
194a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/**
195a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \fn     wlanDrvIf_XmitDummy
196a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \brief  Dummy transmission handler
197a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
198a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * This function is registered at the network stack interface as the packets-transmission
199a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *     handler (replacing wlanDrvIf_Xmit) when the driver is not operational.
200a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Using this dummy handler is more efficient then checking the driver state for every
201a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *     packet transmission.
202a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
203a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \note
204a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  skb - The Linux packet buffer structure
205a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  dev - The driver network-interface handle
206a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \return error
207a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \sa     wlanDrvIf_Xmit
208a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt */
209a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtstatic int wlanDrvIf_XmitDummy (struct sk_buff *skb, struct net_device *dev)
210a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
211ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* Just return error. The driver is not running (network stack frees the packet) */
212ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	return -ENODEV;
213a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt}
214a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
215a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
216a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/**
217a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \fn     wlanDrvIf_NetGetStat
218a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \brief  Provides driver statistics
219a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
220a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Provides driver Tx and Rx statistics to network stack.
221a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
222a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \note
223a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  dev - The driver network-interface handle
224a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \return The statistics pointer
225a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \sa
226a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt */
227a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtstatic struct net_device_stats *wlanDrvIf_NetGetStat (struct net_device *dev)
228a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
229ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev);
230ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	ti_dprintf (TIWLAN_LOG_OTHER, "wlanDrvIf_NetGetStat()\n");
231ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt
232ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	return &drv->stats;
233a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt}
234a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
235a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
236a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/**
237a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \fn     wlanDrvIf_UpdateDriverState
238a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \brief  Update the driver state
239a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
240a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * The DrvMain uses this function to update the OAL with the driver steady state
241a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *     that is relevant for the driver users.
242a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
243a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \note
244a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  hOs          - The driver object handle
245a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  eDriverState - The new driver state
246a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \return void
247a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \sa
248a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt */
249a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtvoid wlanDrvIf_UpdateDriverState (TI_HANDLE hOs, EDriverSteadyState eDriverState)
250a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
251ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)hOs;
252a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
253ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	ti_dprintf(TIWLAN_LOG_OTHER, "wlanDrvIf_UpdateDriverState(): State = %d\n", eDriverState);
254a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
255ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* Save the new state */
256ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	drv->tCommon.eDriverState = eDriverState;
257a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
258ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* If the new state is not RUNNING, replace the Tx handler to a dummy one. */
259ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	if (eDriverState != DRV_STATE_RUNNING) {
260ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
261ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		drv->netdev->hard_start_xmit = wlanDrvIf_XmitDummy;
262ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#else
263ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		drv->netdev->netdev_ops = &tiwlan_ops_dummy;
264ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#endif
265ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	}
266a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt}
267a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
268a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
269a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/**
270a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \fn     wlanDrvIf_HandleInterrupt
271a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \brief  The WLAN interrupt handler
272a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
273a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * The WLAN driver interrupt handler called in the interrupt context.
274a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * The actual handling is done in the driver's context after switching to the workqueue.
275a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
276a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \note
277a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  irq      - The interrupt type
278a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  hDrv     - The driver object handle
279a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  cpu_regs - The CPU registers
280a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \return IRQ_HANDLED
281a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \sa
282a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt */
283a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtirqreturn_t wlanDrvIf_HandleInterrupt (int irq, void *hDrv, struct pt_regs *cpu_regs)
284a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
285ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)hDrv;
286a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
287ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	TWD_InterruptRequest (drv->tCommon.hTWD);
288a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
289ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	return IRQ_HANDLED;
290a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt}
291a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
292a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
293a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/**
294a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \fn     PollIrqHandler
295a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \brief  WLAN IRQ polling handler - for debug!
296a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
297a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * A debug option to catch the WLAN events in polling instead of interrupts.
298a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * A timer calls this function periodically to check the interrupt status register.
299a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
300a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \note
301a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  parm - The driver object handle
302a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \return void
303a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \sa
304a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt */
305a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#ifdef PRIODIC_INTERRUPT
306a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtstatic void wlanDrvIf_PollIrqHandler (TI_HANDLE parm)
307a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
308ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)parm;
309a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
310ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	wlanDrvIf_HandleInterrupt (0, drv, NULL);
311ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	os_periodicIntrTimerStart (drv);
312a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt}
313a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#endif
314a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
315a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
316a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/**
317a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \fn     wlanDrvIf_DriverTask
318a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \brief  The driver task
319a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
320a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * This is the driver's task, where most of its job is done.
321a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * External contexts just save required information and schedule the driver's
322a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *     task to continue the handling.
323a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * See more information in the context engine module (context.c).
324a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
325a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \note
326a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  hDrv - The driver object handle
327a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \return void
328a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \sa
329ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt */
330a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
331a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtstatic void wlanDrvIf_DriverTask (void *hDrv)
332a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
333ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)hDrv;
334a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#else
335a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtstatic void wlanDrvIf_DriverTask(struct work_struct *work)
336a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
337ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#ifdef STACK_PROFILE
338ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	register unsigned long sp asm ("sp");
339ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	unsigned long local_sp = sp;
340ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#endif
341ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	TWlanDrvIfObj *drv = container_of(work, TWlanDrvIfObj, tWork);
342a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#endif
343a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
344a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#ifdef STACK_PROFILE
345ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	unsigned long curr1, base1;
346ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	unsigned long curr2, base2;
347ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	static unsigned long maximum_stack = 0;
348a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#endif
349ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	os_profile (drv, 0, 0);
350a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
351a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#ifdef STACK_PROFILE
352ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	curr1 = check_stack_start(&base1, local_sp + 4, 0);
353a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#endif
354a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
355ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* Call the driver main task */
356ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	context_DriverTask (drv->tCommon.hContext);
357a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
358ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	os_profile (drv, 1, 0);
359ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	os_wake_lock_timeout(drv);
360ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	os_wake_unlock(drv);
361a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#ifdef STACK_PROFILE
362ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	curr2 = check_stack_stop(&base2, 0);
363ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	if (base2 == base1) {
364ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* if the current measurement is bigger then the maximum store it and print*/
365ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		if ((curr1 - curr2) > maximum_stack) {
366ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt			printk("STACK PROFILER GOT THE LOCAL MAXIMMUM!!!! \n");
367ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt			printk("current operation stack use=%lu \n",(curr1 - curr2));
368ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt			printk("total stack use=%lu \n",8192 - curr2 + base2);
369ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt			printk("total stack usage=%lu percent \n",100 * (8192 - curr2 + base2) / 8192);
370a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt			maximum_stack = curr1 - curr2;
371ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		}
372ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	}
373a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#endif
374a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt}
375a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
376a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
377a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/**
378a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \fn     wlanDrvIf_LoadFiles
379a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \brief  Load init files from loader
380a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
381a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * This function is called from the loader context right after the driver
382a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *     is created (in IDLE state).
383a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * It copies the following files to the driver's memory:
384a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *     - Ini-File - The driver's default parameters values
385a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *     - NVS-File - The NVS data for FW usage
386a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *     - FW-Image - The FW program image
387a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
388a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \note
389a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  drv - The driver object handle
390a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \return void
391a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \sa     wlanDrvIf_GetFile
392a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt */
393a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtint wlanDrvIf_LoadFiles (TWlanDrvIfObj *drv, TLoaderFilesData *pInitFiles)
394a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
395a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    if (!pInitFiles)
396a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    {
397a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        ti_dprintf (TIWLAN_LOG_ERROR, "No Init Files!\n");
398a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        return -EINVAL;
399a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    }
400a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
401a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    if (drv->tCommon.eDriverState != DRV_STATE_IDLE)
402a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    {
403a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        ti_dprintf (TIWLAN_LOG_ERROR, "Trying to load files not in IDLE state!\n");
404a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        return -EINVAL;
405a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    }
406a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
407a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    if (pInitFiles->uIniFileLength)
408a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    {
409a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        drv->tCommon.tIniFile.uSize = pInitFiles->uIniFileLength;
410a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        drv->tCommon.tIniFile.pImage = kmalloc (pInitFiles->uIniFileLength, GFP_KERNEL);
411a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        #ifdef TI_MEM_ALLOC_TRACE
412a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt          os_printf ("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n", __FUNCTION__, __LINE__, pInitFiles->uIniFileLength, GFP_KERNEL, pInitFiles->uIniFileLength);
413a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        #endif
414a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        if (!drv->tCommon.tIniFile.pImage)
415a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        {
416a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt            ti_dprintf (TIWLAN_LOG_ERROR, "Cannot allocate buffer for Ini-File!\n");
417a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt            return -ENOMEM;
418a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        }
419a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        memcpy (drv->tCommon.tIniFile.pImage,
420a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt                &pInitFiles->data[pInitFiles->uNvsFileLength + pInitFiles->uFwFileLength],
421a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt                drv->tCommon.tIniFile.uSize);
422a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    }
423a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
424a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    if (pInitFiles->uNvsFileLength)
425a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    {
426a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        drv->tCommon.tNvsImage.uSize = pInitFiles->uNvsFileLength;
427a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        drv->tCommon.tNvsImage.pImage = kmalloc (drv->tCommon.tNvsImage.uSize, GFP_KERNEL);
428a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        #ifdef TI_MEM_ALLOC_TRACE
429ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt          os_printf ("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n",
430a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt              __FUNCTION__, __LINE__, drv->tCommon.tNvsImage.uSize, GFP_KERNEL, drv->tCommon.tNvsImage.uSize);
431a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        #endif
432a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        if (!drv->tCommon.tNvsImage.pImage)
433a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        {
434a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt            ti_dprintf (TIWLAN_LOG_ERROR, "Cannot allocate buffer for NVS image\n");
435a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt            return -ENOMEM;
436a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        }
437a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        memcpy (drv->tCommon.tNvsImage.pImage, &pInitFiles->data[0], drv->tCommon.tNvsImage.uSize );
438a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    }
439a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
440a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    drv->tCommon.tFwImage.uSize = pInitFiles->uFwFileLength;
441a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    if (!drv->tCommon.tFwImage.uSize)
442a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    {
443a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        ti_dprintf (TIWLAN_LOG_ERROR, "No firmware image\n");
444a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        return -EINVAL;
445a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    }
446a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    drv->tCommon.tFwImage.pImage = os_memoryAlloc (drv, drv->tCommon.tFwImage.uSize);
447a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    #ifdef TI_MEM_ALLOC_TRACE
448ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt      os_printf ("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n",
449a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt          __FUNCTION__, __LINE__, drv->tCommon.tFwImage.uSize, GFP_KERNEL, drv->tCommon.tFwImage.uSize);
450a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    #endif
451a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    if (!drv->tCommon.tFwImage.pImage)
452a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    {
453a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        ti_dprintf(TIWLAN_LOG_ERROR, "Cannot allocate buffer for firmware image\n");
454a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        return -ENOMEM;
455a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    }
456a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    memcpy (drv->tCommon.tFwImage.pImage,
457a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt            &pInitFiles->data[pInitFiles->uNvsFileLength],
458a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt            drv->tCommon.tFwImage.uSize);
459a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
460a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    ti_dprintf(TIWLAN_LOG_OTHER, "--------- Eeeprom=%p(%lu), Firmware=%p(%lu), IniFile=%p(%lu)\n",
461a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        drv->tCommon.tNvsImage.pImage, drv->tCommon.tNvsImage.uSize,
462a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        drv->tCommon.tFwImage.pImage,  drv->tCommon.tFwImage.uSize,
463a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt        drv->tCommon.tIniFile.pImage,  drv->tCommon.tIniFile.uSize);
464a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
465a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    return 0;
466a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt}
467a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
468a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
469a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/**
470a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \fn     wlanDrvIf_GetFile
471a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \brief  Provides access to a requested init file
472a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
473a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Provide the requested file information and call the requester callback.
474a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Note that in Linux the files were previously loaded to driver memory
475a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *     by the loader (see wlanDrvIf_LoadFiles).
476a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
477a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \note
478a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  hOs       - The driver object handle
479a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  pFileInfo - The requested file's properties
480a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \return TI_OK
481a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \sa     wlanDrvIf_LoadFiles
482a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt */
483a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtint wlanDrvIf_GetFile (TI_HANDLE hOs, TFileInfo *pFileInfo)
484a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
4855d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)hOs;
486a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
487a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt	if (drv == NULL || pFileInfo == NULL) {
488a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		ti_dprintf(TIWLAN_LOG_ERROR, "wlanDrv_GetFile: ERROR: Null File Handler, Exiting");
489a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		return TI_NOK;
490a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt	}
491a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
4925d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	/* Future option for getting the FW image part by part */
4935d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	pFileInfo->hOsFileDesc = NULL;
4945d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt
4955d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	/* Fill the file's location and size in the file's info structure */
4965d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	switch (pFileInfo->eFileType)
4975d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	{
4985d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	case FILE_TYPE_INI:
4995d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt		pFileInfo->pBuffer = (TI_UINT8 *)drv->tCommon.tIniFile.pImage;
5005d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt		pFileInfo->uLength = drv->tCommon.tIniFile.uSize;
5015d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt		break;
5025d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	case FILE_TYPE_NVS:
5035d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt		pFileInfo->pBuffer = (TI_UINT8 *)drv->tCommon.tNvsImage.pImage;
5045d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt		pFileInfo->uLength = drv->tCommon.tNvsImage.uSize;
5055d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt		break;
506a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt	case FILE_TYPE_FW:
5075d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt		if (drv->tCommon.tFwImage.pImage == NULL)
5085d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt		{
5095d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt			ti_dprintf(TIWLAN_LOG_ERROR, "wlanDrv_GetFile: ERROR: no Firmware image, exiting\n");
5105d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt			return TI_NOK;
5115d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt		}
5125d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt
513a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		pFileInfo->pBuffer = (TI_UINT8 *)drv->tCommon.tFwImage.pImage;
514a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		pFileInfo->bLast		= TI_FALSE;
515a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		pFileInfo->uLength	= 0;
516a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		pFileInfo->uOffset 				= 0;
517a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		pFileInfo->uChunkBytesLeft 		= 0;
518a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		pFileInfo->uChunksLeft 			= BYTE_SWAP_LONG( *((TI_UINT32*)(pFileInfo->pBuffer)) );
519a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		/* check uChunksLeft's Validity */
520a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		if (( pFileInfo->uChunksLeft == 0 ) || ( pFileInfo->uChunksLeft > MAX_CHUNKS_IN_FILE ))
521a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		{
522a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt			ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_GetFile() Read Invalid Chunks Left: %d!\n",pFileInfo->uChunksLeft);
523a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt			return TI_NOK;
524a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		}
525a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		pFileInfo->pBuffer += DRV_ADDRESS_SIZE;
526a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		/* FALL THROUGH */
527a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt	case FILE_TYPE_FW_NEXT:
528a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		/* check dec. validity */
529a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		if ( pFileInfo->uChunkBytesLeft >= pFileInfo->uLength )
530a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		{
531a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt			pFileInfo->uChunkBytesLeft 		-= pFileInfo->uLength;
532a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		}
533a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		/* invalid Dec. */
534a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		else
535a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		{
536a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt			ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_GetFile() No. of Bytes Left < File Length\n");
537a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt			return TI_NOK;
538a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		}
539a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		pFileInfo->pBuffer 	+= pFileInfo->uLength;
540a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
541a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		/* Finished reading all Previous Chunk */
542a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		if ( pFileInfo->uChunkBytesLeft == 0 )
543a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		{
544a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt			/* check dec. validity */
545a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt			if ( pFileInfo->uChunksLeft > 0 )
546a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt			{
547a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt				pFileInfo->uChunksLeft--;
548a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt			}
549a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt			/* invalid Dec. */
550a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt			else
551a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt			{
552a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt				ti_dprintf (TIWLAN_LOG_ERROR, "No. of Bytes Left = 0 and Chunks Left <= 0\n");
553a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt				return TI_NOK;
554a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt			}
555a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt			/* read Chunk's address */
556a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt			pFileInfo->uAddress = BYTE_SWAP_LONG( *((TI_UINT32*)(pFileInfo->pBuffer)) );
557a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt			pFileInfo->pBuffer += DRV_ADDRESS_SIZE;
558a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt			/* read Portion's length */
559a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt			pFileInfo->uChunkBytesLeft = BYTE_SWAP_LONG( *((TI_UINT32*)(pFileInfo->pBuffer)) );
560a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt			pFileInfo->pBuffer += DRV_ADDRESS_SIZE;
561a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		}
562a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		/* Reading Chunk is NOT complete */
563a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		else
564a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		{
565a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt			pFileInfo->uAddress += pFileInfo->uLength;
566a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		}
567a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
568a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		if ( pFileInfo->uChunkBytesLeft < OS_SPECIFIC_RAM_ALLOC_LIMIT )
569a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		{
570a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt			pFileInfo->uLength = pFileInfo->uChunkBytesLeft;
571a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		}
572a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		else
573a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		{
574a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt			pFileInfo->uLength = OS_SPECIFIC_RAM_ALLOC_LIMIT;
575a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		}
576a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
577a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		/* If last chunk to download */
578a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		if (( pFileInfo->uChunksLeft == 0 ) &&
579a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt			( pFileInfo->uLength == pFileInfo->uChunkBytesLeft ))
580a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		{
581a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt			pFileInfo->bLast = TI_TRUE;
582a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt		}
583a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
5845d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt		break;
5855d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	}
586a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
5875d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	/* Call the requester callback */
5885d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	if (pFileInfo->fCbFunc)
5895d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	{
5905d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt		pFileInfo->fCbFunc (pFileInfo->hCbHndl);
5915d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	}
592a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
5935d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	return TI_OK;
594a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt}
595a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
596a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
597a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/**
598a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \fn     wlanDrvIf_SetMacAddress
599a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \brief  Set STA MAC address
600a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
601a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Called by DrvMain from init process.
602a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Copies STA MAC address to the network interface structure.
603a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
604a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \note
605a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  hOs      - The driver object handle
606a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  pMacAddr - The STA MAC address
607a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \return TI_OK
608a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \sa     wlanDrvIf_LoadFiles
609a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt */
610a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtvoid wlanDrvIf_SetMacAddress (TI_HANDLE hOs, TI_UINT8 *pMacAddr)
611a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
612ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)hOs;
613a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
614ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* Copy STA MAC address to the network interface structure */
615ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	MAC_COPY (drv->netdev->dev_addr, pMacAddr);
616a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt}
617a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
618a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
619a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/**
620a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \fn     wlanDrvIf_Start
621a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \brief  Start driver
622a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
623a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Called by network stack upon opening network interface (ifconfig up).
624a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Can also be called from user application or CLI for flight mode.
625a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Start the driver initialization process up to OPERATIONAL state.
626a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
627a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \note
628a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  dev - The driver network-interface handle
629a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \return 0 if succeeded, error if driver not available
630a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \sa     wlanDrvIf_Stop
631a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt */
632a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtint wlanDrvIf_Start (struct net_device *dev)
633a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
634ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev);
6355d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	int status;
636a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
637ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	ti_dprintf (TIWLAN_LOG_OTHER, "wlanDrvIf_Start()\n");
638ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	printk("%s\n", __func__);
639005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt    if (!drv->tCommon.hDrvMain)
640005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt    {
641ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_Start() Driver not created!\n");
642ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		return -ENODEV;
643ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	}
644a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
6455d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	if (DRV_STATE_FAILED == drv->tCommon.eDriverState)
6465d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	{
6475d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt		ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_Start() Driver failed!\n");
6485d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt		return -ENODEV;
6495d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	}
6505d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt
651ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/*
652ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	 *  Insert Start command in DrvMain action queue, request driver scheduling
653ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	 *      and wait for action completion (all init process).
654ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	 */
655ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	os_wake_lock_timeout_enable(drv);
6565d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	status = drvMain_InsertAction (drv->tCommon.hDrvMain, ACTION_TYPE_START);
6575d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	return (status) ? -1 : 0;
658a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt}
659a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
660a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtint wlanDrvIf_Open (struct net_device *dev)
661a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
662ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev);
6635d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	int status = 0;
664a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
665ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	ti_dprintf (TIWLAN_LOG_OTHER, "wlanDrvIf_Open()\n");
666ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	printk("%s\n", __func__);
667ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	if (!drv->tCommon.hDrvMain) {
668ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_Open() Driver not created!\n");
669ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		return -ENODEV;
670ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	}
671a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
6725d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	if (drv->tCommon.eDriverState == DRV_STATE_STOPPED ||
6735d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	    drv->tCommon.eDriverState == DRV_STATE_IDLE) {
6745d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt		status = wlanDrvIf_Start(dev);
6755d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	}
676a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
677ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/*
678ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	 *  Finalize network interface setup
679ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	 */
680ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
681ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	drv->netdev->hard_start_xmit = wlanDrvIf_Xmit;
682ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#else
683ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	drv->netdev->netdev_ops = &tiwlan_ops_pri;
684a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#endif
685ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	drv->netdev->addr_len = MAC_ADDR_LEN;
686ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	netif_start_queue (dev);
687a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
688ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* register 3430 PM hooks in our SDIO driver */
689ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#ifdef TI_CONFIG_PM_HOOKS
690ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#ifndef CONFIG_MMC_EMBEDDED_SDIO
691ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	sdioDrv_register_pm(wlanDrvIf_pm_resume, wlanDrvIf_pm_suspend);
692ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#endif
693ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#endif
6945d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	return status;
695a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt}
696a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
697a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/**
698a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \fn     wlanDrvIf_Stop
699a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \brief  Stop driver
700a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
701a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Called by network stack upon closing network interface (ifconfig down).
702a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Can also be called from user application or CLI for flight mode.
703a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Stop the driver and turn off the device.
704a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
705a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \note
706a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  dev - The driver network-interface handle
707a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \return 0 (OK)
708a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \sa     wlanDrvIf_Start
709a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt */
710a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtint wlanDrvIf_Stop (struct net_device *dev)
711a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
712ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev);
713ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt
714ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	ti_dprintf (TIWLAN_LOG_OTHER, "wlanDrvIf_Stop()\n");
715ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	printk("%s\n", __func__);
7165d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt
7175d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	if (DRV_STATE_FAILED == drv->tCommon.eDriverState)
7185d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	{
7195d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt		return -ENODEV;
7205d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt	}
7215d969c3c4738de33d100a514cc06079c1fdaa0e7Dmitry Shmidt
722ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/*
723ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	 *  Insert Stop command in DrvMain action queue, request driver scheduling
724ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	 *      and wait for Stop process completion.
725ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	 */
726ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	os_wake_lock_timeout_enable(drv);
727ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	drvMain_InsertAction (drv->tCommon.hDrvMain, ACTION_TYPE_STOP);
728ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	return 0;
729a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt}
730a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
731a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtint wlanDrvIf_Release (struct net_device *dev)
732a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
733ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* TWlanDrvIfObj *drv = (TWlanDrvIfObj *)NETDEV_GET_PRIVATE(dev); */
734a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
735ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	ti_dprintf (TIWLAN_LOG_OTHER, "wlanDrvIf_Release()\n");
736ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	printk("%s\n", __func__);
737ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* Disable network interface queue */
738ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	netif_stop_queue (dev);
739ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	return 0;
740a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt}
741a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
742a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/* 3430 PM hooks */
743ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#ifdef TI_CONFIG_PM_HOOKS
744a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtstatic int wlanDrvIf_pm_resume(void)
745a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
746a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    return(wlanDrvIf_Open(pDrvStaticHandle->netdev));
747a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt}
748a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
749a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtstatic int wlanDrvIf_pm_suspend(void)
750a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
751a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    wlanDrvIf_Release(pDrvStaticHandle->netdev);
752a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    return(wlanDrvIf_Stop(pDrvStaticHandle->netdev));
753a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt}
754a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#endif
755a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
756a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/**
757a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \fn     wlanDrvIf_SetupNetif
758a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \brief  Setup driver network interface
759a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
760a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Called in driver creation process.
761a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Setup driver network interface.
762a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
763a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \note
764a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  drv - The driver object handle
765a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \return 0 - OK, else - failure
766a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \sa
767a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt */
768a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtstatic int wlanDrvIf_SetupNetif (TWlanDrvIfObj *drv)
769a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
770ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	struct net_device *dev;
771ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	int res;
772ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt
773ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* Allocate network interface structure for the driver */
774ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	dev = alloc_etherdev (0);
775005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt	if (dev == NULL)
776005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt	{
777ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		ti_dprintf (TIWLAN_LOG_ERROR, "alloc_etherdev() failed\n");
778ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		return -ENOMEM;
779ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	}
780a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
781ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* Setup the network interface */
782ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	ether_setup (dev);
783a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
784ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	NETDEV_SET_PRIVATE(dev,drv);
785ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	drv->netdev = dev;
786ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	strcpy (dev->name, TIWLAN_DRV_IF_NAME);
787ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	netif_carrier_off (dev);
788ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
789a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/* the following is required on at least BSP 23.8 and higher.
790a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    Without it, the Open function of the driver will not be called
791a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    when trying to 'ifconfig up' the interface */
792a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,23)
793ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	dev->validate_addr = NULL;
794ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#endif
795ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	dev->open = wlanDrvIf_Open;
796ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	dev->stop = wlanDrvIf_Release;
797ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	dev->hard_start_xmit = wlanDrvIf_XmitDummy;
798ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	dev->get_stats = wlanDrvIf_NetGetStat;
799ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	dev->do_ioctl = NULL;
800ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#else
801ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	dev->netdev_ops = &tiwlan_ops_dummy;
802a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#endif
803ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	dev->tx_queue_len = 100;
804a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
805ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* Initialize Wireless Extensions interface (WEXT) */
806ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	wlanDrvWext_Init (dev);
807a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
808ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	res = register_netdev (dev);
809005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt	if (res != 0)
810005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt	{
811ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		ti_dprintf (TIWLAN_LOG_ERROR, "register_netdev() failed : %d\n", res);
812ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		kfree (dev);
813ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		return res;
814ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	}
815a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/*
816a615fb1650af6e111053506f1b764b28a5b4631dDmitry ShmidtOn the latest Kernel there is no more support for the below macro.
817a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt*/
818a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
819ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	SET_MODULE_OWNER (dev);
820a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#endif
821ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	return 0;
822a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt}
823a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
824a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/**
825a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \fn     wlanDrvIf_CommandDone
826a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \brief  Free current command semaphore.
827a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
828a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * This routine is called whenever a command has finished executing and Free current command semaphore.
829a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
830a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \note
831a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  hOs           - The driver object handle
832a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  pSignalObject - handle to complete mechanism per OS
833a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  CmdResp_p     - respond structure (TCmdRespUnion) for OSE OS only
834a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \return 0 - OK, else - failure
835a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \sa     wlanDrvIf_Destroy
836a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt */
837a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtvoid wlanDrvIf_CommandDone (TI_HANDLE hOs, void *pSignalObject, TI_UINT8 *CmdResp_p)
838a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
839ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* Free semaphore */
840ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	os_SignalObjectSet (hOs, pSignalObject);
841a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt}
842a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
843a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
844a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/**
845a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \fn     wlanDrvIf_Create
846a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \brief  Create the driver instance
847a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
848a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Allocate driver object.
849a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Initialize driver OS resources (IRQ, workqueue, events socket)
850a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Setup driver network interface.
851a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Create and link all driver modules.
852a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
853a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \note
854a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  void
855a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \return 0 - OK, else - failure
856a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \sa     wlanDrvIf_Destroy
857a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt */
858a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtstatic int wlanDrvIf_Create (void)
859a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
860ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	TWlanDrvIfObj *drv; /* Dm: Failure is not cleaned properly !!! */
861ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	int rc;
862a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
863ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* Allocate driver's structure */
864ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	drv = kmalloc (sizeof(TWlanDrvIfObj), GFP_KERNEL);
865005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt    if (!drv)
866005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt    {
867ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		return -ENOMEM;
868ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	}
869a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#ifdef TI_DBG
870a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt	tb_init(TB_OPTION_NONE);
871a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#endif
872ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	pDrvStaticHandle = drv;  /* save for module destroy */
873ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#ifdef TI_MEM_ALLOC_TRACE
874ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	os_printf ("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n", __FUNCTION__, __LINE__, sizeof(TWlanDrvIfObj), GFP_KERNEL, sizeof(TWlanDrvIfObj));
875ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#endif
876ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	memset (drv, 0, sizeof(TWlanDrvIfObj));
877a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
878ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* Dm:    drv->irq = TNETW_IRQ; */
879ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	drv->tCommon.eDriverState = DRV_STATE_IDLE;
880a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
881ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	drv->tiwlan_wq = create_freezeable_workqueue(DRIVERWQ_NAME);
882ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	if (!drv->tiwlan_wq) {
883ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_Create(): Failed to create workQ!\n");
884ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		rc = -EINVAL;
885ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		goto drv_create_end_1;
886ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	}
887ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	drv->wl_packet = 0;
888ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	drv->wl_count = 0;
889a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#ifdef CONFIG_HAS_WAKELOCK
890ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	wake_lock_init(&drv->wl_wifi, WAKE_LOCK_SUSPEND, "wifi_wake");
891ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	wake_lock_init(&drv->wl_rxwake, WAKE_LOCK_SUSPEND, "wifi_rx_wake");
892a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#endif
893a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
894ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	INIT_WORK(&drv->tWork, wlanDrvIf_DriverTask, (void *)drv);
895a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#else
896ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	INIT_WORK(&drv->tWork, wlanDrvIf_DriverTask);
897a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#endif
898ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	spin_lock_init (&drv->lock);
899a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
900ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* Setup driver network interface. */
901ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	rc = wlanDrvIf_SetupNetif (drv);
902ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	if (rc)	{
903ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		goto drv_create_end_2;
904ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	}
905a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
906ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* Create the events socket interface */
907a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
908a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt	drv->wl_sock = netlink_kernel_create( NETLINK_USERSOCK, 0, NULL, THIS_MODULE );
909a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#else
910ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	drv->wl_sock = netlink_kernel_create(&init_net, NETLINK_USERSOCK, 0, NULL, NULL, THIS_MODULE );
911a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#endif
912ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	if (drv->wl_sock == NULL) {
913ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	        ti_dprintf (TIWLAN_LOG_ERROR, "netlink_kernel_create() failed !\n");
914ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		rc = -EINVAL;
915ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		goto drv_create_end_3;
916ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	}
917a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
918ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* Create all driver modules and link their handles */
919ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	rc = drvMain_Create (drv,
920ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt			&drv->tCommon.hDrvMain,
921ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt			&drv->tCommon.hCmdHndlr,
922ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt			&drv->tCommon.hContext,
923ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt			&drv->tCommon.hTxDataQ,
924ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt			&drv->tCommon.hTxMgmtQ,
925ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt			&drv->tCommon.hTxCtrl,
926ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt			&drv->tCommon.hTWD,
927a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt					&drv->tCommon.hEvHandler,
928a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt                    &drv->tCommon.hCmdDispatch,
929ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		&drv->tCommon.hReport);
930ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	if (rc != TI_OK) {
931ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		ti_dprintf (TIWLAN_LOG_ERROR, "%s: Failed to dvrMain_Create!\n", __func__);
932ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		rc = -EINVAL;
933ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		goto drv_create_end_4;
934ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	}
935ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/*
936ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	 *  Initialize interrupts (or polling mode for debug):
937ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	 */
938a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#ifdef PRIODIC_INTERRUPT
939ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* Debug mode: Polling (the timer is started by HwInit process) */
940ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	drv->hPollTimer = os_timerCreate ((TI_HANDLE)drv, wlanDrvIf_PollIrqHandler, (TI_HANDLE)drv);
941a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#else
942ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* Normal mode: Interrupts (the default mode) */
943ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	rc = hPlatform_initInterrupt (drv, (void*)wlanDrvIf_HandleInterrupt);
944ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	if (rc)	{
945ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		ti_dprintf (TIWLAN_LOG_ERROR, "wlanDrvIf_Create(): Failed to register interrupt handler!\n");
946ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		goto drv_create_end_5;
947ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	}
948a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#endif  /* PRIODIC_INTERRUPT */
949ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	return 0;
950ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidtdrv_create_end_5:
951ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* Destroy all driver modules */
952ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	if (drv->tCommon.hDrvMain) {
953ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		drvMain_Destroy (drv->tCommon.hDrvMain);
954ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	}
955ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidtdrv_create_end_4:
956ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	if (drv->wl_sock) {
957ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		sock_release (drv->wl_sock->sk_socket);
958ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	}
959ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt
960ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidtdrv_create_end_3:
961ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* Release the driver network interface */
962ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	if (drv->netdev) {
963ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		unregister_netdev (drv->netdev);
964ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		free_netdev (drv->netdev);
965ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	}
966ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt
967ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidtdrv_create_end_2:
968ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#ifdef CONFIG_HAS_WAKELOCK
969ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	wake_lock_destroy(&drv->wl_wifi);
970ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	wake_lock_destroy(&drv->wl_rxwake);
971ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#endif
972ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	if (drv->tiwlan_wq)
973ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		destroy_workqueue(drv->tiwlan_wq);
974a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
975ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidtdrv_create_end_1:
976ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	kfree(drv);
977ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	printk("%s: Fail\n", __func__);
978ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	return rc;
979a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt}
980a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
981a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
982a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/**
983a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \fn     wlanDrvIf_Destroy
984a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \brief  Destroy the driver instance
985a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
986a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Destroy all driver modules.
987a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Release driver OS resources (IRQ, workqueue, events socket)
988a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Release driver network interface.
989a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Free init files memory.
990a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * Free driver object.
991a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
992a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \note
993a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  drv - The driver object handle
994a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \return void
995a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \sa     wlanDrvIf_Create
996a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt */
997a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtstatic void wlanDrvIf_Destroy (TWlanDrvIfObj *drv)
998a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
999ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	if (!drv)
1000ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		return;
1001a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
1002ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	if (drv->tiwlan_wq) {
1003ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		cancel_work_sync(&drv->tWork);
1004ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		flush_workqueue(drv->tiwlan_wq);
1005ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	}
1006a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
1007ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* Release the driver network interface */
1008ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	if (drv->netdev) {
1009ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		netif_stop_queue  (drv->netdev);
1010ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		wlanDrvIf_Stop    (drv->netdev);
1011ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		unregister_netdev (drv->netdev);
1012ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		free_netdev (drv->netdev);
1013ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	}
1014a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
1015a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt	/* Destroy all driver modules */
1016ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	if (drv->tCommon.hDrvMain) {
1017ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		drvMain_Destroy (drv->tCommon.hDrvMain);
1018ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	}
1019a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
1020ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* close the ipc_kernel socket*/
1021005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt    if (drv && drv->wl_sock)
1022005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt    {
1023ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		sock_release (drv->wl_sock->sk_socket);
1024ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	}
1025ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/* Release the driver interrupt (or polling timer) */
1026a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#ifdef PRIODIC_INTERRUPT
1027ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	os_timerDestroy (drv, drv->hPollTimer);
1028a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#else
1029005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt    if (drv->irq)
1030005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt    {
1031ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		hPlatform_freeInterrupt(drv);
1032ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	}
1033a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#endif
1034ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	if (drv->tiwlan_wq)
1035ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt		destroy_workqueue(drv->tiwlan_wq);
1036a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
1037a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#ifdef CONFIG_HAS_WAKELOCK
1038ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	wake_lock_destroy(&drv->wl_wifi);
1039ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	wake_lock_destroy(&drv->wl_rxwake);
1040a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#endif
1041ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	/*
1042ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	 *  Free init files memory
1043ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	 */
1044005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt    if (drv->tCommon.tFwImage.pImage)
1045005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt    {
1046005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt        os_memoryFree (drv, drv->tCommon.tFwImage.pImage, drv->tCommon.tFwImage.uSize);
1047005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt        #ifdef TI_MEM_ALLOC_TRACE
1048005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt          os_printf ("MTT:%s:%d ::kfree(0x%p) : %d\n",
1049005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt              __FUNCTION__, __LINE__, drv->tCommon.tFwImage.uSize, -drv->tCommon.tFwImage.uSize);
1050005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt        #endif
1051005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt    }
1052005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt    if (drv->tCommon.tNvsImage.pImage)
1053005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt    {
1054005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt        kfree (drv->tCommon.tNvsImage.pImage);
1055005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt        #ifdef TI_MEM_ALLOC_TRACE
1056005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt          os_printf ("MTT:%s:%d ::kfree(0x%p) : %d\n",
1057005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt              __FUNCTION__, __LINE__, drv->tCommon.tNvsImage.uSize, -drv->tCommon.tNvsImage.uSize);
1058005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt        #endif
1059005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt    }
1060005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt    if (drv->tCommon.tIniFile.pImage)
1061005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt    {
1062005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt        kfree (drv->tCommon.tIniFile.pImage);
1063005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt        #ifdef TI_MEM_ALLOC_TRACE
1064005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt          os_printf ("MTT:%s:%d ::kfree(0x%p) : %d\n",
1065005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt              __FUNCTION__, __LINE__, drv->tCommon.tIniFile.uSize, -drv->tCommon.tIniFile.uSize);
1066005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt        #endif
1067005bbf20350954d05c8a111d3f487d6fddb049bbDmitry Shmidt    }
1068a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
1069a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    /* Free the driver object */
1070a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt#ifdef TI_DBG
1071a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt	tb_destroy();
1072ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#endif
1073ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	kfree (drv);
1074a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt}
1075a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
1076a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
1077a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/**
1078a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \fn     wlanDrvIf_ModuleInit  &  wlanDrvIf_ModuleExit
1079a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \brief  Linux Init/Exit functions
1080a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
1081a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * The driver Linux Init/Exit functions (insmod/rmmod)
1082a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
1083a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \note
1084a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  void
1085a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \return Init: 0 - OK, else - failure.   Exit: void
1086a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \sa     wlanDrvIf_Create, wlanDrvIf_Destroy
1087a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt */
1088ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#ifndef TI_SDIO_STANDALONE
1089ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidtstatic int sdc_ctrl = 2;
1090ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidtmodule_param(sdc_ctrl, int, S_IRUGO | S_IWUSR | S_IWGRP);
1091ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt
1092ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidtextern int sdioDrv_init(int sdcnum);
1093ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidtextern void sdioDrv_exit(void);
1094ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#endif
1095ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt
1096a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtstatic int __init wlanDrvIf_ModuleInit (void)
1097a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
1098ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	printk(KERN_INFO "TIWLAN: driver init\n");
1099ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#ifndef TI_SDIO_STANDALONE
1100ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#ifndef CONFIG_MMC_EMBEDDED_SDIO
1101ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	sdioDrv_init(sdc_ctrl);
1102ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#endif
1103ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#endif
1104ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	return wlanDrvIf_Create ();
1105a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt}
1106a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
1107a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtstatic void __exit wlanDrvIf_ModuleExit (void)
1108a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
1109ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	wlanDrvIf_Destroy (pDrvStaticHandle);
1110ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#ifndef TI_SDIO_STANDALONE
1111ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#ifndef CONFIG_MMC_EMBEDDED_SDIO
1112ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	sdioDrv_exit();
1113ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#endif
1114ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt#endif
1115ddac9c138c5b4b16b99fb8bc5f0f10418efa1029Dmitry Shmidt	printk (KERN_INFO "TI WLAN: driver unloaded\n");
1116a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt}
1117a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
1118a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
1119a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/**
1120a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \fn     wlanDrvIf_StopTx
1121a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \brief  block Tx thread until wlanDrvIf_ResumeTx called .
1122a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
1123a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * This routine is called whenever we need to stop the network stack to send us pakets since one of our Q's is full.
1124a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
1125a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \note
1126a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  hOs           - The driver object handle
1127a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt* \return
1128a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \sa     wlanDrvIf_StopTx
1129a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt */
1130a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtvoid wlanDrvIf_StopTx (TI_HANDLE hOs)
1131a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
1132a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    TWlanDrvIfObj *drv = (TWlanDrvIfObj *)hOs;
1133a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
1134a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    netif_stop_queue (drv->netdev);
1135a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt}
1136a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
1137a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt/**
1138a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \fn     wlanDrvIf_ResumeTx
1139a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \brief  Resume Tx thread .
1140a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
1141a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * This routine is called whenever we need to resume the network stack to send us pakets since our Q's are empty.
1142a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt *
1143a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \note
1144a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \param  hOs           - The driver object handle
1145a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \return
1146a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt * \sa     wlanDrvIf_ResumeTx
1147a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt */
1148a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtvoid wlanDrvIf_ResumeTx (TI_HANDLE hOs)
1149a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt{
1150a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    TWlanDrvIfObj *drv = (TWlanDrvIfObj *)hOs;
1151a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
1152a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt    netif_wake_queue (drv->netdev);
1153a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt}
1154a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidt
1155a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtmodule_init (wlanDrvIf_ModuleInit);
1156a615fb1650af6e111053506f1b764b28a5b4631dDmitry Shmidtmodule_exit (wlanDrvIf_ModuleExit);
1157