blob: 8cd24766b03c48ecbbfa475f0fe4f723cc4d021e [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* linux/arch/arm/mach-msm/board-mahimahi-wifi.c
2*/
3#include <linux/kernel.h>
4#include <linux/init.h>
5#include <linux/platform_device.h>
6#include <linux/delay.h>
7#include <linux/err.h>
8#include <asm/mach-types.h>
9#include <asm/gpio.h>
10#include <asm/io.h>
11#include <linux/skbuff.h>
12#include <linux/wlan_plat.h>
13
14#include "board-mahimahi.h"
15
16int mahimahi_wifi_power(int on);
17int mahimahi_wifi_reset(int on);
18int mahimahi_wifi_set_carddetect(int on);
19
20#define PREALLOC_WLAN_NUMBER_OF_SECTIONS 4
21#define PREALLOC_WLAN_NUMBER_OF_BUFFERS 160
22#define PREALLOC_WLAN_SECTION_HEADER 24
23
24#define WLAN_SECTION_SIZE_0 (PREALLOC_WLAN_NUMBER_OF_BUFFERS * 128)
25#define WLAN_SECTION_SIZE_1 (PREALLOC_WLAN_NUMBER_OF_BUFFERS * 128)
26#define WLAN_SECTION_SIZE_2 (PREALLOC_WLAN_NUMBER_OF_BUFFERS * 512)
27#define WLAN_SECTION_SIZE_3 (PREALLOC_WLAN_NUMBER_OF_BUFFERS * 1024)
28
29#define WLAN_SKB_BUF_NUM 16
30
31static struct sk_buff *wlan_static_skb[WLAN_SKB_BUF_NUM];
32
33typedef struct wifi_mem_prealloc_struct {
34 void *mem_ptr;
35 unsigned long size;
36} wifi_mem_prealloc_t;
37
38static wifi_mem_prealloc_t wifi_mem_array[PREALLOC_WLAN_NUMBER_OF_SECTIONS] = {
39 { NULL, (WLAN_SECTION_SIZE_0 + PREALLOC_WLAN_SECTION_HEADER) },
40 { NULL, (WLAN_SECTION_SIZE_1 + PREALLOC_WLAN_SECTION_HEADER) },
41 { NULL, (WLAN_SECTION_SIZE_2 + PREALLOC_WLAN_SECTION_HEADER) },
42 { NULL, (WLAN_SECTION_SIZE_3 + PREALLOC_WLAN_SECTION_HEADER) }
43};
44
45static void *mahimahi_wifi_mem_prealloc(int section, unsigned long size)
46{
47 if (section == PREALLOC_WLAN_NUMBER_OF_SECTIONS)
48 return wlan_static_skb;
49 if ((section < 0) || (section > PREALLOC_WLAN_NUMBER_OF_SECTIONS))
50 return NULL;
51 if (wifi_mem_array[section].size < size)
52 return NULL;
53 return wifi_mem_array[section].mem_ptr;
54}
55
56int __init mahimahi_init_wifi_mem(void)
57{
58 int i;
59
60 for(i=0;( i < WLAN_SKB_BUF_NUM );i++) {
61 if (i < (WLAN_SKB_BUF_NUM/2))
62 wlan_static_skb[i] = dev_alloc_skb(4096);
63 else
64 wlan_static_skb[i] = dev_alloc_skb(8192);
65 }
66 for(i=0;( i < PREALLOC_WLAN_NUMBER_OF_SECTIONS );i++) {
67 wifi_mem_array[i].mem_ptr = kmalloc(wifi_mem_array[i].size,
68 GFP_KERNEL);
69 if (wifi_mem_array[i].mem_ptr == NULL)
70 return -ENOMEM;
71 }
72 return 0;
73}
74
75static struct resource mahimahi_wifi_resources[] = {
76 [0] = {
77 .name = "bcm4329_wlan_irq",
78 .start = MSM_GPIO_TO_INT(MAHIMAHI_GPIO_WIFI_IRQ),
79 .end = MSM_GPIO_TO_INT(MAHIMAHI_GPIO_WIFI_IRQ),
80 .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL | IORESOURCE_IRQ_SHAREABLE,
81 },
82};
83
84static struct wifi_platform_data mahimahi_wifi_control = {
85 .set_power = mahimahi_wifi_power,
86 .set_reset = mahimahi_wifi_reset,
87 .set_carddetect = mahimahi_wifi_set_carddetect,
88 .mem_prealloc = mahimahi_wifi_mem_prealloc,
89};
90
91static struct platform_device mahimahi_wifi_device = {
92 .name = "bcm4329_wlan",
93 .id = 1,
94 .num_resources = ARRAY_SIZE(mahimahi_wifi_resources),
95 .resource = mahimahi_wifi_resources,
96 .dev = {
97 .platform_data = &mahimahi_wifi_control,
98 },
99};
100
101extern unsigned char *get_wifi_nvs_ram(void);
102extern int wifi_calibration_size_set(void);
103
104static unsigned mahimahi_wifi_update_nvs(char *str, int add_flag)
105{
106#define NVS_LEN_OFFSET 0x0C
107#define NVS_DATA_OFFSET 0x40
108 unsigned char *ptr;
109 unsigned len;
110
111 if (!str)
112 return -EINVAL;
113 ptr = get_wifi_nvs_ram();
114 /* Size in format LE assumed */
115 memcpy(&len, ptr + NVS_LEN_OFFSET, sizeof(len));
116 /* if the last byte in NVRAM is 0, trim it */
117 if (ptr[NVS_DATA_OFFSET + len - 1] == 0)
118 len -= 1;
119 if (add_flag) {
120 strcpy(ptr + NVS_DATA_OFFSET + len, str);
121 len += strlen(str);
122 } else {
123 if (strnstr(ptr + NVS_DATA_OFFSET, str, len))
124 len -= strlen(str);
125 }
126 memcpy(ptr + NVS_LEN_OFFSET, &len, sizeof(len));
127 wifi_calibration_size_set();
128 return 0;
129}
130
131static int __init mahimahi_wifi_init(void)
132{
133 int ret;
134
135 if (!machine_is_mahimahi())
136 return 0;
137
138 printk("%s: start\n", __func__);
139 mahimahi_wifi_update_nvs("sd_oobonly=1\r\n", 0);
140 mahimahi_wifi_update_nvs("btc_params70=0x32\r\n", 1);
141 mahimahi_init_wifi_mem();
142 ret = platform_device_register(&mahimahi_wifi_device);
143 return ret;
144}
145
146late_initcall(mahimahi_wifi_init);