summaryrefslogtreecommitdiff
path: root/sta_dk_4_0_4_32/pform/linux/src
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:32:59 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-03-03 19:32:59 -0800
commit64064216a8433360745f69edddce19a606659163 (patch)
tree8560eb8064c57863da51b30c99e054b8123fd33c /sta_dk_4_0_4_32/pform/linux/src
parentba13e298dff123b5a281d6e2704fcdc684b324fa (diff)
downloadti-64064216a8433360745f69edddce19a606659163.tar.gz
auto import from //depot/cupcake/@135843
Diffstat (limited to 'sta_dk_4_0_4_32/pform/linux/src')
-rw-r--r--sta_dk_4_0_4_32/pform/linux/src/bmtrace.c183
-rwxr-xr-xsta_dk_4_0_4_32/pform/linux/src/chip_stat.c176
-rw-r--r--sta_dk_4_0_4_32/pform/linux/src/env_tst.c106
-rw-r--r--sta_dk_4_0_4_32/pform/linux/src/esta_drv.c2060
-rw-r--r--sta_dk_4_0_4_32/pform/linux/src/ioctl_list.c263
-rw-r--r--sta_dk_4_0_4_32/pform/linux/src/ioctl_utils.c164
-rw-r--r--sta_dk_4_0_4_32/pform/linux/src/ioctl_utils.h95
-rw-r--r--sta_dk_4_0_4_32/pform/linux/src/ipc_k.c120
-rw-r--r--sta_dk_4_0_4_32/pform/linux/src/ipc_k.h46
-rwxr-xr-xsta_dk_4_0_4_32/pform/linux/src/mmc_tnetw1150_api.c545
-rw-r--r--sta_dk_4_0_4_32/pform/linux/src/osRgstry_parser.c232
-rw-r--r--sta_dk_4_0_4_32/pform/linux/src/osapi.c1765
-rw-r--r--sta_dk_4_0_4_32/pform/linux/src/osmemapi.c483
-rw-r--r--sta_dk_4_0_4_32/pform/linux/src/proc_stat.c105
-rw-r--r--sta_dk_4_0_4_32/pform/linux/src/stack_profile.c87
-rw-r--r--sta_dk_4_0_4_32/pform/linux/src/string.c69
-rw-r--r--sta_dk_4_0_4_32/pform/linux/src/tiwlan_profile.c344
-rw-r--r--sta_dk_4_0_4_32/pform/linux/src/tiwlan_profile.h52
-rwxr-xr-xsta_dk_4_0_4_32/pform/linux/src/tnetw_sdio.c235
19 files changed, 7130 insertions, 0 deletions
diff --git a/sta_dk_4_0_4_32/pform/linux/src/bmtrace.c b/sta_dk_4_0_4_32/pform/linux/src/bmtrace.c
new file mode 100644
index 0000000..0a6dea9
--- /dev/null
+++ b/sta_dk_4_0_4_32/pform/linux/src/bmtrace.c
@@ -0,0 +1,183 @@
+/****************************************************************************
+**+-----------------------------------------------------------------------+**
+**| |**
+**| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |**
+**| All rights reserved. |**
+**| |**
+**| Redistribution and use in source and binary forms, with or without |**
+**| modification, are permitted provided that the following conditions |**
+**| are met: |**
+**| |**
+**| * Redistributions of source code must retain the above copyright |**
+**| notice, this list of conditions and the following disclaimer. |**
+**| * Redistributions in binary form must reproduce the above copyright |**
+**| notice, this list of conditions and the following disclaimer in |**
+**| the documentation and/or other materials provided with the |**
+**| distribution. |**
+**| * Neither the name Texas Instruments nor the names of its |**
+**| contributors may be used to endorse or promote products derived |**
+**| from this software without specific prior written permission. |**
+**| |**
+**| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |**
+**| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |**
+**| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
+**| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |**
+**| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
+**| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |**
+**| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
+**| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
+**| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |**
+**| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
+**| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |**
+**| |**
+**+-----------------------------------------------------------------------+**
+****************************************************************************/
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/proc_fs.h>
+
+#include "osApi.h"
+#include "esta_drv.h"
+#include "bmtrace.h"
+
+#define OS_READ_REG(drv,reg,p_val) \
+ os_hwReadMemRegisterUINT32(drv, (UINT32 *)((unsigned long)drv->acx_reg.va + reg), p_val)
+
+typedef struct {
+ unsigned long loc;/* trace entry identification */
+ unsigned long ts;/* Timestamp */
+ unsigned long p1; /* Parameter 1 */
+ unsigned long p2; /* Parameter 2 */
+} bm_entry_t;
+
+typedef struct {
+ int pos;
+ int count;
+ int print_pos;
+ int nusers;
+ unsigned long self_delay;
+ tiwlan_net_dev_t *drv;
+ bm_entry_t entry[1]; /* Array of entries */
+} bm_control_t;
+
+static bm_control_t *bm_control;
+
+static inline int bm_control_size(void)
+{
+ return offsetof(bm_control_t, entry) + sizeof(bm_entry_t)*BM_NUM_ENTRIES;
+}
+
+static int bm_res_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int i;
+ int len=0;
+ int limit=count-80;
+ int entry_count;
+ unsigned long prev=0;
+ int print_pos;
+
+ print_pos = bm_control->print_pos++; /* It will disable tracing as well */
+
+ entry_count = (bm_control->count > BM_NUM_ENTRIES) ? BM_NUM_ENTRIES : bm_control->count;
+
+ /* Skip off entries */
+ if ( print_pos >= entry_count) /* paranoid */
+ {
+ bm_control->pos = bm_control->count = bm_control->print_pos = 0;
+ *eof = 1;
+ return 0;
+ }
+
+ if (!off)
+ {
+ len = sprintf(page, "Events stored: %u discarded: %u\n",
+ entry_count, bm_control->count-entry_count);
+ len += sprintf(page+len, "loc delta ts p1 p2\n");
+ }
+
+ /* Initial index */
+ if (bm_control->count > BM_NUM_ENTRIES)
+ i = (bm_control->pos+print_pos-1)%BM_NUM_ENTRIES;
+ else
+ i = bm_control->print_pos-1;
+
+ for(; (print_pos<entry_count) && (len<=limit); print_pos++)
+ {
+ bm_entry_t *bme= &bm_control->entry[i];
+ len += sprintf(page+len,
+ "%-3lu %-10lu %-10lu %-10lu %-10lu\n",
+ bme->loc,
+ ((bme->ts-prev)>bm_control->self_delay)?bme->ts-prev-bm_control->self_delay:0,
+ bme->ts,
+ bme->p1, bme->p2);
+ prev = bme->ts;
+ ++i;
+ i %= BM_NUM_ENTRIES;
+ }
+ if (print_pos >= entry_count)
+ {
+ *eof = 1;
+ bm_control->pos = bm_control->count = bm_control->print_pos = 0;
+ }
+ else
+ bm_control->print_pos = print_pos;
+ return len;
+}
+
+
+/* Initialization */
+int bm_init(struct tiwlan_net_dev *drv)
+{
+ if (bm_control)
+ {
+ ++bm_control->nusers;
+ return 0;
+ }
+ bm_control = (bm_control_t *)kmalloc(bm_control_size(), GFP_KERNEL);
+ if (!bm_control)
+ return -ENOMEM;
+ memset(bm_control, 0, offsetof(bm_control_t, entry) + sizeof(bm_entry_t)*BM_NUM_ENTRIES);
+ bm_control->nusers = 1;
+ bm_control->drv = drv;
+
+ create_proc_read_entry("bmtrace", 0, NULL, bm_res_read_proc, NULL);
+ /* Measure self-delay */
+ bm_trace(0, 0, 0);
+ bm_trace(0, 0, 0);
+ bm_control->self_delay = bm_control->entry[1].ts - bm_control->entry[0].ts;
+ bm_control->pos = bm_control->count = 0;
+ print_info("%s: self_delay=%lu\n", __FUNCTION__, bm_control->self_delay);
+ return 0;
+}
+
+/* De-initialization */
+void bm_destroy(void)
+{
+ if (--bm_control->nusers)
+ return;
+ remove_proc_entry("bmtrace", NULL);
+ kfree( bm_control );
+}
+
+
+/* Add trace entry. not safe, but will do */
+void bm_trace(int loc, unsigned long p1, unsigned long p2)
+{
+ int pos;
+ if (!bm_control || bm_control->print_pos)
+ return;
+ pos = bm_control->pos;
+ bm_control->pos = (pos+1) % BM_NUM_ENTRIES;
+ ++bm_control->count;
+
+ bm_control->entry[pos].ts = os_timeStampUs(NULL);
+ bm_control->entry[pos].loc= loc;
+ bm_control->entry[pos].p1 = p1;
+ bm_control->entry[pos].p2 = p2;
+}
+
diff --git a/sta_dk_4_0_4_32/pform/linux/src/chip_stat.c b/sta_dk_4_0_4_32/pform/linux/src/chip_stat.c
new file mode 100755
index 0000000..531c055
--- /dev/null
+++ b/sta_dk_4_0_4_32/pform/linux/src/chip_stat.c
@@ -0,0 +1,176 @@
+/****************************************************************************
+**+-----------------------------------------------------------------------+**
+**| |**
+**| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |**
+**| All rights reserved. |**
+**| |**
+**| Redistribution and use in source and binary forms, with or without |**
+**| modification, are permitted provided that the following conditions |**
+**| are met: |**
+**| |**
+**| * Redistributions of source code must retain the above copyright |**
+**| notice, this list of conditions and the following disclaimer. |**
+**| * Redistributions in binary form must reproduce the above copyright |**
+**| notice, this list of conditions and the following disclaimer in |**
+**| the documentation and/or other materials provided with the |**
+**| distribution. |**
+**| * Neither the name Texas Instruments nor the names of its |**
+**| contributors may be used to endorse or promote products derived |**
+**| from this software without specific prior written permission. |**
+**| |**
+**| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |**
+**| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |**
+**| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
+**| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |**
+**| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
+**| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |**
+**| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
+**| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
+**| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |**
+**| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
+**| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |**
+**| |**
+**+-----------------------------------------------------------------------+**
+****************************************************************************/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+
+#include "mmc_tnetw1150_api.h"
+#include "esta_drv.h"
+#include "srcApi.h"
+#include "osApi.h"
+#include "whalHwRegs.h"
+
+#include "tiwlnif.h"
+#include "osUtil.h"
+
+#ifdef TIWLAN_MSM7000
+struct sdio_func *SDIO_GetFunc( void );
+#endif
+
+/* Module parameters */
+static char tiwlan_chip_id[10] = "na";
+module_param_string(chip_id, tiwlan_chip_id, sizeof(tiwlan_chip_id), S_IWUSR | S_IRUGO);
+MODULE_PARM_DESC(tiwlan_chip_id, "WiFi chip id");
+static char fw_version[10] = "na";
+module_param_string(fw_version, fw_version, sizeof(fw_version), S_IWUSR | S_IRUGO);
+MODULE_PARM_DESC(fw_version, "WiFi firmware version");
+
+/* export_wifi_fw_version
+ Exports WiFi firmware version to /sys/module/wlan/parameters/fw_version
+ Returns 0 if OK
+*/
+int export_wifi_fw_version( tiwlan_net_dev_t *drv )
+{
+ TIWLN_VERSION swVer;
+ unsigned long swLen;
+ int ret;
+
+ if (!drv)
+ return -EINVAL;
+
+ swLen = sizeof(swVer);
+ memset(&swVer, 0, swLen);
+ ret = UtilGetSwVersion(&drv->adapter, (unsigned char *)&swVer, &swLen);
+ if (ret != 0)
+ return -EINVAL;
+
+ fw_version[0] = swVer.FWVersion.major + 48;
+ fw_version[1] = '.';
+ fw_version[2] = swVer.FWVersion.minor + 48;
+ fw_version[3] = '.';
+ fw_version[4] = swVer.FWVersion.bugfix + 48;
+ fw_version[5] = '.';
+ fw_version[6] = swVer.FWVersion.subld + 48;
+ fw_version[7] = '.';
+ fw_version[8] = swVer.FWVersion.build + 48;
+ fw_version[9] = '\0';
+ return ret;
+}
+
+/* print_wifi_chip_id
+ Reads WiFi chip id (0x07030101) and prints it
+ Returns 0 if OK
+*/
+int export_wifi_chip_id( void )
+{
+ unsigned char chip_id[4];
+ unsigned long amap;
+#ifdef TIWLAN_MSM7000
+ SDIO_Request_t req;
+ struct sdio_func *func;
+
+ func = SDIO_GetFunc();
+ if (!func)
+ return -EINVAL;
+
+ /* configure partition */
+ amap = SDIO_DOWNLOAD_PARTITION_START;
+ req.buffer = (unsigned char *)&amap;
+ req.buffer_len = 4;
+ req.peripheral_addr = 0x1ffc4;
+ SDIO_SyncWrite(func, &req);
+
+ amap = SDIO_DOWNLOAD_PARTITION_SIZE;
+ req.buffer = (unsigned char *)&amap;
+ req.buffer_len = 4;
+ req.peripheral_addr = 0x1ffc0;
+ SDIO_SyncWrite(func, &req);
+
+ amap = SDIO_REG_PARTITION_START;
+ req.buffer = (unsigned char *)&amap;
+ req.buffer_len = 4;
+ req.peripheral_addr = 0x1ffcc;
+ SDIO_SyncWrite(func, &req);
+
+ amap = SDIO_REG_PARTITION_SIZE;
+ req.buffer = (unsigned char *)&amap;
+ req.buffer_len = 4;
+ req.peripheral_addr = 0x1ffc8;
+ SDIO_SyncWrite(func, &req);
+
+ /* get TIWLAN1251 ID */
+ memset(chip_id, 0, 4);
+ req.buffer = chip_id;
+ req.buffer_len = 4;
+ req.peripheral_addr = SDIO_DOWNLOAD_PARTITION_SIZE + CHIP_ID; /* 0x1BE74 */
+ SDIO_SyncRead(func, &req);
+#endif
+#ifdef TIWLAN_OMAP1610
+ /* Can not be read on this stage - SDIO stack is not initialized yet */
+ amap = TNETW1251_CHIP_ID_PG1_2;
+ memcpy(chip_id, &amap, 4);
+#endif
+
+ if ((chip_id[2] >= 1) && (chip_id[2] <= 3)){
+ tiwlan_chip_id[0] = '1';
+ tiwlan_chip_id[1] = '2';
+ tiwlan_chip_id[2] = '5';
+ tiwlan_chip_id[3] = '1';
+ tiwlan_chip_id[4] = 'P';
+ tiwlan_chip_id[5] = 'G';
+ tiwlan_chip_id[6] = '1';
+ tiwlan_chip_id[7] = '.';
+ }
+ switch(chip_id[2]){
+ case 1:
+ tiwlan_chip_id[8] = '0';
+ printk("TIWLAN: 1251 PG 1.0\n");
+ break;
+ case 2:
+ tiwlan_chip_id[8] = '1';
+ printk("TIWLAN: 1251 PG 1.1\n");
+ break;
+ case 3:
+ tiwlan_chip_id[8] = '2';
+ printk("TIWLAN: 1251 PG 1.2\n");
+ break;
+ default:
+ printk("TIWLAN: invalid chip id = 0x%2x%2x%2x%2x!\n",
+ chip_id[3], chip_id[2], chip_id[1], chip_id[0]);
+ return -EINVAL;
+ };
+ return 0;
+}
diff --git a/sta_dk_4_0_4_32/pform/linux/src/env_tst.c b/sta_dk_4_0_4_32/pform/linux/src/env_tst.c
new file mode 100644
index 0000000..2c5ddf6
--- /dev/null
+++ b/sta_dk_4_0_4_32/pform/linux/src/env_tst.c
@@ -0,0 +1,106 @@
+/****************************************************************************
+**+-----------------------------------------------------------------------+**
+**| |**
+**| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |**
+**| All rights reserved. |**
+**| |**
+**| Redistribution and use in source and binary forms, with or without |**
+**| modification, are permitted provided that the following conditions |**
+**| are met: |**
+**| |**
+**| * Redistributions of source code must retain the above copyright |**
+**| notice, this list of conditions and the following disclaimer. |**
+**| * Redistributions in binary form must reproduce the above copyright |**
+**| notice, this list of conditions and the following disclaimer in |**
+**| the documentation and/or other materials provided with the |**
+**| distribution. |**
+**| * Neither the name Texas Instruments nor the names of its |**
+**| contributors may be used to endorse or promote products derived |**
+**| from this software without specific prior written permission. |**
+**| |**
+**| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |**
+**| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |**
+**| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
+**| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |**
+**| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
+**| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |**
+**| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
+**| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
+**| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |**
+**| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
+**| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |**
+**| |**
+**+-----------------------------------------------------------------------+**
+****************************************************************************/
+
+
+#include <linux/errno.h>
+#include <linux/string.h>
+
+#include "arch_ti.h"
+#include "osTIType.h"
+#include "osApi.h"
+#include "ioctl_init.h"
+
+#include "802_11Defs.h"
+#include "mlmeApi.h"
+
+/****************************************************************************/
+/* */
+/* Definition of Constants */
+/* */
+/****************************************************************************/
+#define SIZEOF_DOT11_MGMT_HEADER 0x18
+#define SIZEOF_MLME_FRAME_INFO 0x60
+#ifdef EXC_MODULE_INCLUDED
+#define SIZEOF_BEACON_FRM 0x57
+#else
+#define SIZEOF_BEACON_FRM 0x53
+#endif
+#define SIZEOF_ELEMENT_HDR 0x02
+#define SIZEOF_MGMT_FRAME 0x920
+#define SIZEOF_ASSOC_RSP_TYPE 0x26
+#define SIZEOF_AUTH_MSG_TYPE 0x0a
+#define SIZEOF_DEATUH_MSG_TYPE 0x02
+#define SIZEOF_DISASSOC_MSG_TYPE 0x02
+
+#define CHECK_STRUCT_SIZE(_type,_size) \
+{ \
+ if (sizeof(_type) != _size) \
+ { \
+ print_info(KERN_INFO"\n.... ERROR in size of %s struct 0x%08x should be 0x%08x.....\n", \
+ #_type, (int)sizeof(_type),(int)_size); \
+ rc = -EINVAL; \
+ } \
+}
+
+/************************************************************************
+ * packed_strct_tst *
+ ************************************************************************
+DESCRIPTION: Used to test structures for the correct packed size
+
+INPUT: Void
+
+OUTPUT: Print Debug statements if the structures are not the expected size
+
+RETURN: 0=success
+ -EINVAL - failure
+
+************************************************************************/
+int packed_struct_tst (void)
+{
+ int rc = 0;
+ print_info("\nTIWLAN: Testing sizes of packed structures...\n");
+ CHECK_STRUCT_SIZE(dot11_mgmtHeader_t, SIZEOF_DOT11_MGMT_HEADER);
+ CHECK_STRUCT_SIZE(dot11_eleHdr_t, SIZEOF_ELEMENT_HDR);
+ CHECK_STRUCT_SIZE(beacon_probeRsp_t, SIZEOF_BEACON_FRM);
+ CHECK_STRUCT_SIZE(assocRsp_t, SIZEOF_ASSOC_RSP_TYPE );
+ CHECK_STRUCT_SIZE(authMsg_t, SIZEOF_AUTH_MSG_TYPE);
+ CHECK_STRUCT_SIZE(deAuth_t, SIZEOF_DEATUH_MSG_TYPE);
+ CHECK_STRUCT_SIZE(disAssoc_t, SIZEOF_DISASSOC_MSG_TYPE);
+ CHECK_STRUCT_SIZE(dot11_mgmtFrame_t, SIZEOF_MGMT_FRAME);
+ CHECK_STRUCT_SIZE(mlmeFrameInfo_t,SIZEOF_MLME_FRAME_INFO);
+ print_info("TIWLAN: packet structure size test %s\n", rc?"failed":"passed");
+
+ return rc;
+}
diff --git a/sta_dk_4_0_4_32/pform/linux/src/esta_drv.c b/sta_dk_4_0_4_32/pform/linux/src/esta_drv.c
new file mode 100644
index 0000000..a802b35
--- /dev/null
+++ b/sta_dk_4_0_4_32/pform/linux/src/esta_drv.c
@@ -0,0 +1,2060 @@
+/****************************************************************************
+**+-----------------------------------------------------------------------+**
+**| |**
+**| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |**
+**| All rights reserved. |**
+**| |**
+**| Redistribution and use in source and binary forms, with or without |**
+**| modification, are permitted provided that the following conditions |**
+**| are met: |**
+**| |**
+**| * Redistributions of source code must retain the above copyright |**
+**| notice, this list of conditions and the following disclaimer. |**
+**| * Redistributions in binary form must reproduce the above copyright |**
+**| notice, this list of conditions and the following disclaimer in |**
+**| the documentation and/or other materials provided with the |**
+**| distribution. |**
+**| * Neither the name Texas Instruments nor the names of its |**
+**| contributors may be used to endorse or promote products derived |**
+**| from this software without specific prior written permission. |**
+**| |**
+**| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |**
+**| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |**
+**| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
+**| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |**
+**| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
+**| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |**
+**| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
+**| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
+**| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |**
+**| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
+**| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |**
+**| |**
+**+-----------------------------------------------------------------------+**
+****************************************************************************/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <net/sock.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/netdevice.h>
+#include <linux/ioctl.h>
+#include <linux/wireless.h>
+#include <linux/etherdevice.h>
+#include <linux/netlink.h>
+#include <linux/completion.h>
+
+#ifdef TIWLAN_CARDBUS
+#include <linux/pci.h>
+#else
+#ifdef TIWLAN_OMAP1610
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+#include <asm/arch-omap/tc.h>
+#else
+#include <mach/tc.h>
+#endif
+#endif
+#ifdef TIWLAN_MSM7000
+#include <linux/mmc/core.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
+#include <asm/arch/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/irqs.h>
+#else
+#include <mach/io.h>
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#endif
+#endif /* !TIWLAN_CARDBUS */
+
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/if_arp.h>
+#include <linux/proc_fs.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/vmalloc.h>
+#include <linux/irq.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+
+#include "esta_drv.h"
+#include "srcApi.h"
+#include "osApi.h"
+#include "whalHwRegs.h"
+
+#if defined(DEBUG_UNKNOWN_INTERRUPT)
+#define _STRING_H
+#include "configMgr.h"
+#include "whalCtrl.h"
+#endif
+
+#include "bmtrace.h"
+#include "osrgstry_parser.h"
+#include "osClsfr.h"
+#include "TI_IPC_Api.h"
+#include "802_11Defs.h"
+#include "Ethernet.h"
+#include "tiwlan_profile.h"
+
+#if defined(CONFIG_TROUT_PWRSINK) || defined(CONFIG_HTC_PWRSINK)
+#define RX_RATE_INTERVAL_SEC 10
+unsigned long num_rx_pkt_new = 0;
+static unsigned long num_rx_pkt_last = 0;
+#endif
+
+#ifdef TIWLAN_MSM7000
+extern unsigned char *get_wifi_nvs_ram(void);
+extern void SDIO_SetFunc( struct sdio_func * );
+static struct proc_dir_entry *tiwlan_calibration;
+static struct completion sdio_wait;
+#ifdef CONFIG_WIFI_CONTROL_FUNC
+static struct wifi_platform_data *wifi_control_data = NULL;
+#endif
+#endif
+
+/* WiFi chip information functions */
+int export_wifi_fw_version( tiwlan_net_dev_t *drv );
+int export_wifi_chip_id( void );
+
+/* Drivers list */
+static LIST_HEAD(tiwlan_drv_list);
+
+/* debug memory access */
+static struct proc_dir_entry *tiwlan_deb_entry;
+static __u32 memdebug_addr;
+static __u32 memdebug_size=1;
+static __u32 memdebug_trans_size;
+
+#define DRV_SHUTDOWN_TEST_DELAY_INTERVAL 100 /* Time in msec to "delay"(/sleep) while waiting for SME to shutdown */
+#define DRV_SHUTDOWN_TEST_MAX_COUNTER 20 /* How many delay/sleep iterations to perform while waiting for SME to shutdown) */
+
+MODULE_DESCRIPTION("TI WLAN Embedded Station Driver");
+MODULE_LICENSE("GPL");
+
+extern int packed_struct_tst(void);
+extern int proc_stat_init(TI_HANDLE);
+extern int proc_stat_destroy(void);
+
+typedef void (* tiwlan_drv_isr_t)(int, void *, struct pt_regs *);
+
+/* network device driver interface */
+static int tiwlan_drv_net_open(struct net_device * dev);
+static int tiwlan_drv_net_stop(struct net_device * dev);
+static int tiwlan_drv_net_xmit(struct sk_buff * skb, struct net_device * dev);
+static struct net_device_stats * tiwlan_drv_net_get_stats(struct net_device * dev);
+
+#define OS_WRITE_REG(drv,reg,val) \
+ os_hwWriteMemRegisterUINT32(drv, (UINT32 *)((unsigned long)drv->acx_reg.va + reg), (__u32)(val))
+
+#define OS_READ_REG(drv,reg,val) \
+ os_hwReadMemRegisterUINT32(drv, (UINT32 *)((unsigned long)drv->acx_reg.va + reg), &val)
+
+#ifdef TIWLAN_OMAP1610
+static void omap_memif_init(void)
+{
+ printk ("First function offset is: %p\n", omap_memif_init);
+#if defined(TIWLAN_OMAP1610_INNOVATOR)
+ print_info("Setting CS1 Ref Clock = TC/4. \n");
+ omap_writel(0x00000004, 0xFFFECC40 ); /* wlan change for cs2 to dynamic wait state */
+ omap_writel(0x0000113a, 0xFFFECC18 ); /* EMIFS (nCS2) configuration */
+#elif defined(TIWLAN_OMAP1610_WIPP) || defined(TIWLAN_OMAP1610_CRTWIPP)
+
+#if defined(TIWLAN_OMAP1610_CRTWIPP)
+ /*
+ Init the GPIO to output*/
+
+ /* Set OMAP pin H19 to GPIO57*/
+
+ omap_writel(omap_readl(0xFFFE1014) | 0x00E00000, 0xFFFE1014 );
+
+ /*ELP_REQ (GPIO_57) by GPIO_DIRECTION - set it as output*/
+ omap_writel(omap_readl(0xFFFBBC34) & (~0x00000200), 0xFFFBBC34 );
+#endif /* TIWLAN_OMAP1610_CRTWIPP */
+
+/* The below configuration enables GPIO25 and GPIO_27 as output GPIOs - for debug purposes */
+#if defined(TIWLAN_OMAP1610_CRTWIPP_GPIO_DEBUG)
+
+ omap_writel(omap_readl(0xFFFE1030) | 0x00000E00, 0xFFFE1030 );/* enable GPIO25 */
+ omap_writel(omap_readl(0xFFFE1030) | 0x00000038, 0xFFFE1030 );/* enable GPIO27 */
+
+ omap_writel(omap_readl(0xFFFBEC34) & (~0x00000200), 0xFFFBEC34 );/* Setting direction (as output) for GPIO25 */
+ omap_writel(omap_readl(0xFFFBEC34) & (~0x00000800), 0xFFFBEC34 );/* Setting direction (as output) for GPIO27 */
+#endif /* TIWLAN_OMAP1610_CRTWIPP_GPIO_DEBUG */
+
+
+ /* RECOVERY*/
+ print_info("Hard reset,perform PMEN toggle\n");
+ os_hardResetTnetw();
+
+ print_info("Setting CS2 Ref Clock = TC/2. \n");
+ __raw_writel(0x1, TIWLAN_OMAP1610_REGBASE+0x4cc); /* CLK=80MHz */
+ omap_writel(0x20, EMIF_CFG_DYNAMIC_WS); /* Full handshake on CS2 */
+ omap_writel(0x2441, EMIFS_CS2_CONFIG); /* 0x2021 on reworked board */
+ omap_writel(0, EMIFS_ACS2);
+
+ print_info("%x=0x%lx\n", 0xFFFECC40, omap_readl(0xFFFECC40) );
+ print_info("%x=0x%lx\n", 0xFFFECC18, omap_readl(0xFFFECC18) );
+ print_info("%x=0x%lx\n", 0xFFFECC58, omap_readl(0xFFFECC58) );
+#endif /* WIPP, CRTWIPP */
+}
+#endif
+
+static int tiwlan_register_events(tiwlan_net_dev_t *drv)
+{
+ IPC_EVENT_PARAMS evParams;
+ int i = 0;
+
+ evParams.uDeliveryType = DELIVERY_PUSH;
+ evParams.uProcessID = 0;
+ evParams.uEventID = 0;
+ evParams.hUserParam = drv;
+ evParams.pfEventCallback = os_IndicateEvent;
+
+
+ for (;i < IPC_EVENT_MAX_OS_EVENT;i++)
+ {
+ evParams.uEventType = i;
+
+ configMgr_RegisterEvent(drv->adapter.CoreHalCtx,(PUCHAR) &evParams,sizeof(IPC_EVENT_PARAMS));
+ }
+
+ return OK;
+}
+
+static int tiwlan_deb_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ __u32 addr=memdebug_addr;
+ __u32 size=memdebug_size;
+ __u32 trans_size=memdebug_trans_size;
+ __u32 end;
+ int in_line=0, max_in_line;
+ int limit=count-80;
+ int i=0;
+ static int toggle;
+
+ *eof = 1;
+ if (!addr || !trans_size)
+ return 0;
+
+ /* fixme: add address validation */
+
+ if (!size)
+ size=1;
+
+ end = addr + size*trans_size;
+ if (trans_size==4)
+ max_in_line = 4;
+ else if (trans_size==2)
+ max_in_line = 8;
+ else
+ max_in_line = 16;
+
+ while(i<limit && addr<end)
+ {
+ if (!in_line)
+ i += sprintf(page+i, "0x%08x: ", addr);
+ if (trans_size==4)
+ {
+ i += sprintf(page+i, "0x%08x", *(__u32 *)addr);
+ addr += 4;
+ }
+ else if (trans_size==2)
+ {
+ i += sprintf(page+i, "0x%04x", *(__u16 *)addr);
+ addr += 2;
+ }
+ else
+ {
+ i += sprintf(page+i, "0x%02x", *(__u8 *)addr);
+ addr += 1;
+ }
+ if (++in_line < max_in_line)
+ *(page+i++)=' ';
+ else
+ {
+ *(page+i++)='\n';
+ in_line = 0;
+ }
+ }
+ *(page+i++)='\n';
+ /* For some reason read proc is get called twice for
+ each "cat" operation
+ */
+ if (toggle)
+ memdebug_addr = addr;
+ toggle = !toggle;
+
+ return i;
+}
+
+static char *rm_get_token(const char **p_buffer, unsigned long *p_buffer_len,
+ char *token, unsigned long token_len,
+ char del)
+{
+ const char *buffer=*p_buffer;
+ __u32 buffer_len = *p_buffer_len;
+
+ while(buffer_len && token_len && *buffer!=del && *buffer)
+ {
+ *token++ = *buffer++;
+ --buffer_len;
+ --token_len;
+ }
+ while (buffer_len && *buffer==del)
+ {
+ ++buffer;
+ --buffer_len;
+ }
+ *token = 0;
+ *p_buffer = buffer;
+ *p_buffer_len = buffer_len;
+ return token;
+}
+
+static int tiwlan_deb_write_proc(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ __u32 addr, size;
+ char token[15];
+ __u32 value;
+ char *end;
+ int buflen=count;
+
+ /* buffer format is:
+ d{w,h,b} addr[/size]
+ s{w,h,b} addr=value
+ */
+ /* Parse string */
+ rm_get_token(&buffer, &count, token, sizeof(token)-1, ' ');
+ if (token[0]=='d')
+ {
+ /* Display */
+ if (!strcmp(token, "dw"))
+ memdebug_trans_size = 4;
+ else if (!strcmp(token, "dh"))
+ memdebug_trans_size = 2;
+ else if (!strcmp(token, "db"))
+ memdebug_trans_size = 1;
+ else
+ {
+ printk(KERN_INFO "rm: mem file write op is dw|dh|db|sw|sh|sb\n");
+ return buflen;
+ }
+ /* Get address */
+ rm_get_token(&buffer, &count, token, sizeof(token)-1, '/');
+ addr = simple_strtoul(token, &end, 0);
+ if ((end && *end) /* || !iopa(addr)*/)
+ {
+ printk(KERN_INFO "rm: address <%s> is invalid\n", token);
+ return buflen;
+ }
+ if ((addr & (memdebug_trans_size-1)))
+ {
+ printk(KERN_INFO "rm: warning: address 0x%x is not aligned to size %u\n",
+ addr, memdebug_trans_size);
+ }
+ memdebug_addr = addr;
+ if (count)
+ {
+ /* Get size */
+ rm_get_token(&buffer, &count, token, sizeof(token)-1, ' ');
+ size = simple_strtoul(token, &end, 0);
+ if (end && *end)
+ {
+ printk(KERN_INFO "rm: size <%s> is invalid. end=<%s>\n",
+ token, end);
+ return buflen;
+ }
+ memdebug_size = size;
+ }
+ return buflen;
+ }
+ if (token[0]=='s')
+ {
+ /* Display */
+ if (!strcmp(token, "sw"))
+ size = 4;
+ else if (!strcmp(token, "sh"))
+ size = 2;
+ else if (!strcmp(token, "sb"))
+ size = 1;
+ else
+ {
+ printk(KERN_INFO "rm: mem file write op is dw|dh|db|sw|sh|sb\n");
+ return buflen;
+ }
+ /* Get address */
+ rm_get_token(&buffer, &count, token, sizeof(token)-1, ' ');
+ addr = simple_strtoul(token, &end, 0);
+ if ((end && *end) /*|| !iopa(addr)*/)
+ {
+ printk(KERN_INFO "rm: address <%s> is invalid\n", token);
+ return buflen;
+ }
+ if ((addr & (size-1)))
+ {
+ printk(KERN_INFO "rm: warning: address 0x%x is not aligned to size %u\n",
+ addr, size);
+ }
+
+ /* Get value */
+ rm_get_token(&buffer, &count, token, sizeof(token)-1, ' ');
+ value = simple_strtoul(token, &end, 0);
+ if (end && *end)
+ {
+ printk(KERN_INFO "rm: value <%s> is invalid. end <%s>\n",
+ token, end);
+ return buflen;
+ }
+ if (size==4)
+ *(__u32 *)addr = value;
+ else if (size==2)
+ {
+ if (value > 0xffff)
+ {
+ printk(KERN_INFO "rm: value <%s> is out of range\n", token);
+ return buflen;
+ }
+ *(__u16 *)addr = value;
+ }
+ else
+ {
+ if (value > 0xff)
+ {
+ printk(KERN_INFO "rm: value <%s> is out of range\n", token);
+ return buflen;
+ }
+ *(__u8 *)addr = value;
+ }
+ memdebug_addr = addr;
+ memdebug_size = 1;
+ memdebug_trans_size = size;
+ }
+ else
+ printk(KERN_INFO "rm: operation <%s> is not supported\n", token);
+ return buflen;
+}
+
+#ifdef TIWLAN_MSM7000
+#define WIFI_NVS_LEN_OFFSET 0x0C
+#define WIFI_NVS_DATA_OFFSET 0x40
+#define WIFI_NVS_MAX_SIZE 0x800UL
+
+static unsigned long tiwlan_get_nvs_size( void )
+{
+ unsigned char *ptr;
+ unsigned long len;
+
+ ptr = get_wifi_nvs_ram();
+ if( ptr == NULL ) {
+ return 0;
+ }
+ /* Size in format LE assumed */
+ memcpy( (void *)&len, (void *)(ptr + WIFI_NVS_LEN_OFFSET), sizeof(len) );
+ len = min( len, (WIFI_NVS_MAX_SIZE-WIFI_NVS_DATA_OFFSET) );
+ return len;
+}
+
+static int tiwlan_calibration_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ unsigned char *ptr;
+ unsigned long len;
+
+ ptr = get_wifi_nvs_ram();
+ if( ptr == NULL ) {
+ return 0;
+ }
+ len = tiwlan_get_nvs_size();
+ /* i += sprintf(page+i, "WiFi Calibration Size = %lu %x bytes\n", len); */
+ memcpy( (void *)page, (void *)(ptr + WIFI_NVS_DATA_OFFSET), len );
+ return len;
+}
+
+static int tiwlan_calibration_write_proc(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ return 0;
+}
+#endif
+
+/*********************************************************************************************/
+/* Impelementation */
+/*********************************************************************************************/
+
+static int tiwlan_drv_net_open(struct net_device * dev)
+{
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)dev->priv;
+
+ ti_nodprintf(TIWLAN_LOG_INFO, "tiwlan_drv_net_open()\n");
+
+ if (!drv->adapter.CoreHalCtx)
+ return -ENODEV;
+
+ netif_start_queue(dev);
+
+ return 0;
+}
+
+
+static int tiwlan_drv_net_stop(struct net_device * dev)
+{
+ ti_nodprintf(TIWLAN_LOG_ERROR, "tiwlan_drv_net_stop()\n");
+
+ netif_stop_queue(dev);
+
+ return 0;
+}
+
+
+/* dummy send packet from Linux TCP/IP stack to WLAN
+ Used when driver is not initialized
+ */
+static int tiwlan_drv_dummy_net_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ /* Network stack takes care of deallocation */
+ return -ENODEV;
+}
+
+void sendFreeFunc(TI_HANDLE pSkb, TI_HANDLE dummy1, TI_STATUS status)
+{
+ struct sk_buff *skb = (struct sk_buff *) pSkb;
+
+ /* print_deb("^^^ free %p %d bytes (%s)\n", skb->data, skb->len, (status==OK) ? "OK" : "ERROR" ); */
+ dev_kfree_skb(skb);
+}
+
+#ifdef DM_USE_WORKQUEUE
+void tiwlan_add_msdu(tiwlan_net_dev_t *drv, mem_MSDU_T *pMsdu)
+{
+ if( pMsdu == NULL )
+ return;
+ pMsdu->msdu_next = NULL;
+ if( drv->txmit_msdu_next != NULL ) {
+ drv->txmit_msdu_last->msdu_next = pMsdu;
+ }
+ else {
+ drv->txmit_msdu_next = pMsdu;
+ }
+ drv->txmit_msdu_last = pMsdu;
+}
+
+mem_MSDU_T *tiwlan_del_msdu(tiwlan_net_dev_t *drv)
+{
+ mem_MSDU_T *pMsdu = NULL;
+
+ if( drv->txmit_msdu_next != NULL ) {
+ pMsdu = drv->txmit_msdu_next;
+ drv->txmit_msdu_next = pMsdu->msdu_next;
+ if( drv->txmit_msdu_next == NULL ) { /* Last MSDU */
+ drv->txmit_msdu_last = NULL;
+ }
+ }
+ return( pMsdu );
+}
+
+static void tiwlan_xmit_handler( struct work_struct *work )
+{
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)container_of( work, struct tiwlan_net_dev, txmit );
+ mem_MSDU_T *pMsdu;
+ unsigned long flags;
+
+ /* printk("TI: %s:\t%lu\n", __FUNCTION__, jiffies); */
+ do {
+ spin_lock_irqsave(&drv->lock, flags);
+ pMsdu = tiwlan_del_msdu(drv);
+ spin_unlock_irqrestore(&drv->lock, flags);
+ if( pMsdu ) {
+ configMgr_sendMsdu(drv->adapter.CoreHalCtx, pMsdu, 0);
+ }
+ } while( pMsdu != NULL );
+#ifdef CONFIG_ANDROID_POWER
+ android_unlock_suspend( &drv->xmit_wake_lock );
+#endif
+}
+#endif
+
+/* send packet from Linux TCP/IP stack to WLAN
+ */
+static int tiwlan_drv_net_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)dev->priv;
+ int status;
+ mem_MSDU_T *pMsdu;
+ UINT32 packetHeaderLength;
+
+#ifndef NO_COPY_SKB
+ char *pMsduData;
+#else
+ mem_BD_T *pCurBd=0;
+#endif
+
+#ifdef DRIVER_PROFILE
+ os_profile (drv, 0, 0);
+#endif
+ bm_trace(20, skb->len, 0);
+
+#ifdef NO_COPY_SKB
+
+ status = configMgr_allocMSDUBufferOnly(drv->adapter.CoreHalCtx, &pMsdu, OS_ABS_TX_MODULE);
+ if(status != OK)
+ {
+ ti_dprintf(TIWLAN_LOG_ERROR, " configMgr_allocMSDUBufferOnly failed !!!\n");
+ ++drv->alloc_msdu_failures;
+ return -ENOMEM;
+ }
+ /* print_deb("$$$ configMgr_allocMSDUBufferOnly()=OK pMsdu=%p\n", pMsdu ); */
+
+ status = configMgr_allocBDs(drv->adapter.CoreHalCtx, 1, &pCurBd);
+
+ if(status != OK) {
+ ++drv->alloc_msdu_failures;
+ ti_dprintf(TIWLAN_LOG_ERROR, " configMgr_allocBDs failed !!!\n");
+ configMgr_memMngrFreeMSDU(drv->adapter.CoreHalCtx, pMsdu->handle);
+ return -ENOMEM;
+ }
+ /* print_deb("$$$ configMgr_allocBDs()=OK pCurBd=%p first=%p\n", pCurBd, pMsdu->firstBDPtr ); */
+
+ pMsdu->freeFunc = sendFreeFunc;
+ pMsdu->freeArgs[0] = (UINT32) skb;
+ pMsdu->dataLen = skb->len;
+ pMsdu->firstBDPtr = pCurBd;
+ pCurBd->dataOffset = skb->data-skb->head;
+ pCurBd->length = skb->len;
+ pCurBd->data = skb->head;
+
+ drv->stats.tx_packets++;
+ drv->stats.tx_bytes += skb->len;
+
+#else /* NO_COPY_SKB */
+
+ /*
+ * Retrieve the Packet Header length
+ * from QoS Manager (through configMgr)
+ * (Header type is determined upon association)
+ */
+ packetHeaderLength = configMgr_getPacketHeaderLength(drv->adapter.CoreHalCtx,skb->data,TX_DATA_DATA_MSDU);
+
+ /*
+ * need to reserve enough space for header translation
+ * in the same first Bd.
+ * Allocate enough place also for 802.11 header (24 bytes or 26 for QoS) and LLC (8 bytes)
+ * to replace the Ethernet header (14 bytes)
+ */
+ status = configMgr_allocMSDU(drv->adapter.CoreHalCtx, &pMsdu,
+ skb->len + packetHeaderLength, OS_ABS_TX_MODULE);
+
+ if(status != OK)
+ {
+ /*ti_dprintf(TIWLAN_LOG_ERROR, " configMgr_allocMSDU failed !!!\n");*/
+ ++drv->alloc_msdu_failures;
+ return -ENOMEM;
+ }
+
+ /*
+ * case 1: only legacy wlan header
+ *
+ * case 2: only QoS wlan header
+ *
+ * case 3: only legacy wlan header with new snap
+ *
+ * case 4: only QoS wlan header with new snap
+ */
+ pMsdu->firstBDPtr->dataOffset = packetHeaderLength - ETHERNET_HDR_LEN;
+ pMsduData = pMsdu->firstBDPtr->data + pMsdu->firstBDPtr->dataOffset;
+ memcpy(pMsduData, skb->data, skb->len);
+ pMsdu->dataLen = skb->len;
+ pMsdu->firstBDPtr->length = pMsdu->dataLen + pMsdu->firstBDPtr->dataOffset;
+
+ drv->stats.tx_packets++;
+ drv->stats.tx_bytes += skb->len;
+ dev_kfree_skb(skb);
+#endif /* NO_COPY_SKB */
+
+ pMsdu->txFlags |= TX_DATA_FROM_OS;
+ pMsdu->qosTag = 0;
+ status = OK;
+
+#ifdef TI_DBG
+ /* Set packet-os-in time stamp */
+ /* TODO: the skb time stamp is not good */
+ /* printk ("\n### sec=%u, usec=%u", skb->stamp.tv_sec, skb->stamp.tv_usec);*/
+ /* pMsdu->timeStamp[0] = skb->stamp.tv_sec * 1000000 + skb->stamp.tv_usec; */
+ /* pMsdu->timeStampNum = 1; */
+#endif
+
+ bm_trace(21, 0, 0);
+ /*
+ * Propagate Msdu through Config Manager.
+ * Set DTag to zero
+ * (note that classification is further handled in the Core)
+ */
+ if (status == OK) {
+#ifdef DM_USE_WORKQUEUE
+ unsigned long flags;
+
+ spin_lock_irqsave(&drv->lock, flags);
+ tiwlan_add_msdu(drv, pMsdu);
+ spin_unlock_irqrestore(&drv->lock, flags);
+ /* printk("TI: %s:\t%lu\n", __FUNCTION__, jiffies); */
+ if( queue_work( drv->tiwlan_wq, &drv->txmit ) != 0 ) {
+#ifdef CONFIG_ANDROID_POWER
+ android_lock_suspend( &drv->xmit_wake_lock );
+#endif
+ }
+#else
+ status = configMgr_sendMsdu(drv->adapter.CoreHalCtx, pMsdu, 0);
+#endif
+ }
+ else
+ configMgr_memMngrFreeMSDU (drv->adapter.CoreHalCtx, (UINT32) pMsdu); /* If status != OK , we won't send the MSDU, so we need to free it */
+
+ if(unlikely(status != OK))
+ {
+ drv->stats.tx_errors++;
+#ifdef NO_COPY_SKB
+ dev_kfree_skb(skb);
+#endif
+ }
+
+ bm_trace(22, 0, 0);
+#ifdef DRIVER_PROFILE
+ os_profile (drv, 1, 0);
+#endif
+
+ return 0;
+}
+
+struct net_device_stats * tiwlan_drv_net_get_stats(struct net_device * dev)
+{
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)dev->priv;
+ ti_dprintf(TIWLAN_LOG_OTHER, "tiwlan_drv_net_get_stats()\n");
+
+ return &drv->stats;
+}
+
+
+static int setup_netif(tiwlan_net_dev_t *drv)
+{
+ struct net_device *dev;
+ int res;
+
+ dev = alloc_etherdev(0);
+ if (dev == NULL)
+ {
+ ti_dprintf(TIWLAN_LOG_ERROR, "alloc_etherdev() failed\n");
+ return -ENOMEM;
+ }
+ ether_setup(dev);
+ dev->priv = drv;
+ drv->netdev = dev;
+ strcpy(dev->name, TIWLAN_DRV_IF_NAME);
+ netif_carrier_off(dev);
+ dev->open = tiwlan_drv_net_open;
+ dev->stop = tiwlan_drv_net_stop;
+ dev->hard_start_xmit = tiwlan_drv_dummy_net_xmit;
+ dev->get_stats = tiwlan_drv_net_get_stats;
+ dev->tx_queue_len = 100;
+
+ res = tiwlan_ioctl_init(dev);
+ if( res < 0 )
+ {
+ ti_dprintf(TIWLAN_LOG_ERROR, "tiwlan_ioctl_init() failed : %d\n", res);
+ kfree(dev);
+ return res;
+ }
+
+ res = register_netdev(dev);
+ if (res != 0)
+ {
+ ti_dprintf(TIWLAN_LOG_ERROR, "register_netdev() failed : %d\n", res);
+ kfree(dev);
+ return res;
+ }
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+ SET_MODULE_OWNER(dev);
+#endif
+ return 0;
+}
+
+
+/* tiwlan_interrupt
+ TIWLAN interrupt handler. Disables interrupts and awakes tasklet.
+*/
+#if !(defined(HW_ACCESS_SDIO)||defined(HW_ACCESS_WSPI))
+static irqreturn_t tiwlan_interrupt (int irq, void *netdrv, struct pt_regs *cpu_regs)
+{
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)netdrv;
+
+ /*
+ * Workaround for the Linux 2.6 pending IRQ bug:
+ * If a pending IRQ is handled on a WLAN ISR, the ISR is called again
+ * even though it disabled itself in the first call. To protect against
+ * re-entrance, this flag is checked, and if it is already set (meaning
+ * that the ISR is called twice before the tasklet was called) nothing is done.
+ */
+ if (drv->interrupt_pending == 0)
+ {
+ UINT32 interruptVector;
+
+ interruptVector = configMgr_checkInterrupts(drv->adapter.CoreHalCtx);
+ if (interruptVector != 0)
+ {
+ configMgr_disableInterrupts(drv->adapter.CoreHalCtx);
+ drv->interrupt_pending = 1;
+ tasklet_schedule (&drv->tl);
+ }
+ else
+ {
+#if DEBUG_UNKNOWN_INTERRUPT
+ ti_dprintf (TIWLAN_LOG_ERROR,
+ "%s - ERROR - interrupt isn't TNET interrupt! interrupt vector = 0x%08X\n",
+ __FUNCTION__, interruptVector);
+#endif
+ }
+ }
+ return IRQ_HANDLED;
+}
+
+#else
+
+static irqreturn_t tiwlan_interrupt (int irq, void *netdrv, struct pt_regs *cpu_regs)
+{
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)netdrv;
+
+ drv->interrupt_pending = 1;
+ /* printk("TI: %s:\t%lu\n", __FUNCTION__, jiffies); */
+#ifdef DM_USE_WORKQUEUE
+ if( queue_work( drv->tiwlan_wq, &drv->tirq ) != 0 ) {
+#ifdef CONFIG_ANDROID_POWER
+ android_lock_suspend( &drv->irq_wake_lock );
+#endif
+ }
+ /* disable_irq( drv->irq ); Dm: No need, we can loose IRQ */
+#else
+ tasklet_schedule( &drv->tl );
+#endif
+ return IRQ_HANDLED;
+}
+#endif
+
+
+static void tiwlan_poll_irq_handler(unsigned long parm)
+{
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)parm;
+ bm_trace(2, 0, 0);
+
+ tiwlan_interrupt(0, drv, NULL);
+ mod_timer(&drv->poll_timer, jiffies + TIWLAN_IRQ_POLL_INTERVAL);
+}
+
+static void tiwlan_handle_control_requests( tiwlan_net_dev_t *drv )
+{
+ bm_trace(4, 0, 0);
+
+ /* Handle control requests (timers, ioctls) */
+ while(!list_empty(&drv->request_q))
+ {
+ struct list_head *entry = drv->request_q.next;
+ tiwlan_req_t *req = list_entry(entry, tiwlan_req_t, list);
+ tiwlan_req_t tmp_req;
+ unsigned long flags;
+
+ spin_lock_irqsave(&drv->lock, flags);
+ list_del_init(entry);
+ spin_unlock_irqrestore(&drv->lock, flags);
+
+ ti_nodprintf(TIWLAN_LOG_INFO, "%s: f=0x%x req=0x%x reply_expected=%d\n",
+ __FUNCTION__, req->u.req.f, req, req->u.req.reply_expected);
+
+ tmp_req.u.req.p1 = 0x1234;
+ tmp_req.u.req.p2 = 0x4321;
+ tmp_req.u.req.p3 = 0x1221;
+ tmp_req.u.req.p4 = 0x4334;
+ tmp_req.u.req.reply_expected = 0x50;
+
+ req->u.reply = req->u.req.f(req);
+
+ if ((tmp_req.u.req.p1 != 0x1234) || (tmp_req.u.req.p2 != 0x4321) || (tmp_req.u.req.p3 != 0x1221) || (tmp_req.u.req.p4 != 0x4334) || (tmp_req.u.req.reply_expected != 0x50))
+ {
+ printk("\n\n !!! ERROR: STACK CORRUPTION !!! : \nf=%p\n", tmp_req.u.req.f);
+ if (!req->u.req.reply_expected)
+ printk("timer handler: %p\n", (void *)tmp_req.u.req.p1);
+ }
+
+ ti_nodprintf(TIWLAN_LOG_INFO, "%s: f=0x%x req=0x%x reply_expected=%d reply=%d\n",
+ __FUNCTION__, req->u.req.f, req, req->u.req.reply_expected, req->u.reply);
+ if (req->u.req.reply_expected)
+ {
+ ti_nodprintf(TIWLAN_LOG_INFO, "%s: about to awake task\n", __FUNCTION__);
+ complete(&req->u.req.comp);
+ }
+ }
+
+ bm_trace(5, 0, 0);
+
+ /* DbgCB_Insert(0, DBG_MODULE_OS, DBG_TYPE_TASKLET, 1)*/
+}
+
+#ifdef DM_USE_WORKQUEUE
+static void tiwlan_irq_handler( struct work_struct *work )
+{
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)container_of( work, struct tiwlan_net_dev, tirq );
+
+ /* if the driver was unloaded by that time we need to ignore all the timers */
+ if (drv->unload_driver) {
+#ifdef CONFIG_ANDROID_POWER
+ android_unlock_suspend( &drv->irq_wake_lock );
+#endif
+ /* enable_irq( drv->irq ); */
+ return;
+ }
+ /* printk("TI: %s:\t%lu\n", __FUNCTION__, jiffies); */
+ configMgr_handleInterrupts( drv->adapter.CoreHalCtx );
+ tiwlan_handle_control_requests( drv );
+#ifdef CONFIG_ANDROID_POWER
+ if( drv->receive_packet ) {
+ drv->receive_packet = 0;
+ /* Keep awake for 500 ms to give a chance to network stack */
+ android_lock_suspend_auto_expire( &drv->rx_wake_lock, (HZ >> 1) );
+ }
+ android_unlock_suspend( &drv->irq_wake_lock );
+#endif
+ /* enable_irq( drv->irq ); */
+}
+#endif
+
+/* tiwlan_tasklet_handler
+ WLAN protocol tasklet. Most of work happens in the
+ context of this tasklet.
+*/
+#ifdef DM_USE_WORKQUEUE
+static void tiwlan_work_handler( struct work_struct *work )
+#else
+static void tiwlan_tasklet_handler( unsigned long netdrv )
+#endif
+{
+#ifdef DM_USE_WORKQUEUE
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)container_of( work, struct tiwlan_net_dev, tw );
+#else
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)netdrv;
+#endif
+#ifdef STACK_PROFILE
+ unsigned int curr1, base1;
+ unsigned int curr2, base2;
+ static unsigned int maximum_stack = 0;
+#endif
+
+ /* if the driver was unloaded by that time we need to ignore all the timers */
+ if (drv->unload_driver) {
+#ifdef CONFIG_ANDROID_POWER
+ android_unlock_suspend( &drv->timer_wake_lock );
+#endif
+ return;
+ }
+ /* printk("TI: %s:\t%lu\n", __FUNCTION__, jiffies); */
+#if 0
+ ti_dprintf(TIWLAN_LOG_INFO, "%s in\n" , __FUNCTION__);
+#endif
+
+#ifdef DRIVER_PROFILE
+ os_profile (drv, 0, 0);
+#endif
+ bm_trace(3, 0, 0);
+
+#ifdef STACK_PROFILE
+ curr1 = check_stack_start(&base1);
+#endif
+
+ /* Handle bus transaction interrupts */
+ if (drv->dma_done)
+ {
+ drv->dma_done = 0;
+ configMgr_HandleBusTxn_Complete(drv->adapter.CoreHalCtx);
+ }
+
+ /* don't call for "Handle interrupts, timers, ioctls" while recovery process */
+ if (configMgr_areInputsFromOsDisabled(drv->adapter.CoreHalCtx) == TRUE) {
+#ifdef CONFIG_ANDROID_POWER
+ android_unlock_suspend( &drv->timer_wake_lock );
+#endif
+ return;
+ }
+
+ /* Handle firmware interrupts */
+#ifndef DM_USE_WORKQUEUE
+ if (drv->interrupt_pending)
+ {
+ drv->interrupt_pending = 0;
+ configMgr_handleInterrupts(drv->adapter.CoreHalCtx);
+ }
+#endif
+
+ tiwlan_handle_control_requests( drv );
+
+#ifdef STACK_PROFILE
+ curr2 = check_stack_stop(&base2);
+
+ if (base2 == base1)
+ {
+ /* if the current measurement is bigger then the maximum store it and print*/
+ if ((curr1 - curr2) > maximum_stack)
+ {
+ printk("STACK PROFILER GOT THE LOCAL MAXIMMUM!!!! \n");
+ printk("current operation stack use =%d \n",(curr1 - curr2));
+ printk("total stack use=%d \n",8192 - curr2 + base2);
+ printk("total stack usage= %d percent \n",100 * (8192 - curr2 + base2) / 8192);
+ maximum_stack = curr1 - curr2;
+ }
+ }
+#endif
+
+#ifdef DRIVER_PROFILE
+ os_profile (drv, 1, 0);
+#endif
+
+#if 0
+ ti_dprintf(TIWLAN_LOG_INFO, "%s out\n" , __FUNCTION__);
+#endif
+#ifdef CONFIG_ANDROID_POWER
+ android_unlock_suspend( &drv->timer_wake_lock );
+#endif
+}
+
+#if defined(CONFIG_TROUT_PWRSINK) || defined(CONFIG_HTC_PWRSINK)
+static void tiwlan_rx_watchdog(struct work_struct *work)
+{
+ struct delayed_work *dwork = (struct delayed_work *) container_of(work, struct delayed_work, work);
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)container_of( dwork, struct tiwlan_net_dev, trxw );
+
+ unsigned long num_rx_pkts = num_rx_pkt_new - num_rx_pkt_last;
+ /* Contribute 10mA (200mA x 5%) for 1 pkt/sec, and plus 8mA base. */
+ unsigned percent = (5 * num_rx_pkts / RX_RATE_INTERVAL_SEC) + PWRSINK_WIFI_PERCENT_BASE;
+
+
+ if (drv->unload_driver)
+ return;
+
+ percent = (percent > 100) ? 100 : percent;
+ /* printk(KERN_INFO "num_rx_pkts=%ld, percent=%d\n", num_rx_pkts, percent); */
+#ifdef CONFIG_HTC_PWRSINK
+ htc_pwrsink_set(PWRSINK_WIFI, percent);
+#else
+ trout_pwrsink_set(PWRSINK_WIFI, percent);
+#endif
+
+ num_rx_pkt_last = num_rx_pkt_new;
+
+ if (drv && drv->tiwlan_wq)
+ queue_delayed_work(drv->tiwlan_wq, &drv->trxw, msecs_to_jiffies(MSEC_PER_SEC * RX_RATE_INTERVAL_SEC));
+}
+#endif
+
+/* tiwlan_send_wait_reply
+ This internal interface function creates request and sends
+ it to the control tasklet for processing.
+ The calling process is blocked until the request is replied.
+ Function f is being called in the context of the control tasklet.
+ The request block that is passed to the function as a parameter
+ contains p1, p2, p3, p4.
+ The function return code is propagated back to the caller.
+ tiwlan_send_req_and_wait returns (*f) return code or
+ -ENOMEM if failed to allocate a request.
+*/
+int tiwlan_send_wait_reply(tiwlan_net_dev_t *drv,
+ int (*f)(tiwlan_req_t *req),
+ unsigned long p1,
+ unsigned long p2,
+ unsigned long p3,
+ unsigned long p4)
+{
+ tiwlan_req_t req;
+ unsigned long flags;
+
+ /* Send request to tiwlan_tasklet and wait for reply */
+
+ req.drv = drv;
+ req.u.req.f = f;
+ req.u.req.p1 = p1;
+ req.u.req.p2 = p2;
+ req.u.req.p3 = p3;
+ req.u.req.p4 = p4;
+ req.u.req.reply_expected = 1;
+ init_completion(&req.u.req.comp);
+
+ spin_lock_irqsave(&drv->lock, flags);
+ list_add_tail(&req.list, &drv->request_q);
+ spin_unlock_irqrestore(&drv->lock, flags);
+
+#ifdef DM_USE_WORKQUEUE
+ /* printk("TI: %s:\t%lu\n", __FUNCTION__, jiffies); */
+ if( queue_work( drv->tiwlan_wq, &drv->tw ) != 0 ) {
+#ifdef CONFIG_ANDROID_POWER
+ android_lock_suspend( &drv->timer_wake_lock );
+#endif
+ }
+#else
+ tasklet_schedule( &drv->tl );
+#endif
+ wait_for_completion(&req.u.req.comp);
+
+ return req.u.reply;
+}
+
+
+#define WLAN_PCMCIA_CFG_REG 0x0524
+/* tiwlan_set_hw_access */
+static int tiwlan_set_hw_access(tiwlan_net_dev_t *drv)
+{
+#ifdef TIWLAN_OMAP1610
+ OS_WRITE_REG(drv, HI_CFG, 0x00000a00);
+
+#if ! ((defined(HW_ACCESS_SDIO)||defined(HW_ACCESS_WSPI)) && defined(TNETW1150))
+ OS_WRITE_REG(drv, WLAN_PCMCIA_CFG_REG, 0xC6880000);
+ OS_WRITE_REG(drv, PCI_ARB_CFG, 0x2);
+#endif
+
+#endif
+ return 0;
+}
+
+
+/* tiwlan_free_drv
+ Unmap h/w regions and free driver's structure
+*/
+static void tiwlan_free_drv(tiwlan_net_dev_t *drv)
+{
+#ifdef TIWLAN_OMAP1610
+ if (drv->acx_mem.pa && drv->acx_mem.va)
+ iounmap(drv->acx_mem.va);
+ if (drv->acx_reg.pa && drv->acx_reg.va && drv->acx_reg.va != drv->acx_reg.va)
+ iounmap(drv->acx_reg.va);
+#endif
+ kfree(drv);
+}
+
+
+/* tiwlan_alloc_drv
+ Allocate driver's structure and map h/w regions
+*/
+static tiwlan_net_dev_t *
+tiwlan_alloc_drv(unsigned long reg_start, unsigned long reg_size,
+ unsigned long mem_start, unsigned long mem_size,
+ int map_io, int irq)
+{
+ static tiwlan_net_dev_t *drv;
+ drv = kmalloc(sizeof(tiwlan_net_dev_t), GFP_KERNEL);
+#ifdef TI_MEM_ALLOC_TRACE
+ os_printf("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n", __FUNCTION__, __LINE__, sizeof(tiwlan_net_dev_t), GFP_KERNEL, sizeof(tiwlan_net_dev_t));
+#endif/*I_MEM_ALLOC_TRACE*/
+
+ if (!drv)
+ return NULL;
+ memset(drv, 0, sizeof(tiwlan_net_dev_t));
+ drv->acx_mem.size = mem_size;
+ drv->acx_reg.size = reg_size;
+#ifdef TIWLAN_OMAP1610
+ if (map_io)
+ {
+ drv->acx_mem.pa = mem_start;
+ drv->acx_reg.pa = reg_start;
+ drv->acx_mem.va = ioremap(drv->acx_mem.pa, drv->acx_mem.size);
+ if (drv->acx_mem.pa!=drv->acx_reg.pa || drv->acx_mem.size!=drv->acx_reg.size)
+ drv->acx_reg.va = ioremap(drv->acx_reg.pa, drv->acx_reg.size);
+ else
+ drv->acx_reg.va = drv->acx_mem.va;
+ }
+ else
+ {
+ /* Memory is already mapped */
+ drv->acx_mem.va = (void *)mem_start;
+ drv->acx_reg.va = (void *)reg_start;
+ }
+#endif /* Dm: */
+ drv->irq = irq;
+ return drv;
+}
+
+
+/* tiwlan_init_drv
+ Called in process context
+ */
+int tiwlan_init_drv (tiwlan_net_dev_t *drv, tiwlan_dev_init_t *init_info)
+{
+ initTable_t *init_table;
+ int rc;
+ void *pWLAN_Images[4];
+
+ /* printk("%s\n", __FUNCTION__); */
+ /* It is OK if already initialized */
+ if (drv->adapter.CoreHalCtx)
+ return 0;
+
+ init_table = os_memoryAlloc (drv, sizeof(initTable_t));
+
+#ifdef TI_MEM_ALLOC_TRACE
+ osPrintf ("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n", __FUNCTION__, __LINE__, sizeof(initTable_t), GFP_KERNEL, sizeof(initTable_t));
+#endif/*I_MEM_ALLOC_TRACE*/
+ if (!init_table)
+ {
+ ti_dprintf(TIWLAN_LOG_ERROR, "Cannot allocate init_table\n");
+ return -ENOMEM;
+ }
+
+ if (init_info)
+ {
+ drv->eeprom_image.size = init_info->eeprom_image_length;
+ if (drv->eeprom_image.size)
+ {
+ drv->eeprom_image.va = os_memoryAlloc (drv, drv->eeprom_image.size);
+
+#ifdef TI_MEM_ALLOC_TRACE
+ osPrintf ("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n", __FUNCTION__, __LINE__, drv->eeprom_image.size, GFP_KERNEL, drv->eeprom_image.size);
+#endif
+ if (!drv->eeprom_image.va)
+ {
+ ti_dprintf (TIWLAN_LOG_ERROR, "Cannot allocate buffer for eeprom image\n");
+ drv->eeprom_image.size = 0;
+ return -ENOMEM;
+ }
+ memcpy (drv->eeprom_image.va, &init_info->data[0], drv->eeprom_image.size );
+ }
+
+#ifdef FIRMWARE_DYNAMIC_LOAD
+ drv->firmware_image.size = init_info->firmware_image_length;
+ if (!drv->firmware_image.size)
+ {
+ ti_dprintf (TIWLAN_LOG_ERROR, "No firmware image\n");
+ return -EINVAL;
+ }
+ drv->firmware_image.va = os_memoryAlloc (drv,drv->firmware_image.size);
+#ifdef TI_MEM_ALLOC_TRACE
+ osPrintf ("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n", __FUNCTION__, __LINE__, drv->firmware_image.size, GFP_KERNEL, drv->firmware_image.size);
+#endif
+ if (!drv->firmware_image.va)
+ {
+ ti_dprintf(TIWLAN_LOG_ERROR, "Cannot allocate buffer for firmware image\n");
+ drv->firmware_image.size = 0;
+ if (drv->eeprom_image.va)
+ os_memoryFree (drv, drv->eeprom_image.va, drv->eeprom_image.size);
+ return -ENOMEM;
+ }
+ memcpy (drv->firmware_image.va,
+ &init_info->data[init_info->eeprom_image_length],
+ drv->firmware_image.size);
+#else
+ extern unsigned char tiwlan_fwimage[];
+ extern unsigned int sizeof_tiwlan_fwimage;
+
+ drv->firmware_image.size = sizeof_tiwlan_fwimage;
+ drv->firmware_image.va = tiwlan_fwimage;
+#endif
+ }
+
+ print_deb ("--------- Eeeprom=%p(%lu), Firmware=%p(%lu)\n",
+ drv->eeprom_image.va,
+ drv->eeprom_image.size,
+ drv->firmware_image.va,
+ drv->firmware_image.size);
+
+ /* Init defaults */
+ if ((rc = osInitTable_IniFile (drv,
+ init_table,
+ (init_info && init_info->init_file_length) ?
+ &init_info->data[init_info->eeprom_image_length+init_info->firmware_image_length] : NULL,
+ init_info ? init_info->init_file_length : 0)))
+ {
+ ti_dprintf (TIWLAN_LOG_ERROR, "osInitTable_IniFile failed :cannot initialize defaults\n");
+ os_memoryFree (drv, init_table, sizeof(initTable_t));
+
+#ifdef TI_MEM_ALLOC_TRACE
+ os_printf("MTT:%s:%d ::kfree(0x%p) : %d\n", __FUNCTION__, __LINE__, sizeof(initTable_t), -sizeof(initTable_t));
+#endif
+ return rc;
+ }
+
+ pWLAN_Images[0] = (void *)drv->firmware_image.va;
+ pWLAN_Images[1] = (void *)drv->firmware_image.size;
+ pWLAN_Images[2] = (void *)drv->eeprom_image.va;
+ pWLAN_Images[3] = (void *)drv->eeprom_image.size;
+
+ drv->adapter.CoreHalCtx = configMgr_create (drv,
+ pWLAN_Images,
+ init_table,
+ (macAddress_t *) &drv->adapter.CurrentAddr);
+ if (!(drv->adapter.CoreHalCtx))
+ {
+#ifdef FIRMWARE_DYNAMIC_LOAD
+ os_memoryFree(drv,drv->firmware_image.va, drv->firmware_image.size);
+ os_memoryFree (drv, drv->eeprom_image.va, drv->eeprom_image.size);
+#endif
+ os_memoryFree (drv, init_table, sizeof(initTable_t));
+ ti_dprintf(TIWLAN_LOG_ERROR, "Cannot allocate CoreHalCtx\n");
+ return -ENOMEM;
+ }
+
+ drv->interrupt_pending = 0;
+ drv->dma_done = 0;
+
+ if (drv->irq)
+ {
+#ifndef PRIODIC_INTERRUPT
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
+ unsigned long flags;
+ /*
+ * Disable all interrupts for not to catch the tiwlan irq
+ * between request_irq and disable_irq
+ */
+ spin_lock_irqsave (&(drv->lock), flags);
+ if ((rc = request_irq (drv->irq, tiwlan_interrupt, SA_SHIRQ, drv->netdev->name, drv)))
+#else
+ if ((rc = request_irq (drv->irq, (irq_handler_t)tiwlan_interrupt, IRQF_SHARED | IRQF_TRIGGER_FALLING /*Dm:*/, drv->netdev->name, drv)))
+#endif
+ {
+ print_err ("TIWLAN: Failed to register interrupt handler\n");
+ configMgr_stop (drv->adapter.CoreHalCtx);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
+ spin_unlock_irqrestore (&drv->lock, flags);
+#endif
+ return rc;
+ }
+#ifdef CONFIG_ANDROID_POWER
+ set_irq_wake(drv->irq, 1);
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
+ set_irq_type (drv->irq, IRQT_FALLING);
+#else
+ set_irq_type (drv->irq, IRQ_TYPE_EDGE_FALLING);
+#endif
+ disable_irq (drv->irq);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
+ spin_unlock_irqrestore (&drv->lock, flags);
+#endif
+#else
+ printk (" tiwlan_init_drv :PRIODIC_INTERRUPT drv->irq %x\n",drv->irq);
+#endif
+ }
+ else
+ {
+ /* Debug mode: polling */
+ mod_timer (&drv->poll_timer, jiffies + TIWLAN_IRQ_POLL_INTERVAL);
+ }
+
+ /*
+ * Now that all parts of the driver have been created and handles linked
+ * proceed to download the FW code
+ */
+ configMgr_init (drv,
+ drv->adapter.CoreHalCtx,
+ pWLAN_Images,
+ init_table,
+ (macAddress_t *) &drv->adapter.CurrentAddr);
+
+ /* Wait for the download to complete */
+ os_WaitComplete ((void *)drv);
+
+ os_memoryFree (drv, init_table, sizeof(initTable_t));
+
+ if (rc == OK)
+ {
+ proc_stat_init (drv->adapter.CoreHalCtx);
+#ifdef TI_MEM_ALLOC_TRACE
+ osPrintf ("MTT:%s:%d ::kfree(0x%p) : %d\n", __FUNCTION__, __LINE__, sizeof(initTable_t), -sizeof(initTable_t));
+#endif/*I_MEM_ALLOC_TRACE*/
+
+ if (drv->adapter.CoreHalCtx == NULL)
+ {
+ ti_dprintf (TIWLAN_LOG_ERROR, "configMgr_create failed\n");
+ return -ENODEV;
+ }
+
+ /* eeprom buffer is going to be deallocated by the caller. It is no longer needed anyway */
+#if 0
+ drv->eeprom_image.va = NULL;
+ drv->eeprom_image.size = 0;
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
+ drv->wl_sock = netlink_kernel_create(NETLINK_USERSOCK, 0, NULL, THIS_MODULE); /* Dm: */
+#else
+ drv->wl_sock = netlink_kernel_create(NETLINK_USERSOCK, 0, NULL, NULL, THIS_MODULE); /* Dm: */
+#endif
+#else
+ drv->wl_sock = netlink_kernel_create(&init_net, NETLINK_USERSOCK, 0, NULL, NULL, THIS_MODULE); /* Dm: */
+#endif
+ if (drv->wl_sock == NULL)
+ {
+ ti_dprintf(TIWLAN_LOG_ERROR, "netlink_kernel_create() failed !\n");
+ /* TODO: free in destroy */
+ return -EINVAL;
+ }
+
+ /* Finalize network interface setup */
+ drv->netdev->hard_start_xmit = tiwlan_drv_net_xmit;
+ memcpy (drv->netdev->dev_addr, drv->adapter.CurrentAddr, MAC_ADDR_LEN);
+ drv->netdev->addr_len = MAC_ADDR_LEN;
+
+ /* Register the relevant events with the event handler */
+ tiwlan_register_events (drv);
+
+ /* Mark that init stage has succeded */
+ drv->initialized = 1;
+
+ return 0;
+ }
+
+ return -ENODEV;
+}
+
+#ifdef CONFIG_ANDROID_POWER
+#ifndef CONFIG_HAS_WAKELOCK
+/* Wrapper for Init wake lock */
+static void android_init_suspend_wakelock(android_suspend_lock_t *lp,char *nm)
+{
+ lp->name = nm;
+ android_init_suspend_lock( lp );
+}
+#endif
+#endif
+
+/* tiwlan_start_drv
+*/
+int tiwlan_start_drv(tiwlan_net_dev_t *drv)
+{
+ /* printk("%s\n", __FUNCTION__); */
+ if (!drv->initialized)
+ {
+ ti_dprintf(TIWLAN_LOG_ERROR, "Attempt to start driver before initilization has succeeded\n");
+ return -ENODEV;
+ }
+ if (!drv->adapter.CoreHalCtx)
+ {
+ ti_dprintf(TIWLAN_LOG_ERROR, "Attempt to start driver before creating config_manager\n");
+ return -ENODEV;
+ }
+ if (drv->started)
+ {
+ /*ti_dprintf(TIWLAN_LOG_ERROR, "Attempt to start driver that has already started\n");*/
+ return -EALREADY;
+ }
+ if (configMgr_start(drv->adapter.CoreHalCtx) != OK)
+ {
+ print_err("TIWLAN: Failed to start config manager\n");
+ return -EINVAL;
+ }
+ drv->started = 1;
+
+#ifdef SDIO_INTERRUPT_HANDLING_ON
+ configMgr_SlaveAckMaskNotification(drv->adapter.CoreHalCtx);
+#endif
+ if (drv->netdev)
+ netif_start_queue(drv->netdev);
+#ifdef CONFIG_TROUT_PWRSINK
+ trout_pwrsink_set(PWRSINK_WIFI, PWRSINK_WIFI_PERCENT_BASE);
+#endif
+#ifdef CONFIG_HTC_PWRSINK
+ htc_pwrsink_set(PWRSINK_WIFI, PWRSINK_WIFI_PERCENT_BASE);
+#endif
+ export_wifi_fw_version(drv);
+ return 0;
+}
+
+
+/* tiwlan_destroy_drc
+*/
+static void tiwlan_destroy_drv(tiwlan_net_dev_t *drv)
+{
+ int waitShutdownCounter;
+
+ /* close the ipc_kernel socket*/
+ if (drv && drv->wl_sock) {
+ sock_release(drv->wl_sock->sk_socket);
+ }
+
+ bm_destroy();
+
+ tiwlan_stop_and_destroy_drv(drv);
+#ifdef DM_USE_WORKQUEUE
+ while( tiwlan_del_msdu(drv) != NULL );
+#endif
+ if (drv->adapter.CoreHalCtx)
+ {
+ /* Delay return to OS until all driver components (HAL/SME) are shutdown */
+ for (waitShutdownCounter=1; waitShutdownCounter<=DRV_SHUTDOWN_TEST_MAX_COUNTER; waitShutdownCounter++)
+ {
+ /* Check if HAL/SME are stopped - If so - exit loop and return to OS */
+ if (configMgr_DriverShutdownStatus(drv->adapter.CoreHalCtx) == DRIVER_SHUTDOWN_COMPLETE)
+ {
+ break;
+ }
+ /* Delay of 100ms between shutdown test */
+ mdelay ( DRV_SHUTDOWN_TEST_DELAY_INTERVAL );
+ }
+
+ /* If driver was not shutdown properly - destroy all timers "manually" and exit*/
+ if ( waitShutdownCounter == DRV_SHUTDOWN_TEST_MAX_COUNTER+1 )
+ {
+ os_printf("Timeout while waiting for driver to shutdown...Shutdown status flag=0x%x\n",configMgr_DriverShutdownStatus(drv->adapter.CoreHalCtx));
+ }
+
+ drv->unload_driver = 1;
+
+ proc_stat_destroy();
+ if (drv->irq) {
+#ifdef CONFIG_ANDROID_POWER
+ set_irq_wake(drv->irq, 0);
+#endif
+ free_irq(drv->irq, drv);
+ }
+ else
+ del_timer_sync(&drv->poll_timer);
+
+ /* Unload all modules (free memory) & destroy timers */
+ configMgr_UnloadModules (drv->adapter.CoreHalCtx);
+
+#ifdef FIRMWARE_DYNAMIC_LOAD
+ if( drv->firmware_image.va ) {
+ os_memoryFree(drv,drv->firmware_image.va, drv->firmware_image.size);
+#ifdef TI_MEM_ALLOC_TRACE
+ os_printf("MTT:%s:%d ::kfree(0x%p) : %d\n", __FUNCTION__, __LINE__, drv->firmware_image.size, -drv->firmware_image.size);
+#endif /*I_MEM_ALLOC_TRACE*/
+ }
+ if( drv->eeprom_image.va )
+ {
+ os_memoryFree (drv, drv->eeprom_image.va, drv->eeprom_image.size);
+#ifdef TI_MEM_ALLOC_TRACE
+ os_printf("MTT:%s:%d ::kfree(0x%p) : %d\n", __FUNCTION__, __LINE__, drv->eeprom_image.size, -drv->eeprom_image.size);
+#endif /*I_MEM_ALLOC_TRACE*/
+ }
+#endif /*FIRMWARE_DYNAMIC_LOAD*/
+ }
+#ifdef DM_USE_WORKQUEUE
+#if defined(CONFIG_TROUT_PWRSINK) || defined(CONFIG_HTC_PWRSINK)
+ cancel_delayed_work_sync(&drv->trxw);
+#endif
+ destroy_workqueue(drv->tiwlan_wq);
+#endif
+#ifdef CONFIG_TROUT_PWRSINK
+ trout_pwrsink_set(PWRSINK_WIFI, 0);
+#endif
+#ifdef CONFIG_HTC_PWRSINK
+ htc_pwrsink_set(PWRSINK_WIFI, 0);
+#endif
+#ifdef CONFIG_ANDROID_POWER
+ android_uninit_suspend_lock(&drv->irq_wake_lock);
+ android_uninit_suspend_lock(&drv->xmit_wake_lock);
+ android_uninit_suspend_lock(&drv->timer_wake_lock);
+ android_uninit_suspend_lock(&drv->rx_wake_lock);
+#endif
+ unregister_netdev(drv->netdev);
+ tiwlan_free_drv(drv);
+}
+
+
+/* tiwlan_create_dev
+ Create tiwlan device instance.
+ Returns 0 if OK
+*/
+static int
+tiwlan_create_drv(unsigned long reg_start, unsigned long reg_size,
+ unsigned long mem_start, unsigned long mem_size,
+ int map_io, int irq,
+ void *priv, tiwlan_net_dev_t **p_drv)
+{
+ tiwlan_net_dev_t *drv;
+ int rc;
+
+ /* printk("%s\n", __FUNCTION__); */
+ /* Allocate device and map h/w regions */
+ drv = tiwlan_alloc_drv(reg_start, reg_size, mem_start, mem_size, map_io, irq);
+ if (!drv)
+ return -ENOMEM;
+
+ /* Check h/w access */
+ if (tiwlan_set_hw_access(drv))
+ {
+ tiwlan_free_drv(drv);
+ return -ENODEV;
+ }
+
+#ifdef DM_USE_WORKQUEUE
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
+ drv->tiwlan_wq = create_singlethread_workqueue("tiwlan_wifi_wq");
+#else
+ drv->tiwlan_wq = create_freezeable_workqueue("tiwlan_wifi_wq");
+#endif
+ if( !(drv->tiwlan_wq) ) {
+ tiwlan_free_drv(drv);
+ printk(KERN_ERR "Failed to create workqueue\n");
+ return -EINVAL;
+ }
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
+ INIT_WORK( &drv->tw, tiwlan_work_handler, &drv->tw );
+ INIT_WORK( &drv->txmit, tiwlan_xmit_handler, &drv->txmit );
+ INIT_WORK( &drv->tirq, tiwlan_irq_handler, &drv->tirq );
+#else
+ INIT_WORK( &drv->tw, tiwlan_work_handler );
+ INIT_WORK( &drv->txmit, tiwlan_xmit_handler );
+ INIT_WORK( &drv->tirq, tiwlan_irq_handler );
+#endif
+ drv->txmit_msdu_next = drv->txmit_msdu_last = NULL;
+#else
+ tasklet_init( &drv->tl, tiwlan_tasklet_handler, (unsigned long)drv );
+#endif
+
+#if defined(CONFIG_TROUT_PWRSINK) || defined(CONFIG_HTC_PWRSINK)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
+ INIT_DELAYED_WORK( &drv->trxw, tiwlan_rx_watchdog, &drv->trxw );
+#else
+ INIT_DELAYED_WORK( &drv->trxw, tiwlan_rx_watchdog );
+#endif
+#endif
+
+#ifdef CONFIG_ANDROID_POWER
+ drv->receive_packet = 0;
+ android_init_suspend_wakelock(&drv->irq_wake_lock,"tiwlan_irq_wake");
+ android_init_suspend_wakelock(&drv->xmit_wake_lock,"tiwlan_xmit_wake");
+ android_init_suspend_wakelock(&drv->timer_wake_lock,"tiwlan_timer_wake");
+ android_init_suspend_wakelock(&drv->rx_wake_lock,"tiwlan_rx_wake");
+#endif
+ spin_lock_init(&drv->lock);
+ INIT_LIST_HEAD(&drv->request_q);
+ init_timer(&drv->poll_timer);
+ drv->poll_timer.function = tiwlan_poll_irq_handler;
+ drv->poll_timer.data = (unsigned long)drv;
+
+ /* Init the completion obhect needed for init async purpose */
+ init_completion(&drv->comp);
+
+ /* Register network device */
+ rc = setup_netif(drv);
+ if (rc)
+ {
+ tiwlan_free_drv(drv);
+ return rc;
+ }
+ drv->priv = priv;
+
+ list_add(&drv->list, &tiwlan_drv_list);
+ if (p_drv)
+ *p_drv = drv;
+
+ drv->initialized = 0;
+
+ /* Profiler */
+#ifdef DRIVER_PROFILING
+ tiwlan_profile_create (drv);
+#endif
+
+ bm_init(drv);
+
+#ifdef NO_USERMODE_WORKAROUND
+ rc = tiwlan_init_drv(drv, NULL);
+ rc = rc ? rc : tiwlan_start_drv(drv);
+#endif
+
+ return 0;
+}
+
+/* tiwlan_stop_driver
+*/
+int tiwlan_stop_drv(tiwlan_net_dev_t *drv)
+{
+ if (!drv->adapter.CoreHalCtx)
+ return 0;
+
+ if (drv->netdev)
+ netif_stop_queue(drv->netdev);
+
+ drv->started = 0;
+ configMgr_stop(drv->adapter.CoreHalCtx);
+
+#ifdef CONFIG_TROUT_PWRSINK
+ trout_pwrsink_set(PWRSINK_WIFI, 0);
+#endif
+#ifdef CONFIG_HTC_PWRSINK
+ htc_pwrsink_set(PWRSINK_WIFI, 0);
+#endif
+ return 0;
+}
+
+/* tiwlan_stop__and_destroy_driver
+*/
+int tiwlan_stop_and_destroy_drv(tiwlan_net_dev_t *drv)
+{
+ if (!drv->adapter.CoreHalCtx)
+ return 0;
+
+ if (drv->netdev)
+ netif_stop_queue(drv->netdev);
+
+ /* Start unload process by calling smeSm_stop, and halting the HAL */
+ /* SmeSm_stop finish notification will be one by setting flags */
+ configMgr_InitiateUnload(drv->adapter.CoreHalCtx);
+ drv->started = 0;
+ return 0;
+}
+
+void *wifi_kernel_prealloc(int section, unsigned long size)
+{
+#ifdef CONFIG_WIFI_CONTROL_FUNC
+ if( wifi_control_data && wifi_control_data->mem_prealloc )
+ return wifi_control_data->mem_prealloc( section, size );
+ else
+#endif
+ return NULL;
+}
+
+#ifdef TIWLAN_CARDBUS
+
+static struct pci_device_id tnetw1130_pci_tbl[] __devinitdata =
+{
+ { VENDOR_ID_TI, DEVICE_ID_TI_WLAN, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ { 0, }
+};
+
+static int __devinit
+tnetw1130_pci_init_one(struct pci_dev *pcidev, const struct pci_device_id *id)
+{
+ tiwlan_net_dev_t *drv;
+ int rc;
+
+ print_info("tnetw1130_pci_init_one:\n");
+ /* IT: for some reason interrupt doesn't work.
+ use poling mode for now (comments around
+ pcidev->irq below)
+ */
+ rc = tiwlan_create_drv(pcidev->resource[0].start,
+ pcidev->resource[0].end - pcidev->resource[0].start,
+ pcidev->resource[1].start,
+ pcidev->resource[1].end - pcidev->resource[1].start,
+ 1,
+ 0/*pcidev->irq*/, pcidev, &drv);
+ if (!rc)
+ pcidev->driver_data = drv;
+ return rc;
+}
+
+void tnetw1130_pci_remove(struct pci_dev *dev)
+{
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)dev->driver_data;
+ if (drv)
+ {
+ dev->driver_data = NULL;
+ tiwlan_destroy_drv(drv);
+ }
+}
+
+static struct pci_driver tnetw1130_pci_driver = {
+ .name = "tnetw1130",
+ .id_table = tnetw1130_pci_tbl,
+ .probe = tnetw1130_pci_init_one,
+ .remove = tnetw1130_pci_remove
+};
+
+#endif /* #ifdef TIWLAN_CARDBUS */
+
+#ifdef TIWLAN_OMAP1610
+int omap1610_drv_create(void)
+{
+ omap_memif_init();
+ return tiwlan_create_drv(TIWLAN_OMAP1610_REGBASE, TIWLAN_OMAP1610_REGSIZE,
+ TIWLAN_OMAP1610_MEMBASE, TIWLAN_OMAP1610_MEMSIZE,
+ 0, TIWLAN_OMAP1610_IRQ, NULL, NULL);
+}
+#endif /* #ifdef TIWLAN_OMAP1610 */
+
+#ifdef TIWLAN_MSM7000
+
+#define TROUT_IRQ MSM_GPIO_TO_INT(29)
+
+static void tiwlan_sdio_irq(struct sdio_func *func)
+{
+ printk("%s:\n", __FUNCTION__);
+}
+
+static const struct sdio_device_id tiwlan_sdio_ids[] = {
+ { SDIO_DEVICE_CLASS(SDIO_CLASS_WLAN) },
+ { },
+};
+
+MODULE_DEVICE_TABLE(sdio, tiwlan_sdio_ids);
+
+int tiwlan_sdio_init(struct sdio_func *func)
+{
+ int rc;
+
+ rc = sdio_enable_func(func);
+ if (rc)
+ return rc;
+
+ rc = sdio_set_block_size(func, 512);
+ if( rc ) {
+ sdio_disable_func(func);
+ }
+ return rc;
+}
+
+static int tiwlan_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)
+{
+ int rc;
+
+ SDIO_SetFunc( NULL );
+ if (func->vendor != VENDOR_ID_TI || func->device != DEVICE_ID_TI_WLAN)
+ return -ENODEV;
+
+ printk(KERN_INFO
+ "TIWLAN: Found SDIO controller (vendor 0x%x, device 0x%x)\n",
+ func->vendor, func->device);
+
+#ifdef CONFIG_TROUT_PWRSINK
+ trout_pwrsink_set(PWRSINK_WIFI, PWRSINK_WIFI_PERCENT_BASE);
+#endif
+#ifdef CONFIG_HTC_PWRSINK
+ htc_pwrsink_set(PWRSINK_WIFI, PWRSINK_WIFI_PERCENT_BASE);
+#endif
+
+ sdio_claim_host(func);
+
+ rc = tiwlan_sdio_init(func);
+ if (rc)
+ goto err2;
+
+ rc = sdio_claim_irq(func, tiwlan_sdio_irq);
+ if (rc)
+ goto err1;
+
+ SDIO_SetFunc( func );
+
+ rc = tiwlan_create_drv(0, 0, 0, 0, 0, TROUT_IRQ, NULL, NULL);
+
+ printk(KERN_INFO "TIWLAN: Driver initialized (rc %d)\n", rc);
+ complete(&sdio_wait);
+ return rc;
+err1:
+ sdio_disable_func(func);
+err2:
+ sdio_release_host(func);
+ complete(&sdio_wait);
+ printk(KERN_ERR "TIWLAN: SDIO failure (err %d)\n", rc);
+ return rc;
+}
+
+static void tiwlan_sdio_remove(struct sdio_func *func)
+{
+ printk(KERN_DEBUG "TIWLAN: Releasing SDIO resources\n");
+ sdio_release_irq(func);
+ sdio_disable_func(func);
+ sdio_release_host(func);
+ printk(KERN_DEBUG "TIWLAN: SDIO resources released\n");
+}
+
+static struct sdio_driver tiwlan_sdio_drv = {
+ .probe = tiwlan_sdio_probe,
+ .remove = tiwlan_sdio_remove,
+ .name = "sdio_tiwlan",
+ .id_table = tiwlan_sdio_ids,
+};
+
+#ifdef CONFIG_WIFI_CONTROL_FUNC
+static int wifi_probe( struct platform_device *pdev )
+{
+ struct wifi_platform_data *wifi_ctrl = (struct wifi_platform_data *)(pdev->dev.platform_data);
+
+ printk("%s\n", __FUNCTION__);
+ if( wifi_ctrl ) {
+ wifi_control_data = wifi_ctrl;
+ if( wifi_ctrl->set_power )
+ wifi_ctrl->set_power(1); /* Power On */
+ if( wifi_ctrl->set_reset )
+ wifi_ctrl->set_reset(0); /* Reset clear */
+ if( wifi_ctrl->set_carddetect )
+ wifi_ctrl->set_carddetect(1); /* CardDetect (0->1) */
+ }
+ return 0;
+}
+
+static int wifi_remove( struct platform_device *pdev )
+{
+ struct wifi_platform_data *wifi_ctrl = (struct wifi_platform_data *)(pdev->dev.platform_data);
+
+ printk("%s\n", __FUNCTION__);
+ if( wifi_ctrl ) {
+ if( wifi_ctrl->set_carddetect )
+ wifi_ctrl->set_carddetect(0); /* CardDetect (1->0) */
+ if( wifi_ctrl->set_reset )
+ wifi_ctrl->set_reset(1); /* Reset active */
+ if( wifi_ctrl->set_power )
+ wifi_ctrl->set_power(0); /* Power Off */
+ }
+ return 0;
+}
+
+static struct platform_driver wifi_device = {
+ .probe = wifi_probe,
+ .remove = wifi_remove,
+ .suspend = NULL,
+ .resume = NULL,
+ .driver = {
+ .name = "msm_wifi",
+ },
+};
+
+static int wifi_add_dev( void )
+{
+ return platform_driver_register( &wifi_device );
+}
+
+static void wifi_del_dev( void )
+{
+ platform_driver_unregister( &wifi_device );
+}
+
+int msm_wifi_power( int on )
+{
+ printk("%s\n", __FUNCTION__);
+ if( wifi_control_data && wifi_control_data->set_power ) {
+ wifi_control_data->set_power(on);
+ }
+ return 0;
+}
+
+int msm_wifi_reset( int on )
+{
+ printk("%s\n", __FUNCTION__);
+ if( wifi_control_data && wifi_control_data->set_reset ) {
+ wifi_control_data->set_reset(on);
+ }
+ return 0;
+}
+#endif
+#endif /* TIWLAN_MSM7000 */
+
+static int __init tiwlan_module_init(void)
+{
+ int rc = 0;
+
+ printk(KERN_INFO "TIWLAN: Driver loading\n");
+ /* Check sizes of basic structures to ensure that compilation
+ options are OK
+ */
+ if (packed_struct_tst())
+ ;/*IT: return -EINVAL; */
+
+ tiwlan_deb_entry = create_proc_entry(TIWLAN_DBG_PROC, 0644, NULL);
+ if (tiwlan_deb_entry == NULL)
+ return -EINVAL;
+ tiwlan_deb_entry->read_proc = tiwlan_deb_read_proc;
+ tiwlan_deb_entry->write_proc = tiwlan_deb_write_proc;
+#ifdef TIWLAN_MSM7000
+ init_completion(&sdio_wait);
+#endif
+#ifdef TIWLAN_CARDBUS
+ if ((rc=pci_register_driver(&tnetw1130_pci_driver)) < 0)
+ print_err("TIWLAN: PCMCIA driver failed to register\n");
+ remove_proc_entry(TIWLAN_DBG_PROC, NULL);
+ return rc;
+ }
+ printk(KERN_INFO "TIWLAN: Driver loaded\n");
+ return 0;
+
+#elif defined(TIWLAN_OMAP1610)
+ rc = omap1610_drv_create();
+ export_wifi_chip_id();
+ printk(KERN_INFO "TIWLAN: Driver loaded\n");
+ return rc;
+
+#elif defined(TIWLAN_MSM7000)
+#ifdef CONFIG_WIFI_CONTROL_FUNC
+ wifi_add_dev();
+#else
+ trout_wifi_power(1); /* Power On */
+ trout_wifi_reset(0); /* Reset clear */
+ trout_wifi_set_carddetect(1); /* CardDetect (0->1) */
+#endif
+
+ /* Register ourselves as an SDIO driver */
+ rc = sdio_register_driver(&tiwlan_sdio_drv);
+ if (rc < 0) {
+ printk(KERN_ERR "sdio register failed (%d)\n", rc);
+ remove_proc_entry(TIWLAN_DBG_PROC, NULL);
+ return rc;
+ }
+ /* rc = tiwlan_create_drv(0, 0, 0, 0, 0, TROUT_IRQ, NULL, NULL); -- Called in probe */
+
+ tiwlan_calibration = create_proc_entry("calibration", 0644, NULL);
+ if (tiwlan_calibration == NULL) {
+ remove_proc_entry(TIWLAN_DBG_PROC, NULL);
+ return -EINVAL;
+ }
+ tiwlan_calibration->size = tiwlan_get_nvs_size();
+ tiwlan_calibration->read_proc = tiwlan_calibration_read_proc;
+ tiwlan_calibration->write_proc = tiwlan_calibration_write_proc;
+
+ if (!wait_for_completion_timeout(&sdio_wait, msecs_to_jiffies(10000))) {
+ printk(KERN_ERR "%s: Timed out waiting for device detect\n", __func__);
+ remove_proc_entry(TIWLAN_DBG_PROC, NULL);
+ remove_proc_entry("calibration", NULL);
+ sdio_unregister_driver(&tiwlan_sdio_drv);
+#ifdef CONFIG_WIFI_CONTROL_FUNC
+ wifi_del_dev();
+#else
+ trout_wifi_set_carddetect(0); /* CardDetect (1->0) */
+ trout_wifi_reset(1); /* Reset active */
+ trout_wifi_power(0); /* Power Off */
+#endif
+ return -ENODEV;
+ }
+ export_wifi_chip_id();
+ printk(KERN_INFO "TIWLAN: Driver loaded\n");
+ return 0;
+
+#else
+
+#error Either TIWLAN_CARDBUS, TIWLAN_OMAP1610 or TIWLAN_MSM7000 must be defined
+
+#endif
+}
+
+static void __exit tiwlan_module_cleanup(void)
+{
+ struct list_head *l;
+ struct list_head *tmp;
+
+ printk(KERN_INFO "TIWLAN: Driver unloading\n");
+#ifdef TIWLAN_CARDBUS
+ pci_unregister_driver(&tnetw1130_pci_driver);
+#endif
+ list_for_each_safe(l, tmp, &tiwlan_drv_list)
+ {
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)list_entry(l, tiwlan_net_dev_t, list);
+ list_del(l);
+ tiwlan_destroy_drv(drv);
+ }
+ remove_proc_entry(TIWLAN_DBG_PROC, NULL);
+#ifdef TIWLAN_MSM7000
+ remove_proc_entry("calibration", NULL);
+ sdio_unregister_driver(&tiwlan_sdio_drv);
+#ifdef CONFIG_WIFI_CONTROL_FUNC
+ wifi_del_dev();
+#else
+ trout_wifi_set_carddetect(0); /* CardDetect (1->0) */
+ trout_wifi_reset(1); /* Reset active */
+ trout_wifi_power(0); /* Power Off */
+#endif
+#endif
+ printk(KERN_INFO "TIWLAN: Driver unloaded\n");
+}
+
+module_init(tiwlan_module_init);
+module_exit(tiwlan_module_cleanup);
diff --git a/sta_dk_4_0_4_32/pform/linux/src/ioctl_list.c b/sta_dk_4_0_4_32/pform/linux/src/ioctl_list.c
new file mode 100644
index 0000000..5c3fa32
--- /dev/null
+++ b/sta_dk_4_0_4_32/pform/linux/src/ioctl_list.c
@@ -0,0 +1,263 @@
+/****************************************************************************
+**+-----------------------------------------------------------------------+**
+**| |**
+**| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |**
+**| All rights reserved. |**
+**| |**
+**| Redistribution and use in source and binary forms, with or without |**
+**| modification, are permitted provided that the following conditions |**
+**| are met: |**
+**| |**
+**| * Redistributions of source code must retain the above copyright |**
+**| notice, this list of conditions and the following disclaimer. |**
+**| * Redistributions in binary form must reproduce the above copyright |**
+**| notice, this list of conditions and the following disclaimer in |**
+**| the documentation and/or other materials provided with the |**
+**| distribution. |**
+**| * Neither the name Texas Instruments nor the names of its |**
+**| contributors may be used to endorse or promote products derived |**
+**| from this software without specific prior written permission. |**
+**| |**
+**| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |**
+**| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |**
+**| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
+**| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |**
+**| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
+**| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |**
+**| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
+**| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
+**| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |**
+**| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
+**| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |**
+**| |**
+**+-----------------------------------------------------------------------+**
+****************************************************************************/
+
+
+#include "arch_ti.h"
+
+#include <asm/uaccess.h> /* copy_to_user() */
+#include <linux/netdevice.h>
+#include <linux/ioctl.h>
+#include <linux/completion.h>
+#include <linux/vmalloc.h>
+
+#include "esta_drv.h"
+#include "tiwlan_profile.h"
+#include "ioctl_init.h"
+#include "ioctl_utils.h"
+#include "tiioctl.h"
+#include "ipc_k.h"
+
+
+void print_priv_ioctl_params(struct net_device *dev, tiioctl_req_t *req, char *extra)
+{
+ print_deb(" priv_ioctl_params(*dev:%p,*req:%p, *extra:%p)\n", dev, req, extra);
+ print_deb(" wrqu.point: user_data=%p, length=%ld, cmd=%ld\n", (void *) req->user_data_pointer,
+ req->length, req->cmd );
+ print_deb(" wrqu dump: ");
+ print_memory_dump((char *) req, sizeof(*req) );
+ print_deb("\n");
+
+ if( extra )
+ {
+ print_deb(" extra (%p) :", extra );
+ print_memory_dump(extra, req->length );
+ print_deb("\n");
+ }
+}
+
+/*sends complete to the user after to signal the completion of the asynchronous */
+/*operation (need to set *pIoCompleteFlag = FALSE, at osCmd.c).*/
+
+void os_IoctlComplete(PTIWLN_ADAPTER_T pAdapter, TI_STATUS ReturnStatus )
+{
+ *pAdapter->pCompleteReply = (int)ReturnStatus;
+ complete(pAdapter->IoctlComp);
+}
+
+
+NTSTATUS DispatchCommand(PTIWLN_ADAPTER_T pAdapter,ULONG ioControlCode,PULONG outBufLen,
+ ULONG inBufLen,PVOID ioBuffer,PUINT8 pIoCompleteFlag);
+
+int ti1610_ioctl_priv_proc_tl(tiwlan_req_t *req_data)
+{
+ struct net_device *dev = req_data->drv->netdev;
+ tiioctl_req_t *req = (tiioctl_req_t *) req_data->u.req.p1;
+ static unsigned int drv_started = 0;
+ static UINT8 IoCompleteFlag ;
+
+ ULONG *data = (ULONG *) req_data->u.req.p2;
+
+ int res = -EINVAL;
+
+ print_deb("priv_ioctl_proc(): cmd=%ld, data=%p (user_data=%lx), lenght=%ld\n",
+ req->cmd, data, req->user_data_pointer, req->length);
+ if( !drv_started && (req->cmd != TIWLN_DRIVER_STATUS_SET)) { /* Dm: Fix */
+ return res;
+ }
+
+ switch( req->cmd ) {
+ case TIWLN_DRIVER_STATUS_SET:
+ if(*data)
+ res = tiwlan_start_drv( (tiwlan_net_dev_t *)dev->priv );
+ else
+ res = tiwlan_stop_drv( (tiwlan_net_dev_t *)dev->priv );
+
+ if( res == OK )
+ drv_started = !drv_started;
+ break;
+
+ case TIWLN_SEND_EAPOL_PACKET:
+ res = os_sendPacket(dev, data, req->length);
+ break;
+#ifdef TI_DBG
+ case TIWLN_DRIVER_DEBUG_PRINT:
+ res = util_hal_debug_print(dev, data);
+ break;
+#endif /* TI_DBG */
+ default:
+ {
+ res = DispatchCommand(&req_data->drv->adapter, req->cmd, &req->length, req->length, data,&IoCompleteFlag );
+ /* If we do not have to send complete to user back then set the Falg to FALSE
+ The Complete will be sent from another contect of command completion from FW */
+ if(IoCompleteFlag == FALSE)
+ {
+ req_data->u.req.reply_expected = FALSE;
+ /****** TO DO - This solution will have a problem in case of two async ioctrls (in case of two utility adapters). ******/
+ /* Store the semaphore for later competion */
+ (req_data->drv->adapter).IoctlComp = &(req_data->u.req.comp);
+ /* Store the pointer of the result status for later competion */
+ (req_data->drv->adapter).pCompleteReply = &(req_data->u.reply);
+ }
+
+ }
+ }
+ return res;
+}
+
+int ti1610_do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ tiioctl_req_t *req = (tiioctl_req_t *) &rq->ifr_ifru;
+ char *extra, *kbuf = NULL;
+ int res, aval_data_size = ((char *) req + sizeof(*req)) - (char *)&req->user_data_pointer; /* = ~4 bytes */
+ /*int is_get_cmd = (req->cmd_type & IOCTL_GET);*/
+
+ print_deb("ti1610_do_ioctl(cmd=%lu(%s%s)) - user_data_pointer=0x%lx, len = %lu, aval_data_size=%d\n",
+ req->cmd,
+ (req->cmd_type & IOCTL_GET) ? "GET" : "", (req->cmd_type & IOCTL_SET) ? "SET" : "",
+ req->user_data_pointer, req->length, aval_data_size );
+
+ /* driver is already initialized */
+ if ((req->cmd == TIWLN_SET_INIT_INFO) && (((tiwlan_net_dev_t *)dev->priv)->adapter.CoreHalCtx))
+ {
+ return 0;
+ }
+
+ if( req->length > aval_data_size )
+ {
+ if( req->user_data_pointer == 0 )
+ return -EFAULT;
+
+ print_deb("ti1610_do_ioctl() - alloc %ld bytes\n", req->length );
+ kbuf = extra = os_memoryAlloc(NULL,req->length);
+#ifdef TI_MEM_ALLOC_TRACE
+ os_printf("MTT:%s:%d ::kmalloc(%lu, %x) : %lu\n", __FUNCTION__, __LINE__, req->length, GFP_KERNEL, req->length);
+#endif/*I_MEM_ALLOC_TRACE*/
+
+ if( !extra )
+ return -ENOBUFS;
+ if( req->cmd_type & IOCTL_SET )
+ {
+ if( copy_from_user(extra, (void *) req->user_data_pointer, req->length) )
+ return -EFAULT;
+ }
+ else {
+ os_memoryZero( NULL, extra, req->length );
+ }
+ } else
+ extra = (char *) &req->user_data_pointer;
+
+ /* Driver initialization must be performed in process context.
+ The rest is handled in the context of dedicated tasklet
+ */
+ if (req->cmd == TIWLN_SET_INIT_INFO)
+ {
+ tiwlan_dev_init_t *init_info = (tiwlan_dev_init_t *)extra;
+ print_deb("TIWLN_SET_INIT_INFO: el=%d il=%d, fl=%d\n",
+ init_info?init_info->eeprom_image_length:0,
+ init_info?init_info->init_file_length:0,
+ init_info?init_info->firmware_image_length:0 );
+ res = tiwlan_init_drv((tiwlan_net_dev_t *)dev->priv, init_info);
+ }
+
+#ifdef DRIVER_PROFILING
+ else if (req->cmd == TIWLAN_PROFILING_REPORT)
+ {
+ res = tiwlan_profile_report((tiwlan_net_dev_t *)dev->priv);
+ }
+ else if (req->cmd == TIWLAN_PROFILING_CPU_ESTIMATOR_CMD) {
+ /* get the command cpu estimator command parameter */
+ unsigned int command_param = *((unsigned int *)extra);
+ /* extract the command type which is the MSB byte of the command param*/
+ unsigned int command_type = 0xFF & (command_param >> 24);
+ /* extract the data of the command which are the 3 LSB bytes of the command param */
+ unsigned int command_data = 0xFFFFFF & command_param;
+ /* execute the command according to its type */
+ switch (command_type)
+ {
+ case TIWLAN_PROFILING_CPU_ESTIMATOR_CMD_START:
+ res = tiwlan_profile_cpu_usage_estimator_start((tiwlan_net_dev_t *)dev->priv,
+ /* the data in this case is the estimator
+ resolution in milliseconds */
+ command_data * 1000);
+ break;
+ case TIWLAN_PROFILING_CPU_ESTIMATOR_CMD_STOP:
+ res = tiwlan_profile_cpu_usage_estimator_stop((tiwlan_net_dev_t *)dev->priv);
+ break;
+ case TIWLAN_PROFILING_CPU_ESTIMATOR_CMD_RESET:
+ res =tiwlan_profile_cpu_usage_estimator_reset((tiwlan_net_dev_t *)dev->priv);
+ break;
+ default:
+ res = 0;
+ printk("\n\n%s: cpu usage estimator unknow command: param = %x\n\n\n",
+ __FUNCTION__, command_param);
+ }
+ }
+#endif
+
+ else
+ {
+ res = tiwlan_send_wait_reply((tiwlan_net_dev_t *)dev->priv, ti1610_ioctl_priv_proc_tl,
+ (unsigned long)req, (unsigned long)extra, 0, 0);
+ }
+
+ if( !res )
+ {
+ if( (req->cmd_type & IOCTL_GET) && kbuf /*req->length > aval_data_size*/ )
+ {
+ print_deb("ti1610_do_ioctl(): ...copy from %p to %p %ld bytes\n\n", extra, (void *) req->user_data_pointer, req->length );
+ print_memory_dump(extra, min(32,(int) req->length) );
+ if( copy_to_user( (void *) req->user_data_pointer, extra, req->length ) )
+ return -EFAULT;
+ }
+ }
+ print_deb("ti1610_do_ioctl() = %d (req = %p, user_data_pointer=0x%lx, extra=%p)\n\n", res, req, req->user_data_pointer, extra );
+
+ if( kbuf ){
+ os_memoryFree(NULL,kbuf,sizeof(kbuf));
+#ifdef TI_MEM_ALLOC_TRACE
+ os_printf("MTT:%s:%d ::kfree(0x%p) : %d\n", __FUNCTION__, __LINE__, kbuf, -req->length);
+#endif/*I_MEM_ALLOC_TRACE*/
+ }
+ return res;
+}
+
+
+int tiwlan_ioctl_init( struct net_device *dev )
+{
+ dev->do_ioctl = ti1610_do_ioctl;
+
+ return 0;
+}
+
diff --git a/sta_dk_4_0_4_32/pform/linux/src/ioctl_utils.c b/sta_dk_4_0_4_32/pform/linux/src/ioctl_utils.c
new file mode 100644
index 0000000..54f4ac5
--- /dev/null
+++ b/sta_dk_4_0_4_32/pform/linux/src/ioctl_utils.c
@@ -0,0 +1,164 @@
+/****************************************************************************
+**+-----------------------------------------------------------------------+**
+**| |**
+**| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |**
+**| All rights reserved. |**
+**| |**
+**| Redistribution and use in source and binary forms, with or without |**
+**| modification, are permitted provided that the following conditions |**
+**| are met: |**
+**| |**
+**| * Redistributions of source code must retain the above copyright |**
+**| notice, this list of conditions and the following disclaimer. |**
+**| * Redistributions in binary form must reproduce the above copyright |**
+**| notice, this list of conditions and the following disclaimer in |**
+**| the documentation and/or other materials provided with the |**
+**| distribution. |**
+**| * Neither the name Texas Instruments nor the names of its |**
+**| contributors may be used to endorse or promote products derived |**
+**| from this software without specific prior written permission. |**
+**| |**
+**| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |**
+**| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |**
+**| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
+**| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |**
+**| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
+**| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |**
+**| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
+**| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
+**| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |**
+**| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
+**| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |**
+**| |**
+**+-----------------------------------------------------------------------+**
+****************************************************************************/
+
+
+#include "ioctl_init.h"
+#include "esta_drv.h"
+
+#include "ioctl_utils.h"
+
+#include "report.h"
+#include "osClsfr.h"
+
+#define CONFIG_MGR(dev) ((configMgr_t *) \
+ ((dev && dev->priv) ? ((tiwlan_net_dev_t *) dev->priv)->adapter.CoreHalCtx : NULL ) )
+
+
+typedef struct
+{
+ int err_code;
+ char *desc;
+}
+configMgr_error_desc_t;
+
+
+static configMgr_error_desc_t configMgr_error_desc[] =
+{
+ { OK, "OK" },
+ { NOK, "NOK" },
+ { PARAM_NOT_SUPPORTED, "PARAM_NOT_SUPPORTED" },
+ { PARAM_VALUE_NOT_VALID, "PARAM_VALUE_NOT_VALID" },
+ { CONFIGURATION_NOT_VALID, "CONFIGURATION_NOT_VALID" },
+ { NO_SITE_SELECTED_YET, "NO_SITE_SELECTED_YET" },
+ { RE_SCAN_NEEDED, "RE_SCAN_NEEDED" },
+ { EXTERNAL_SET_PARAM_DENIED, "EXTERNAL_SET_PARAM_DENIED" },
+ { EXTERNAL_GET_PARAM_DENIED, "EXTERNAL_GET_PARAM_DENIED" },
+ { PARAM_MODULE_NUMBER_INVALID, "PARAM_MODULE_NUMBER_INVALID" },
+ { STATION_IS_NOT_RUNNING, "STATION_IS_NOT_RUNNING" },
+ { CARD_IS_NOT_INSTALLED, "CARD_IS_NOT_INSTALLED" },
+ /* Data path section */
+ /* { RX_BSS_TYPE_ERROR ,*/
+ /* { RX_BSS_ID_ERROR ,*/
+ /* { TX_QUEUE_SELECTED_OK ,*/
+ /* { NO_TX_QUEUE_SELECTED ,*/
+ /* { TX_STATUS_PENDING ,*/
+ /* { TX_STATUS_NO_RESOURCES ,*/
+ /* { TX_STATUS_FAILURE ,*/
+ /* { TX_STATUS_OK ,*/
+
+ /* 4x section */
+ /* { MAKE_CONCATENATION ,*/
+ /* { SEND_ONE_MSDU ,*/
+ /* { DO_NOT_SEND_MSDU ,*/
+ /* { FOUR_X_DISABLE ,*/
+ /**/
+ /* (Scanning section) */
+ /* { NO_COUNTRY ,*/
+ /**/
+ /* (Setting power after select) */
+ /* { TX_POWER_SHOULD_NOT_BE_SET ,*/
+ /* (changing service channel) */
+ /* { CHANNEL_CHANGED ,*/
+ /* { SUPPORT_IMMEDIATE_MEASUREMENT_ONLY,*/
+ /* { MEASUREMENT_TYPE_NOT_SUPPORT,*/
+ /* { MEASUREMENT_CAN_NOT_EXECUTED_IN_PARALLEL,*/
+ /* { MEASUREMENT_REQUEST_IGNORED,*/
+ /* { CANNOT_SET_MEASUREMENT_PARAM_WHEN_ACTIVATED,*/
+ /* { REGULATORY_DOMAIN_SET_TX_POWER_PARAM,*/
+ /* { CANNOT_SET_CHANNEL_THAT_IS_NOT_SUPPORTED,*/
+};
+
+
+int print_err_desc(int err)
+{
+ int i;
+ for( i=0; i<SIZE_ARR(configMgr_error_desc);i++ )
+ {
+ if(configMgr_error_desc[i].err_code == err )
+ {
+ print_err("---err(%d) configMgr() = %s\n", err, configMgr_error_desc[i].desc );
+ return -err;
+ }
+ }
+ print_err("---err(%d) configMgr failed\n", err);
+ return -err;
+}
+
+void print_memory_dump(char *addr, int size )
+{
+#ifdef DEBUG_MESSAGES
+ int i;
+ char buf[4096];
+
+ if( size * 4 > sizeof(buf) ) {
+ print_err("print_memory_dump(): buffer too small\n");
+ return;
+ }
+
+ buf[0] = 0;
+ for(i=0; i<size; i++ ) {
+ if( !(i % 16) )
+ sprintf(&buf[strlen(buf)], "%s%p: ", (i) ? "\n" : "", addr+i );
+ sprintf(&buf[strlen(buf)], "%02x ", (unsigned char)addr[i] );
+ }
+ print_info("%s\n", buf);
+#endif /* DEBUG_MESSAGES */
+}
+
+#ifdef TI_DBG
+#ifndef TIWLAN_MSM7000
+TI_STATUS debugFunction(TI_HANDLE hConfigMgr,
+ UINT32 functionNumber,
+ void *pParam);
+#endif
+#endif
+int util_hal_debug_print(struct net_device *dev, ULONG *data)
+{
+ hal_print_param_t *p = (hal_print_param_t *) data;
+ UINT32 opt_data = 0;
+
+ if( p->optional_param )
+ {
+ if( copy_from_user(&opt_data, p->optional_param, sizeof(opt_data) ) )
+ return -EFAULT;
+ }
+
+ print_deb("HAL_DEBUG_PRINT: func_id=%d, param=%x\n", p->func_id, opt_data );
+#ifdef TI_DBG
+ debugFunction(CONFIG_MGR(dev), p->func_id, &opt_data );
+#endif
+ return 0;
+}
+
diff --git a/sta_dk_4_0_4_32/pform/linux/src/ioctl_utils.h b/sta_dk_4_0_4_32/pform/linux/src/ioctl_utils.h
new file mode 100644
index 0000000..05dd459
--- /dev/null
+++ b/sta_dk_4_0_4_32/pform/linux/src/ioctl_utils.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**+-----------------------------------------------------------------------+**
+**| |**
+**| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |**
+**| All rights reserved. |**
+**| |**
+**| Redistribution and use in source and binary forms, with or without |**
+**| modification, are permitted provided that the following conditions |**
+**| are met: |**
+**| |**
+**| * Redistributions of source code must retain the above copyright |**
+**| notice, this list of conditions and the following disclaimer. |**
+**| * Redistributions in binary form must reproduce the above copyright |**
+**| notice, this list of conditions and the following disclaimer in |**
+**| the documentation and/or other materials provided with the |**
+**| distribution. |**
+**| * Neither the name Texas Instruments nor the names of its |**
+**| contributors may be used to endorse or promote products derived |**
+**| from this software without specific prior written permission. |**
+**| |**
+**| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |**
+**| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |**
+**| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
+**| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |**
+**| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
+**| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |**
+**| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
+**| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
+**| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |**
+**| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
+**| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |**
+**| |**
+**+-----------------------------------------------------------------------+**
+****************************************************************************/
+
+
+#ifndef TI1610_IOCTL_UTILS
+#define TI1610_IOCTL_UTILS
+
+#include <linux/netdevice.h>
+#include <asm/uaccess.h> /* copy_from_user() */
+
+#include "osTIType.h"
+
+void print_memory_dump(char *addr, int size );
+
+int util_get_statistics(struct net_device *dev, ULONG *statistic_data, ULONG *length );
+
+int util_get_param( struct net_device *dev, UINT32 param_type, ULONG *data, UINT32 max_param_len);
+int util_set_param( struct net_device *dev, UINT32 param_type, ULONG *data, UINT32 max_param_len );
+int util_get_report_param( struct net_device *dev, UINT32 param_type, ULONG *data, UINT32 max_param_len);
+int util_set_report_param( struct net_device *dev, UINT32 param_type, ULONG *data, UINT32 max_param_len);
+
+/*int util_get_bssid(struct net_device *dev, int cmd, union iwreq_data *wrqu );*/
+int util_get_network_type_in_use(struct net_device *dev, /*int cmd, */ULONG *data );
+int util_write_hw_register(struct net_device *dev, ULONG *data );
+int util_read_hw_register(struct net_device *dev, ULONG *data );
+int util_hal_debug_print(struct net_device *dev, ULONG *data);
+int util_get_sw_version(struct net_device *dev, ULONG *data );
+int util_get_network_types_supported(struct net_device *dev, ULONG *data );
+int util_get_number_of_antennas(struct net_device *dev, ULONG *data );
+int util_get_rssi(struct net_device *dev, ULONG *data );
+int util_get_bssid_list(struct net_device *dev, ULONG *data, ULONG *length );
+int util_set_privacy_filter(struct net_device *dev, ULONG *data );
+int util_get_privacy_filter(struct net_device *dev, ULONG *data, ULONG *length );
+int util_disassociate(struct net_device *dev);
+int util_set_ssid(struct net_device *dev, void *buf, ULONG length); /* data - pointer to OS_802_11_SSID */
+int util_get_ssid(struct net_device *dev, ULONG configMgr_param, void *data, ULONG *length);
+/*int util_get_ssid(struct net_device *dev, void *data, ULONG *length); ( data - pointer to OS_802_11_SSID) */
+
+int util_get_desired_channel(struct net_device *dev, ULONG *data);
+int util_get_authentication_mode(struct net_device *dev, ULONG *data);
+int util_get_rts_threshold(struct net_device *dev, ULONG *data);
+int util_get_short_preamble(struct net_device *dev, ULONG *data);
+
+int util_poll_ap_packets (struct net_device *dev);
+int util_config_tx_classifier(struct net_device *dev,UINT8 *inParamsBuff,UINT32 inParamsBuffLen);
+
+
+int util_get_fragmentation_threshold(struct net_device *dev, ULONG *data);
+int util_get_infrastructure_mode(struct net_device *dev, ULONG *data);
+int util_get_desired_infrastructure_mode(struct net_device *dev, ULONG *data);
+int util_get_wep_status(struct net_device *dev, ULONG *data);
+int util_get_power_mode(struct net_device *dev, ULONG *data);
+int util_get_tx_antenna(struct net_device *dev, ULONG *data);
+int util_get_rx_antenna(struct net_device *dev, ULONG *data);
+int util_get_short_preamble(struct net_device *dev, ULONG *data);
+int util_get_enable_leap(struct net_device *dev, ULONG *data);
+int util_set_wep_status(struct net_device *dev, ULONG *data);
+int util_add_wep(struct net_device *dev, void *data, ULONG length);
+int util_add_key(struct net_device *dev, void *data, ULONG length);
+int util_remove_key(struct net_device *dev, void *data, ULONG length);
+int util_remove_wep(struct net_device *dev, void *data, ULONG length);
+int util_get_association_info(struct net_device *dev, ULONG *data, ULONG *length );
+#endif
diff --git a/sta_dk_4_0_4_32/pform/linux/src/ipc_k.c b/sta_dk_4_0_4_32/pform/linux/src/ipc_k.c
new file mode 100644
index 0000000..9975c75
--- /dev/null
+++ b/sta_dk_4_0_4_32/pform/linux/src/ipc_k.c
@@ -0,0 +1,120 @@
+/****************************************************************************
+**+-----------------------------------------------------------------------+**
+**| |**
+**| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |**
+**| All rights reserved. |**
+**| |**
+**| Redistribution and use in source and binary forms, with or without |**
+**| modification, are permitted provided that the following conditions |**
+**| are met: |**
+**| |**
+**| * Redistributions of source code must retain the above copyright |**
+**| notice, this list of conditions and the following disclaimer. |**
+**| * Redistributions in binary form must reproduce the above copyright |**
+**| notice, this list of conditions and the following disclaimer in |**
+**| the documentation and/or other materials provided with the |**
+**| distribution. |**
+**| * Neither the name Texas Instruments nor the names of its |**
+**| contributors may be used to endorse or promote products derived |**
+**| from this software without specific prior written permission. |**
+**| |**
+**| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |**
+**| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |**
+**| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
+**| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |**
+**| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
+**| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |**
+**| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
+**| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
+**| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |**
+**| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
+**| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |**
+**| |**
+**+-----------------------------------------------------------------------+**
+****************************************************************************/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/stddef.h>
+#include <linux/netdevice.h>
+#include <linux/rtnetlink.h>
+#include <linux/netlink.h>
+
+#include "osTIType.h"
+#include "esta_drv.h"
+#include "osApi.h"
+#include "ioctl_init.h"
+#include "cli_cu_common.h"
+#include "TI_IPC_Api.h"
+
+UINT32 IPCKernelInit (TI_HANDLE hAdapter,TI_HANDLE hIPCEv)
+{
+ return 0;
+}
+
+UINT32 IPCKernelDeInit (TI_HANDLE hAdapter)
+{
+ return 0;
+}
+
+
+/*******************************************************/
+INT32 IPC_EventSend(TI_HANDLE hAdapter, tiUINT8* pEvData, UINT32 EvDataSize)
+{
+ struct sk_buff *skb;
+ int res;
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *) hAdapter;
+ UINT32 realSize = 0;
+ UINT32 msgSize;
+ struct nlmsghdr *nlh;
+ tiUINT8 *msg;
+
+ /* This event is targetted to the OS process Id 0 is not a valid pId for LINUX*/
+
+ if ((( IPC_EVENT_PARAMS *) pEvData) ->uProcessID == 0)
+ {
+ (( IPC_EVENT_PARAMS *) pEvData) ->pfEventCallback(( IPC_EV_DATA *) pEvData);
+ return 0;
+ }
+
+ /* set the payload size */
+ msgSize = (( IPC_EV_DATA *) pEvData) ->uBufferSize + offsetof(IPC_EV_DATA,uBuffer);
+
+ /* add the netlink header size */
+ realSize = NLMSG_SPACE(msgSize);
+
+ /* allocate the complete message */
+ skb = dev_alloc_skb(realSize);
+ if (!skb) {
+ printk(KERN_ERR "Failed to allocate new skb with size=%u.\n",realSize);
+ return -1;
+ }
+
+ /* set the netlink header params */
+ nlh = NLMSG_PUT(skb, 0, 0, NLMSG_DONE, realSize - sizeof(*nlh));
+
+ /* get the payload pointer */
+ msg = (char *)NLMSG_DATA(nlh);
+
+ /* copy the data to the payload */
+ memcpy(msg,pEvData,msgSize);
+
+ NETLINK_CB(skb).pid = 0; /* from kernel */
+ NETLINK_CB(skb).dst_group = RTNLGRP_LINK;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
+ NETLINK_CB(skb).dst_pid = (( IPC_EVENT_PARAMS *) pEvData) ->uProcessID; /* Dm: */
+#endif
+
+ /* send the message*/
+ res = netlink_unicast(drv->wl_sock, skb, (( IPC_EVENT_PARAMS *) pEvData) ->uProcessID, MSG_DONTWAIT);
+
+ /* Sanity checks. As far as we're concerned this error is unrecovarable.*/
+ if (res >= 0)
+ {
+ return 0;
+ }
+
+nlmsg_failure:
+ ti_dprintf(TIWLAN_LOG_INFO,"IPC kernel: did not send the netlink message\n");
+ return -1;
+}
diff --git a/sta_dk_4_0_4_32/pform/linux/src/ipc_k.h b/sta_dk_4_0_4_32/pform/linux/src/ipc_k.h
new file mode 100644
index 0000000..e0b442f
--- /dev/null
+++ b/sta_dk_4_0_4_32/pform/linux/src/ipc_k.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+**+-----------------------------------------------------------------------+**
+**| |**
+**| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |**
+**| All rights reserved. |**
+**| |**
+**| Redistribution and use in source and binary forms, with or without |**
+**| modification, are permitted provided that the following conditions |**
+**| are met: |**
+**| |**
+**| * Redistributions of source code must retain the above copyright |**
+**| notice, this list of conditions and the following disclaimer. |**
+**| * Redistributions in binary form must reproduce the above copyright |**
+**| notice, this list of conditions and the following disclaimer in |**
+**| the documentation and/or other materials provided with the |**
+**| distribution. |**
+**| * Neither the name Texas Instruments nor the names of its |**
+**| contributors may be used to endorse or promote products derived |**
+**| from this software without specific prior written permission. |**
+**| |**
+**| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |**
+**| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |**
+**| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
+**| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |**
+**| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
+**| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |**
+**| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
+**| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
+**| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |**
+**| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
+**| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |**
+**| |**
+**+-----------------------------------------------------------------------+**
+****************************************************************************/
+
+
+#ifndef _IPC_K
+#define _IPC_K
+
+#include "osTIType.h"
+
+
+/*INT32 IPC_EventSend(struct net_device *dev, sk_buff *skb, UINT32 pid);*/
+#endif
+
+
diff --git a/sta_dk_4_0_4_32/pform/linux/src/mmc_tnetw1150_api.c b/sta_dk_4_0_4_32/pform/linux/src/mmc_tnetw1150_api.c
new file mode 100755
index 0000000..4efee19
--- /dev/null
+++ b/sta_dk_4_0_4_32/pform/linux/src/mmc_tnetw1150_api.c
@@ -0,0 +1,545 @@
+/* mmc_tnetw1150_api.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Copyright © Texas Instruments Incorporated (Oct 2005)
+ * THIS CODE/PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDED BUT NOT LIMITED TO , THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * This program has been modified from its original operation by Texas
+ * Instruments Incorporated. These changes are covered under version 2
+ * of the GNU General Public License, dated June 1991.
+ *
+ * Copyright © Google Inc (Feb 2008)
+ */
+/*-------------------------------------------------------------------*/
+#ifdef TIWLAN_MSM7000
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include "mmc_tnetw1150_api.h"
+#include <linux/mmc/core.h>
+
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio_func.h>
+
+#define SDIO_INVALID_PERIPHERAL_ADDRESS 0x1FFFF
+
+/* CCCR 0x000000 - 0x0000ff */
+/* Function Basic Register (Function 1) 0x000100 - 0x0001ff */
+ /* 0x101 - Function 1 Extended standard I/O device type code */
+ /* 0x102 - RFU[4-0] EnableHighPower Supports High-Power[1-0] SHP[0] */
+ /* 0x103 - 0x108 - RFU */
+ /* 0x109 - 0x10b - Pointer to Function 1 Card Information Structure */
+ /* 0x10c - 0x10e - Pointer to Function 1 Code Storage Area */
+ /* 0x10f - Data access window to Function 1 Code Storage Area */
+ /* 0x110 - 0x111 - I/O block size for Function 1 */
+ /* 0x112 - 0x1ff - RFU */
+/* Function Basic Register (Function 2) 0x000200 - 0x0002ff */
+/* Function Basic Register (Function 3) 0x000300 - 0x0003ff */
+/* Function Basic Register (Function 4) 0x000400 - 0x0004ff */
+/* Function Basic Register (Function 5) 0x000500 - 0x0005ff */
+/* Function Basic Register (Function 6) 0x000600 - 0x0006ff */
+/* Function Basic Register (Function 7) 0x000700 - 0x0007ff */
+/* RFU 0x000800 - 0x000fff */
+/* CIS common and per-function area 0x001000 - 0x017fff */
+/* RFU 0x018000 - 0x01ffff */
+#define SDIO_FUNC1_OFFSET 0x1FFC0
+
+typedef struct
+{
+ Peripheral_Address mem_start_addr;
+ Peripheral_Address mem_part_size;
+ Peripheral_Address mem_end_addr;
+ Peripheral_Address reg_start_addr;
+ Peripheral_Address reg_part_size;
+ Peripheral_Address reg_end_addr;
+} SDIO_TNETW_partitions;
+static SDIO_TNETW_partitions TNETW_table;
+
+static SDIO_TNETWConfigParams TNETW_params;
+
+#ifdef CONFIG_MMC_TNET_INFO
+typedef struct {
+ u8 scr_space[SDIO_FUNC1_OFFSET]; /* 0x000000 - 0x01ffbf;
+ 131072B(128kB)-64B=131008B(0x01ffc0) */
+ u32 amap_size1; /* 0x01ffc0 */
+ u32 amap_offset1; /* 0x01ffc4 */
+ u32 amap_size2; /* 0x01ffc8 */
+ u32 amap_offset2; /* 0x01ffcc */
+ u32 amap_size3; /* 0x01ffd0 */
+ u32 amap_offset3; /* 0x01ffd4 */
+ u32 amap_offset4; /* 0x01ffd8 */
+ u32 cis_offset; /* 0x01ffdc - Card Information Structure */
+ u32 csa_offset; /* 0x01ffe0 - Code Storage Area */
+ u8 filler[16]; /* 0x01ffe4 - 0x01fff3 */
+ u32 wr_err_len; /* 0x01fff4 */
+ u32 wr_err_addr; /* 0x01fff8 */
+ u32 status; /* 0x01fffc */
+} SDIO_FUNC1AddressMap;
+SDIO_FUNC1AddressMap mapping;
+
+int sdio_tnetw1150_dump(int count)
+{
+ unsigned long from;
+ unsigned long br_offset;
+ unsigned long offset=0;
+ unsigned long p1_offset=0;
+ unsigned long p2_offset=0;
+ struct mmc_request request;
+ int lines;
+ int i=0;
+ int second_part=0;
+
+ printk("%s:\n", __FUNCTION__);
+#define TNETW1150_OFFSET 1024
+ from=TNETW1150_OFFSET*count;
+ if((from+TNETW1150_OFFSET)>(SDIO_FUNC1_OFFSET+64))
+ return -1;
+ br_offset=TNETW1150_OFFSET*count;
+ if(br_offset>=TNETW_params.map_reg[0].reg_size) {
+ second_part=1;
+ p2_offset = SDIO_DRIVER_REG_PARTITION_START;
+ offset = TNETW_params.map_reg[1].scr_offset - TNETW_params.map_reg[0].reg_size;
+ }
+ else {
+ p1_offset += SDIO_DOWNLOAD_PARTITION_START;
+ offset = TNETW_params.map_reg[0].scr_offset;
+ }
+
+ request.cmd=SD_IO_RW_DIRECT;
+ request.buffer_len=1;
+ request.nob=0;
+ request.block_len=0;
+ request.buffer=&mapping.scr_space[from];
+ printk(" TNETW1150 try br_offset:0x%08lx offset:0x%08lx):\n", br_offset, offset);
+ do {
+ request.arg = SDIO_CMD52_READ(0,FUNCTION_SELECT_1,0,br_offset);
+ if(__submit_control_request(omap_mmc_dev_get_handle(), &request)!=SDIO_SUCCESS)
+ return SDIO_FAILURE;
+ udelay(1);
+ *request.buffer = (char)omap_readw(OMAP_MMC_RSP6);
+ i++;
+ request.buffer++;
+ br_offset++;
+ } while(i<TNETW1150_OFFSET);
+
+ printk(" TNETW1150 SCR Address Space (start:0x%08lx end:0x%08lx part:%d offset:0x%08lx):\n", from, from+TNETW1150_OFFSET-1, second_part+1, (!second_part)?p1_offset:p2_offset);
+
+ lines=TNETW1150_OFFSET/16;
+ for(i=0; i<lines;i++, from+=16)
+ printk("SDIO:0x%04lx(SCR:0x%04lx): %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", from, (!second_part)?(from+p1_offset):(from-p2_offset+SDIO_REG_PARTITION_START), mapping.scr_space[from], mapping.scr_space[from+1], mapping.scr_space[from+2], mapping.scr_space[from+3], mapping.scr_space[from+4], mapping.scr_space[from+5], mapping.scr_space[from+6], mapping.scr_space[from+7], mapping.scr_space[from+8], mapping.scr_space[from+9], mapping.scr_space[from+10], mapping.scr_space[from+11], mapping.scr_space[from+12], mapping.scr_space[from+13], mapping.scr_space[from+14], mapping.scr_space[from+15]);
+
+ return 0;
+}
+EXPORT_SYMBOL(sdio_tnetw1150_dump);
+
+int sdio_tnetw1150_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+ int len=0;
+ int br_offset = SDIO_FUNC1_OFFSET;
+ struct mmc_request request;
+ u8 buf[64];
+ u8 buf3[3];
+ int bytes_to_read=64;
+ int i;
+#define CCCR_SIZE 17
+ u8 buf_ccr[CCCR_SIZE];
+ u8 buf_ccr_offset[CCCR_SIZE] = {
+ CCCR_SDIO_REVISION, CCCR_SD_SPECIFICATION_REVISION, CCCR_IO_ENABLE,
+ CCCR_IO_READY, CCCR_INT_ENABLE, CCCR_INT_PENDING,
+ CCCR_IO_ABORT, CCCR_BUS_INTERFACE_CONTOROL, CCCR_CARD_CAPABILITY,
+ CCCR_COMMON_CIS_POINTER, CCCR_COMMON_CIS_POINTER+1, CCCR_COMMON_CIS_POINTER+2,
+ CCCR_BUS_SUSPEND, CCCR_FUNCTION_SELECT, CCCR_EXEC_FLAGS,
+ CCCR_READY_FLAGS, CCCR_FNO_BLOCK_SIZE,
+ };
+#define FBR_SIZE 9
+ u8 buf_fbr[FBR_SIZE];
+ u16 buf_fbr_offset[FBR_SIZE] = {
+ FBR_PTR_F1_CIS, FBR_PTR_F1_CIS+1, FBR_PTR_F1_CIS+2,
+ FBR_PTR_F1_CSA, FBR_PTR_F1_CSA+1, FBR_PTR_F1_CSA+2,
+ FBR_WIN_F1_CSA, FBR_F1_IO_BLK_SIZE, FBR_F1_IO_BLK_SIZE+1,
+ };
+
+ request.cmd=SD_IO_RW_DIRECT;
+ request.buffer_len=1;
+ request.nob=0;
+ request.block_len=0;
+ request.buffer=&buf[0];
+ for (i=0; i<bytes_to_read;i++,request.buffer++,br_offset++) {
+ request.arg = SDIO_CMD52_READ(0,FUNCTION_SELECT_1,0,br_offset);
+ if(__submit_control_request(omap_mmc_dev_get_handle(), &request)!=SDIO_SUCCESS)
+ return SDIO_FAILURE;
+ *request.buffer = (char)omap_readw(OMAP_MMC_RSP6);
+ }
+ memcpy(&mapping.amap_size1, &buf, 64);
+
+ count -= 80; /* some reserve */
+ len += (len<count)?sprintf(page+len, " TNETW1150 partitions:\n"):0;
+ len += (len<count)?sprintf(page+len, " Memory: "):0;
+ len += (len<count)?sprintf(page+len, " start:0x%08lx end:0x%08lx size:0x%08lx bytes\n", TNETW_table.mem_start_addr, TNETW_table.mem_end_addr, TNETW_table.mem_part_size):0;
+ len += (len<count)?sprintf(page+len, " Registers: "):0;
+ len += (len<count)?sprintf(page+len, " start:0x%08lx end:0x%08lx size:0x%08lx bytes\n", TNETW_table.reg_start_addr, TNETW_table.reg_end_addr, TNETW_table.reg_part_size):0;
+
+ len += (len<count)?sprintf(page+len, " SDIO Function 1 Address Map:\n"):0;
+ len += (len<count)?sprintf(page+len, " amap_size1:0x%08x amap_offset1:0x%08x\n", mapping.amap_size1, mapping.amap_offset1):0;
+ len += (len<count)?sprintf(page+len, " amap_size2:0x%08x amap_offset2:0x%08x\n", mapping.amap_size2, mapping.amap_offset2):0;
+ len += (len<count)?sprintf(page+len, " amap_size3:0x%08x amap_offset3:0x%08x\n", mapping.amap_size3, mapping.amap_offset3):0;
+ len += (len<count)?sprintf(page+len, " amap_offset4:0x%08x\n", mapping.amap_offset4):0;
+ len += (len<count)?sprintf(page+len, " cis_offset:0x%08x csa_offset :0x%08x\n", mapping.cis_offset, mapping.csa_offset):0;
+ len += (len<count)?sprintf(page+len, " wr_err_len:0x%08x wr_err_addr :0x%08x\n", mapping.wr_err_len, mapping.wr_err_addr):0;
+ len += (len<count)?sprintf(page+len, " status :0x%08x\n", mapping.status):0;
+
+ request.cmd=SD_IO_RW_DIRECT;
+ request.buffer_len=1;
+ request.nob=0;
+ request.block_len=0;
+ request.buffer=&buf_ccr[0];
+ for (i=0; i<CCCR_SIZE;i++,request.buffer++) {
+ request.arg = SDIO_CMD52_READ(0,FUNCTION_SELECT_0,0,buf_ccr_offset[i]);
+ if(__submit_control_request(omap_mmc_dev_get_handle(), &request)!=SDIO_SUCCESS)
+ return SDIO_FAILURE;
+ *request.buffer = (char)omap_readw(OMAP_MMC_RSP6);
+ }
+
+ len += (len<count)?sprintf(page+len, "\n Card Common Control Registers:\n"):0;
+ len += (len<count)?sprintf(page+len, " \
+ REVISION :0x%02x SD_SPEC_REVISION :0x%02x IO_ENABLE :0x%02x\n \
+ IO_READY :0x%02x INT_ENABLE :0x%02x INT_PENDING :0x%02x\n \
+ IO_ABORT :0x%02x BUS_INTERFACE_CONTOROL :0x%02x CARD_CAPABILITY :0x%02x\n \
+ COMMON_CIS_POINTER[2]:0x%02x COMMON_CIS_POINTER[1] :0x%02x COMMON_CIS_POINTER[0]:0x%02x\n \
+ BUS_SUSPEND :0x%02x FUNCTION_SELECT :0x%02x EXEC_FLAGS :0x%02x\n \
+ READY_FLAGS :0x%02x FNO_BLOCK_SIZE :0x%02x\n" , buf_ccr[0], buf_ccr[1], buf_ccr[2], buf_ccr[3], buf_ccr[4], buf_ccr[5], buf_ccr[6], buf_ccr[7], buf_ccr[8], buf_ccr[11], buf_ccr[10], buf_ccr[9], buf_ccr[12], buf_ccr[13], buf_ccr[14], buf_ccr[15], buf_ccr[16]):0;
+
+ request.cmd=SD_IO_RW_DIRECT;
+ request.buffer_len=1;
+ request.nob=0;
+ request.block_len=0;
+
+ request.buffer=&buf3[0];
+ for (i=0; i<3;i++,request.buffer++) {
+ request.arg = SDIO_CMD52_READ(0,FUNCTION_SELECT_1,0,FBR_PTR_F1_IO_DEV);
+ if(__submit_control_request(omap_mmc_dev_get_handle(), &request)!=SDIO_SUCCESS)
+ return SDIO_FAILURE;
+ *request.buffer = (char)omap_readw(OMAP_MMC_RSP6);
+ }
+
+ request.buffer=&buf_fbr[0];
+ for (i=0; i<FBR_SIZE;i++,request.buffer++) {
+ request.arg = SDIO_CMD52_READ(0,FUNCTION_SELECT_1,0,buf_fbr_offset[i]);
+ if(__submit_control_request(omap_mmc_dev_get_handle(), &request)!=SDIO_SUCCESS)
+ return SDIO_FAILURE;
+ *request.buffer = (char)omap_readw(OMAP_MMC_RSP6);
+ }
+
+ len += (len<count)?sprintf(page+len, "\n Function Basic Registers(Func 1):\n"):0;
+ len += (len<count)?sprintf(page+len, " \
+ Func 1 CSA enable and CSA support : 0x%02x 0x%02x\n \
+ Func 1 Ext stand. I/O device i/f and type code : 0x%02x 0x%02x\n \
+ EHP|SHP[1]|SHP[0] : 0x%02x\n \
+ Pointer to Func 1 Card Information Structure :0x%02x 0x%02x 0x%02x\n \
+ Pointer to Func 1 Code Storage Area :0x%02x 0x%02x 0x%02x\n \
+ Data access window to Func 1 Code Storage Area : 0x%02x\n \
+ I/O block size for Func 1 : 0x%02x 0x%02x\n", ((buf3[0]&0x80)>>7), ((buf3[0]&0x40)>>6), (buf3[1]&0x0f), buf3[1], (buf3[2]&0x07), buf_fbr[2], buf_fbr[1], buf_fbr[0], buf_fbr[5], buf_fbr[4], buf_fbr[3], buf_fbr[6], buf_fbr[8], buf_fbr[7]):0;
+
+ *eof = 1;
+ return len;
+}
+#endif /*CONFIG_MMC_TNET_STATISTICS*/
+
+
+/*
+ Initialization of TNETW memory configuration.
+*/
+extern int debug_level;
+SDIO_Status SDIO_TNETWInit(SDIO_TNETWConfigParams *params)
+{
+ /* debug_level=3; */
+ /* printk("%s\n", __FUNCTION__); */
+
+ memset(&TNETW_params, 0, sizeof(SDIO_TNETWConfigParams));
+
+ if(!params) {
+ /* printk("%s set to default\n", __FUNCTION__); */
+ /* set to default value in case params is not presented */
+ TNETW_params.num_of_parts = 2;
+ /* First time initialization */
+ TNETW_params.map_reg[0].reg_size = SDIO_DOWNLOAD_PARTITION_SIZE;
+ TNETW_params.map_reg[0].scr_offset = SDIO_DOWNLOAD_PARTITION_START;
+ /* After firmware has been downloaded, data memory region
+ has to be re-initialized as following:
+ TNETW_params.map_reg[0].reg_size = SDIO_MEM_PARTITION_START;
+ TNETW_params.map_reg[0].scr_offset = SDIO_MEM_PARTITION_SIZE;
+ */
+ TNETW_params.map_reg[1].reg_size = SDIO_REG_PARTITION_SIZE;
+ TNETW_params.map_reg[1].scr_offset = SDIO_REG_PARTITION_START;
+ }
+ else {
+ /* printk("%s: params->num_of_parts=%d\n", __FUNCTION__, params->num_of_parts); */
+ /* validate input parameters */
+ switch(params->num_of_parts) {
+ case 1:
+ if(params->map_reg[0].reg_size > AMAP_ONE_REGION)
+ return SDIO_FAILURE;
+ break;
+ case 2:
+ if((params->map_reg[0].reg_size + params->map_reg[1].reg_size) > AMAP_ONE_REGION)
+ return SDIO_FAILURE;
+ break;
+ case 3:
+ if((params->map_reg[0].reg_size + params->map_reg[1].reg_size + params->map_reg[2].reg_size) > AMAP_ONE_REGION)
+ return SDIO_FAILURE;
+ break;
+ case 4:
+ if((params->map_reg[0].reg_size + params->map_reg[1].reg_size + params->map_reg[2].reg_size + params->map_reg[3].reg_size) > AMAP_ONE_REGION)
+ return SDIO_FAILURE;
+ break;
+ default:
+ return SDIO_FAILURE;
+ }
+ memcpy(&TNETW_params, params, sizeof(SDIO_TNETWConfigParams));
+ }
+
+#ifdef CONFIG_PROC_FS
+#ifdef CONFIG_MMC_TNET_INFO
+ create_proc_read_entry("sdio_tnetw1150", 0, NULL, sdio_tnetw1150_read_proc, NULL);
+#endif
+#endif
+
+ /* printk("%s completed\n", __FUNCTION__); */
+
+ return SDIO_SUCCESS;
+}
+
+SDIO_Status SDIO_TNETWReset(SDIO_TNETWConfigParams *params)
+{
+ /* printk("%s\n", __FUNCTION__); */
+
+ memset(&TNETW_params, 0, sizeof(SDIO_TNETWConfigParams));
+
+ if(!params) {
+ /* printk("%s set to default\n", __FUNCTION__); */
+ /* set to default value in case params is not presented */
+ TNETW_params.num_of_parts = 2;
+
+ /* After firmware has been downloaded, data memory region
+ has to be re-initialized as following */
+ TNETW_params.map_reg[0].reg_size = SDIO_MEM_PARTITION_START;
+ TNETW_params.map_reg[0].scr_offset = SDIO_MEM_PARTITION_SIZE;
+ TNETW_params.map_reg[1].reg_size = SDIO_REG_PARTITION_SIZE;
+ TNETW_params.map_reg[1].scr_offset = SDIO_REG_PARTITION_START;
+ }
+ else {
+ /* printk("%s: params->num_of_parts=%d\n", __FUNCTION__, params->num_of_parts); */
+ /* validate input parameters */
+ switch(params->num_of_parts) {
+ case 1:
+ if(params->map_reg[0].reg_size > AMAP_ONE_REGION)
+ return SDIO_FAILURE;
+ break;
+ case 2:
+ if((params->map_reg[0].reg_size + params->map_reg[1].reg_size) > AMAP_ONE_REGION)
+ return SDIO_FAILURE;
+ break;
+ case 3:
+ if((params->map_reg[0].reg_size + params->map_reg[1].reg_size + params->map_reg[2].reg_size) > AMAP_ONE_REGION)
+ return SDIO_FAILURE;
+ break;
+ case 4:
+ if((params->map_reg[0].reg_size + params->map_reg[1].reg_size + params->map_reg[2].reg_size + params->map_reg[3].reg_size) > AMAP_ONE_REGION)
+ return SDIO_FAILURE;
+ break;
+ default:
+ return SDIO_FAILURE;
+ }
+ memcpy(&TNETW_params, params, sizeof(SDIO_TNETWConfigParams));
+ }
+
+ /* printk("%s completed\n", __FUNCTION__); */
+
+ return SDIO_SUCCESS;
+}
+
+
+static SDIO_Status config_partition(SDIO_Handle sdioHandle, int partition_no, Peripheral_Address start_addr, SDIO_BufferLength part_size)
+{
+ struct sdio_func *func = (struct sdio_func *) sdioHandle;
+ u8 data;
+ int br_offset = SDIO_FUNC1_OFFSET + (partition_no-1)*8;
+ int i, rc;
+
+ /* printk("%s: partition_no=%d\n", __FUNCTION__, partition_no); */
+
+ /* Set size - write out 4 bytes by 4 requests */
+ if (partition_no < AMAP_MAX_REGIONS)
+ {
+ for(i=0;i<4;i++,br_offset++) {
+ data = (part_size>>(8*i))&0xFF;
+
+ /* put R/W Flag (1 for write); Function Number(1), RAW Flag(0),
+ Register Address - the address of the byte of data inside
+ of the selected function that will be written
+ (br_offset for func1),
+ Write Data - for a direct write command, this is the byte=data,
+ that will be written to the selected address=br_offset).
+ */
+ sdio_writeb(func, data, br_offset, &rc);
+ if (rc < 0) {
+ printk(KERN_ERR "%s: Error writing size\n", __FUNCTION__);
+ return SDIO_FAILURE;
+ }
+ /* printk("%s: offset byte=%d data=0x%08x at=0x%08x\n", __FUNCTION__, i, data, br_offset); */
+ }
+
+ /* Set offset - write out 4 bytes by 4 requests */
+ for(i=0;i<4;i++,br_offset++) {
+ data = (start_addr>>(8*i))&0xFF;
+ sdio_writeb(func, data, br_offset, &rc);
+ if (rc < 0) {
+ printk(KERN_ERR "%s: Error writing offset\n", __FUNCTION__);
+ return SDIO_FAILURE;
+ }
+ /* printk("%s: offset byte=%d data=0x%08x at=0x%08x\n", __FUNCTION__, i, data, br_offset); */
+ }
+ }
+#if 0
+ if( partition_no == 2 ) {
+ unsigned long id1;
+ for(i=0,br_offset=0x1ce34;i<4;i++,br_offset++) {
+ data = sdio_readb(func, br_offset, &rc);
+ if (rc < 0) {
+ printk(KERN_ERR "%s: Error reading offset\n", __FUNCTION__);
+ return SDIO_FAILURE;
+ }
+ printk("%s: offset byte=%d data=0x%08x at=0x%08x\n", __FUNCTION__, i, data, br_offset);
+ }
+ rc = sdio_memcpy_fromio(func, &id1, 0x1ce34, 4); /* Dm: Important - DO NOT REMOVE !!! */
+ if (rc < 0) {
+ printk(KERN_ERR "%s: Error reading offset\n", __FUNCTION__);
+ return SDIO_FAILURE;
+ }
+ printk("%s: data=0x%08x at=0x%08x\n", __FUNCTION__, id1, br_offset);
+ }
+#endif
+ return SDIO_SUCCESS;
+}
+
+/*
+ This function configures the slave SDIO device for the required
+ operation mode.
+*/
+SDIO_Status SDIO_TNETWConfig(SDIO_Handle sdioHandle, Peripheral_ConfigParams **peripheral_info)
+{
+ SDIO_Status rc;
+
+ /* printk("%s\n", __FUNCTION__); */
+
+ TNETW_table.mem_start_addr = TNETW_params.map_reg[0].scr_offset;
+ TNETW_table.mem_part_size = TNETW_params.map_reg[0].reg_size;
+ TNETW_table.mem_end_addr = TNETW_table.mem_start_addr + TNETW_table.mem_part_size - 1;
+
+ TNETW_table.reg_start_addr = TNETW_params.map_reg[1].scr_offset;
+ TNETW_table.reg_part_size = TNETW_params.map_reg[1].reg_size;
+ TNETW_table.reg_end_addr = TNETW_table.reg_start_addr + TNETW_table.reg_part_size - 1;
+#if 0
+ printk("%s: memory area: start_addr=0x%08lx end_addr=0x%08lx part_size=0x%08lx\n", __FUNCTION__, TNETW_table.mem_start_addr, TNETW_table.mem_end_addr, TNETW_table.mem_part_size);
+ printk("%s: register area: start_addr=0x%08lx end_addr=0x%08lx part_size=0x%08lx\n", __FUNCTION__, TNETW_table.reg_start_addr, TNETW_table.reg_end_addr, TNETW_table.reg_part_size);
+#endif
+ /* Configure 17-bits address range in peripheral */
+ rc=config_partition(sdioHandle, 1, TNETW_table.mem_start_addr, TNETW_table.mem_part_size);
+ rc = (rc==SDIO_SUCCESS)?config_partition(sdioHandle, 2, TNETW_table.reg_start_addr, TNETW_table.reg_part_size):rc;
+
+ if(*peripheral_info)
+ *peripheral_info = (void *)&TNETW_table;
+
+ /* printk("%s: TNETW1150 partitions:\n", __FUNCTION__);
+ printk("Memory : start:0x%08lx end:0x%08lx size:0x%08lx bytes\n", TNETW_table.mem_start_addr, TNETW_table.mem_end_addr, TNETW_table.mem_part_size);
+ printk("Registers: start:0x%08lx end:0x%08lx size:0x%08lx bytes\n", TNETW_table.reg_start_addr, TNETW_table.reg_end_addr, TNETW_table.reg_part_size);
+ */
+
+ return rc;
+}
+
+/*
+ This function performs convertion of peripheral adddress into 17 bits
+ SDIO address. If found that the memory partition configuration must be
+ changed, the memory is re-mapped in accordance to requested address.
+*/
+SDIO_Address SDIO_ConvertTNETWToSDIOMaster(Peripheral_Address in_tnetw_address, SDIO_BufferLength packet_size)
+{
+ SDIO_Address out_sdio_address;
+
+#ifdef CONFIG_SDIO_ADDRESS_MAPPING_BY_APPLICATION
+ out_sdio_address = in_tnetw_address;
+#else
+ Peripheral_Address tnetw_last_address = in_tnetw_address + packet_size - 1;
+
+ /* printk("%s:\n", __FUNCTION__); */
+
+ if ((in_tnetw_address >= TNETW_table.mem_start_addr) && (tnetw_last_address <= TNETW_table.mem_end_addr)) {
+ /* printk("%s part1 from=0x%08lx to 0x%08lx\n", __FUNCTION__, in_tnetw_address, tnetw_last_address); */
+ /* address in the 1-st partition range (data memory space) */
+ out_sdio_address = in_tnetw_address - TNETW_table.mem_start_addr;
+ }
+ else if ((in_tnetw_address >= TNETW_table.reg_start_addr) && (tnetw_last_address <= TNETW_table.reg_end_addr)) {
+ /* printk("%s part2 from=0x%08lx to 0x%08lx\n", __FUNCTION__, in_tnetw_address, tnetw_last_address); */
+ /* address in the 2-nd partition range (register memory space) */
+ out_sdio_address = in_tnetw_address - TNETW_table.reg_start_addr + TNETW_table.mem_part_size;
+ }
+ else {
+ /* printk("%s peripheral addresses from=0x%08lx to 0x%08lx is out of range\n", __FUNCTION__, in_tnetw_address, tnetw_last_address); */
+ /* invalid address */
+ return SDIO_INVALID_PERIPHERAL_ADDRESS;
+ }
+ /* printk("%s: in_tnetw_addr=0x%08lx out_sdio_addr=0x%08lx\n", __FUNCTION__, in_tnetw_address, out_sdio_address); */
+
+#endif /* CONFIG_SDIO_ADDRESS_MAPPING_BY_APPLICATION */
+
+ return out_sdio_address;
+}
+
+SDIO_Status SDIO_TNETW_Set_ELP_Reg(SDIO_Handle sdioHandle, Peripheral_Address start_addr, unsigned int data)
+{
+ struct sdio_func *func = (struct sdio_func *) sdioHandle;
+ u8 data1 = 0;
+ int br_offset = start_addr;
+ int i, rc;
+
+ /* Set size - write out 4 bytes by 4 requests */
+ for(i=0;i<1;i++,br_offset++) {
+ data1 = (data>>(8*i))&0xFF;
+
+ /* put R/W Flag (1 for write); Function Number(1), RAW Flag(0),
+ Register Address - the address of the byte of data inside
+ of the selected function that will be written
+ (br_offset for func1),
+ Write Data - for a direct write command, this is the byte=data,
+ that will be written to the selected address=br_offset).
+ */
+ sdio_writeb(func, data1, br_offset, &rc);
+ if (rc < 0) {
+ printk(KERN_ERR "%s: Error writing size\n", __FUNCTION__);
+ return SDIO_FAILURE;
+ }
+ }
+ return SDIO_SUCCESS;
+}
+
+SDIO_Status SDIO_TNETW_Get_ELP_Reg(SDIO_Handle sdioHandle, Peripheral_Address start_addr, unsigned int *data)
+{
+ struct sdio_func *func = (struct sdio_func *) sdioHandle;
+ int br_offset = start_addr;
+ int rc;
+
+ *(u8*)data = sdio_readb_ext(func, br_offset, &rc, 0x01);
+ if (rc) {
+ printk(KERN_ERR "%s: Error reading sdio register (%d)\n", __FUNCTION__, rc);
+ return SDIO_FAILURE;
+ }
+ return SDIO_SUCCESS;
+}
+
+#endif /* TIWLAN_MSM7000 */
diff --git a/sta_dk_4_0_4_32/pform/linux/src/osRgstry_parser.c b/sta_dk_4_0_4_32/pform/linux/src/osRgstry_parser.c
new file mode 100644
index 0000000..88c99d1
--- /dev/null
+++ b/sta_dk_4_0_4_32/pform/linux/src/osRgstry_parser.c
@@ -0,0 +1,232 @@
+/****************************************************************************
+**+-----------------------------------------------------------------------+**
+**| |**
+**| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |**
+**| All rights reserved. |**
+**| |**
+**| Redistribution and use in source and binary forms, with or without |**
+**| modification, are permitted provided that the following conditions |**
+**| are met: |**
+**| |**
+**| * Redistributions of source code must retain the above copyright |**
+**| notice, this list of conditions and the following disclaimer. |**
+**| * Redistributions in binary form must reproduce the above copyright |**
+**| notice, this list of conditions and the following disclaimer in |**
+**| the documentation and/or other materials provided with the |**
+**| distribution. |**
+**| * Neither the name Texas Instruments nor the names of its |**
+**| contributors may be used to endorse or promote products derived |**
+**| from this software without specific prior written permission. |**
+**| |**
+**| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |**
+**| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |**
+**| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
+**| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |**
+**| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
+**| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |**
+**| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
+**| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
+**| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |**
+**| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
+**| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |**
+**| |**
+**+-----------------------------------------------------------------------+**
+****************************************************************************/
+
+#include "osrgstry_parser.h"
+
+extern VOID regReadLastDbgState(PTIWLN_ADAPTER_T pAdapter);
+
+static char *init_file = NULL;
+static int init_file_length= 0;
+static PNDIS_CONFIGURATION_PARAMETER pNdisParm;
+
+extern int osInitTable_IniFile(tiwlan_net_dev_t *drv, initTable_t *InitTable, char *file_buf, int file_length)
+{
+ NDIS_CONFIGURATION_PARAMETER parm;
+
+ init_file = file_buf;
+ init_file_length = file_length;
+ pNdisParm = &parm;
+
+ regFillInitTable( &drv->adapter, InitTable );
+#ifdef TI_DBG
+ regReadLastDbgState(&drv->adapter);
+#endif
+
+ return 0;
+}
+
+unsigned long TiDebugFlag;
+
+/* void PRINT( char * type, char *format, ... )*/
+/* {*/
+/* return ;*/
+/* }*/
+
+NDIS_STATUS NdisUnicodeStringToAnsiString( IN OUT PANSI_STRING DestinationString,
+ IN PUNICODE_STRING SourceString )
+{
+ if( DestinationString->MaximumLength < SourceString->Length )
+ return NDIS_STATUS_BUFFER_TOO_SHORT;
+
+ DestinationString->Length = SourceString->Length;
+ os_memoryCopy( NULL, DestinationString->Buffer, SourceString->Buffer, SourceString->Length );
+ return NDIS_STATUS_SUCCESS;
+
+}
+
+#ifndef tolower
+#define tolower(c) ( (c) | 0x20)
+#endif
+
+ /* Search sub-string in memory buffer */
+ /* From '#' to EOL ---- remarks */
+char *mem_str(char *buf, char *str, char *end_buf)
+{
+ int i;
+
+ for( ; buf <= end_buf; buf++ )
+ {
+ if( *buf == '#' )
+ {
+ buf = strchr(buf+1, '\n' );
+ if( !buf )
+ return NULL;
+
+ }
+ for( i=0; &buf[i] <= end_buf && buf[i] && str[i] && (tolower(buf[i]) == tolower(str[i])); i++ ) ;
+
+ if ((!str[i]) && (!((tolower(*(buf-1))>='a') && (tolower(*(buf-1))<='z'))))
+ return buf;
+ }
+ return NULL;
+}
+
+char * ltrim(char *s )
+{
+ while( *s == ' ' || *s == '\t' ) s++;
+ return s;
+}
+
+VOID NdisReadConfiguration( OUT PNDIS_STATUS status, OUT PNDIS_CONFIGURATION_PARAMETER *param_value,
+ IN NDIS_HANDLE config_handle, IN PNDIS_STRING keyword, IN NDIS_PARAMETER_TYPE param_type )
+{
+#ifdef USE_INIT_FILE
+ char *name = keyword->Buffer;
+ char *s, *buf = init_file, *end_buf = init_file + init_file_length;
+ static int count = 0;
+
+ *status = NDIS_STATUS_FAILURE;
+ *param_value = pNdisParm;
+
+ if( !count )
+ {
+ print_deb("\n++++++++++++\n%s+++++++++++\n", init_file);
+ count++;
+ }
+
+ if( !name || !*name || !init_file || !init_file_length )
+ return ;
+
+ memset(pNdisParm, 0, sizeof(NDIS_CONFIGURATION_PARAMETER));
+
+ while(buf < end_buf)
+ {
+ buf = ltrim(buf);
+ if( !(s = mem_str(buf, name, end_buf)) )
+ break;
+
+ buf = ltrim(s + strlen(name));
+ if( *buf == '=' )
+ buf++;
+ else {
+ /*print_err("\n...init_config err: delim not found (=): ** %s **\n", buf );*/
+ buf = s + 1; /*strlen(name);*/
+ continue;
+ }
+ buf = ltrim(buf);
+ if( param_type == NdisParameterString )
+ {
+ char *remark = NULL;
+
+ s = strchr(buf, '\n');
+ if( !s )
+ s = buf+strlen(buf);
+
+ remark = memchr(buf, '#', s - buf); /* skip remarks */
+ if( remark )
+ {
+ do { /* remove whitespace */
+ remark--;
+ } while( *remark == ' ' || *remark == '\t' );
+
+ pNdisParm->ParameterData.StringData.Length = remark - buf + 1;
+ }
+ else
+ pNdisParm->ParameterData.StringData.Length = s - buf;
+
+ pNdisParm->ParameterData.StringData.Buffer = (PUCHAR)&pNdisParm->StringBuffer[0];
+ pNdisParm->ParameterData.StringData.MaximumLength = NDIS_MAX_STRING_LEN;
+ if( !pNdisParm->ParameterData.StringData.Length > NDIS_MAX_STRING_LEN )
+ {
+ *status = NDIS_STATUS_BUFFER_TOO_SHORT;
+ return;
+ }
+ memcpy(pNdisParm->ParameterData.StringData.Buffer, buf, pNdisParm->ParameterData.StringData.Length);
+ print_info("NdisReadConfiguration(): %s = (%d)'%s'\n", name, pNdisParm->ParameterData.StringData.Length, pNdisParm->ParameterData.StringData.Buffer);
+ }
+ else if( param_type == NdisParameterInteger )
+ {
+ char *end_p;
+ pNdisParm->ParameterData.IntegerData = simple_strtol(buf, &end_p, 0);
+ if (end_p && *end_p && *end_p!=' ' && *end_p!='\n'
+ && *end_p!='\r' && *end_p!='\t')
+ {
+ print_err("\n...init_config: invalid int value for <%s> : %s\n", name, buf );
+ return;
+ }
+ /*print_deb(" NdisReadConfiguration(): buf = %p (%.20s)\n", buf, buf );*/
+ print_info("NdisReadConfiguration(): %s = %d\n", name, (INT32) pNdisParm->ParameterData.IntegerData);
+ }
+ else
+ {
+ print_err("NdisReadConfiguration(): unknow parameter type %d for %s\n", param_type, name );
+ return;
+ }
+ *status = NDIS_STATUS_SUCCESS;
+ return;
+
+ }
+/* print_deb("NdisReadConfiguration(%d): (%c)%s - not found\n", init_file_length,*/
+/* (param_type == NdisParameterString) ? 'S' : 'D', name );*/
+#else
+ /* No init file support */
+ *status = NDIS_STATUS_FAILURE;
+
+#endif
+ return ;
+}
+
+VOID NdisWriteConfiguration( OUT PNDIS_STATUS Status,
+ IN NDIS_HANDLE ConfigurationHandle,
+ IN PNDIS_STRING Keyword,
+ IN PNDIS_CONFIGURATION_PARAMETER ParameterValue )
+{
+ print_err(" NdisWriteConfiguration(): ** not implemented yet ...\n");
+}
+
+VOID NdisReadNetworkAddress( OUT PNDIS_STATUS Status, OUT PVOID *NetworkAddress, OUT PUINT NetworkAddressLength,
+ IN NDIS_HANDLE ConfigurationHandle )
+{
+ print_err(" NdisReadNetworkAddress(): ** not implemented yet ...\n");
+}
+
+VOID NdisMIndicateStatus(
+ NDIS_HANDLE MiniportAdapterHandle,
+ NDIS_STATUS GeneralStatus,
+ PVOID StatusBuffer,
+ UINT StatusBufferSize
+)
+{
+}
diff --git a/sta_dk_4_0_4_32/pform/linux/src/osapi.c b/sta_dk_4_0_4_32/pform/linux/src/osapi.c
new file mode 100644
index 0000000..c90e717
--- /dev/null
+++ b/sta_dk_4_0_4_32/pform/linux/src/osapi.c
@@ -0,0 +1,1765 @@
+/****************************************************************************
+**+-----------------------------------------------------------------------+**
+**| |**
+**| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |**
+**| All rights reserved. |**
+**| |**
+**| Redistribution and use in source and binary forms, with or without |**
+**| modification, are permitted provided that the following conditions |**
+**| are met: |**
+**| |**
+**| * Redistributions of source code must retain the above copyright |**
+**| notice, this list of conditions and the following disclaimer. |**
+**| * Redistributions in binary form must reproduce the above copyright |**
+**| notice, this list of conditions and the following disclaimer in |**
+**| the documentation and/or other materials provided with the |**
+**| distribution. |**
+**| * Neither the name Texas Instruments nor the names of its |**
+**| contributors may be used to endorse or promote products derived |**
+**| from this software without specific prior written permission. |**
+**| |**
+**| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |**
+**| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |**
+**| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
+**| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |**
+**| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
+**| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |**
+**| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
+**| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
+**| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |**
+**| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
+**| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |**
+**| |**
+**+-----------------------------------------------------------------------+**
+****************************************************************************/
+
+
+#include "arch_ti.h"
+
+#include <linux/stddef.h>
+#include <linux/string.h>
+#include <linux/time.h>
+#include <linux/timer.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/vmalloc.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/time.h>
+#include <linux/list.h>
+#include <asm/io.h>
+
+#include "debug_module.h"
+#include "esta_drv.h"
+#ifdef DRIVER_PROFILING
+#include "tiwlan_profile.h"
+#endif
+#include "osApi.h"
+#include "osTIType.h"
+#include "srcApi.h"
+#include "whalHwRegs.h"
+#include "bmtrace.h"
+#include "TI_IPC_Api.h"
+#include "whalBus_Defs.h"
+#include "802_11Defs.h"
+#include "Ethernet.h"
+
+#define OS_PROTECT_HANDLE 0xffffeee0
+/*#define DEBUG_REG_ACCESS*/
+
+#ifdef DEBUG_REG_ACCESS
+#define PRINT_REG(fmt, args...) print_info(fmt, args)
+#else
+#define PRINT_REG(fmt, args...)
+#endif
+#define NOPRINT_REG(fmt, args...)
+
+#ifdef ESTA_TIMER_DEBUG
+#define esta_timer_log(fmt,args...) printk(fmt, ## args)
+#else
+#define esta_timer_log(fmt,args...)
+#endif
+
+#define FRAG_SIZE 200
+
+/* Wlan chip reset defines */
+#define GPIO_16 16
+#define GPIO_16_DIRECTION_OUTPUT 0
+#define GPIO_16_CLEAR 0
+#define GPIO_16_SET 1
+
+#define GPIO1_IRQSTATUS1 0xFFFBE418
+#define GPIO1_DATAIN 0xFFFBE42C
+
+/********************* LOCAL DECLARATIONS ************************/
+static inline void os_timer_dec_use_count(timer_obj_t *tmr);
+static int os_tl_timerHandlr(struct tiwlan_req *req);
+static void os_timerHandlr(unsigned long parm);
+static void send_frag(char* msg, int message_len, int level, int module);
+
+BOOL use_debug_module = FALSE;
+
+/****************************************************************************************
+ * *
+ * OS Report API *
+ * *
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * os_setDebugMode()
+ ****************************************************************************************
+DESCRIPTION: Set the Debug Mode
+
+INPUT:
+
+RETURN: None
+
+NOTES:
+*****************************************************************************************/
+void os_setDebugMode(BOOL enable)
+{
+ use_debug_module = enable;
+}
+
+
+/****************************************************************************************
+ * os_printf()
+ ****************************************************************************************
+DESCRIPTION: Print formatted output.
+
+INPUT: format - Specifies the string, to be printed
+
+RETURN: None
+
+NOTES:
+*****************************************************************************************/
+void os_printf(const char *format ,...)
+{
+ static int from_new_line = 1; /* Used to save the last message EOL */
+ static UINT8 module = 0; /* Used to save the last message module */
+ static UINT8 level = 0; /* Used to save the last message level */
+ va_list ap;
+ static char msg[500];
+ char *p_msg = msg; /* Pointer to the message */
+ UINT16 message_len;
+ UINT32 sec = 0;
+ UINT32 uSec = 0;
+
+ /* Format the message and keep the message length */
+ va_start(ap,format);
+ message_len = vsnprintf(&msg[1], sizeof(msg) - 1, format, ap);
+
+
+ if (use_debug_module)
+ {
+ /*********************/
+ /* Use debug module */
+ /*******************/
+
+ if (msg[1] == '$')
+ {
+ /************************************
+ Message format: "$XX"
+ |||
+ message prefix ----|||
+ module index -------||
+ severity index ------|
+ ************************************/
+
+ level = (msg[2] - 'A');
+ module = (msg[3] - 'A');
+ }
+ else
+ {
+ send_frag(msg, message_len, level, module);
+ }
+ }
+ else
+ {
+ /***********************/
+ /* Use regular printk */
+ /*********************/
+
+ if( from_new_line )
+ {
+ if (msg[1] == '$')
+ {
+ p_msg += 4;
+ }
+
+ sec = os_timeStampUs(NULL);
+ uSec = sec % 1000000;
+ sec /= 1000000;
+
+ printk(KERN_INFO DRIVER_NAME ": %d.%06d: %s",sec,uSec,p_msg);
+ }
+ else
+ {
+ printk(&msg[1]);
+ }
+
+ from_new_line = ( msg[message_len] == '\n' );
+ }
+}
+
+static void send_frag(char* msg, int message_len, int level, int module)
+{
+#ifdef TIWLAN_OMAP1610 /* Dm: */
+ int return_value;
+ int offset = 1;
+ int TmpLen;
+ char* FragMsg;
+
+ do
+ {
+ TmpLen = min(message_len - offset, FRAG_SIZE);
+ FragMsg = msg + offset - 1;
+ FragMsg[0] = module;
+
+ return_value = debug_module_enqueue_message(DEBUG_MODULE_TRACE_QUEUE_ID, level, FragMsg, TmpLen+1, CONTROL_CODE_TYPE_MESSAGE);
+
+ if (return_value)
+ {
+ /* Message overrun */
+
+ /* Send the overrun indication to the debug module */
+ os_memoryCopy(NULL, &msg[1], "*** Message Overrun ***", strlen("*** Message Overrun ***"));
+ msg[0] = 0;
+ debug_module_enqueue_message(DEBUG_MODULE_TRACE_QUEUE_ID, 0, msg, (strlen("*** Message Overrun ***") + 1), CONTROL_CODE_TYPE_MESSAGE);
+
+ /* Print overrun indication to the terminal */
+ /*printk(KERN_INFO DRIVER_NAME ": %d.%06d: %s\n", sec, uSec, "**** Debug module message overrun! ****\n");*/
+ }
+ offset += TmpLen;
+ }while (offset < message_len);
+
+#endif
+}
+
+/****************************************************************************************
+ * *
+ * OS DMA CALLBACK API *
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * os_TNETWIF_BusTxn_Complete()
+ ****************************************************************************************
+DESCRIPTION: Callback directly called at an IRQ context from the SPI modue
+ This should triger a tasklet_schedule so that the End of DMA will be handled
+ in a tasklet context and then be directed to the TNETWIF to call the Client callback.
+
+INPUT: OsContext - our adapter context.
+
+RETURN: None
+
+NOTES:
+*****************************************************************************************/
+void os_TNETWIF_BusTxn_Complete(TI_HANDLE OsContext,int status)
+{
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)OsContext;
+
+ drv->dma_done = 1;
+#ifdef DM_USE_WORKQUEUE
+ /* printk("TI: %s:\t%lu\n", __FUNCTION__, jiffies); */
+ if( queue_work( drv->tiwlan_wq, &drv->tw ) != 0 ) {
+#ifdef CONFIG_ANDROID_POWER
+ android_lock_suspend( &drv->timer_wake_lock );
+#endif
+ }
+#else
+ tasklet_schedule(&drv->tl);
+#endif
+}
+
+/****************************************************************************************
+ * *
+ * OS TIMER API *
+ * *
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * os_timerCreate()
+ ****************************************************************************************
+DESCRIPTION: This function creates and initializes a timer object associated with a
+ caller's pRoutine function.
+
+ARGUMENTS:
+
+RETURN: A handle of the created timer.
+ TI_HANDLE_INVALID if there is insufficient memory available
+
+NOTES: Using the Kernel timer feature, problem is that kernel timers are one-shots.
+ For timers that are periodic this abstraction layer will have to mediate
+ between the callback function and the re-submission of a timer request.
+
+*****************************************************************************************/
+TI_HANDLE
+os_timerCreate(
+ TI_HANDLE OsContext,
+ PTIMER_FUNCTION pRoutine,
+ TI_HANDLE Context
+ )
+{
+ timer_obj_t *tmr;
+
+#ifdef ESTA_TIMER_DEBUG
+ esta_timer_log("\n\n%s:%d ::os_timerCreate(%p,%p,%p)",__FUNCTION__, __LINE__,OsContext,pRoutine,Context);
+#endif
+ ti_nodprintf(TIWLAN_LOG_INFO, "\n----> os_timerCreate function = 0x%08x , context= 0x%08x",
+ (int)pRoutine, (int)Context);
+
+ os_profile (OsContext, 6, 0);
+
+ tmr = os_memoryAlloc (OsContext, sizeof(timer_obj_t));
+ if (tmr == NULL)
+ return(TI_HANDLE_INVALID);
+
+ memset (tmr,0,sizeof(timer_obj_t));
+
+ init_timer(&tmr->timer);
+ INIT_LIST_HEAD(&tmr->req.list);
+ tmr->timer.function = os_timerHandlr;
+ tmr->timer.data = (int)tmr;
+ tmr->req.drv = (tiwlan_net_dev_t *)OsContext;
+ tmr->req.u.req.p1 = (UINT32)pRoutine;
+ tmr->req.u.req.p2 = (UINT32)Context;
+ tmr->req.u.req.f = os_tl_timerHandlr;
+ tmr->use_count = 1;
+
+ esta_timer_log("=%p\n\n", tmr);
+
+ return (TI_HANDLE)tmr;
+}
+
+
+/****************************************************************************************
+ * os_timerDestroy()
+ ****************************************************************************************
+DESCRIPTION: This function destroy the timer object.
+
+ARGUMENTS:
+
+RETURN:
+
+NOTES: Returning the Kernel level timer_list memory allocation and the
+ abstraction level timer object.
+*****************************************************************************************/
+VOID
+os_timerDestroy(
+ TI_HANDLE OsContext,
+ TI_HANDLE TimerHandle
+ )
+{
+ timer_obj_t *tmr = TimerHandle;
+
+ os_profile (OsContext, 6, 0);
+
+ os_timerStop (OsContext, TimerHandle);
+ os_timer_dec_use_count (tmr);
+}
+
+
+/****************************************************************************************
+ * os_timerStart()
+ ****************************************************************************************
+DESCRIPTION: This function start the timer object.
+
+ARGUMENTS:
+
+RETURN:
+
+NOTES:
+*****************************************************************************************/
+VOID
+os_timerStart(
+ TI_HANDLE OsContext,
+ TI_HANDLE TimerHandle,
+ UINT32 DelayMs,
+ BOOL bPeriodic
+ )
+{
+ timer_obj_t *tmr= (timer_obj_t *)TimerHandle;
+
+ UINT32 jiffie_cnt = msecs_to_jiffies(DelayMs);
+
+#ifdef ESTA_TIMER_DEBUG
+ esta_timer_log("\n\n%s:%d ::os_timerStart(%p,%p,%u,%d)\n\n",__FUNCTION__, __LINE__,OsContext,TimerHandle,DelayMs,bPeriodic);
+#endif
+
+ tmr->req.u.req.p3 = bPeriodic;
+ tmr->req.u.req.p4 = jiffie_cnt;
+ tmr->timer.data = (unsigned long)tmr;
+ mod_timer(&tmr->timer, jiffies + jiffie_cnt);
+
+
+ return;
+}
+
+/****************************************************************************************
+ * os_stopTimer()
+ ****************************************************************************************
+DESCRIPTION: This function stop the timer object.
+
+ARGUMENTS:
+
+RETURN:
+
+NOTES:
+*****************************************************************************************/
+VOID
+os_timerStop(
+ TI_HANDLE OsContext,
+ TI_HANDLE TimerHandle
+ )
+{
+ timer_obj_t *tmr= (timer_obj_t *)TimerHandle;
+
+ del_timer_sync(&tmr->timer);
+ tmr->req.u.req.p3 = 0; /* Turn "periodic" off */
+ list_del_init(&tmr->req.list);
+
+ return;
+}
+
+/****************************************************************************************
+ * os_periodicIntrTimerStart()
+ ****************************************************************************************
+DESCRIPTION: This function starts the periodic interrupt mechanism. This mode is used
+ when interrupts that usually received from the Fw is now masked, and we are
+ checking for any need of Fw handling in time periods.
+
+ARGUMENTS:
+
+RETURN:
+
+NOTES: Power level of the CHIP should be always awake in this mode (no ELP)
+*****************************************************************************************/
+VOID
+os_periodicIntrTimerStart(
+ TI_HANDLE OsContext
+ )
+{
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)OsContext;
+
+ mod_timer (&drv->poll_timer, jiffies + TIWLAN_IRQ_POLL_INTERVAL);
+}
+
+/****************************************************************************************
+ * os_timeStampMs()
+ ****************************************************************************************
+DESCRIPTION: This function returns the number of milliseconds that have elapsed since
+ the system was booted.
+
+ARGUMENTS: OsContext - our adapter context.
+
+RETURN:
+
+NOTES:
+*****************************************************************************************/
+UINT32
+os_timeStampMs(
+ TI_HANDLE OsContext
+ )
+{
+ struct timeval tv;
+ do_gettimeofday(&tv);
+ return tv.tv_sec*1000 + tv.tv_usec/1000;
+}
+
+/****************************************************************************************
+ * os_timeStampUs()
+ ****************************************************************************************
+DESCRIPTION: This function returns the number of microseconds that have elapsed since
+ the system was booted.
+
+ARGUMENTS: OsContext - our adapter context.
+ Note that sometimes this function will be called with NULL(!!!) as argument!
+
+RETURN:
+
+NOTES:
+*****************************************************************************************/
+UINT32
+os_timeStampUs(
+ TI_HANDLE OsContext
+ )
+{
+ struct timeval tv;
+ do_gettimeofday(&tv);
+ return tv.tv_sec*1000000 + tv.tv_usec;
+}
+
+/****************************************************************************************
+ * os_StalluSec()
+ ****************************************************************************************
+DESCRIPTION: This function make delay in microseconds.
+
+ARGUMENTS: OsContext - our adapter context.
+ uSec - delay time in microseconds
+
+RETURN:
+
+NOTES:
+*****************************************************************************************/
+VOID
+os_StalluSec(
+ TI_HANDLE OsContext,
+ UINT32 uSec
+ )
+{
+ /*UINT32 usec_now = os_timeStampUs(OsContext);
+ while(os_timeStampUs(OsContext) - usec_now < uSec)
+ ;
+ */
+ udelay(uSec);
+}
+
+/****************************************************************************************
+ * os_WaitComplete()
+ ****************************************************************************************
+DESCRIPTION: This function start waiting for the complete
+
+ARGUMENTS:
+
+RETURN:
+
+NOTES: can be called only from process context, and not from tasklet
+*****************************************************************************************/
+VOID
+os_WaitComplete(
+ TI_HANDLE OsContext
+ )
+{
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)OsContext;
+
+ /* ti_dprintf(TIWLAN_LOG_INFO, "os_WaitComplete drv %x drv->comp %x\n",(UINT32)drv,(UINT32)&drv->comp); */
+
+ /*
+ he tasklet should them send back the user (here)the completion event so the user could
+ go through the configuration phase
+ */
+ wait_for_completion(&drv->comp);
+}
+
+/****************************************************************************************
+ * os_Complete()
+ ****************************************************************************************
+DESCRIPTION: This function signals to the waiting process that completion occured
+
+ARGUMENTS:
+
+RETURN:
+
+NOTES:
+*****************************************************************************************/
+VOID
+os_Complete(
+ TI_HANDLE OsContext
+ )
+{
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)OsContext;
+
+ /* ti_dprintf(TIWLAN_LOG_INFO, "os_Complete drv %x drv->comp %x\n",(UINT32)drv, (UINT32)&drv->comp); */
+
+ /*
+ Call the completion routine that will unblock the caller that was waiting on that object
+ */
+ complete(&drv->comp);
+}
+
+
+
+/****************************************************************************************
+ * *
+ * Hardware access functions API *
+ * *
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * os_clearWlanReady()
+ ****************************************************************************************
+DESCRIPTION: Clear the WLAN Ready Interrupt Line stored in the PIC Controller
+
+INPUT: None
+
+RETURN: None
+
+NOTES:
+*****************************************************************************************/
+
+__inline__ VOID
+os_clearWlanReady(
+ void)
+{
+#ifdef TIWLAN_OMAP1610
+ omap_writel(4,GPIO1_IRQSTATUS1);
+#endif
+}
+
+
+/****************************************************************************************
+ * os_senseIrqLine()
+ ****************************************************************************************
+DESCRIPTION: Read the WLAN_IRQ line
+
+INPUT: void
+
+RETURN: Read value
+
+NOTES:
+*****************************************************************************************/
+
+__inline__ UINT32
+os_senseIrqLine(
+ TI_HANDLE OsContext
+ )
+{
+#ifdef TIWLAN_OMAP1610
+ return (omap_readl(GPIO1_DATAIN) & 0x4);
+#else
+ return 0;
+#endif
+}
+
+
+
+/****************************************************************************************
+ * os_hwGetRegistersAddr()
+ ****************************************************************************************
+DESCRIPTION:
+
+ARGUMENTS:
+
+RETURN:
+
+NOTES:
+*****************************************************************************************/
+PVOID
+os_hwGetRegistersAddr(
+ TI_HANDLE OsContext
+ )
+{
+ return (PVOID)OS_API_REG_ADRR;
+}
+
+/****************************************************************************************
+ * os_hwGetMemoryAddr()
+ ****************************************************************************************
+DESCRIPTION:
+
+ARGUMENTS:
+
+RETURN:
+
+NOTES:
+*****************************************************************************************/
+PVOID
+os_hwGetMemoryAddr(
+ TI_HANDLE OsContext
+ )
+{
+ return (PVOID)OS_API_MEM_ADRR;
+}
+
+/****************************************************************************************
+ * os_memoryGetPhysicalLow()
+ ****************************************************************************************
+DESCRIPTION: return the lower 32 bits of a 64bit number / address *
+
+ARGUMENTS:
+
+RETURN:
+
+NOTES:
+*****************************************************************************************/
+UINT32 os_memoryGetPhysicalLow (OS_PHYSICAL_ADDRESS pAddr)
+{
+ UINT32 res;
+ res = pAddr & 0xffffffff;
+ ti_dprintf(TIWLAN_LOG_ERROR, "\n 64bit low. Got 0x%x; Returning 0x%x \n", (UINT32)pAddr, res);
+ return res;
+}
+
+/****************************************************************************************
+ * os_memoryGetPhysicalHigh()
+ ****************************************************************************************
+DESCRIPTION: return the higher order 32 bits of a 64bit number / address *
+
+ARGUMENTS:
+
+RETURN:
+
+NOTES:
+*****************************************************************************************/
+UINT32 os_memoryGetPhysicalHigh (OS_PHYSICAL_ADDRESS pAddr)
+{
+ UINT32 res;
+ res = pAddr >> 32;
+ ti_dprintf(TIWLAN_LOG_ERROR, "\n 64bit high. Got 0x%x; Returning 0x%x \n", (UINT32)pAddr, res);
+ return res;
+}
+
+
+/****************************************************************************************
+ * *
+ * Protection services API *
+ * *
+ ****************************************************************************************
+ * OS protection is implemented as dummy functions because *
+ * all driver code is executed in context of a single tasklet, *
+ * except IOCTL handlers and xmition. *
+ * Protection in IOCTL handlers and hard_start_xmit is done by different *
+ * means. *
+ ****************************************************************************************/
+
+
+/****************************************************************************************
+ * os_protectCreate()
+ ****************************************************************************************
+DESCRIPTION:
+
+ARGUMENTS: OsContext - our adapter context.
+
+RETURN: A handle of the created mutex/spinlock.
+ TI_HANDLE_INVALID if there is insufficient memory available or problems
+ initializing the mutex
+
+NOTES:
+*****************************************************************************************/
+TI_HANDLE
+os_protectCreate(
+ TI_HANDLE OsContext
+ )
+{
+ return (TI_HANDLE)OS_PROTECT_HANDLE;
+}
+
+
+
+/****************************************************************************************
+ * os_protectDestroy()
+ ****************************************************************************************
+DESCRIPTION:
+
+ARGUMENTS: OsContext - our adapter context.
+
+RETURN: None - This had better work since there is not a return value to the user
+
+NOTES:
+*****************************************************************************************/
+VOID
+os_protectDestroy(
+ TI_HANDLE OsContext,
+ TI_HANDLE ProtectCtx
+ )
+{
+ return;
+}
+
+
+/****************************************************************************************
+ * os_protectLock()
+ ****************************************************************************************
+DESCRIPTION:
+
+ARGUMENTS: OsContext - our adapter context.
+
+RETURN: None - This had better work since there is not a return value to the user
+
+NOTES:
+*****************************************************************************************/
+VOID
+os_protectLock(
+ TI_HANDLE OsContext,
+ TI_HANDLE ProtectContext
+ )
+{
+#if 1 /* uncomment for work in INDIRECT mode (HwACXAccessMethod=0) */
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)OsContext;
+ spin_lock_irqsave(&drv->lock, drv->flags);
+#endif
+}
+
+
+/****************************************************************************************
+ * os_protectUnlock()
+ ****************************************************************************************
+DESCRIPTION:
+
+ARGUMENTS: OsContext - our adapter context.
+
+RETURN: None - This had better work since there is not a return value to the user
+
+NOTES:
+*****************************************************************************************/
+VOID
+os_protectUnlock(
+ TI_HANDLE OsContext,
+ TI_HANDLE ProtectContext
+ )
+{
+#if 1 /* uncomment for work in INDIRECT mode (HwACXAccessMethod=0) */
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)OsContext;
+ spin_unlock_irqrestore(&drv->lock, drv->flags);
+#endif
+}
+
+
+/*-----------------------------------------------------------------------------
+
+Routine Name:
+
+ os_resetWakeOnGpio
+
+Routine Description:
+
+ set the GPIO to low after awaking the TNET from ELP.
+
+Arguments:
+
+ OsContext - our adapter context.
+
+
+Return Value:
+
+ None
+
+-----------------------------------------------------------------------------*/
+VOID
+os_hardResetTnetw( void )
+{
+/*
+ * Define the OMAP GPIO registers, the TNETW reset is currently connected
+ * to GPIO 16, this logic assumes that the loading code had muxed the
+ * GPIO 16 to the Y1 pinout.
+ */
+ /* direction out */
+#ifdef TIWLAN_OMAP1610
+ omap_set_gpio_direction(GPIO_16, GPIO_16_DIRECTION_OUTPUT);
+
+ /* clear reset WLAN chip */
+ omap_set_gpio_dataout(GPIO_16, GPIO_16_CLEAR);
+
+ /* wait for 50msec */
+ mdelay(50);
+ omap_set_gpio_dataout(GPIO_16, GPIO_16_SET);
+
+ /* wait for 50msec */
+ mdelay(50);
+#endif /* Dm: */
+#ifdef TIWLAN_MSM7000
+ msm_wifi_reset(1); /* Reset active */
+ msm_wifi_power(0); /* Power disable */
+ msm_wifi_power(1); /* Power enable */
+ msm_wifi_reset(0); /* Reset clear */
+#endif
+}
+
+
+#ifndef GWSI_DRIVER
+
+/****************************************************************************************
+ START OF TI DRIVER API
+*****************************************************************************************/
+
+/****************************************************************************************
+ * os_setWakeOnGpio()
+ ****************************************************************************************
+DESCRIPTION: set the GPIO to high for awaking the TNET from ELP.
+
+ARGUMENTS: OsContext - our adapter context.
+
+RETURN: None
+
+NOTES:
+*****************************************************************************************/
+VOID
+os_setWakeOnGpio(
+ TI_HANDLE OsContext
+ )
+{
+#ifdef TIWLAN_OMAP1610
+ /*
+ Clear ELP_REQ by GPIO_CLEAR_DATAOUT
+ */
+ os_resetWakeOnGpio(OsContext);
+
+ /*
+ Rising edge on ELP_REQ by GPIO_SET_DATAOUT
+ */
+ omap_writel(0x00000200, 0xFFFBBCF0);
+#endif
+}
+
+/****************************************************************************************
+ * os_resetWakeOnGpio()
+ ****************************************************************************************
+DESCRIPTION: set the GPIO to low after awaking the TNET from ELP.
+
+ARGUMENTS: OsContext - our adapter context.
+
+RETURN: None
+
+NOTES:
+*****************************************************************************************/
+VOID
+os_resetWakeOnGpio(
+ TI_HANDLE OsContext
+ )
+{
+ /*
+ Clear ELP_REQ by GPIO_CLEAR_DATAOUT
+ */
+#ifdef TIWLAN_OMAP1610
+ omap_writel(0x00000200, 0xFFFBBCB0);
+#endif
+}
+
+/****************************************************************************************
+ * _os_memorySharedFree()
+ ****************************************************************************************
+DESCRIPTION:
+
+ARGUMENTS:
+
+RETURN:
+
+NOTES:
+*****************************************************************************************/
+VOID
+_os_memorySharedFree(
+ TI_HANDLE OsContext,
+ PVOID pVirtual,
+ UINT32 Size,
+ OS_PHYSICAL_ADDRESS pPhysical
+ )
+{
+ ti_dprintf(TIWLAN_LOG_ERROR, "\n\n\n %s is not implemented\n\n\n", __FUNCTION__);
+}
+
+/****************************************************************************************
+ * _os_memorySharedAlloc()
+ ****************************************************************************************
+DESCRIPTION:
+
+ARGUMENTS:
+
+RETURN:
+
+NOTES:
+*****************************************************************************************/
+PVOID
+_os_memorySharedAlloc(
+ TI_HANDLE OsContext,
+ UINT32 Size,
+ OS_PHYSICAL_ADDRESS *pPhysical
+ )
+{
+ ti_dprintf(TIWLAN_LOG_ERROR, "\n\n\n %s is not implemented\n\n\n", __FUNCTION__);
+ return NULL;
+}
+
+/****************************************************************************************
+ * os_powerStateBusy()
+ ****************************************************************************************
+DESCRIPTION: notify to the host that the TI_WLAN application is busy.
+
+ARGUMENTS: OsContext - our adapter context.
+
+RETURN:
+
+NOTES:
+*****************************************************************************************/
+VOID
+os_powerStateBusy(
+ TI_HANDLE OsContext
+ )
+{
+#if 0
+ ti_dprintf(TIWLAN_LOG_INFO,
+ "%s(%d) - os_powerStateBusy: TI_WLAN is busy!\n",
+ __FILE__,__LINE__);
+#endif
+}
+
+/****************************************************************************************
+ * os_powerStateIdle()
+ ****************************************************************************************
+DESCRIPTION: notify to the host that the TI_WLAN application is idle.
+
+ARGUMENTS: OsContext - our adapter context.
+
+RETURN:
+
+NOTES:
+*****************************************************************************************/
+VOID
+os_powerStateIdle(
+ TI_HANDLE OsContext
+ )
+{
+#if 0
+ ti_dprintf(TIWLAN_LOG_INFO,
+ "%s(%d) - os_powerStateIdle: TI_WLAN is idle!\n",
+ __FILE__,__LINE__);
+#endif
+}
+
+/****************************************************************************************
+ * os_memoryMove()
+ ****************************************************************************************
+DESCRIPTION: Move memory block from pSource to pDestination
+
+ARGUMENTS: OsContext - Our adapter context.
+ pDestination - destination
+ pSource - source
+ Size - Number of characters
+RETURN:
+
+NOTES:
+*****************************************************************************************/
+VOID
+os_memoryMove(
+ TI_HANDLE pOsContext,
+ PVOID pDestination,
+ PVOID pSource,
+ UINT32 Size
+ )
+{
+ memmove(pDestination, pSource, Size);
+}
+
+
+/****************************************************************************************
+ * os_memoryMoveToHw()
+ ****************************************************************************************
+DESCRIPTION: This function copies data from a system-space buffer to device memory.
+
+ARGUMENTS: OsContext - Our adapter context.
+
+ pTarget - Specifies the base address within a device memory range where
+ the copy should begin.
+
+ pSource - Pointer to a system-space buffer from which this function copies
+ data to the destination range.
+
+ Size - Specifies the number of bytes to copy.
+
+RETURN: None
+
+NOTES:
+*****************************************************************************************/
+VOID
+os_memoryMoveToHw(
+ TI_HANDLE OsContext,
+ PVOID pTarget,
+ PVOID pSource,
+ UINT32 Size
+ )
+{
+ print_info("\nos_memoryMoveToHw pTarget 0x%08x pSource 0x%08x Size 0x%08x",(int)pTarget, (int)pSource,(int)Size);
+ print_info("\n-------------------------> Not Implemented <--------------------------------------------------- ");
+}
+
+/****************************************************************************************
+ * os_memoryMoveFromHw()
+ ****************************************************************************************
+DESCRIPTION: This function copies data from a system-space buffer to device memory.
+
+ARGUMENTS: OsContext - Our adapter context.
+
+ pTarget - Pointer to a system-space buffer into which this function copies
+ data from device memory.
+
+ pSource - Specifies the base virtual address within device memory from
+ which to copy the data.
+
+ Size - Specifies the number of bytes to copy.
+
+RETURN: None
+
+NOTES:
+*****************************************************************************************/
+VOID
+os_memoryMoveFromHw(
+ TI_HANDLE OsContext,
+ PVOID pTarget,
+ PVOID pSource,
+ UINT32 Size
+ )
+{
+ print_info("\nos_memoryMoveFromHw pTarget 0x%08x pSource 0x%08x Size 0x%08x",(int)pTarget, (int)pSource,(int)Size);
+ print_info("\n-------------------------> Not Implemented <--------------------------------------------------- ");
+}
+
+/****************************************************************************************
+ * os_hwReadMemRegisterUINT8()
+ ****************************************************************************************
+DESCRIPTION: Reads a UINT8 from a memory-mapped device register.
+
+ARGUMENTS: OsContext - our adapter context.
+
+ Register - Pointer to the memory-mapped register.
+
+ Data - Pointer to the caller-supplied variable in which this function
+ returns the UINT8 read from Register.
+
+RETURN: None
+
+NOTES:
+*****************************************************************************************/
+VOID
+os_hwReadMemRegisterUINT8(
+ TI_HANDLE OsContext,
+ PUCHAR Register,
+ PUINT8 Data
+ )
+{
+ *Data = *Register;
+ PRINT_REG("R8: %p=0x%x\n", Register, *Data);
+ return;
+}
+
+/****************************************************************************************
+ * os_hwWriteMemRegisterUINT16()
+ ****************************************************************************************
+DESCRIPTION: Writes a 'unsigned short' to a memory-mapped device register.
+
+ARGUMENTS: OsContext - our adapter context.
+
+ Register - Pointer to the memory-mapped register.
+
+ Data - Specifies the caller-supplied UINT16 that this function transfers
+ to the Register.
+
+RETURN: None
+
+NOTES:
+*****************************************************************************************/
+VOID
+os_hwWriteMemRegisterUINT16(
+ TI_HANDLE OsContext,
+ PUINT16 Register,
+ UINT16 Data
+ )
+{
+ PRINT_REG("W16: %p=0x%x\n", Register, Data);
+ *Register = Data;
+ return;
+}
+
+/****************************************************************************************
+ * os_hwReadMemRegisterUINT16()
+ ****************************************************************************************
+DESCRIPTION: Reads a UINT16 from a memory-mapped device register.
+
+ARGUMENTS: OsContext - our adapter context.
+
+ Register - Pointer to the memory-mapped register.
+
+ Data - Pointer to the caller-supplied variable in which this function
+ returns the UINT16 read from Register.
+
+RETURN: None
+
+NOTES:
+*****************************************************************************************/
+VOID
+os_hwReadMemRegisterUINT16(
+ TI_HANDLE OsContext,
+ PUINT16 Register,
+ PUINT16 Data
+ )
+{
+ *Data = *Register;
+ PRINT_REG("R16: %p=0x%x\n", Register, *Data);
+ return;
+}
+
+/****************************************************************************************
+ * os_hwWriteMemRegisterUINT32()
+ ****************************************************************************************
+DESCRIPTION: Writes a 'unsigned long' to a memory-mapped device register.
+
+ARGUMENTS: OsContext - our adapter context.
+
+ Register - Pointer to the memory-mapped register.
+
+ Data - Specifies the caller-supplied UINT32 that this function transfers
+ to the Register.
+
+RETURN: None
+
+NOTES:
+*****************************************************************************************/
+VOID
+os_hwWriteMemRegisterUINT32(
+ TI_HANDLE OsContext,
+ PUINT32 Register,
+ UINT32 Data
+ )
+{
+ PRINT_REG("W32: %p=0x%x\n", Register, Data);
+ *Register = Data;
+ return;
+}
+
+
+/****************************************************************************************
+ * os_hwReadMemRegisterUINT32()
+ ****************************************************************************************
+DESCRIPTION: Reads a UINT32 from a memory-mapped device register.
+
+ARGUMENTS: OsContext - our adapter context.
+
+ Register - Pointer to the memory-mapped register.
+
+ Data - Pointer to the caller-supplied variable in which this function
+ returns the UINT32 read from Register.
+
+RETURN: None
+
+NOTES:
+*****************************************************************************************/
+VOID
+os_hwReadMemRegisterUINT32(
+ TI_HANDLE OsContext,
+ PUINT32 Register,
+ PUINT32 Data
+ )
+{
+ *Data = *Register;
+ PRINT_REG("R32: %p=0x%x\n", Register, *Data);
+ return;
+}
+
+
+/****************************************************************************************
+ * os_receivePacket()
+ ****************************************************************************************
+DESCRIPTION:
+
+ARGUMENTS:
+
+RETURN:
+
+NOTES:
+*****************************************************************************************/
+BOOL
+os_receivePacket(
+ TI_HANDLE OsContext,
+ PVOID pPacket,
+ UINT16 Length
+ )
+{
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)OsContext;
+ struct sk_buff *skb;
+ mem_MSDU_T* pMsdu = (mem_MSDU_T*)pPacket;
+ mem_BD_T *pCurBd;
+ ti_nodprintf(TIWLAN_LOG_INFO, "os_receivePacket - Received EAPOL len-%d\n", pMsdu->firstBDPtr->length );
+
+ bm_trace(10, Length, 0);
+
+ if (pMsdu->firstBDPtr->length > Length) { /* Dm: Security fix */
+ ti_dprintf(TIWLAN_LOG_ERROR, " TI: %s - Security Error\n", __FUNCTION__);
+ return FALSE;
+ }
+
+ skb = dev_alloc_skb(Length+2);
+ if(!skb) {
+ print_deb(" os_receivePacket() : dev_alloc_skb failed!\n");
+ configMgr_memMngrFreeMSDU(drv->adapter.CoreHalCtx, memMgr_MsduHandle(pPacket));
+ drv->stats.rx_dropped++;
+ return FALSE;
+ }
+ skb_reserve(skb, 2);
+
+ pCurBd = pMsdu->firstBDPtr;
+ while (pCurBd) {
+ memcpy(skb_put(skb,pCurBd->length),pCurBd->data+pCurBd->dataOffset,pCurBd->length);
+ pCurBd = pCurBd->nextBDPtr;
+ }
+
+ skb->dev = drv->netdev;
+ skb->protocol = eth_type_trans(skb, drv->netdev);
+ skb->ip_summed = CHECKSUM_NONE;
+
+ drv->stats.rx_packets++;
+ drv->stats.rx_bytes += skb->len;
+
+ bm_trace(11, Length, 0);
+#ifdef CONFIG_ANDROID_POWER
+ drv->receive_packet = 1; /* Remember to stay awake */
+#endif
+ netif_rx(skb);
+
+ configMgr_memMngrFreeMSDU(drv->adapter.CoreHalCtx, memMgr_MsduHandle(pPacket));
+
+ bm_trace(12, Length, 0);
+
+ return TRUE;
+}
+
+/****************************************************************************************
+ * os_sendPacket()
+ ****************************************************************************************
+DESCRIPTION: send EAPOL packet from Supplicant
+
+ARGUMENTS:
+
+RETURN:
+
+NOTES:
+*****************************************************************************************/
+INT32
+os_sendPacket(
+ TI_HANDLE OsContext,
+ PVOID pPacket,
+ UINT16 Length
+ )
+{
+ struct net_device *dev = (struct net_device *)OsContext;
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)dev->priv;
+
+ INT32 status;
+ mem_MSDU_T* pMsdu;
+ char *pMsduData;
+ UINT32 packetHeaderLength;
+
+ ti_nodprintf(TIWLAN_LOG_INFO, "os_sendPacket - Transmit EAPOL len-%x\n",Length );
+
+ /*
+ * Allocate enough place also for 802.11 header (24 bytes) and LLC (8 bytes)
+ * to replace the Ethernet header (14 bytes)
+ */
+ if(!Length)
+ {
+ ti_dprintf(TIWLAN_LOG_ERROR, " EAPOL Packet Length = 0 \n");
+ return -1;
+ }
+ /*
+ * Retrieve the Packet Header length
+ * from QoS Manager (through configMgr) and RSN
+ */
+ packetHeaderLength = configMgr_getPacketHeaderLength(drv->adapter.CoreHalCtx,pPacket,TX_DATA_EAPOL_MSDU);
+
+ /*
+ * need to reserve enough space for header translation
+ * in the same first Bd.
+ * Allocate enough place also for 802.11 header (24 bytes or 26 for QoS) and LLC (8 bytes)
+ * to replace the Ethernet header (14 bytes)
+ */
+
+ status = configMgr_allocMSDU(drv->adapter.CoreHalCtx, &pMsdu,
+ Length + packetHeaderLength , OS_ABS_TX_MODULE);
+ if(status != OK)
+ {
+ ti_dprintf(TIWLAN_LOG_ERROR, " configMgr_allocMSDU failed !!!\n");
+ ++drv->alloc_msdu_failures;
+ return -ENOMEM;
+ }
+
+ /*
+ * case 1: only legacy wlan header
+ *
+ * case 2: only QoS wlan header
+ *
+ * case 3: only legacy wlan header with new snap
+ *
+ * case 4: only QoS wlan header with new snap
+ */
+ pMsdu->firstBDPtr->dataOffset = packetHeaderLength - ETHERNET_HDR_LEN;
+ pMsduData = pMsdu->firstBDPtr->data + pMsdu->firstBDPtr->dataOffset;
+ memcpy(pMsduData, pPacket, Length);
+ pMsdu->dataLen = Length;
+ pMsdu->firstBDPtr->length = pMsdu->dataLen + pMsdu->firstBDPtr->dataOffset;
+ pMsdu->freeFunc = 0;
+ pMsdu->freeArgs[0] = 0;
+ pMsdu->freeArgs[1] = 0;
+
+ /*
+ * Propagate Msdu through Config Manager.
+ * Set DTag to 0
+ * (note that classification is further handled in the Core)
+ */
+ status = configMgr_sendMsdu(drv->adapter.CoreHalCtx, pMsdu, 0);
+
+ return status;
+}
+
+
+#endif /* NDEF GWSI_DRIVER*/
+
+
+
+/*******************************************************************************************************
+
+ LOCAL FUNCTIONS
+
+********************************************************************************************************/
+
+/*-----------------------------------------------------------------------------
+Routine Name:
+
+ os_timer_dec_use_count
+
+Routine Description:
+
+ This function is decrements timer use count.
+ When use_count becomes 0, the timer block is destroyed
+-----------------------------------------------------------------------------*/
+static inline void os_timer_dec_use_count(timer_obj_t *tmr)
+{
+ if (unlikely(!tmr->use_count)) {
+ ti_dprintf(TIWLAN_LOG_ERROR, "\n\n\n %s: attempt to delete a deleted timer %p\n\n\n", __FUNCTION__, tmr);
+ tmr->use_count = 1;
+ }
+ if (!(--tmr->use_count))
+ os_memoryFree(tmr->req.drv, tmr, sizeof(timer_obj_t));
+}
+
+
+/*-----------------------------------------------------------------------------
+
+Routine Name:
+
+ os_tl_timerHandlr
+
+Routine Description:
+
+ This function is called in context of the control tasklet.
+ It evokes user timer handler and restarts the timer if periodic
+
+Arguments:
+ p1 - user handler
+ p2 - user parameter
+ p3 - periodic
+ p4 - jiffies
+
+Return Value:
+
+ None.
+
+Notes:
+
+-----------------------------------------------------------------------------*/
+static int os_tl_timerHandlr(struct tiwlan_req *req)
+{
+ timer_obj_t *tmr= (timer_obj_t *)req;
+ PTIMER_FUNCTION f = (PTIMER_FUNCTION)req->u.req.p1;
+ TI_HANDLE parm = (TI_HANDLE)req->u.req.p2;
+
+ esta_timer_log("%s: req=0x%x f=0x%p parm=0x%p\n", __FUNCTION__, req, f, parm);
+ ++tmr->use_count;
+ f(parm);
+ if (req->u.req.p3) /* Periodic ? */
+ mod_timer(&tmr->timer, jiffies + req->u.req.p4);
+ os_timer_dec_use_count(tmr);
+
+ return 0;
+}
+
+
+/*-----------------------------------------------------------------------------
+
+Routine Name:
+
+ os_timerHandlr
+
+Routine Description:
+
+ This function is called on timer expiration in context of
+ softIsr. It delegates the timer handling to the control tasklet.
+
+Arguments:
+ parm - timer object handle
+
+Return Value:
+
+ None.
+
+Notes:
+
+-----------------------------------------------------------------------------*/
+static void os_timerHandlr(unsigned long parm)
+{
+ timer_obj_t *tmr= (timer_obj_t *)parm;
+ tiwlan_net_dev_t *drv = tmr->req.drv;
+ unsigned long flags;
+
+ esta_timer_log("%s: drv=%p f=0x%x ctx=0x%x\n",
+ __FUNCTION__, tmr->req.drv, tmr->req.u.req.p1, tmr->req.u.req.p2);
+
+ spin_lock_irqsave(&drv->lock, flags);
+ list_del(&tmr->req.list);
+ list_add_tail(&tmr->req.list, &drv->request_q);
+ spin_unlock_irqrestore(&drv->lock, flags);
+#ifdef DM_USE_WORKQUEUE
+ /* printk("TI: %s:\t%lu\n", __FUNCTION__, jiffies); */
+ if( queue_work( drv->tiwlan_wq, &drv->tw ) != 0 ) {
+#ifdef CONFIG_ANDROID_POWER
+ android_lock_suspend( &drv->timer_wake_lock );
+#endif
+ }
+#else
+ tasklet_schedule(&drv->tl);
+#endif
+}
+
+
+/*-----------------------------------------------------------------------------
+
+Routine Name:
+
+ os_connectionStatus
+
+Routine Description:
+
+The eSTA-DK will call this API so the OS stack is aware that the
+WLAN layer is ready to function.
+
+Arguments:
+cStatus = 1; WLAN in ready for network packets
+cStatus = 0; WLAN in not ready for network packets
+
+Return Value:
+
+ None
+
+-----------------------------------------------------------------------------*/
+
+tiINT32
+os_IndicateEvent(IPC_EV_DATA* pData)
+{
+ IPC_EVENT_PARAMS * pInParam = (IPC_EVENT_PARAMS *)pData;
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)(pInParam->hUserParam);
+ /*UCHAR AuthBuf[sizeof(ULONG) + sizeof(OS_802_11_AUTHENTICATION_REQUEST)];*/
+
+ ti_nodprintf(TIWLAN_LOG_INFO, "\n os_ConnectionStatus Event 0x%08x \n", CsStatus->Event);
+
+ switch(pInParam->uEventType)
+ {
+ case IPC_EVENT_ASSOCIATED:
+ if (drv->netdev != NULL) {
+ netif_carrier_on(drv->netdev);
+#if defined(CONFIG_TROUT_PWRSINK) || defined(CONFIG_HTC_PWRSINK)
+ queue_delayed_work(drv->tiwlan_wq, &drv->trxw, 0);
+#endif
+ }
+ break;
+
+ case IPC_EVENT_DISASSOCIATED:
+ if (drv->netdev != NULL) {
+#if defined(CONFIG_TROUT_PWRSINK) || defined(CONFIG_HTC_PWRSINK)
+ unsigned percent;
+
+ cancel_delayed_work_sync(&drv->trxw);
+ percent = ( drv->started ) ? PWRSINK_WIFI_PERCENT_BASE : 0;
+#ifdef CONFIG_HTC_PWRSINK
+ htc_pwrsink_set(PWRSINK_WIFI, percent);
+#else
+ trout_pwrsink_set(PWRSINK_WIFI, percent);
+#endif
+#endif
+ netif_carrier_off(drv->netdev);
+ }
+ break;
+
+ case IPC_EVENT_LINK_SPEED:
+ drv->adapter.LinkSpeed = (*(PULONG)pData->uBuffer * 10000) / 2;
+ ti_nodprintf(TIWLAN_LOG_INFO, "\n Link Speed = 0x%08x \n",drv->adapter.LinkSpeed);
+ break;
+
+ case IPC_EVENT_AUTH_SUCC:
+/* *(PULONG)AuthBuf = os802_11StatusType_Authentication;
+ memcpy((PUCHAR)&AuthBuf[sizeof(ULONG)], pData->uBuffer,sizeof(OS_802_11_AUTHENTICATION_REQUEST));*/
+ ti_dprintf(TIWLAN_LOG_OTHER, "\n Auth Succ Event from Driver to another BSSID. \n");
+ break;
+
+ case IPC_EVENT_SCAN_COMPLETE:
+ ti_dprintf(TIWLAN_LOG_OTHER, "\n Driver Event = Scan Complete. \n");
+ break;
+
+ case IPC_EVENT_TIMEOUT:
+ ti_dprintf(TIWLAN_LOG_OTHER, "\n Driver Event = Timeout. \n");
+ break;
+
+ case IPC_EVENT_CCKM_START:
+ ti_dprintf(TIWLAN_LOG_OTHER, "\n Driver Event = IPC_EVENT_CCKM_START \n");
+ break;
+
+ default:
+ ti_dprintf(TIWLAN_LOG_ERROR, "\n Unrecognized driver event. \n");
+ break;
+
+ }
+
+ return OK;
+}
+
+
+/****************************************************************************/
+/* The following 4 functions are debug functions that enable the user
+ to set/reset GPIO_25 and GPIO_27 in the OMAP - for debug purposes.
+ Note: In order to enable GPIO_25/GPIO_27 the user must enable the define
+ TIWLAN_OMAP1610_CRTWIPP_GPIO_DEBUG in the esta_drv.c/osapi.c files. */
+
+void os_ToggleDebugGPIO(int count)
+{
+#if 0
+ int i,j;
+
+ omap_writel(0x00000200, 0xFFFBBCB0 );/* 0 */
+ for(i=0;i<count;i++)
+ {
+ omap_writel(0x00000200, 0xFFFBBCF0 );/* 1 */
+ for(j=0;j<100;j++);
+ omap_writel(0x00000200, 0xFFFBBCB0 );/* 0 */
+ for(j=0;j<100;j++);
+ }
+#endif
+}
+#ifdef TIWLAN_OMAP1610_CRTWIPP_GPIO_DEBUG
+VOID
+os_SetGpio_25(
+ TI_HANDLE OsContext
+ )
+{
+ /*
+ Setting GPIO_25 by GPIO_SET_DATAOUT
+ */
+ omap_writel(0x00000200, 0xFFFBECF0 );
+}
+
+
+VOID
+os_ResetGpio25(
+ TI_HANDLE OsContext
+ )
+{
+ /*
+ Clear GPIO_25 by GPIO_CLEAR_DATAOUT
+ */
+ omap_writel(0x00000200, 0xFFFBECB0 );
+}
+
+
+VOID
+os_SetGpio27(
+ TI_HANDLE OsContext
+ )
+{
+ /*
+ Setting GPIO_27 by GPIO_SET_DATAOUT
+ */
+ omap_writel(0x00000800, 0xFFFBECF0 );
+}
+
+
+VOID
+os_ResetGpio27(
+ TI_HANDLE OsContext
+ )
+{
+ /*
+ Clear GPIO_27 by GPIO_CLEAR_DATAOUT
+ */
+ omap_writel(0x00000800, 0xFFFBECB0 );
+}
+#endif
+/******************************************************************************/
+
+VOID
+os_disableIrq( TI_HANDLE OsContext)
+{
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)OsContext;
+ disable_irq (drv->irq);
+}
+
+VOID
+os_enableIrq( TI_HANDLE OsContext)
+{
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)OsContext;
+ enable_irq (drv->irq);
+}
+
+int
+os_getFirmwareImage(
+ TI_HANDLE OsContext,
+ PUINT8 *pBuffer,
+ PUINT32 Length,
+ UINT8 RadioType
+ )
+{
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)OsContext;
+
+ *pBuffer = drv->firmware_image.va;
+ *Length = drv->firmware_image.size;
+
+ return OK;
+}
+
+
+/*-----------------------------------------------------------------------------
+
+Routine Name:
+
+ os_getRadioImage
+
+Routine Description:
+
+
+Arguments:
+
+
+Return Value:
+
+ OK
+
+-----------------------------------------------------------------------------*/
+int
+os_getRadioImage(
+ TI_HANDLE OsContext,
+ PUINT8 *pBuffer,
+ PUINT32 Length,
+ UINT8 RadioType
+ )
+{
+
+#ifdef FIRMWARE_DYNAMIC_LOAD
+ tiwlan_net_dev_t *drv = (tiwlan_net_dev_t *)OsContext;
+
+ *pBuffer = drv->eeprom_image.va;
+ *Length = drv->eeprom_image.size;
+#else
+ extern unsigned char tiwlan_radimage[];
+ extern unsigned int sizeof_tiwlan_radimage;
+ *pBuffer = (PUINT8)tiwlan_radimage;
+ *Length = sizeof_tiwlan_radimage;
+#endif
+ ti_dprintf(TIWLAN_LOG_INFO, "%s: radio type: 0x%x\n", __FUNCTION__, RadioType);
+
+ return OK;
+}
+
+
+#ifdef DRIVER_PROFILING
+void _os_profile (TI_HANDLE OsContext, UINT32 fn, UINT32 par)
+{
+ tiwlan_profile (OsContext, fn, par);
+}
+#endif
+
+VOID
+os_closeFirmwareImage( TI_HANDLE OsContext )
+{
+ return;
+}
+
+VOID
+os_closeRadioImage( TI_HANDLE OsContext )
+{
+ return;
+}
diff --git a/sta_dk_4_0_4_32/pform/linux/src/osmemapi.c b/sta_dk_4_0_4_32/pform/linux/src/osmemapi.c
new file mode 100644
index 0000000..d22eacb
--- /dev/null
+++ b/sta_dk_4_0_4_32/pform/linux/src/osmemapi.c
@@ -0,0 +1,483 @@
+/****************************************************************************
+**+-----------------------------------------------------------------------+**
+**| |**
+**| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |**
+**| All rights reserved. |**
+**| |**
+**| Redistribution and use in source and binary forms, with or without |**
+**| modification, are permitted provided that the following conditions |**
+**| are met: |**
+**| |**
+**| * Redistributions of source code must retain the above copyright |**
+**| notice, this list of conditions and the following disclaimer. |**
+**| * Redistributions in binary form must reproduce the above copyright |**
+**| notice, this list of conditions and the following disclaimer in |**
+**| the documentation and/or other materials provided with the |**
+**| distribution. |**
+**| * Neither the name Texas Instruments nor the names of its |**
+**| contributors may be used to endorse or promote products derived |**
+**| from this software without specific prior written permission. |**
+**| |**
+**| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |**
+**| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |**
+**| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
+**| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |**
+**| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
+**| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |**
+**| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
+**| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
+**| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |**
+**| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
+**| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |**
+**| |**
+**+-----------------------------------------------------------------------+**
+****************************************************************************/
+
+
+#include "arch_ti.h"
+
+#include <linux/stddef.h>
+#include <linux/string.h>
+#include <linux/time.h>
+#include <linux/timer.h>
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/vmalloc.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/time.h>
+#include <linux/list.h>
+
+#include "osApi.h"
+#include "osTIType.h"
+#include "esta_drv.h"
+
+typedef void (*os_free)(void *);
+struct os_mem_block
+{
+ struct list_head blk_list;
+ os_free f_free;
+ __u32 size;
+ __u32 signature;
+};
+#define MEM_BLOCK_START (('m'<<24) | ('e'<<16) | ('m'<<8) | 's')
+#define MEM_BLOCK_END (('m'<<24) | ('e'<<16) | ('m'<<8) | 'e')
+
+/****************************************************************************************
+ * *
+ * OS Memory API *
+ * *
+ ****************************************************************************************/
+
+/****************************************************************************************
+ * os_memoryAlloc()
+ ****************************************************************************************
+DESCRIPTION: Allocates resident (nonpaged) system-space memory.
+
+ARGUMENTS: OsContext - our adapter context.
+ Size - Specifies the size, in bytes, to be allocated.
+
+RETURN: Pointer to the allocated memory.
+ NULL if there is insufficient memory available.
+
+NOTES: With the call to vmalloc it is assumed that this function will
+ never be called in an interrupt context. vmalloc has the potential to
+ sleep the caller while waiting for memory to become available.
+
+*****************************************************************************************/
+PVOID
+os_memoryAlloc(
+ TI_HANDLE OsContext,
+ UINT32 Size
+ )
+{
+ struct os_mem_block *blk;
+ __u32 total_size = Size + sizeof(struct os_mem_block) + sizeof(__u32);
+
+#ifdef TI_MEM_ALLOC_TRACE
+ os_printf("MTT:%s:%d ::os_memoryAlloc(0x%p, %lu) : %lu\n",__FUNCTION__, __LINE__,OsContext,Size,total_size);
+#endif
+ if( total_size < Size ) { /* Dm: Security fix */
+ return NULL;
+ }
+ /*
+ memory optimization issue. Allocate 8 kB and less from the SLAB allocator (2^n)
+ otherwise allocate from virtual pool.
+ */
+ /* 2 pages */
+ if (Size <= 2 * 4096)
+ {
+ if (in_atomic())
+ blk = kmalloc(total_size, GFP_ATOMIC);
+ else
+ blk = kmalloc(total_size, GFP_KERNEL);
+ if (!blk)
+ return NULL;
+ blk->f_free = (os_free)kfree;
+ }
+ else
+ {
+ /* We expect that the big allocations should be made outside the interrupt,
+ otherwise fail
+ */
+ if (in_atomic())
+ return NULL;
+ blk = vmalloc(total_size);
+ if (!blk)
+ return NULL;
+ blk->f_free = (os_free)vfree;
+ }
+
+ os_profile (OsContext, 4, total_size);
+
+ /*list_add(&blk->blk_list, &drv->mem_blocks);*/
+ blk->size = Size;
+ blk->signature = MEM_BLOCK_START;
+ *(__u32 *)((unsigned char *)blk + total_size - sizeof(__u32)) = MEM_BLOCK_END;
+ return (PVOID)((char *)blk + sizeof(struct os_mem_block));
+}
+
+/****************************************************************************************
+ * os_memoryPreFree()
+ ****************************************************************************************
+DESCRIPTION: Frees preallocated by the kernel memory.
+
+ARGUMENTS: ptr - pointer to memory
+*****************************************************************************************/
+void os_memoryPreFree( void *ptr )
+{
+}
+
+/****************************************************************************************
+ * os_memoryPreAlloc()
+ ****************************************************************************************
+DESCRIPTION: Gets system-space memory preallocated by kernel.
+
+ARGUMENTS: OsContext - our adapter context.
+ section - section number
+ Size - Specifies the size, in bytes, to be allocated.
+
+RETURN: Pointer to the allocated memory.
+ NULL if there is insufficient memory available.
+*****************************************************************************************/
+PVOID
+os_memoryPreAlloc(
+ TI_HANDLE OsContext,
+ int section,
+ UINT32 Size
+ )
+{
+ struct os_mem_block *blk;
+ __u32 total_size = Size + sizeof(struct os_mem_block) + sizeof(__u32);
+
+#ifdef TI_MEM_ALLOC_TRACE
+ os_printf("MTT:%s:%d ::os_memoryPreAlloc(0x%p, %lu) : %lu\n",__FUNCTION__, __LINE__,OsContext,Size,total_size);
+#endif
+ if( total_size < Size ) { /* Dm: Security fix */
+ return NULL;
+ }
+
+ blk = (struct os_mem_block *)wifi_kernel_prealloc( section, total_size );
+ if( !blk ) {
+ return os_memoryAlloc(OsContext, Size);
+ }
+ blk->f_free = (os_free)os_memoryPreFree;
+
+ os_profile (OsContext, 4, total_size);
+
+ /*list_add(&blk->blk_list, &drv->mem_blocks);*/
+ blk->size = Size;
+ blk->signature = MEM_BLOCK_START;
+ *(__u32 *)((unsigned char *)blk + total_size - sizeof(__u32)) = MEM_BLOCK_END;
+ return (PVOID)((char *)blk + sizeof(struct os_mem_block));
+}
+
+
+/****************************************************************************************
+ * os_memoryCAlloc()
+ ****************************************************************************************
+DESCRIPTION: Allocates an array in memory with elements initialized to 0.
+
+ARGUMENTS: OsContext - our adapter context.
+ Number - Number of elements
+ Size - Length in bytes of each element
+
+RETURN: None
+
+NOTES:
+*****************************************************************************************/
+PVOID
+os_memoryCAlloc(
+ TI_HANDLE OsContext,
+ UINT32 Number,
+ UINT32 Size
+ )
+{
+ PVOID pAllocatedMem;
+ ULONG MemSize;
+
+#ifdef TI_MEM_ALLOC_TRACE
+ os_printf("MTT:%s:%d ::os_memoryCAlloc(0x%p, %lu, %lu) : %lu\n",__FUNCTION__,__LINE__,OsContext,Number,Size,Number*Size);
+#endif
+ MemSize = Number * Size;
+
+ if( (Number > 0) && (Size >= (0xFFFFFFFFUL / Number)) ) { /* Dm: Security fix */
+ return NULL;
+ }
+
+ pAllocatedMem = os_memoryAlloc(OsContext, MemSize);
+
+ if(!pAllocatedMem)
+ return NULL;
+
+ memset(pAllocatedMem,0,MemSize);
+
+ return pAllocatedMem;
+}
+
+/****************************************************************************************
+ * os_memoryFree()
+ ****************************************************************************************
+DESCRIPTION: This function releases a block of memory previously allocated with the
+ os_memoryAlloc function.
+
+
+ARGUMENTS: OsContext - our adapter context.
+ pMemPtr - Pointer to the base virtual address of the allocated memory.
+ This address was returned by the os_memoryAlloc function.
+ Size - Specifies the size, in bytes, of the memory block to be released.
+ This parameter must be identical to the Length that was passed to
+ os_memoryAlloc.
+
+RETURN: None
+
+NOTES:
+*****************************************************************************************/
+VOID
+os_memoryFree(
+ TI_HANDLE OsContext,
+ PVOID pMemPtr,
+ UINT32 Size
+ )
+{
+ struct os_mem_block *blk =
+ (struct os_mem_block *)((char *)pMemPtr - sizeof(struct os_mem_block));
+
+#ifdef TI_MEM_ALLOC_TRACE
+ os_printf("MTT:%s:%d ::os_memoryFree(0x%p, 0x%p, %lu) : %d\n",__FUNCTION__,__LINE__,OsContext,pMemPtr,Size,-Size);
+#endif
+ if (blk->signature != MEM_BLOCK_START)
+ {
+ printk("\n\n%s: memory block signature is incorrect - 0x%x\n\n\n",
+ __FUNCTION__, blk->signature);
+ return;
+ }
+ *(char *)(&blk->signature) = '~';
+ if (*(__u32 *)((unsigned char *)blk + blk->size + sizeof(struct os_mem_block))
+ != MEM_BLOCK_END)
+ {
+ printk("\n\n%s: memory block corruption. Size=%u\n\n\n",
+ __FUNCTION__, blk->size);
+ }
+
+ os_profile (OsContext, 5, blk->size + sizeof(struct os_mem_block) + sizeof(__u32));
+
+ blk->f_free(blk);
+}
+
+
+/****************************************************************************************
+ * os_memorySet()
+ ****************************************************************************************
+DESCRIPTION: This function fills a block of memory with given value.
+
+ARGUMENTS: OsContext - our adapter context.
+ pMemPtr - Specifies the base address of a block of memory
+ Value - Specifies the value to set
+ Length - Specifies the size, in bytes, to copy.
+
+RETURN: None
+
+NOTES:
+*****************************************************************************************/
+VOID
+os_memorySet(
+ TI_HANDLE OsContext,
+ PVOID pMemPtr,
+ INT32 Value,
+ UINT32 Length
+ )
+{
+ memset(pMemPtr,Value,Length);
+}
+
+/****************************************************************************************
+ * _os_memoryAlloc4HwDma()
+ ****************************************************************************************
+DESCRIPTION: Allocates resident (nonpaged) system-space memory for DMA operations.
+
+ARGUMENTS: OsContext - our adapter context.
+ Size - Specifies the size, in bytes, to be allocated.
+
+RETURN: Pointer to the allocated memory.
+ NULL if there is insufficient memory available.
+
+NOTES:
+
+*****************************************************************************************/
+PVOID
+os_memoryAlloc4HwDma(
+ TI_HANDLE pOsContext,
+ UINT32 Size
+ )
+{
+ struct os_mem_block *blk;
+ __u32 total_size = Size + sizeof(struct os_mem_block) + sizeof(__u32);
+ /*
+ if the size is greater than 2 pages then we cant allocate the memory through kmalloc so the function fails
+ */
+ if (Size < 2 * OS_PAGE_SIZE)
+ {
+ blk = kmalloc(total_size, GFP_ATOMIC);
+ if (!blk)
+ return NULL;
+ blk->f_free = (os_free)kfree;
+ }
+ else
+ {
+ printk("\n\n%s: memory cant be allocated-Size = %d\n\n\n",
+ __FUNCTION__, Size);
+ return NULL;
+ }
+
+ blk->size = Size;
+ blk->signature = MEM_BLOCK_START;
+ *(__u32 *)((unsigned char *)blk + total_size - sizeof(__u32)) = MEM_BLOCK_END;
+ return (PVOID)((char *)blk + sizeof(struct os_mem_block));
+}
+
+/****************************************************************************************
+ * _os_memory4HwDmaFree()
+ ****************************************************************************************
+DESCRIPTION: This function releases a block of memory previously allocated with the
+ _os_memoryAlloc4HwDma function.
+
+
+ARGUMENTS: OsContext - our adapter context.
+ pMemPtr - Pointer to the base virtual address of the allocated memory.
+ This address was returned by the os_memoryAlloc function.
+ Size - Specifies the size, in bytes, of the memory block to be released.
+ This parameter must be identical to the Length that was passed to
+ os_memoryAlloc.
+
+RETURN: None
+
+NOTES:
+*****************************************************************************************/
+void
+os_memory4HwDmaFree(
+ TI_HANDLE pOsContext,
+ PVOID pMem_ptr,
+ UINT32 Size
+ )
+{
+ struct os_mem_block *blk =
+ (struct os_mem_block *)((char *)pMem_ptr - sizeof(struct os_mem_block));
+
+ if (blk->signature != MEM_BLOCK_START)
+ {
+ printk("\n\n%s: memory block signature is incorrect - 0x%x\n\n\n",
+ __FUNCTION__, blk->signature);
+ return;
+ }
+ *(char *)(&blk->signature) = '~';
+ if (*(__u32 *)((unsigned char *)blk + blk->size + sizeof(struct os_mem_block))
+ != MEM_BLOCK_END)
+ {
+ printk("\n\n%s: memory block corruption. Size=%u\n\n\n",
+ __FUNCTION__, blk->size);
+ }
+
+ blk->f_free(blk);
+}
+
+/****************************************************************************************
+ * os_memoryZero()
+ ****************************************************************************************
+DESCRIPTION: This function fills a block of memory with 0s.
+
+ARGUMENTS: OsContext - our adapter context.
+ pMemPtr - Specifies the base address of a block of memory
+ Length - Specifies how many bytes to fill with 0s.
+
+RETURN: None
+
+NOTES:
+*****************************************************************************************/
+VOID
+os_memoryZero(
+ TI_HANDLE OsContext,
+ PVOID pMemPtr,
+ UINT32 Length
+ )
+{
+ memset(pMemPtr,0,Length);
+}
+
+
+/****************************************************************************************
+ * os_memoryCopy()
+ ****************************************************************************************
+DESCRIPTION: This function copies a specified number of bytes from one caller-supplied
+ location to another.
+
+ARGUMENTS: OsContext - our adapter context.
+ pDstPtr - Destination buffer
+ pSrcPtr - Source buffer
+ Size - Specifies the size, in bytes, to copy.
+
+RETURN: None
+
+NOTES:
+*****************************************************************************************/
+VOID
+os_memoryCopy(
+ TI_HANDLE OsContext,
+ PVOID pDstPtr,
+ PVOID pSrcPtr,
+ UINT32 Size
+ )
+{
+ memcpy(pDstPtr,pSrcPtr,Size);
+}
+
+/****************************************************************************************
+ * os_memoryCompare()
+ ****************************************************************************************
+DESCRIPTION: Compare characters in two buffers.
+
+ARGUMENTS: OsContext - our adapter context.
+ Buf1 - First buffer
+ Buf2 - Second buffer
+ Count - Number of characters
+
+RETURN: The return value indicates the relationship between the buffers:
+ < 0 Buf1 less than Buf2
+ 0 Buf1 identical to Buf2
+ > 0 Buf1 greater than Buf2
+
+NOTES:
+*****************************************************************************************/
+INT32
+os_memoryCompare(
+ TI_HANDLE OsContext,
+ PUINT8 Buf1,
+ PUINT8 Buf2,
+ INT32 Count
+ )
+{
+ return memcmp(Buf1, Buf2, Count);
+}
diff --git a/sta_dk_4_0_4_32/pform/linux/src/proc_stat.c b/sta_dk_4_0_4_32/pform/linux/src/proc_stat.c
new file mode 100644
index 0000000..3c2c1fe
--- /dev/null
+++ b/sta_dk_4_0_4_32/pform/linux/src/proc_stat.c
@@ -0,0 +1,105 @@
+/****************************************************************************
+**+-----------------------------------------------------------------------+**
+**| |**
+**| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |**
+**| All rights reserved. |**
+**| |**
+**| Redistribution and use in source and binary forms, with or without |**
+**| modification, are permitted provided that the following conditions |**
+**| are met: |**
+**| |**
+**| * Redistributions of source code must retain the above copyright |**
+**| notice, this list of conditions and the following disclaimer. |**
+**| * Redistributions in binary form must reproduce the above copyright |**
+**| notice, this list of conditions and the following disclaimer in |**
+**| the documentation and/or other materials provided with the |**
+**| distribution. |**
+**| * Neither the name Texas Instruments nor the names of its |**
+**| contributors may be used to endorse or promote products derived |**
+**| from this software without specific prior written permission. |**
+**| |**
+**| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |**
+**| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |**
+**| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
+**| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |**
+**| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
+**| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |**
+**| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
+**| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
+**| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |**
+**| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
+**| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |**
+**| |**
+**+-----------------------------------------------------------------------+**
+****************************************************************************/
+
+
+/* Dm: #include <linux/config.h> */
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/proc_fs.h>
+
+#include "healthMonitor.h"
+#include "whalCtrl.h"
+#include "osTIType.h"
+#include "configMgr.h"
+
+int proc_stat_res_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data);
+static struct proc_dir_entry *res;
+
+int proc_stat_init(TI_HANDLE *pHandle)
+{
+ configMgr_t *pConfigManager = (configMgr_t *)pHandle;
+ res = proc_mkdir("tiwlan", NULL);
+ create_proc_read_entry("tiwlan0_proc_stat", 0, res, proc_stat_res_read_proc, pConfigManager->hHealthMonitor);
+ return 0;
+}
+
+int proc_stat_res_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+ int len=0;
+ healthMonitor_t *pHealthMonitor = (healthMonitor_t*) data;
+ WHAL_CTRL *pWhalCtrl = (WHAL_CTRL *)pHealthMonitor->hHalCtrl;
+ whalCtrl_hwStatus_t *pHwStatus = &pWhalCtrl->pHwCtrl->HwStatus;
+
+ count -= 80; /* some reserve */
+
+ len += (len<count)?sprintf(page+len,"-------------- STA Health Configuration ---------------\n"):0;
+ len += (len<count)?sprintf(page+len,"Full recovery enabled = %d\n",pHealthMonitor->bFullRecoveryEnable):0;
+ len += (len<count)?sprintf(page+len,"Timer interval = %d msec\n",pHealthMonitor->timerInterval):0;
+ len += (len<count)?sprintf(page+len,"\n"):0;
+
+
+ len += (len<count)?sprintf(page+len,"-------------- STA Health Failure Statistics ---------------\n"):0;
+ len += (len<count)?sprintf(page+len,"Health test perfomred = %d\n",pHealthMonitor->numOfHealthTests):0;
+ len += (len<count)?sprintf(page+len,"Full recovery performed = %d\n",pHealthMonitor->numOfRecoveryPerformed):0;
+ len += (len<count)?sprintf(page+len,"No scan complete failure = %d\n",pHealthMonitor->recoveryTriggersNumber[ NO_SCAN_COMPLETE_FAILURE ]):0;
+ len += (len<count)?sprintf(page+len,"Mailbox failure = %d\n",pHealthMonitor->recoveryTriggersNumber[ MBOX_FAILURE ]):0;
+ len += (len<count)?sprintf(page+len,"HW awake failure = %d\n",pHealthMonitor->recoveryTriggersNumber[ HW_AWAKE_FAILURE ]):0;
+ len += (len<count)?sprintf(page+len,"Bus error = %d\n",pHealthMonitor->recoveryTriggersNumber[ BUS_ERROR ]):0;
+ len += (len<count)?sprintf(page+len,"Device error = %d\n",pHealthMonitor->recoveryTriggersNumber[ DEVICE_ERROR ]):0;
+ len += (len<count)?sprintf(page+len,"Tx Stuck Errors = %d\n",pHealthMonitor->recoveryTriggersNumber[ TX_STUCK ]):0;
+ len += (len<count)?sprintf(page+len,"Disconnect timeouts = %d\n",pHealthMonitor->recoveryTriggersNumber[ DISCONNECT_TIMEOUT ]):0;
+ len += (len<count)?sprintf(page+len,"Power save failures = %d\n",pHealthMonitor->recoveryTriggersNumber[ POWER_SAVE_FAILURE ]):0;
+ len += (len<count)?sprintf(page+len,"measurement failures = %d\n",pHealthMonitor->recoveryTriggersNumber[ MEASUREMENT_FAILURE ]):0;
+
+ len += (len<count)?sprintf(page+len,"--------------- whalCtrl_PrintHwStatus ---------------\n\n"):0;
+ len += (len<count)?sprintf(page+len,"NumMboxErrDueToPeriodicBuiltInTestCheck = %d\n", pHwStatus->NumMboxErrDueToPeriodicBuiltInTestCheck):0;
+ len += (len<count)?sprintf(page+len,"NumMboxFailures = %d\n", pHwStatus->NumMboxFailures):0;
+ len += (len<count)?sprintf(page+len, "\n"):0;
+ *eof = 1;
+ return len;
+}
+
+int proc_stat_destroy(void)
+{
+ remove_proc_entry("tiwlan0_proc_stat", res);
+ remove_proc_entry("tiwlan", NULL);
+ return 0;
+}
+
+
+
+
+
diff --git a/sta_dk_4_0_4_32/pform/linux/src/stack_profile.c b/sta_dk_4_0_4_32/pform/linux/src/stack_profile.c
new file mode 100644
index 0000000..fbe5839
--- /dev/null
+++ b/sta_dk_4_0_4_32/pform/linux/src/stack_profile.c
@@ -0,0 +1,87 @@
+/****************************************************************************
+**+-----------------------------------------------------------------------+**
+**| |**
+**| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |**
+**| All rights reserved. |**
+**| |**
+**| Redistribution and use in source and binary forms, with or without |**
+**| modification, are permitted provided that the following conditions |**
+**| are met: |**
+**| |**
+**| * Redistributions of source code must retain the above copyright |**
+**| notice, this list of conditions and the following disclaimer. |**
+**| * Redistributions in binary form must reproduce the above copyright |**
+**| notice, this list of conditions and the following disclaimer in |**
+**| the documentation and/or other materials provided with the |**
+**| distribution. |**
+**| * Neither the name Texas Instruments nor the names of its |**
+**| contributors may be used to endorse or promote products derived |**
+**| from this software without specific prior written permission. |**
+**| |**
+**| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |**
+**| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |**
+**| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
+**| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |**
+**| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
+**| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |**
+**| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
+**| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
+**| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |**
+**| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
+**| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |**
+**| |**
+**+-----------------------------------------------------------------------+**
+****************************************************************************/
+
+
+#include <linux/stddef.h>
+
+unsigned long check_stack(unsigned long *base)
+{
+
+ register unsigned long sp asm ("sp");
+ unsigned long retval = sp;
+ *base = ((sp & ~0x1fff) + 0x380);
+ return retval;
+}
+
+unsigned long check_stack_start(unsigned long *base)
+{
+ unsigned long i;
+ unsigned long from,to;
+
+ to = check_stack(&from);
+ *base = from;
+
+ /* run from the stack pointer down to the base */
+ for (i = from;i<to;i+=4)
+ {
+ /* fill up the pattern */
+ *(long *)i = 0xdeadbeef;
+ }
+/* printk("check_stack_start: from =%x to=%x data=%x\n",from,to,*(long *)(from+4));*/
+ return to;
+}
+
+unsigned long check_stack_stop(unsigned long *base)
+{
+ unsigned long i;
+ unsigned long from,to;
+
+ to = check_stack(&from);
+ *base = from;
+
+ /* run from the stack pointer down to the base */
+ for (i = from;i<to;i+=4)
+ {
+ /* check up the pattern */
+ if ((*(long *)i) != 0xdeadbeef)
+ break;
+ }
+
+ /*printk("check_stack_stop: from =%x to=%x data=%x data=%x i=0x%x\n",from,to,*(long *)from,*(long *)(from+4),i);*/
+ /* return the first time when the pattern doesn't match */
+ return i;
+}
+
+
diff --git a/sta_dk_4_0_4_32/pform/linux/src/string.c b/sta_dk_4_0_4_32/pform/linux/src/string.c
new file mode 100644
index 0000000..9b22807
--- /dev/null
+++ b/sta_dk_4_0_4_32/pform/linux/src/string.c
@@ -0,0 +1,69 @@
+/****************************************************************************
+**+-----------------------------------------------------------------------+**
+**| |**
+**| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |**
+**| All rights reserved. |**
+**| |**
+**| Redistribution and use in source and binary forms, with or without |**
+**| modification, are permitted provided that the following conditions |**
+**| are met: |**
+**| |**
+**| * Redistributions of source code must retain the above copyright |**
+**| notice, this list of conditions and the following disclaimer. |**
+**| * Redistributions in binary form must reproduce the above copyright |**
+**| notice, this list of conditions and the following disclaimer in |**
+**| the documentation and/or other materials provided with the |**
+**| distribution. |**
+**| * Neither the name Texas Instruments nor the names of its |**
+**| contributors may be used to endorse or promote products derived |**
+**| from this software without specific prior written permission. |**
+**| |**
+**| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |**
+**| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |**
+**| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
+**| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |**
+**| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
+**| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |**
+**| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
+**| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
+**| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |**
+**| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
+**| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |**
+**| |**
+**+-----------------------------------------------------------------------+**
+****************************************************************************/
+
+
+/**
+ * memcmp - Compare two areas of memory
+ * @cs: One area of memory
+ * @ct: Another area of memory
+ * @count: The size of the area.
+ */
+int memcmp(const void * cs,const void * ct, unsigned int count)
+{
+ const unsigned char *su1, *su2;
+ int res = 0;
+
+ for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
+ if ((res = *su1 - *su2) != 0)
+ break;
+ return res;
+}
+
+/**
+ * strcmp - Compare two strings
+ * @cs: One string
+ * @ct: Another string
+ */
+int strcmp(const char * cs,const char * ct)
+{
+ register signed char __res;
+
+ while (1) {
+ if ((__res = *cs - *ct++) != 0 || !*cs++)
+ break;
+ }
+
+ return __res;
+}
diff --git a/sta_dk_4_0_4_32/pform/linux/src/tiwlan_profile.c b/sta_dk_4_0_4_32/pform/linux/src/tiwlan_profile.c
new file mode 100644
index 0000000..fca59ea
--- /dev/null
+++ b/sta_dk_4_0_4_32/pform/linux/src/tiwlan_profile.c
@@ -0,0 +1,344 @@
+/****************************************************************************
+**+-----------------------------------------------------------------------+**
+**| |**
+**| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |**
+**| All rights reserved. |**
+**| |**
+**| Redistribution and use in source and binary forms, with or without |**
+**| modification, are permitted provided that the following conditions |**
+**| are met: |**
+**| |**
+**| * Redistributions of source code must retain the above copyright |**
+**| notice, this list of conditions and the following disclaimer. |**
+**| * Redistributions in binary form must reproduce the above copyright |**
+**| notice, this list of conditions and the following disclaimer in |**
+**| the documentation and/or other materials provided with the |**
+**| distribution. |**
+**| * Neither the name Texas Instruments nor the names of its |**
+**| contributors may be used to endorse or promote products derived |**
+**| from this software without specific prior written permission. |**
+**| |**
+**| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |**
+**| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |**
+**| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
+**| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |**
+**| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
+**| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |**
+**| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
+**| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
+**| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |**
+**| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
+**| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |**
+**| |**
+**+-----------------------------------------------------------------------+**
+****************************************************************************/
+
+
+
+#include "esta_drv.h"
+
+
+static void tiwlan_profile_bus_access_start (void *os, unsigned);
+static void tiwlan_profile_bus_access_end (void *os, unsigned);
+static void tiwlan_profile_driver_entry_start (void *os, unsigned);
+static void tiwlan_profile_driver_entry_end (void *os, unsigned);
+static void tiwlan_profile_memory_alloc (void *os, unsigned);
+static void tiwlan_profile_memory_free (void *os, unsigned);
+static void tiwlan_profile_buf_alloc (void * os, unsigned);
+static void tiwlan_profile_timer_create (void * os, unsigned);
+static void tiwlan_profile_timer_destroy (void * os, unsigned);
+
+
+int tiwlan_profile_create (tiwlan_net_dev_t *drv)
+{
+ drv->fpro [0] = NULL;
+ drv->fpro [1] = NULL;
+ drv->fpro [2] = NULL;
+ drv->fpro [3] = NULL;
+ drv->fpro [4] = tiwlan_profile_memory_alloc;
+ drv->fpro [5] = tiwlan_profile_memory_free;
+ drv->fpro [6] = tiwlan_profile_timer_create;
+ drv->fpro [7] = tiwlan_profile_timer_destroy;
+ drv->fpro [8] = tiwlan_profile_buf_alloc;
+
+ drv->cpu_usage_estimator_start_time = 0;
+ drv->cpu_usage_estimator_stop_time = 0;
+ drv->max_heap_bytes_allocated = 0;
+ drv->max_buf_bytes_allocated = 0;
+ drv->cur_heap_bytes_allocated = 0;
+ drv->max_number_of_timers = 0;
+ drv->cur_number_of_timers = 0;
+
+ return 0;
+}
+
+
+/* Call register profiler banchmark */
+int tiwlan_profile (tiwlan_net_dev_t *drv, unsigned bm, unsigned par)
+{
+ if (drv && bm < MAX_PROFILE_BM && drv->fpro [bm])
+ {
+ (*drv->fpro [bm]) (drv, par);
+ }
+
+ return 0;
+}
+
+
+/* Stop CPU estimation for a driver entry and maintains the resolution of the estimator */
+void tiwlan_profile_bus_access_start (void * os, unsigned par)
+{
+ tiwlan_net_dev_t * drv = (tiwlan_net_dev_t *) os;
+
+ if (drv != NULL)
+ {
+ /* Save the current entry's start time */
+ drv->bus_driver_entry_start_time = os_timeStampUs (drv);
+ }
+}
+
+
+/* Starts CPU estimation for a bus driver entry */
+void tiwlan_profile_bus_access_end (void * os, unsigned par)
+{
+ tiwlan_net_dev_t * drv = (tiwlan_net_dev_t *) os;
+ unsigned current_entry_cpu_usage;
+
+ if (drv != NULL)
+ {
+ /* Save the current entry's start time */
+ current_entry_cpu_usage = os_timeStampUs (drv) - drv->bus_driver_entry_start_time;
+
+ /* Make sure that it is not a negative value */
+ if ((int)current_entry_cpu_usage < 0)
+ {
+ printk("\n\n%s: cpu usage estimation corrupted. entry_start=%u, entry_cpu_time = %d\n\n\n",
+ __FUNCTION__, drv->bus_driver_entry_start_time, current_entry_cpu_usage);
+ }
+ /* Update the total time of driver CPU usage */
+ else
+ {
+ drv->total_us_of_bus_access_cpu_time += current_entry_cpu_usage;
+ }
+ }
+}
+
+
+/* Starts CPU estimation for a driver entry */
+void tiwlan_profile_driver_entry_start (void * os, unsigned par)
+{
+ tiwlan_net_dev_t * drv = (tiwlan_net_dev_t *) os;
+
+ if (drv != NULL)
+ {
+ drv->driver_entry_start_time = os_timeStampUs (drv);
+ }
+}
+
+
+/* Stop CPU estimation for a driver entry and maintains the resolution of the estimator */
+void tiwlan_profile_driver_entry_end (void * os, unsigned par)
+{
+ tiwlan_net_dev_t * drv = (tiwlan_net_dev_t *) os;
+ unsigned current_entry_cpu_usage, driver_entry_end_time;
+
+ if (drv == NULL)
+ return;
+
+ /* Get the current entry's end time */
+ driver_entry_end_time = os_timeStampUs (drv);
+
+ /* Calculate the current entries CPU run time */
+ current_entry_cpu_usage = driver_entry_end_time - drv->driver_entry_start_time;
+
+ /* Make sure that it is not a negative value */
+ if ((int)current_entry_cpu_usage < 0)
+ {
+ printk("\n\n%s: cpu usage estimation corrupted. entry_start=%u, entry_end=%u, entry_cpu_time = %d\n\n\n",
+ __FUNCTION__, drv->driver_entry_start_time, driver_entry_end_time, current_entry_cpu_usage);
+ }
+ /* Update the total time of driver CPU usage */
+ else
+ {
+ drv->total_us_of_cpu_time += current_entry_cpu_usage;
+ }
+}
+
+
+void tiwlan_profile_memory_alloc (void * os, unsigned size)
+{
+ tiwlan_net_dev_t * drv = (tiwlan_net_dev_t *) os;
+
+ if (drv != NULL)
+ {
+ /* Increase current heap allocation counter */
+ drv->cur_heap_bytes_allocated += size;
+ /* Update maximum if execceded */
+ if (drv->max_heap_bytes_allocated < drv->cur_heap_bytes_allocated)
+ {
+ drv->max_heap_bytes_allocated = drv->cur_heap_bytes_allocated;
+ }
+ }
+}
+
+
+void tiwlan_profile_memory_free (void * os, unsigned size)
+{
+ tiwlan_net_dev_t * drv = (tiwlan_net_dev_t *) os;
+
+ if (drv != NULL)
+ {
+ /* Decrease amount from heap allocation counter */
+ drv->cur_heap_bytes_allocated -= size;
+ /* Check for overflow */
+ if ((int)drv->cur_heap_bytes_allocated < 0)
+ {
+ printk("\n\n%s: memory heap allocation calculation corrupted. Size=%u, Current allocation = %d\n\n\n",
+ __FUNCTION__, size, drv->cur_heap_bytes_allocated);
+ drv->cur_heap_bytes_allocated = 0;
+ }
+ }
+}
+
+
+void tiwlan_profile_buf_alloc (void * os, unsigned size)
+{
+ tiwlan_net_dev_t * drv = (tiwlan_net_dev_t *) os;
+
+ if (drv != NULL)
+ {
+ drv->max_buf_bytes_allocated += size;
+ }
+}
+
+
+void tiwlan_profile_timer_create (void * os, unsigned par)
+{
+ tiwlan_net_dev_t * drv = (tiwlan_net_dev_t *) os;
+
+ if (drv)
+ {
+ /* Increase the current active timer counter */
+ drv->cur_number_of_timers ++;
+ /* Update maximum if execceded */
+ if (drv->max_number_of_timers < drv->cur_number_of_timers)
+ {
+ drv->max_number_of_timers = drv->cur_number_of_timers;
+ }
+ }
+}
+
+
+void tiwlan_profile_timer_destroy (void * os, unsigned par)
+{
+ tiwlan_net_dev_t * drv = (tiwlan_net_dev_t *) os;
+
+ if (drv)
+ {
+ /* Decrease the current active timer counter */
+ drv->cur_number_of_timers --;
+ }
+}
+
+
+/*
+ * Start CPU estimator
+ * NOTE: this function does not run in a driver context
+ */
+int tiwlan_profile_cpu_usage_estimator_start (tiwlan_net_dev_t * drv, unsigned int resolution)
+{
+ /*
+ * Reset estimation parameters - no need for spin lock since
+ * estimator is not running
+ */
+ drv->total_us_of_cpu_time = 0;
+ drv->total_us_of_bus_access_cpu_time = 0;
+ drv->cpu_usage_estimator_start_time = os_timeStampUs (drv);
+ drv->cpu_usage_estimator_stop_time = 0;
+
+ /* Set the new resolution */
+ drv->cpu_usage_estimator_resolution = resolution;
+
+ /* Register profiler banchmarks */
+ drv->fpro [0] = tiwlan_profile_driver_entry_start;
+ drv->fpro [1] = tiwlan_profile_driver_entry_end;
+ drv->fpro [2] = tiwlan_profile_bus_access_start;
+ drv->fpro [3] = tiwlan_profile_bus_access_end;
+
+ return 0;
+}
+
+
+/*
+ * Stop CPU estimator and save the last CPU estimation
+ * NOTE: this function does not run in a driver context
+ */
+int tiwlan_profile_cpu_usage_estimator_stop (tiwlan_net_dev_t * drv)
+{
+ drv->cpu_usage_estimator_stop_time = os_timeStampUs (drv);
+
+ /* Unregister profiler banchmarks */
+ drv->fpro [0] = NULL;
+ drv->fpro [1] = NULL;
+ drv->fpro [2] = NULL;
+ drv->fpro [3] = NULL;
+
+ return 0;
+}
+
+
+/*
+ * Reset CPU estimation
+ * NOTE: this function is not run in a driver context
+ */
+int tiwlan_profile_cpu_usage_estimator_reset (tiwlan_net_dev_t * drv)
+{
+ /* Reset accumulated driver time and the last estimation */
+ drv->total_us_of_cpu_time = 0;
+ drv->total_us_of_bus_access_cpu_time = 0;
+ drv->cpu_usage_estimator_start_time = 0;
+ drv->cpu_usage_estimator_stop_time = 0;
+
+ return 0;
+}
+
+
+/* Print to the screen the latest resource usage and CPU estimation */
+int tiwlan_profile_report (tiwlan_net_dev_t *drv)
+{
+ unsigned total_time, drv_cpu_usage = 0, bus_cpu_usage = 0;
+
+ printk ("\nDriver Resource Usage");
+ printk ("\n=====================");
+ printk ("\nMaximum Heap Memory Allocated: %u (bytes)", drv->max_heap_bytes_allocated);
+ printk ("\nCurrent Heap Memory Allocated: %u (bytes)", drv->cur_heap_bytes_allocated);
+ printk ("\nBuffer Memory Allocated: %u (bytes)", drv->max_buf_bytes_allocated);
+ printk ("\nFirmware Image Memory Allocated: %u (bytes)", (unsigned)drv->firmware_image.size);
+ printk ("\nEEPROM Image Memory Allocated: %u (bytes)", (unsigned)drv->eeprom_image.size);
+ printk ("\nMaximum Active Timers: %u", drv->max_number_of_timers);
+ printk ("\nCurrent Active Timers: %u", drv->cur_number_of_timers);
+
+ /* Check that the estimation has been started and stopped stopped */
+ if (drv->cpu_usage_estimator_stop_time != 0)
+ {
+ total_time = drv->cpu_usage_estimator_stop_time - drv->cpu_usage_estimator_start_time;
+
+ total_time /= 100;
+
+ if ((int)total_time > 0)
+ {
+ drv_cpu_usage = drv->total_us_of_cpu_time / total_time;
+ bus_cpu_usage = drv->total_us_of_bus_access_cpu_time / total_time;
+
+ printk ("\nTotal Test Run Time: %u (usec)", total_time);
+ printk ("\nTotal Driver Run Time: %u (usec)", drv->total_us_of_cpu_time);
+ printk ("\nTotal Bus Access Time: %u (usec)", drv->total_us_of_bus_access_cpu_time);
+ printk ("\nTotal CPU Usage: %u%%", drv_cpu_usage);
+ printk ("\nBus Access CPU Usage: %u%%", bus_cpu_usage);
+ printk ("\n");
+ }
+ }
+
+ return 0;
+}
+
diff --git a/sta_dk_4_0_4_32/pform/linux/src/tiwlan_profile.h b/sta_dk_4_0_4_32/pform/linux/src/tiwlan_profile.h
new file mode 100644
index 0000000..b9bb34f
--- /dev/null
+++ b/sta_dk_4_0_4_32/pform/linux/src/tiwlan_profile.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+**+-----------------------------------------------------------------------+**
+**| |**
+**| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |**
+**| All rights reserved. |**
+**| |**
+**| Redistribution and use in source and binary forms, with or without |**
+**| modification, are permitted provided that the following conditions |**
+**| are met: |**
+**| |**
+**| * Redistributions of source code must retain the above copyright |**
+**| notice, this list of conditions and the following disclaimer. |**
+**| * Redistributions in binary form must reproduce the above copyright |**
+**| notice, this list of conditions and the following disclaimer in |**
+**| the documentation and/or other materials provided with the |**
+**| distribution. |**
+**| * Neither the name Texas Instruments nor the names of its |**
+**| contributors may be used to endorse or promote products derived |**
+**| from this software without specific prior written permission. |**
+**| |**
+**| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |**
+**| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |**
+**| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
+**| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |**
+**| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
+**| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |**
+**| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
+**| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
+**| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |**
+**| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
+**| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |**
+**| |**
+**+-----------------------------------------------------------------------+**
+****************************************************************************/
+
+
+#ifndef TIWLAN_PROFILE
+#define TIWLAN_PROFILE
+
+#ifdef DRIVER_PROFILING
+
+int tiwlan_profile_create (tiwlan_net_dev_t *drv);
+int tiwlan_profile_cpu_usage_estimator_start (tiwlan_net_dev_t * drv, unsigned int resolution);
+int tiwlan_profile_cpu_usage_estimator_stop (tiwlan_net_dev_t * drv);
+int tiwlan_profile_cpu_usage_estimator_reset (tiwlan_net_dev_t * drv);
+int tiwlan_profile_report (tiwlan_net_dev_t * drv);
+int tiwlan_profile (tiwlan_net_dev_t * drv, unsigned bm, unsigned par);
+
+
+#endif
+
+#endif
diff --git a/sta_dk_4_0_4_32/pform/linux/src/tnetw_sdio.c b/sta_dk_4_0_4_32/pform/linux/src/tnetw_sdio.c
new file mode 100755
index 0000000..bc88b9c
--- /dev/null
+++ b/sta_dk_4_0_4_32/pform/linux/src/tnetw_sdio.c
@@ -0,0 +1,235 @@
+/* tnetw_sdio.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Copyright © Texas Instruments Incorporated (Oct 2005)
+ * THIS CODE/PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
+ * EITHER EXPRESS OR IMPLIED, INCLUDED BUT NOT LIMITED TO , THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ * This program has been modified from its original operation by Texas
+ * Instruments Incorporated. These changes are covered under version 2
+ * of the GNU General Public License, dated June 1991.
+ *
+ * Copyright © Google Inc (Feb 2008)
+ */
+/*-------------------------------------------------------------------*/
+#ifdef TIWLAN_MSM7000
+#include <linux/delay.h>
+#include <linux/mmc/core.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+#include "esta_drv.h"
+#include "mmc_omap_api.h"
+#include "osApi.h"
+#define DM_DMA_WORKAROUND
+/*-------------------------------------------------------------------*/
+extern int tiwlan_sdio_init(struct sdio_func *func);
+extern int sdio_reset_comm(struct mmc_card *card);
+/*-------------------------------------------------------------------*/
+static struct sdio_func *tiwlan_func = NULL;
+static int sdio_reset_flag = 0;
+#ifdef DM_DMA_WORKAROUND
+#define DMA_THRESHOLD_SIZE 64
+static void *sdio_dma_ptr = NULL;
+#endif
+/*-------------------------------------------------------------------*/
+void SDIO_SetFunc( struct sdio_func *func )
+{
+ tiwlan_func = func;
+}
+
+struct sdio_func *SDIO_GetFunc( void )
+{
+ return( tiwlan_func );
+}
+
+SDIO_Status SDIO_Init(SDIO_ConfigParams *ConfigParams, SDIO_Handle *Handle)
+{
+ if( Handle == NULL ) {
+ printk(KERN_ERR "Error: SDIO_Init() called with NULL!\n");
+ return SDIO_FAILURE;
+ }
+ *Handle = (SDIO_Handle)SDIO_GetFunc();
+ if( (*Handle) == NULL ) {
+ printk(KERN_ERR "Error: SDIO_Init() called before SDIO probe completed!\n");
+ return SDIO_FAILURE;
+ }
+#ifdef DM_DMA_WORKAROUND
+ if( !sdio_dma_ptr ) {
+ sdio_dma_ptr = kmalloc( PAGE_SIZE, GFP_KERNEL );
+ if( !sdio_dma_ptr )
+ return SDIO_FAILURE;
+ }
+#endif
+ return SDIO_SUCCESS;
+}
+
+SDIO_Status SDIO_Shutdown(SDIO_Handle Handle)
+{
+ /* printk("%s:\n", __FUNCTION__); */
+#ifdef DM_DMA_WORKAROUND
+ if( sdio_dma_ptr ) {
+ kfree( sdio_dma_ptr );
+ sdio_dma_ptr = NULL;
+ }
+#endif
+ return SDIO_SUCCESS;
+}
+
+SDIO_Status SDIO_Start(SDIO_Handle Handle)
+{
+ struct sdio_func *func = (struct sdio_func *)Handle;
+
+ /* printk("%s:\n", __FUNCTION__); */
+ if( func ) {
+ if( sdio_reset_flag ) {
+ sdio_reset_flag = 0;
+ if( tiwlan_sdio_init(func) ) {
+ printk("TI: tiwlan_sdio_init Error !\n");
+ return SDIO_FAILURE;
+ }
+ }
+ }
+ return SDIO_SUCCESS;
+}
+
+SDIO_Status SDIO_Reset(SDIO_Handle Handle)
+{
+ struct sdio_func *func = (struct sdio_func *)Handle;
+
+ /* printk("%s:\n", __FUNCTION__); */
+ if( func && func->card ) {
+ sdio_reset_comm(func->card);
+ }
+ return SDIO_SUCCESS;
+}
+
+SDIO_Status SDIO_Stop(SDIO_Handle Handle, unsigned long Wait_Window)
+{
+ /* printk("%s:\n", __FUNCTION__); */
+ sdio_reset_flag = 1;
+ return SDIO_Reset( Handle );
+}
+
+static int read_direct(struct sdio_func *func, unsigned char *buf,
+ unsigned long addr, unsigned len)
+{
+ unsigned i;
+ int rc0, rc = 0;
+
+ for(i=0;( i < len );i++,addr++) {
+ *buf++ = (unsigned char)sdio_readb(func, addr, &rc0);
+ if( rc0 != 0 )
+ rc = rc0;
+ }
+ return rc;
+}
+
+static int write_direct(struct sdio_func *func, unsigned long addr,
+ unsigned char *buf, unsigned len)
+{
+ unsigned i;
+ int rc0, rc = 0;
+
+ for(i=0;( i < len );i++,addr++) {
+ sdio_writeb(func, *buf++, addr, &rc0);
+ if( rc0 != 0 )
+ rc = rc0;
+ }
+ return rc;
+}
+
+SDIO_Status SDIO_SyncRead(SDIO_Handle Handle, SDIO_Request_t *Req)
+{
+ struct sdio_func *func = (struct sdio_func *)Handle;
+ int rc, retries = 5;
+
+#if 0
+ printk("%s: p_addr = 0x%.8lx, sz = %d\n",
+ __FUNCTION__,
+ Req->peripheral_addr,
+ Req->buffer_len);
+#endif
+
+ while(retries) {
+ if( retries > 2 )
+#ifdef DM_DMA_WORKAROUND
+ if( Req->buffer_len < DMA_THRESHOLD_SIZE ) {
+ rc = sdio_memcpy_fromio(func, Req->buffer, Req->peripheral_addr, Req->buffer_len);
+ }
+ else {
+ rc = sdio_memcpy_fromio(func, sdio_dma_ptr, Req->peripheral_addr, Req->buffer_len);
+ memcpy( Req->buffer, sdio_dma_ptr, Req->buffer_len );
+ }
+#else
+ rc = sdio_memcpy_fromio(func, Req->buffer, Req->peripheral_addr, Req->buffer_len);
+#endif
+ else
+ rc = read_direct(func, Req->buffer, Req->peripheral_addr, Req->buffer_len);
+
+ if (rc) {
+ printk(KERN_ERR "%s: Read operation failed (%d) (retries = %d)\n",
+ __FUNCTION__, rc, retries);
+ retries--;
+ continue;
+ }
+ if (retries != 5)
+ printk(KERN_ERR "%s: Retry succeeded\n", __FUNCTION__);
+ return SDIO_SUCCESS;
+ }
+ printk(KERN_ERR "%s: Giving up\n", __FUNCTION__);
+ return SDIO_FAILURE;
+}
+
+SDIO_Status SDIO_SyncWrite(SDIO_Handle Handle, SDIO_Request_t *Req)
+{
+ struct sdio_func *func = (struct sdio_func *)Handle;
+ int rc, retries = 5;
+#ifdef DM_DMA_WORKAROUND
+ void *dma_ptr;
+#endif
+
+#if 0
+ printk("%s: p_addr = 0x%.8lx, sz = %d\n",
+ __FUNCTION__,
+ Req->peripheral_addr,
+ Req->buffer_len);
+#endif
+
+ while(retries) {
+ if( retries > 2 ) {
+#ifdef DM_DMA_WORKAROUND
+ if( Req->buffer_len < DMA_THRESHOLD_SIZE ) {
+ dma_ptr = Req->buffer;
+ }
+ else {
+ dma_ptr = sdio_dma_ptr;
+ memcpy( dma_ptr, Req->buffer, Req->buffer_len );
+ }
+ rc = sdio_memcpy_toio(func, Req->peripheral_addr, dma_ptr, Req->buffer_len);
+#else
+ rc = sdio_memcpy_toio(func, Req->peripheral_addr, Req->buffer, Req->buffer_len);
+#endif
+ }
+ else
+ rc = write_direct(func, Req->peripheral_addr, Req->buffer, Req->buffer_len);
+
+ if (rc) {
+ printk(KERN_ERR "%s: Write operation failed (%d) (retries = %d)\n",
+ __FUNCTION__, rc, retries);
+ retries--;
+ continue;
+ }
+
+ if (retries != 5)
+ printk(KERN_ERR "%s: Retry succeeded\n", __FUNCTION__);
+ return SDIO_SUCCESS;
+ }
+ printk(KERN_ERR "%s: Giving up\n", __FUNCTION__);
+ return SDIO_FAILURE;
+}
+#endif