staging: xgifb: clean up register function variable names
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / staging / ath6kl / os / linux / ar6000_android.c
CommitLineData
30295c89
VM
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23#include "ar6000_drv.h"
24#include "htc.h"
25#include <linux/vmalloc.h>
26#include <linux/fs.h>
27
30295c89
VM
28#ifdef CONFIG_HAS_EARLYSUSPEND
29#include <linux/earlysuspend.h>
30#endif
31
1071a134 32bool enable_mmc_host_detect_change = false;
30295c89
VM
33static void ar6000_enable_mmchost_detect_change(int enable);
34
35
36char fwpath[256] = "/system/wifi";
37int wowledon;
38unsigned int enablelogcat;
39
40extern int bmienable;
41extern struct net_device *ar6000_devices[];
42extern char ifname[];
43
30295c89
VM
44const char def_ifname[] = "wlan0";
45module_param_string(fwpath, fwpath, sizeof(fwpath), 0644);
46module_param(enablelogcat, uint, 0644);
47module_param(wowledon, int, 0644);
48
49#ifdef CONFIG_HAS_EARLYSUSPEND
50static int screen_is_off;
51static struct early_suspend ar6k_early_suspend;
52#endif
53
1f4c34bd 54static int (*ar6000_avail_ev_p)(void *, void *);
30295c89
VM
55
56#if defined(CONFIG_ANDROID_LOGGER) && (!defined(CONFIG_MMC_MSM))
57int logger_write(const enum logidx index,
58 const unsigned char prio,
59 const char __kernel * const tag,
60 const char __kernel * const fmt,
61 ...)
62{
63 int ret = 0;
64 va_list vargs;
65 struct file *filp = (struct file *)-ENOENT;
66 mm_segment_t oldfs;
67 struct iovec vec[3];
68 int tag_bytes = strlen(tag) + 1, msg_bytes;
69 char *msg;
70 va_start(vargs, fmt);
71 msg = kvasprintf(GFP_ATOMIC, fmt, vargs);
72 va_end(vargs);
73 if (!msg)
74 return -ENOMEM;
75 if (in_interrupt()) {
76 /* we have no choice since aio_write may be blocked */
77 printk(KERN_ALERT "%s", msg);
78 goto out_free_message;
79 }
80 msg_bytes = strlen(msg) + 1;
81 if (msg_bytes <= 1) /* empty message? */
82 goto out_free_message; /* don't bother, then */
83 if ((msg_bytes + tag_bytes + 1) > 2048) {
84 ret = -E2BIG;
85 goto out_free_message;
86 }
87
88 vec[0].iov_base = (unsigned char *) &prio;
89 vec[0].iov_len = 1;
90 vec[1].iov_base = (void *) tag;
91 vec[1].iov_len = strlen(tag) + 1;
92 vec[2].iov_base = (void *) msg;
93 vec[2].iov_len = strlen(msg) + 1;
94
95 oldfs = get_fs();
96 set_fs(KERNEL_DS);
97 do {
98 filp = filp_open("/dev/log/main", O_WRONLY, S_IRUSR);
99 if (IS_ERR(filp) || !filp->f_op) {
100 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: filp_open /dev/log/main error\n", __FUNCTION__));
101 ret = -ENOENT;
102 break;
103 }
104
105 if (filp->f_op->aio_write) {
106 int nr_segs = sizeof(vec) / sizeof(vec[0]);
107 int len = vec[0].iov_len + vec[1].iov_len + vec[2].iov_len;
108 struct kiocb kiocb;
109 init_sync_kiocb(&kiocb, filp);
110 kiocb.ki_pos = 0;
111 kiocb.ki_left = len;
112 kiocb.ki_nbytes = len;
113 ret = filp->f_op->aio_write(&kiocb, vec, nr_segs, kiocb.ki_pos);
114 }
115
116 } while (0);
117
118 if (!IS_ERR(filp)) {
119 filp_close(filp, NULL);
120 }
121 set_fs(oldfs);
122out_free_message:
123 if (msg) {
124 kfree(msg);
125 }
126 return ret;
127}
128#endif
129
130int android_logger_lv(void *module, int mask)
131{
132 switch (mask) {
133 case ATH_DEBUG_ERR:
134 return 6;
135 case ATH_DEBUG_INFO:
136 return 4;
137 case ATH_DEBUG_WARN:
138 return 5;
139 case ATH_DEBUG_TRC:
140 return 3;
141 default:
142#ifdef DEBUG
143 if (!module) {
144 return 3;
145 } else if (module == &GET_ATH_MODULE_DEBUG_VAR_NAME(driver)) {
146 return (mask <=ATH_DEBUG_MAKE_MODULE_MASK(3)) ? 3 : 2;
147 } else if (module == &GET_ATH_MODULE_DEBUG_VAR_NAME(htc)) {
148 return 2;
149 } else {
150 return 3;
151 }
152#else
153 return 3; /* DEBUG */
154#endif
155 }
156}
157
4c42080f 158static int android_readwrite_file(const char *filename, char *rbuf, const char *wbuf, size_t length)
30295c89
VM
159{
160 int ret = 0;
161 struct file *filp = (struct file *)-ENOENT;
162 mm_segment_t oldfs;
163 oldfs = get_fs();
164 set_fs(KERNEL_DS);
165 do {
166 int mode = (wbuf) ? O_RDWR : O_RDONLY;
167 filp = filp_open(filename, mode, S_IRUSR);
168 if (IS_ERR(filp) || !filp->f_op) {
169 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: file %s filp_open error\n", __FUNCTION__, filename));
170 ret = -ENOENT;
171 break;
172 }
173
174 if (length==0) {
175 /* Read the length of the file only */
176 struct inode *inode;
177
178 inode = GET_INODE_FROM_FILEP(filp);
179 if (!inode) {
180 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Get inode from %s failed\n", __FUNCTION__, filename));
181 ret = -ENOENT;
182 break;
183 }
184 ret = i_size_read(inode->i_mapping->host);
185 break;
186 }
187
188 if (wbuf) {
189 if ( (ret=filp->f_op->write(filp, wbuf, length, &filp->f_pos)) < 0) {
190 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Write %u bytes to file %s error %d\n", __FUNCTION__,
191 length, filename, ret));
192 break;
193 }
194 } else {
195 if ( (ret=filp->f_op->read(filp, rbuf, length, &filp->f_pos)) < 0) {
196 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Read %u bytes from file %s error %d\n", __FUNCTION__,
197 length, filename, ret));
198 break;
199 }
200 }
201 } while (0);
202
203 if (!IS_ERR(filp)) {
204 filp_close(filp, NULL);
205 }
206 set_fs(oldfs);
207
208 return ret;
209}
210
211int android_request_firmware(const struct firmware **firmware_p, const char *name,
212 struct device *device)
213{
214 int ret = 0;
215 struct firmware *firmware;
216 char filename[256];
217 const char *raw_filename = name;
218 *firmware_p = firmware = kzalloc(sizeof(*firmware), GFP_KERNEL);
219 if (!firmware)
220 return -ENOMEM;
221 sprintf(filename, "%s/%s", fwpath, raw_filename);
222 do {
223 size_t length, bufsize, bmisize;
224
225 if ( (ret=android_readwrite_file(filename, NULL, NULL, 0)) < 0) {
226 break;
227 } else {
228 length = ret;
229 }
230
231 bufsize = ALIGN(length, PAGE_SIZE);
232 bmisize = A_ROUND_UP(length, 4);
233 bufsize = max(bmisize, bufsize);
234 firmware->data = vmalloc(bufsize);
235 firmware->size = length;
236 if (!firmware->data) {
237 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: Cannot allocate buffer for firmware\n", __FUNCTION__));
238 ret = -ENOMEM;
239 break;
240 }
241
242 if ( (ret=android_readwrite_file(filename, (char*)firmware->data, NULL, length)) != length) {
243 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: file read error, ret %d request %d\n", __FUNCTION__, ret, length));
244 ret = -1;
245 break;
246 }
247
248 } while (0);
249
250 if (ret<0) {
251 if (firmware) {
252 if (firmware->data)
253 vfree(firmware->data);
254 kfree(firmware);
255 }
256 *firmware_p = NULL;
257 } else {
258 ret = 0;
259 }
260 return ret;
261}
262
263void android_release_firmware(const struct firmware *firmware)
264{
265 if (firmware) {
266 if (firmware->data)
267 vfree(firmware->data);
268 kfree(firmware);
269 }
270}
271
1f4c34bd 272static int ar6000_android_avail_ev(void *context, void *hif_handle)
30295c89 273{
1f4c34bd 274 int ret;
30295c89
VM
275 ar6000_enable_mmchost_detect_change(0);
276 ret = ar6000_avail_ev_p(context, hif_handle);
30295c89
VM
277 return ret;
278}
279
280/* Useful for qualcom platform to detect our wlan card for mmc stack */
281static void ar6000_enable_mmchost_detect_change(int enable)
282{
283#ifdef CONFIG_MMC_MSM
284#define MMC_MSM_DEV "msm_sdcc.1"
285 char buf[3];
286 int length;
287
288 if (!enable_mmc_host_detect_change) {
289 return;
290 }
291 length = snprintf(buf, sizeof(buf), "%d\n", enable ? 1 : 0);
292 if (android_readwrite_file("/sys/devices/platform/" MMC_MSM_DEV "/detect_change",
293 NULL, buf, length) < 0) {
294 /* fall back to polling */
295 android_readwrite_file("/sys/devices/platform/" MMC_MSM_DEV "/polling", NULL, buf, length);
296 }
297#endif
298}
299
300#ifdef CONFIG_HAS_EARLYSUSPEND
301static void android_early_suspend(struct early_suspend *h)
302{
303 screen_is_off = 1;
304}
305
306static void android_late_resume(struct early_suspend *h)
307{
308 screen_is_off = 0;
309}
310#endif
311
312void android_module_init(OSDRV_CALLBACKS *osdrvCallbacks)
313{
314 bmienable = 1;
315 if (ifname[0] == '\0')
316 strcpy(ifname, def_ifname);
30295c89
VM
317#ifdef CONFIG_HAS_EARLYSUSPEND
318 ar6k_early_suspend.suspend = android_early_suspend;
319 ar6k_early_suspend.resume = android_late_resume;
320 ar6k_early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
321 register_early_suspend(&ar6k_early_suspend);
322#endif
323
324 ar6000_avail_ev_p = osdrvCallbacks->deviceInsertedHandler;
325 osdrvCallbacks->deviceInsertedHandler = ar6000_android_avail_ev;
326
327 ar6000_enable_mmchost_detect_change(1);
328}
329
330void android_module_exit(void)
331{
332#ifdef CONFIG_HAS_EARLYSUSPEND
333 unregister_early_suspend(&ar6k_early_suspend);
30295c89
VM
334#endif
335 ar6000_enable_mmchost_detect_change(1);
336}
337
338#ifdef CONFIG_PM
1071a134 339void android_ar6k_check_wow_status(AR_SOFTC_T *ar, struct sk_buff *skb, bool isEvent)
30295c89
VM
340{
341 if (
342#ifdef CONFIG_HAS_EARLYSUSPEND
343 screen_is_off &&
344#endif
345 skb && ar->arConnected) {
1071a134 346 bool needWake = false;
30295c89 347 if (isEvent) {
4853ac05
JP
348 if (A_NETBUF_LEN(skb) >= sizeof(u16)) {
349 u16 cmd = *(const u16 *)A_NETBUF_DATA(skb);
30295c89
VM
350 switch (cmd) {
351 case WMI_CONNECT_EVENTID:
352 case WMI_DISCONNECT_EVENTID:
1071a134 353 needWake = true;
30295c89
VM
354 break;
355 default:
356 /* dont wake lock the system for other event */
357 break;
358 }
359 }
360 } else if (A_NETBUF_LEN(skb) >= sizeof(ATH_MAC_HDR)) {
361 ATH_MAC_HDR *datap = (ATH_MAC_HDR *)A_NETBUF_DATA(skb);
362 if (!IEEE80211_IS_MULTICAST(datap->dstMac)) {
363 switch (A_BE2CPU16(datap->typeOrLen)) {
364 case 0x0800: /* IP */
365 case 0x888e: /* EAPOL */
366 case 0x88c7: /* RSN_PREAUTH */
367 case 0x88b4: /* WAPI */
1071a134 368 needWake = true;
30295c89
VM
369 break;
370 case 0x0806: /* ARP is not important to hold wake lock */
371 default:
372 break;
373 }
374 }
375 }
376 if (needWake) {
377 /* keep host wake up if there is any event and packate comming in*/
30295c89
VM
378 if (wowledon) {
379 char buf[32];
380 int len = sprintf(buf, "on");
381 android_readwrite_file("/sys/power/state", NULL, buf, len);
382
383 len = sprintf(buf, "%d", 127);
384 android_readwrite_file("/sys/class/leds/lcd-backlight/brightness",
385 NULL, buf,len);
386 }
387 }
388 }
389}
390#endif /* CONFIG_PM */