add MTK-combo-module,continue with commit 17f39ed917874e77e80411f33faba1b7ee8138c8
[firefly-linux-kernel-4.4.55.git] / drivers / mtk_wcn_combo / drv_wlan / wlan / os / linux / hif / sdio / sdio.c
1 /******************************************************************************
2 *[File]             sdio.c
3 *[Version]          v1.0
4 *[Revision Date]    2010-03-01
5 *[Author]
6 *[Description]
7 *    The program provides SDIO HIF driver
8 *[Copyright]
9 *    Copyright (C) 2010 MediaTek Incorporation. All Rights Reserved.
10 ******************************************************************************/
11
12
13 /*******************************************************************************
14 * LEGAL DISCLAIMER
15 *
16 * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND
17 * AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK
18 * SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE
19 * PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY
20 * DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
21 * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
22 * PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE
23 * ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY
24 * WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK
25 * SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY
26 * WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE
27 * FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO
28 * CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
29 *
30 * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
31 * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL
32 * BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT
33 * ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY
34 * BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
35 *
36 * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
37 * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT
38 * OF LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING
39 * THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN
40 * FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE
41 * (ICC).
42 ********************************************************************************
43 */
44
45 /*
46 ** $Log: sdio.c $
47  *
48  * 11 10 2011 cp.wu
49  * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
50  * 1. eliminaite direct calls to printk in porting layer.
51  * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
52  *
53  * 10 19 2011 yuche.tsai
54  * [WCXRP00001045] [WiFi Direct][Driver] Check 2.1 branch.
55  * Branch 2.1
56  * Davinci Maintrunk Label: MT6620_WIFI_DRIVER_FW_TRUNK_MT6620E5_111019_0926.
57  *
58  * 03 18 2011 cp.wu
59  * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver
60  * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk
61  *
62  * 03 18 2011 cp.wu
63  * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous memory consumption
64  * deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK.
65  *
66  * 03 15 2011 cp.wu
67  * [WCXRP00000559] [MT6620 Wi-Fi][Driver] Combine TX/RX DMA buffers into a single one to reduce physically continuous memory consumption
68  * 1. deprecate CFG_HANDLE_IST_IN_SDIO_CALLBACK
69  * 2. Use common coalescing buffer for both TX/RX directions
70  *
71  *
72  * 03 07 2011 terry.wu
73  * [WCXRP00000521] [MT6620 Wi-Fi][Driver] Remove non-standard debug message
74  * Toggle non-standard debug messages to comments.
75  *
76  * 11 15 2010 jeffrey.chang
77  * [WCXRP00000181] [MT6620 Wi-Fi][Driver] fix the driver message "GLUE_FLAG_HALT skip INT" during unloading
78  * Fix GLUE_FALG_HALT message which cause driver to hang
79  *
80  * 11 08 2010 cp.wu
81  * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period
82  * correct typo
83  *
84  * 11 08 2010 cp.wu
85  * [WCXRP00000166] [MT6620 Wi-Fi][Driver] use SDIO CMD52 for enabling/disabling interrupt to reduce transaction period
86  * change to use CMD52 for enabling/disabling interrupt to reduce SDIO transaction time
87  *
88  * 11 01 2010 yarco.yang
89  * [WCXRP00000149] [MT6620 WI-Fi][Driver]Fine tune performance on MT6516 platform
90  * Add code to run WlanIST in SDIO callback.
91  *
92  * 10 19 2010 cp.wu
93  * [WCXRP00000122] [MT6620 Wi-Fi][Driver] Preparation for YuSu source tree integration
94  * remove HIF_SDIO_ONE flags because the settings could be merged for runtime detection instead of compile-time.
95  *
96  * 10 19 2010 jeffrey.chang
97  * [WCXRP00000120] [MT6620 Wi-Fi][Driver] Refine linux kernel module to the license of MTK propietary and enable MTK HIF by default
98  * Refine linux kernel module to the license of MTK and enable MTK HIF
99  *
100  * 08 21 2010 jeffrey.chang
101  * NULL
102  * 1) add sdio two setting
103  * 2) bug fix of sdio glue
104  *
105  * 08 18 2010 jeffrey.chang
106  * NULL
107  * support multi-function sdio
108  *
109  * 08 18 2010 cp.wu
110  * NULL
111  * #if defined(__X86__) is not working, change to use #ifdef CONFIG_X86.
112  *
113  * 08 17 2010 cp.wu
114  * NULL
115  * add ENE SDIO host workaround for x86 linux platform.
116  *
117  * 07 08 2010 cp.wu
118  *
119  * [WPD00003833] [MT6620 and MT5931] Driver migration - move to new repository.
120  *
121  * 06 06 2010 kevin.huang
122  * [WPD00003832][MT6620 5931] Create driver base
123  * [MT6620 5931] Create driver base
124  *
125  * 05 07 2010 jeffrey.chang
126  * [WPD00003826]Initial import for Linux port
127  * Fix hotplug bug
128  *
129  * 03 28 2010 jeffrey.chang
130  * [WPD00003826]Initial import for Linux port
131  * clear sdio interrupt
132  *
133  * 03 24 2010 jeffrey.chang
134  * [WPD00003826]Initial import for Linux port
135  * initial import for Linux port
136 **
137 */
138
139 /*******************************************************************************
140 *                         C O M P I L E R   F L A G S
141 ********************************************************************************
142 */
143
144 /*******************************************************************************
145 *                    E X T E R N A L   R E F E R E N C E S
146 ********************************************************************************
147 */
148
149 #include "gl_os.h"
150
151 #if MTK_WCN_HIF_SDIO
152 #include "hif_sdio.h"
153 #else
154 #include <linux/mmc/card.h>
155 #include <linux/mmc/host.h>
156 #include <linux/mmc/sdio.h>
157 #include <linux/mmc/sdio_func.h> /* sdio_readl(), etc */
158 #include <linux/mmc/sdio_ids.h>
159 #endif
160
161 #include <linux/mm.h>
162 //#ifndef CONFIG_X86  modify by Nicolas Luo
163 #ifdef CONFIG_ARM
164 #include <asm/memory.h>
165 #endif
166 #include "mt6620_reg.h"
167
168 #if CFG_DBG_GPIO_PINS/* FIXME: move to platform or custom header */
169 #include <mach/mt6516_gpio.h>
170 #endif
171
172 /*******************************************************************************
173 *                              C O N S T A N T S
174 ********************************************************************************
175 */
176
177 #if MTK_WCN_HIF_SDIO
178
179
180 /*
181  * function prototypes
182  *
183  */
184
185 static INT32
186 mtk_sdio_probe(MTK_WCN_HIF_SDIO_CLTCTX, const MTK_WCN_HIF_SDIO_FUNCINFO *);
187
188 static INT32
189 mtk_sdio_remove(MTK_WCN_HIF_SDIO_CLTCTX);
190 static INT32 mtk_sdio_interrupt(MTK_WCN_HIF_SDIO_CLTCTX);
191
192 /*
193  * sdio function info table
194  */
195
196 static MTK_WCN_HIF_SDIO_FUNCINFO funcInfo[] = {
197 #if defined(MT6620)
198     { MTK_WCN_HIF_SDIO_FUNC(0x037a, 0x020a, 0x1, 512) },
199     { MTK_WCN_HIF_SDIO_FUNC(0x037a, 0x020c, 0x2, 512) },
200     { MTK_WCN_HIF_SDIO_FUNC(0x037a, 0x018a, 0x1, 512) },
201     { MTK_WCN_HIF_SDIO_FUNC(0x037a, 0x018c, 0x2, 512) },
202 #elif defined(MT5931)
203     { MTK_WCN_HIF_SDIO_FUNC(0x037a, 0x5931, 0x1, 512) },
204 #elif defined(MT6628)
205     { MTK_WCN_HIF_SDIO_FUNC(0x037a, 0x6628, 0x1, 512) },
206 #endif
207 };
208
209
210 static MTK_WCN_HIF_SDIO_CLTINFO cltInfo = {
211     .func_tbl = funcInfo,
212     .func_tbl_size = sizeof(funcInfo)/sizeof(MTK_WCN_HIF_SDIO_FUNCINFO),
213     .hif_clt_probe = mtk_sdio_probe,
214     .hif_clt_remove = mtk_sdio_remove,
215     .hif_clt_irq = mtk_sdio_interrupt,
216 };
217
218 #else
219
220 static const struct sdio_device_id mtk_sdio_ids[] = {
221 #if defined(MT6620)
222         { SDIO_DEVICE(0x037a, 0x020a) }, /* Not an SDIO standard class device */
223         { SDIO_DEVICE(0x037a, 0x020b) }, /* Not an SDIO standard class device */
224         { SDIO_DEVICE(0x037a, 0x020c) }, /* Not an SDIO standard class device */
225 #elif defined(MT5931)
226         { SDIO_DEVICE(0x037a, 0x5931) }, /* Not an SDIO standard class device */
227 #elif defined(MT6628)
228         { SDIO_DEVICE(0x037a, 0x6628) }, /* Not an SDIO standard class device */
229 #endif
230         { /* end: all zeroes */ },
231 };
232
233 MODULE_DEVICE_TABLE(sdio, mtk_sdio_ids);
234
235 #endif
236
237 /*******************************************************************************
238 *                             D A T A   T Y P E S
239 ********************************************************************************
240 */
241
242
243 /*******************************************************************************
244 *                            P U B L I C   D A T A
245 ********************************************************************************
246 */
247
248 /*******************************************************************************
249 *                           P R I V A T E   D A T A
250 ********************************************************************************
251 */
252 static probe_card pfWlanProbe = NULL;
253 static remove_card pfWlanRemove = NULL;
254
255
256 #if (MTK_WCN_HIF_SDIO == 0)
257 static struct sdio_driver mtk_sdio_driver = {
258         .name           = "wlan", /* "MTK SDIO WLAN Driver" */
259         .id_table       = mtk_sdio_ids,
260         .probe          = NULL,
261         .remove         = NULL,
262 };
263 #endif
264
265
266 #if CFG_DBG_GPIO_PINS
267
268 /* debug pins */
269 UINT_32 dbgPinSTP[] = {
270     GPIO_PLATFORM(33)/* CMFLASH, IDX_ERR J613 */
271     , GPIO_PLATFORM(62)/* EINT3, IDX_TX_THREAD */
272     , GPIO_PLATFORM(80)/* SPI_CS_N, IDX_TX_REQ J613 */
273     , GPIO_PLATFORM(81)/* SPI_SCK, IDX_TX_PORT_WRITE J613 */
274     , GPIO_PLATFORM(17) /* CMRST, IDX_STP_MTX_BT J618 */
275     , GPIO_PLATFORM(18) /* CMPDN, IDX_STP_MTX_FM J613 */
276     , GPIO_PLATFORM(19) /* CMVREF,IDX_STP_MTX_GPS J613 */
277     , GPIO_INVALID /* REMOVED, IDX_STP_MTX_WIFI */
278     , GPIO_INVALID /* REMOVED, IDX_STP_MTX_WMT */
279     , GPIO_PLATFORM(135) /* SCL2, IDX_LOOP_CNT  J616 */
280     , GPIO_PLATFORM(136) /* SDA2, IDX_NO_BUF J616 */
281     , GPIO_PLATFORM(30) /* CAM_MECHSH0, IDX_BT_TX, J613 low-active */
282     , GPIO_PLATFORM(31) /* CAM_MECHSH1, IDX_BT_RX, J613 low-active */
283     , GPIO_PLATFORM(124) /* GPS_PWR_EN, ThreadDSPIn [GPS] */
284     , GPIO_PLATFORM(125) /* GPS_SYNC, mtk_sys_msg_recv [GPS] */
285     , GPIO_PLATFORM(21) /* GPS_EINT8, dump_nmea_data [GPS] */
286     , GPIO_PLATFORM(29) /* CAM_STROBE, IDX_GPS_TX, J613 low-active */
287     , GPIO_PLATFORM(20) /*CMHREF, J613 UNUSED */
288 //    , GPIO_6516(64) /* EINT5, REMOVED!!! for MT6620-Wi-Fi Int */
289 //    , GPIO_6516(122) /* BT_PWR_EN, REMOVED!!! for MT6620-PMU_EN */
290 //    , GPIO_6516(123) /* BT_RESET, REMOVED!!! for MT6620-RST */
291 };
292 #endif
293 /*******************************************************************************
294 *                                 M A C R O S
295 ********************************************************************************
296 */
297
298 /*******************************************************************************
299 *                   F U N C T I O N   D E C L A R A T I O N S
300 ********************************************************************************
301 */
302
303 /*******************************************************************************
304 *                              F U N C T I O N S
305 ********************************************************************************
306 */
307 #if CFG_DBG_GPIO_PINS
308 void debug_gpio_init(void)
309 {
310     int i;
311
312     for (i = 0; i < sizeof(dbgPinSTP)/sizeof(dbgPinSTP[0]); ++i) {
313         if (GPIO_INVALID == dbgPinSTP[i]) {
314             continue;
315         }
316         //printk(KERN_INFO "[%s] %ld \n", __FUNCTION__, dbgPinSTP[i]);
317         mt_set_gpio_pull_enable(dbgPinSTP[i], 0); /* disable pull */
318         mt_set_gpio_dir(dbgPinSTP[i], GPIO_DIR_OUT); /* set output */
319         mt_set_gpio_mode(dbgPinSTP[i], GPIO_MODE_00); /* set gpio mode */
320
321         /* toggle twice to check if ok: */
322         mt_set_gpio_out(dbgPinSTP[i], GPIO_OUT_ZERO); /* tie low */
323         mt_set_gpio_out(dbgPinSTP[i], GPIO_OUT_ONE); /* tie high*/
324         mt_set_gpio_out(dbgPinSTP[i], GPIO_OUT_ZERO); /* tie low */
325         mt_set_gpio_out(dbgPinSTP[i], GPIO_OUT_ONE); /* tie high*/
326     }
327     //printk(KERN_INFO "[%s] initialization ok \n", __FUNCTION__);
328 }
329
330 void debug_gpio_deinit(void)
331 {
332     int i;
333     for (i = 0; i < sizeof(dbgPinSTP)/sizeof(dbgPinSTP[0]); ++i) {
334         if (GPIO_INVALID == dbgPinSTP[i]) {
335             continue;
336         }
337         //printk(KERN_INFO "[%s] %ld \n", __FUNCTION__, dbgPinSTP[i]);
338         mt_set_gpio_dir(dbgPinSTP[i], GPIO_DIR_IN);
339     }
340
341     //printk(KERN_INFO "[%s] k\n", __FUNCTION__);
342 }
343
344 void mtk_wcn_stp_debug_gpio_assert(UINT_32 dwIndex, UINT_32 dwMethod)
345 {
346     unsigned int i;
347
348     if (dwIndex >= (sizeof(dbgPinSTP)/sizeof(dbgPinSTP[0]))) {
349         //printk(KERN_INFO "[%s] invalid dwIndex(%ld) \n", __FUNCTION__, dwIndex);
350         return;
351     }
352
353     if (dwIndex > IDX_STP_MAX) {
354         //printk(KERN_INFO "[%s] dwIndex(%ld) > IDX_STP_MAX(%d) \n", __FUNCTION__, dwIndex, IDX_STP_MAX);
355     }
356
357     if (GPIO_INVALID == dbgPinSTP[dwIndex]) {
358         return;
359     }
360
361     if (dwMethod & DBG_TIE_DIR) {
362         if (dwMethod & DBG_HIGH) {
363             mt_set_gpio_out(dbgPinSTP[dwIndex], GPIO_OUT_ONE);
364         }
365         else {
366             mt_set_gpio_out(dbgPinSTP[dwIndex], GPIO_OUT_ZERO);
367         }
368         return;
369     }
370
371     if (dwMethod & DBG_TOGGLE(0)) {
372         for (i = 0; i < DBG_TOGGLE_NUM(dwMethod); ++i) {
373             mt_set_gpio_out(dbgPinSTP[dwIndex], GPIO_OUT_ZERO);
374             mt_set_gpio_out(dbgPinSTP[dwIndex], GPIO_OUT_ONE);
375         }
376         return;
377     }
378
379     return;
380 }
381 #endif
382
383 /*----------------------------------------------------------------------------*/
384 /*!
385 * \brief This function is a SDIO interrupt callback function
386 *
387 * \param[in] func  pointer to SDIO handle
388 *
389 * \return void
390 */
391 /*----------------------------------------------------------------------------*/
392
393 #if MTK_WCN_HIF_SDIO
394
395 static INT32 mtk_sdio_interrupt(MTK_WCN_HIF_SDIO_CLTCTX cltCtx)
396 {
397     P_GLUE_INFO_T prGlueInfo = NULL;
398     INT32 ret = 0;
399
400     prGlueInfo = mtk_wcn_hif_sdio_get_drvdata(cltCtx);
401
402     ASSERT(prGlueInfo);
403
404     if (!prGlueInfo) {
405         //printk(KERN_INFO DRV_NAME"No glue info in mtk_sdio_interrupt()\n");
406         return (-HIF_SDIO_ERR_FAIL);
407     }
408
409     if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) {
410         //printk(KERN_INFO DRV_NAME"GLUE_FLAG_HALT skip INT\n");
411         ret = mtk_wcn_hif_sdio_writel(cltCtx, MCR_WHLPCR, WHLPCR_INT_EN_CLR);
412         return ret;
413     }
414
415     ret = mtk_wcn_hif_sdio_writel(cltCtx, MCR_WHLPCR, WHLPCR_INT_EN_CLR);
416
417     set_bit (GLUE_FLAG_INT_BIT, &prGlueInfo->u4Flag);
418
419     /* when we got sdio interrupt, we wake up the tx servie thread*/
420     wake_up_interruptible(&prGlueInfo->waitq);
421
422     return ret;
423 }
424
425 #else
426
427 static unsigned int in_interrupt = 0;
428
429 static void mtk_sdio_interrupt(struct sdio_func *func)
430 {
431     P_GLUE_INFO_T prGlueInfo = NULL;
432
433     int ret = 0;
434
435     prGlueInfo = sdio_get_drvdata(func);
436     ASSERT(prGlueInfo);
437
438     if (!prGlueInfo) {
439         //printk(KERN_INFO DRV_NAME"No glue info in mtk_sdio_interrupt()\n");
440         return;
441     }
442
443     if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) {
444         sdio_writel(prGlueInfo->rHifInfo.func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, &ret);
445         //printk(KERN_INFO DRV_NAME"GLUE_FLAG_HALT skip INT\n");
446         return;
447     }
448
449     sdio_writel(prGlueInfo->rHifInfo.func, WHLPCR_INT_EN_CLR, MCR_WHLPCR, &ret);
450
451     #if 0
452     wlanISR(prGlueInfo->prAdapter, TRUE);
453
454     if (prGlueInfo->u4Flag & GLUE_FLAG_HALT) {
455         /* Should stop now... skip pending interrupt */
456         //printk(KERN_INFO DRV_NAME"ignore pending interrupt\n");
457     }
458     else {
459         wlanIST(prGlueInfo->prAdapter);
460     }
461     #endif
462
463     set_bit (GLUE_FLAG_INT_BIT, &prGlueInfo->u4Flag);
464
465     /* when we got sdio interrupt, we wake up the tx servie thread*/
466     wake_up_interruptible(&prGlueInfo->waitq);
467 }
468 #endif
469
470 /*----------------------------------------------------------------------------*/
471 /*!
472 * \brief This function is a SDIO probe function
473 *
474 * \param[in] func   pointer to SDIO handle
475 * \param[in] id     pointer to SDIO device id table
476 *
477 * \return void
478 */
479 /*----------------------------------------------------------------------------*/
480
481 #if MTK_WCN_HIF_SDIO
482
483 // FIXME: global variable
484 static const MTK_WCN_HIF_SDIO_FUNCINFO *prFunc;
485
486
487 static INT32
488 mtk_sdio_probe(MTK_WCN_HIF_SDIO_CLTCTX cltCtx, const MTK_WCN_HIF_SDIO_FUNCINFO *prFuncInfo)
489 {
490     INT32 ret = HIF_SDIO_ERR_SUCCESS;
491
492     prFunc = prFuncInfo;
493
494     if (pfWlanProbe((PVOID) &cltCtx) != WLAN_STATUS_SUCCESS) {
495         //printk(KERN_WARNING DRV_NAME"pfWlanProbe fail!call pfWlanRemove()\n");
496         pfWlanRemove();
497         ret = -(HIF_SDIO_ERR_FAIL);
498     } else {
499         //printk(KERN_INFO DRV_NAME"mtk_wifi_sdio_probe() done(%d)\n", ret);
500     }
501     return ret;
502 }
503 #else
504 static int mtk_sdio_probe (
505     struct sdio_func *func,
506     const struct sdio_device_id *id
507     )
508 {
509     int ret = 0;
510     int i = 0;
511
512     //printk(KERN_INFO DRV_NAME "mtk_sdio_probe()\n");
513
514     ASSERT(func);
515     ASSERT(id);
516
517     //printk(KERN_INFO DRV_NAME "Basic struct size checking...\n");
518     //printk(KERN_INFO DRV_NAME "sizeof(struct device) = %d\n", sizeof(struct device));
519     //printk(KERN_INFO DRV_NAME "sizeof(struct mmc_host) = %d\n", sizeof(struct mmc_host));
520     //printk(KERN_INFO DRV_NAME "sizeof(struct mmc_card) = %d\n", sizeof(struct mmc_card));
521     //printk(KERN_INFO DRV_NAME "sizeof(struct mmc_driver) = %d\n", sizeof(struct mmc_driver));
522     //printk(KERN_INFO DRV_NAME "sizeof(struct mmc_data) = %d\n", sizeof(struct mmc_data));
523     //printk(KERN_INFO DRV_NAME "sizeof(struct mmc_command) = %d\n", sizeof(struct mmc_command));
524     //printk(KERN_INFO DRV_NAME "sizeof(struct mmc_request) = %d\n", sizeof(struct mmc_request));
525     //printk(KERN_INFO DRV_NAME "sizeof(struct sdio_func) = %d\n", sizeof(struct sdio_func));
526
527     //printk(KERN_INFO DRV_NAME "Card information checking...\n");
528     //printk(KERN_INFO DRV_NAME "func = 0x%p\n", func);
529     //printk(KERN_INFO DRV_NAME "Number of info = %d:\n", func->card->num_info);
530
531     for (i = 0; i < func->card->num_info; i++) {
532         //printk(KERN_INFO DRV_NAME "info[%d]: %s\n", i, func->card->info[i]);
533     }
534
535     sdio_claim_host(func);
536     ret = sdio_enable_func(func);
537     sdio_release_host(func);
538
539     if (ret) {
540         //printk(KERN_INFO DRV_NAME"sdio_enable_func failed!\n");
541         goto out;
542     }
543     //printk(KERN_INFO DRV_NAME"sdio_enable_func done!\n");
544
545     if (pfWlanProbe((PVOID)func) != WLAN_STATUS_SUCCESS) {
546         //printk(KERN_WARNING DRV_NAME"pfWlanProbe fail!call pfWlanRemove()\n");
547         pfWlanRemove();
548         ret = -1;
549     }
550     else {
551 #if CFG_DBG_GPIO_PINS
552     //printk(KERN_INFO "[%s] init debug gpio, 20100815 \n", __FUNCTION__);
553     /* Debug pins initialization */
554     debug_gpio_init();
555 #endif
556     }
557
558 out:
559     //printk(KERN_INFO DRV_NAME"mtk_sdio_probe() done(%d)\n", ret);
560     return ret;
561 }
562 #endif
563
564
565 #if MTK_WCN_HIF_SDIO
566 static INT32
567 mtk_sdio_remove(MTK_WCN_HIF_SDIO_CLTCTX cltCtx)
568 {
569     INT32 ret = HIF_SDIO_ERR_SUCCESS;
570     //printk(KERN_INFO DRV_NAME"pfWlanRemove done\n");
571     pfWlanRemove();
572
573     return ret;
574 }
575 #else
576 static void
577 mtk_sdio_remove (
578     struct sdio_func *func
579     )
580 {
581     //printk(KERN_INFO DRV_NAME"mtk_sdio_remove()\n");
582
583 #if CFG_DBG_GPIO_PINS
584     //printk(KERN_INFO "[%s] deinit debug gpio \n", __FUNCTION__);
585     debug_gpio_deinit();
586 #endif
587
588     ASSERT(func);
589     //printk(KERN_INFO DRV_NAME"pfWlanRemove done\n");
590     pfWlanRemove();
591
592     sdio_claim_host(func);
593     sdio_disable_func(func);
594     //printk(KERN_INFO DRV_NAME"sdio_disable_func() done\n");
595     sdio_release_host(func);
596
597     //printk(KERN_INFO DRV_NAME"mtk_sdio_remove() done\n");
598 }
599 #endif
600
601 #if (MTK_WCN_HIF_SDIO == 0)
602 static int
603 mtk_sdio_suspend (
604     struct device * pDev,
605     pm_message_t state
606     )
607 {
608     //printk(KERN_INFO "mtk_sdio: mtk_sdio_suspend dev(0x%p)\n", pDev);
609     //printk(KERN_INFO "mtk_sdio: MediaTek SDIO WLAN driver\n");
610
611     return 0;
612 }
613
614 int mtk_sdio_resume (
615     struct device * pDev
616     )
617 {
618     //printk(KERN_INFO "mtk_sdio: mtk_sdio_resume dev(0x%p)\n", pDev);
619
620     return 0;
621 }
622 #endif
623
624
625 /*----------------------------------------------------------------------------*/
626 /*!
627 * \brief This function will register sdio bus to the os
628 *
629 * \param[in] pfProbe    Function pointer to detect card
630 * \param[in] pfRemove   Function pointer to remove card
631 *
632 * \return The result of registering sdio bus
633 */
634 /*----------------------------------------------------------------------------*/
635 WLAN_STATUS
636 glRegisterBus (
637     probe_card pfProbe,
638     remove_card pfRemove
639     )
640 {
641     int ret = 0;
642
643     ASSERT(pfProbe);
644     ASSERT(pfRemove);
645
646     //printk(KERN_INFO "mtk_sdio: MediaTek SDIO WLAN driver\n");
647     //printk(KERN_INFO "mtk_sdio: Copyright MediaTek Inc.\n");
648
649     pfWlanProbe = pfProbe;
650     pfWlanRemove = pfRemove;
651
652 #if MTK_WCN_HIF_SDIO
653     /* register MTK sdio client */
654     ret = ((mtk_wcn_hif_sdio_client_reg(&cltInfo) == HIF_SDIO_ERR_SUCCESS) ? WLAN_STATUS_SUCCESS : WLAN_STATUS_FAILURE);
655 #else
656     mtk_sdio_driver.probe = mtk_sdio_probe;
657     mtk_sdio_driver.remove = mtk_sdio_remove;
658
659     mtk_sdio_driver.drv.suspend = mtk_sdio_suspend;
660     mtk_sdio_driver.drv.resume = mtk_sdio_resume;
661
662     ret = (sdio_register_driver(&mtk_sdio_driver) == 0) ? WLAN_STATUS_SUCCESS : WLAN_STATUS_FAILURE;
663 #endif
664
665     return ret;
666 } /* end of glRegisterBus() */
667
668
669 /*----------------------------------------------------------------------------*/
670 /*!
671 * \brief This function will unregister sdio bus to the os
672 *
673 * \param[in] pfRemove   Function pointer to remove card
674 *
675 * \return (none)
676 */
677 /*----------------------------------------------------------------------------*/
678 VOID
679 glUnregisterBus(
680     remove_card pfRemove
681     )
682 {
683     ASSERT(pfRemove);
684     pfRemove();
685
686 #if MTK_WCN_HIF_SDIO
687     /* unregister MTK sdio client */
688     mtk_wcn_hif_sdio_client_unreg(&cltInfo);
689 #else
690     sdio_unregister_driver(&mtk_sdio_driver);
691 #endif
692
693     return;
694 } /* end of glUnregisterBus() */
695
696
697 /*----------------------------------------------------------------------------*/
698 /*!
699 * \brief This function stores hif related info, which is initialized before.
700 *
701 * \param[in] prGlueInfo Pointer to glue info structure
702 * \param[in] u4Cookie   Pointer to UINT_32 memory base variable for _HIF_HPI
703 *
704 * \return (none)
705 */
706 /*----------------------------------------------------------------------------*/
707 VOID
708 glSetHifInfo (
709     P_GLUE_INFO_T prGlueInfo,
710     UINT_32 u4Cookie
711     )
712 {
713     P_GL_HIF_INFO_T prHif = NULL;
714
715     prHif = &prGlueInfo->rHifInfo;
716
717 #if MTK_WCN_HIF_SDIO
718     //prHif->prFuncInfo = ((MTK_WCN_HIF_SDIO_FUNCINFO *) u4Cookie);
719     prHif->prFuncInfo = prFunc;
720     prHif->cltCtx = *((MTK_WCN_HIF_SDIO_CLTCTX *) u4Cookie);
721     mtk_wcn_hif_sdio_set_drvdata(prHif->cltCtx, prGlueInfo);
722
723 #else
724     prHif->func = (struct sdio_func *) u4Cookie;
725
726     //printk(KERN_INFO DRV_NAME"prHif->func->dev = 0x%p\n", &prHif->func->dev);
727     //printk(KERN_INFO DRV_NAME"prHif->func->vendor = 0x%04X\n", prHif->func->vendor);
728     //printk(KERN_INFO DRV_NAME"prHif->func->device = 0x%04X\n", prHif->func->device);
729     //printk(KERN_INFO DRV_NAME"prHif->func->func = 0x%04X\n", prHif->func->num);
730
731     sdio_set_drvdata(prHif->func, prGlueInfo);
732
733     SET_NETDEV_DEV(prGlueInfo->prDevHandler, &prHif->func->dev);
734 #endif
735
736     return;
737 } /* end of glSetHifInfo() */
738
739 /*----------------------------------------------------------------------------*/
740 /*!
741 * \brief This function clears hif related info.
742 *
743 * \param[in] prGlueInfo Pointer to glue info structure
744 *
745 * \return (none)
746 */
747 /*----------------------------------------------------------------------------*/
748 VOID
749 glClearHifInfo (
750     P_GLUE_INFO_T prGlueInfo
751     )
752 {
753     //P_GL_HIF_INFO_T prHif = NULL;
754     //ASSERT(prGlueInfo);
755     //prHif = &prGlueInfo->rHifInfo;
756
757     return;
758 } /* end of glClearHifInfo() */
759
760
761 /*----------------------------------------------------------------------------*/
762 /*!
763 * \brief Initialize bus operation and hif related information, request resources.
764 *
765 * \param[out] pvData    A pointer to HIF-specific data type buffer.
766 *                       For eHPI, pvData is a pointer to UINT_32 type and stores a
767 *                       mapped base address.
768 *
769 * \return (none)
770 */
771 /*----------------------------------------------------------------------------*/
772 BOOL
773 glBusInit (
774     PVOID pvData
775     )
776 {
777 #if (MTK_WCN_HIF_SDIO == 0)
778     int ret = 0;
779     struct sdio_func *func = NULL;
780
781     ASSERT(pvData);
782
783     func = (struct sdio_func *) pvData;
784
785     sdio_claim_host(func);
786     ret = sdio_set_block_size(func, 512);
787     sdio_release_host(func);
788
789     if (ret) {
790         //printk(KERN_INFO DRV_NAME"sdio_set_block_size 512 failed!\n");
791     }
792     else {
793         //printk(KERN_INFO DRV_NAME"sdio_set_block_size 512 done!\n");
794     }
795
796     //printk(KERN_INFO DRV_NAME"param: func->cur_blksize(%d)\n", func->cur_blksize);
797     //printk(KERN_INFO DRV_NAME"param: func->max_blksize(%d)\n", func->max_blksize);
798     //printk(KERN_INFO DRV_NAME"param: func->card->host->max_blk_size(%d)\n", func->card->host->max_blk_size);
799     //printk(KERN_INFO DRV_NAME"param: func->card->host->max_blk_count(%d)\n", func->card->host->max_blk_count);
800 #endif
801     return TRUE;
802 } /* end of glBusInit() */
803
804
805 /*----------------------------------------------------------------------------*/
806 /*!
807 * \brief Stop bus operation and release resources.
808 *
809 * \param[in] pvData A pointer to struct net_device.
810 *
811 * \return (none)
812 */
813 /*----------------------------------------------------------------------------*/
814 VOID
815 glBusRelease (
816     PVOID pvData
817     )
818 {
819
820     return;
821 } /* end of glBusRelease() */
822
823
824 /*----------------------------------------------------------------------------*/
825 /*!
826 * \brief Setup bus interrupt operation and interrupt handler for os.
827 *
828 * \param[in] pvData     A pointer to struct net_device.
829 * \param[in] pfnIsr     A pointer to interrupt handler function.
830 * \param[in] pvCookie   Private data for pfnIsr function.
831 *
832 * \retval WLAN_STATUS_SUCCESS   if success
833 *         NEGATIVE_VALUE   if fail
834 */
835 /*----------------------------------------------------------------------------*/
836 INT_32
837 glBusSetIrq (
838     PVOID pvData,
839     PVOID pfnIsr,
840     PVOID pvCookie
841     )
842 {
843     int ret = 0;
844
845 #if (MTK_WCN_HIF_SDIO == 0)
846     struct net_device *prNetDevice = NULL;
847     P_GLUE_INFO_T prGlueInfo = NULL;
848     P_GL_HIF_INFO_T prHifInfo = NULL;
849
850     ASSERT(pvData);
851     if (!pvData) {
852         return -1;
853     }
854     prNetDevice = (struct net_device *) pvData;
855
856     prGlueInfo = (P_GLUE_INFO_T) netdev_priv(prNetDevice);
857     ASSERT(prGlueInfo);
858     if (!prGlueInfo) {
859         return -1;
860     }
861
862     prHifInfo = &prGlueInfo->rHifInfo;
863
864     sdio_claim_host(prHifInfo->func);
865     ret = sdio_claim_irq(prHifInfo->func, mtk_sdio_interrupt);
866     sdio_release_host(prHifInfo->func);
867 #endif
868     return ret;
869 } /* end of glBusSetIrq() */
870
871
872 /*----------------------------------------------------------------------------*/
873 /*!
874 * \brief Stop bus interrupt operation and disable interrupt handling for os.
875 *
876 * \param[in] pvData     A pointer to struct net_device.
877 * \param[in] pvCookie   Private data for pfnIsr function.
878 *
879 * \return (none)
880 */
881 /*----------------------------------------------------------------------------*/
882 VOID
883 glBusFreeIrq (
884     PVOID pvData,
885     PVOID pvCookie
886     )
887 {
888 #if (MTK_WCN_HIF_SDIO == 0)
889     struct net_device *prNetDevice = NULL;
890     P_GLUE_INFO_T prGlueInfo = NULL;
891     P_GL_HIF_INFO_T prHifInfo = NULL;
892     int ret = 0;
893
894     ASSERT(pvData);
895     if (!pvData) {
896         //printk(KERN_INFO DRV_NAME"%s null pvData\n", __FUNCTION__);
897         return;
898     }
899     prNetDevice = (struct net_device *) pvData;
900
901     prGlueInfo = (P_GLUE_INFO_T) netdev_priv(prNetDevice);
902     ASSERT(prGlueInfo);
903     if (!prGlueInfo) {
904         //printk(KERN_INFO DRV_NAME"%s no glue info\n", __FUNCTION__);
905         return;
906     }
907
908     prHifInfo = &prGlueInfo->rHifInfo;
909
910     sdio_claim_host(prHifInfo->func);
911     ret = sdio_release_irq(prHifInfo->func);
912     sdio_release_host(prHifInfo->func);
913 #endif
914
915     return;
916 } /* end of glBusreeIrq() */
917
918
919 /*----------------------------------------------------------------------------*/
920 /*!
921 * \brief Read a 32-bit device register
922 *
923 * \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure.
924 * \param[in] u4Register Register offset
925 * \param[in] pu4Value   Pointer to variable used to store read value
926 *
927 * \retval TRUE          operation success
928 * \retval FALSE         operation fail
929 */
930 /*----------------------------------------------------------------------------*/
931 BOOL
932 kalDevRegRead (
933     IN  P_GLUE_INFO_T   prGlueInfo,
934     IN  UINT_32         u4Register,
935     OUT PUINT_32        pu4Value
936     )
937 {
938     int ret = 0;
939
940     ASSERT(prGlueInfo);
941     ASSERT(pu4Value);
942
943 #if MTK_WCN_HIF_SDIO
944     ret = mtk_wcn_hif_sdio_readl(prGlueInfo->rHifInfo.cltCtx, u4Register, (PUINT32) pu4Value);
945 #else
946     if (!in_interrupt) {
947         sdio_claim_host(prGlueInfo->rHifInfo.func);
948     }
949
950     *pu4Value = sdio_readl(prGlueInfo->rHifInfo.func, u4Register, &ret);
951
952     if (!in_interrupt) {
953         sdio_release_host(prGlueInfo->rHifInfo.func);
954     }
955 #endif
956
957     if (ret) {
958         DBGLOG(HAL, ERROR, ("sdio_readl() reports error: %x", ret));
959     }
960
961     return (ret) ? FALSE : TRUE;
962 } /* end of kalDevRegRead() */
963
964
965 /*----------------------------------------------------------------------------*/
966 /*!
967 * \brief Write a 32-bit device register
968 *
969 * \param[in] prGlueInfo Pointer to the GLUE_INFO_T structure.
970 * \param[in] u4Register Register offset
971 * \param[in] u4Value    Value to be written
972 *
973 * \retval TRUE          operation success
974 * \retval FALSE         operation fail
975 */
976 /*----------------------------------------------------------------------------*/
977 BOOL
978 kalDevRegWrite (
979     IN P_GLUE_INFO_T  prGlueInfo,
980     IN UINT_32        u4Register,
981     IN UINT_32        u4Value
982     )
983 {
984     int ret = 0;
985
986     ASSERT(prGlueInfo);
987
988 #if MTK_WCN_HIF_SDIO
989     ret = mtk_wcn_hif_sdio_writel(prGlueInfo->rHifInfo.cltCtx, u4Register, u4Value);
990 #else
991     if (!in_interrupt) {
992         sdio_claim_host(prGlueInfo->rHifInfo.func);
993     }
994
995     sdio_writel(prGlueInfo->rHifInfo.func, u4Value, u4Register, &ret);
996
997     if (!in_interrupt) {
998         sdio_release_host(prGlueInfo->rHifInfo.func);
999     }
1000 #endif
1001
1002     if (ret) {
1003         DBGLOG(HAL, ERROR, ("sdio_writel() reports error: %x", ret));
1004     }
1005
1006     return (ret) ? FALSE : TRUE;
1007 } /* end of kalDevRegWrite() */
1008
1009
1010 /*----------------------------------------------------------------------------*/
1011 /*!
1012 * \brief Read device I/O port
1013 *
1014 * \param[in] prGlueInfo         Pointer to the GLUE_INFO_T structure.
1015 * \param[in] u2Port             I/O port offset
1016 * \param[in] u2Len              Length to be read
1017 * \param[out] pucBuf            Pointer to read buffer
1018 * \param[in] u2ValidOutBufSize  Length of the buffer valid to be accessed
1019 *
1020 * \retval TRUE          operation success
1021 * \retval FALSE         operation fail
1022 */
1023 /*----------------------------------------------------------------------------*/
1024 BOOL
1025 kalDevPortRead (
1026     IN  P_GLUE_INFO_T   prGlueInfo,
1027     IN  UINT_16         u2Port,
1028     IN  UINT_16         u2Len,
1029     OUT PUINT_8         pucBuf,
1030     IN  UINT_16         u2ValidOutBufSize
1031     )
1032 {
1033     P_GL_HIF_INFO_T prHifInfo = NULL;
1034     PUINT_8 pucDst = NULL;
1035     int count = u2Len;
1036     int ret = 0;
1037     int bNum = 0;
1038
1039 #if (MTK_WCN_HIF_SDIO == 0)
1040     struct sdio_func *prSdioFunc = NULL;
1041 #endif
1042
1043     #if DBG
1044     //printk(KERN_INFO DRV_NAME"++kalDevPortRead++ buf:0x%p, port:0x%x, length:%d\n", pucBuf, u2Port, u2Len);
1045     #endif
1046
1047     ASSERT(prGlueInfo);
1048     prHifInfo = &prGlueInfo->rHifInfo;
1049
1050     ASSERT(pucBuf);
1051     pucDst = pucBuf;
1052
1053     ASSERT(u2Len <= u2ValidOutBufSize);
1054
1055 #if (MTK_WCN_HIF_SDIO == 0)
1056     prSdioFunc = prHifInfo->func;
1057
1058     ASSERT(prSdioFunc->cur_blksize > 0);
1059
1060     if (!in_interrupt) {
1061         sdio_claim_host(prSdioFunc);
1062     }
1063
1064     /* Split buffer into multiple single block to workaround hifsys */
1065     while (count >= prSdioFunc->cur_blksize) {
1066         count -= prSdioFunc->cur_blksize;
1067         bNum++;
1068     }
1069     if (count > 0 && bNum > 0) {
1070         bNum++;
1071     }
1072
1073     if (bNum > 0) {
1074         ret = sdio_readsb(prSdioFunc, pucDst, u2Port, prSdioFunc->cur_blksize * bNum);
1075
1076 #ifdef CONFIG_X86
1077         /* ENE workaround */
1078         {
1079             int tmp;
1080             sdio_writel(prSdioFunc, 0x0, SDIO_X86_WORKAROUND_WRITE_MCR, &tmp);
1081         }
1082 #endif
1083
1084     }
1085     else {
1086         ret = sdio_readsb(prSdioFunc, pucDst, u2Port, count);
1087     }
1088
1089     if (!in_interrupt) {
1090         sdio_release_host(prSdioFunc);
1091     }
1092 #else
1093
1094     /* Split buffer into multiple single block to workaround hifsys */
1095     while (count >= (prGlueInfo->rHifInfo).prFuncInfo->blk_sz) {
1096         count -= ((prGlueInfo->rHifInfo).prFuncInfo->blk_sz);
1097         bNum++;
1098     }
1099     if (count > 0 && bNum > 0) {
1100         bNum++;
1101     }
1102
1103     if (bNum > 0) {
1104         ret = mtk_wcn_hif_sdio_read_buf(prGlueInfo->rHifInfo.cltCtx, u2Port, (PUINT32) pucDst,
1105                  ((prGlueInfo->rHifInfo).prFuncInfo->blk_sz) * bNum);
1106     }
1107     else {
1108         ret = mtk_wcn_hif_sdio_read_buf(prGlueInfo->rHifInfo.cltCtx, u2Port, (PUINT32) pucDst, count);
1109     }
1110 #endif
1111
1112     if (ret) {
1113         DBGLOG(HAL, ERROR, ("sdio_readsb() reports error: %x", ret));
1114     }
1115
1116     return (ret) ? FALSE : TRUE;
1117 } /* end of kalDevPortRead() */
1118
1119
1120 /*----------------------------------------------------------------------------*/
1121 /*!
1122 * \brief Write device I/O port
1123 *
1124 * \param[in] prGlueInfo         Pointer to the GLUE_INFO_T structure.
1125 * \param[in] u2Port             I/O port offset
1126 * \param[in] u2Len              Length to be write
1127 * \param[in] pucBuf             Pointer to write buffer
1128 * \param[in] u2ValidInBufSize   Length of the buffer valid to be accessed
1129 *
1130 * \retval TRUE          operation success
1131 * \retval FALSE         operation fail
1132 */
1133 /*----------------------------------------------------------------------------*/
1134 BOOL
1135 kalDevPortWrite (
1136     IN P_GLUE_INFO_T  prGlueInfo,
1137     IN UINT_16        u2Port,
1138     IN UINT_16        u2Len,
1139     IN PUINT_8        pucBuf,
1140     IN UINT_16        u2ValidInBufSize
1141     )
1142 {
1143     P_GL_HIF_INFO_T prHifInfo = NULL;
1144     PUINT_8 pucSrc = NULL;
1145     int count = u2Len;
1146     int ret = 0;
1147     int bNum = 0;
1148
1149 #if (MTK_WCN_HIF_SDIO == 0)
1150     struct sdio_func *prSdioFunc = NULL;
1151 #endif
1152
1153     #if DBG
1154     //printk(KERN_INFO DRV_NAME"++kalDevPortWrite++ buf:0x%p, port:0x%x, length:%d\n", pucBuf, u2Port, u2Len);
1155     #endif
1156
1157     ASSERT(prGlueInfo);
1158     prHifInfo = &prGlueInfo->rHifInfo;
1159
1160     ASSERT(pucBuf);
1161     pucSrc = pucBuf;
1162
1163     ASSERT(u2Len <= u2ValidInBufSize);
1164
1165 #if (MTK_WCN_HIF_SDIO == 0)
1166     prSdioFunc = prHifInfo->func;
1167     ASSERT(prSdioFunc->cur_blksize > 0);
1168
1169     if (!in_interrupt) {
1170         sdio_claim_host(prSdioFunc);
1171     }
1172
1173     /* Split buffer into multiple single block to workaround hifsys */
1174     while (count >= prSdioFunc->cur_blksize) {
1175         count -= prSdioFunc->cur_blksize;
1176         bNum++;
1177     }
1178     if (count > 0 && bNum > 0) {
1179         bNum++;
1180     }
1181
1182     if (bNum > 0) { // block mode
1183         ret = sdio_writesb(prSdioFunc, u2Port, pucSrc, prSdioFunc->cur_blksize * bNum);
1184
1185 #ifdef CONFIG_X86
1186         /* ENE workaround */
1187         {
1188             int tmp;
1189             sdio_writel(prSdioFunc, 0x0, SDIO_X86_WORKAROUND_WRITE_MCR, &tmp);
1190         }
1191 #endif
1192
1193     }
1194     else {  // byte mode
1195
1196         ret = sdio_writesb(prSdioFunc, u2Port, pucSrc, count);
1197     }
1198
1199     if (!in_interrupt) {
1200         sdio_release_host(prSdioFunc);
1201     }
1202 #else
1203     /* Split buffer into multiple single block to workaround hifsys */
1204     while (count >= ((prGlueInfo->rHifInfo).prFuncInfo->blk_sz)) {
1205         count -= ((prGlueInfo->rHifInfo).prFuncInfo->blk_sz);
1206         bNum++;
1207     }
1208     if (count > 0 && bNum > 0) {
1209         bNum++;
1210     }
1211
1212     if (bNum > 0) { // block mode
1213         ret = mtk_wcn_hif_sdio_write_buf(prGlueInfo->rHifInfo.cltCtx, u2Port, (PUINT32) pucSrc,
1214                              ((prGlueInfo->rHifInfo).prFuncInfo->blk_sz) * bNum);
1215     }
1216     else {  // byte mode
1217         ret = mtk_wcn_hif_sdio_write_buf(prGlueInfo->rHifInfo.cltCtx, u2Port, (PUINT32) pucSrc, count);
1218     }
1219 #endif
1220
1221     if (ret) {
1222         DBGLOG(HAL, ERROR, ("sdio_writesb() reports error: %x", ret));
1223     }
1224
1225     return (ret) ? FALSE : TRUE;
1226 } /* end of kalDevPortWrite() */
1227
1228
1229 /*----------------------------------------------------------------------------*/
1230 /*!
1231 * \brief Write device I/O port in byte with CMD52
1232 *
1233 * \param[in] prGlueInfo         Pointer to the GLUE_INFO_T structure.
1234 * \param[in] u4Addr             I/O port offset
1235 * \param[in] ucData             Single byte of data to be written
1236 *
1237 * \retval TRUE          operation success
1238 * \retval FALSE         operation fail
1239 */
1240 /*----------------------------------------------------------------------------*/
1241 BOOL
1242 kalDevWriteWithSdioCmd52 (
1243     IN P_GLUE_INFO_T    prGlueInfo,
1244     IN UINT_32          u4Addr,
1245     IN UINT_8           ucData
1246     )
1247 {
1248     int ret = 0;
1249
1250 #if (MTK_WCN_HIF_SDIO == 0)
1251     if (!in_interrupt) {
1252         sdio_claim_host(prGlueInfo->rHifInfo.func);
1253     }
1254
1255     sdio_writeb(prGlueInfo->rHifInfo.func, ucData, u4Addr, &ret);
1256
1257     if (!in_interrupt) {
1258         sdio_release_host(prGlueInfo->rHifInfo.func);
1259     }
1260 #else
1261     ret = mtk_wcn_hif_sdio_writeb(prGlueInfo->rHifInfo.cltCtx, u4Addr, ucData);
1262 #endif
1263
1264     if (ret) {
1265         DBGLOG(HAL, ERROR, ("sdio_writeb() reports error: %x", ret));
1266     }
1267
1268     return (ret) ? FALSE : TRUE;
1269
1270 } /* end of kalDevWriteWithSdioCmd52() */
1271
1272
1273 VOID
1274 glSetPowerState (
1275     IN P_GLUE_INFO_T  prGlueInfo,
1276     IN UINT_32 ePowerMode
1277     )
1278 {
1279     return;
1280 }
1281