add MTK-combo-module,continue with commit 17f39ed917874e77e80411f33faba1b7ee8138c8
[firefly-linux-kernel-4.4.55.git] / drivers / mtk_wcn_combo / drv_wlan / wlan / os / linux / gl_proc.c
1 /*
2 ** $Id: //Department/DaVinci/BRANCHES/MT6620_WIFI_DRIVER_V2_2/os/linux/gl_proc.c#1 $
3 */
4
5 /*! \file   "gl_proc.c"
6     \brief  This file defines the interface which can interact with users in /proc fs.
7
8     Detail description.
9 */
10
11 /*******************************************************************************
12 * Copyright (c) 2007 MediaTek Inc.
13 *
14 * All rights reserved. Copying, compilation, modification, distribution
15 * or any other use whatsoever of this material is strictly prohibited
16 * except in accordance with a Software License Agreement with
17 * MediaTek Inc.
18 ********************************************************************************
19 */
20
21 /*******************************************************************************
22 * LEGAL DISCLAIMER
23 *
24 * BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND
25 * AGREES THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK
26 * SOFTWARE") RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE
27 * PROVIDED TO BUYER ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY
28 * DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
29 * LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
30 * PARTICULAR PURPOSE OR NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE
31 * ANY WARRANTY WHATSOEVER WITH RESPECT TO THE SOFTWARE OF ANY THIRD PARTY
32 * WHICH MAY BE USED BY, INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK
33 * SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY
34 * WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE
35 * FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S SPECIFICATION OR TO
36 * CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
37 *
38 * BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
39 * LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL
40 * BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT
41 * ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY
42 * BUYER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
43 *
44 * THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
45 * WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT
46 * OF LAWS PRINCIPLES.  ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING
47 * THEREOF AND RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN
48 * FRANCISCO, CA, UNDER THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE
49 * (ICC).
50 ********************************************************************************
51 */
52
53 /*
54 ** $Log: gl_proc.c $
55  *
56  * 11 10 2011 cp.wu
57  * [WCXRP00001098] [MT6620 Wi-Fi][Driver] Replace printk by DBG LOG macros in linux porting layer
58  * 1. eliminaite direct calls to printk in porting layer.
59  * 2. replaced by DBGLOG, which would be XLOG on ALPS platforms.
60  *
61  * 03 18 2011 cp.wu
62  * [WCXRP00000577] [MT6620 Wi-Fi][Driver][FW] Create V2.0 branch for firmware and driver
63  * create V2.0 driver release based on label "MT6620_WIFI_DRIVER_V2_0_110318_1600" from main trunk
64  *
65  * 12 10 2010 kevin.huang
66  * [WCXRP00000128] [MT6620 Wi-Fi][Driver] Add proc support to Android Driver for debug and driver status check
67  * Add Linux Proc Support
68 **  \main\maintrunk.MT5921\19 2008-09-02 21:08:37 GMT mtk01461
69 **  Fix the compile error of SPRINTF()
70 **  \main\maintrunk.MT5921\18 2008-08-10 18:48:28 GMT mtk01461
71 **  Update for Driver Review
72 **  \main\maintrunk.MT5921\17 2008-08-04 16:52:01 GMT mtk01461
73 **  Add proc dbg print message of DOMAIN_INDEX level
74 **  \main\maintrunk.MT5921\16 2008-07-10 00:45:16 GMT mtk01461
75 **  Remove the check of MCR offset, we may use the MCR address which is not align to DW boundary or proprietary usage.
76 **  \main\maintrunk.MT5921\15 2008-06-03 20:49:44 GMT mtk01461
77 **  \main\maintrunk.MT5921\14 2008-06-02 22:56:00 GMT mtk01461
78 **  Rename some functions for linux proc
79 **  \main\maintrunk.MT5921\13 2008-06-02 20:23:18 GMT mtk01461
80 **  Revise PROC mcr read / write for supporting TELNET
81 **  \main\maintrunk.MT5921\12 2008-03-28 10:40:25 GMT mtk01461
82 **  Remove temporary set desired rate in linux proc
83 **  \main\maintrunk.MT5921\11 2008-01-07 15:07:29 GMT mtk01461
84 **  Add User Update Desired Rate Set for QA in Linux
85 **  \main\maintrunk.MT5921\10 2007-12-11 00:11:14 GMT mtk01461
86 **  Fix SPIN_LOCK protection
87 **  \main\maintrunk.MT5921\9 2007-12-04 18:07:57 GMT mtk01461
88 **  Add additional debug category to proc
89 **  \main\maintrunk.MT5921\8 2007-11-02 01:03:23 GMT mtk01461
90 **  Unify TX Path for Normal and IBSS Power Save + IBSS neighbor learning
91 **  \main\maintrunk.MT5921\7 2007-10-25 18:08:14 GMT mtk01461
92 **  Add VOIP SCAN Support  & Refine Roaming
93 ** Revision 1.3  2007/07/05 07:25:33  MTK01461
94 ** Add Linux initial code, modify doc, add 11BB, RF init code
95 **
96 ** Revision 1.2  2007/06/27 02:18:51  MTK01461
97 ** Update SCAN_FSM, Initial(Can Load Module), Proc(Can do Reg R/W), TX API
98 **
99 */
100
101 /*******************************************************************************
102 *                         C O M P I L E R   F L A G S
103 ********************************************************************************
104 */
105
106 /*******************************************************************************
107 *                    E X T E R N A L   R E F E R E N C E S
108 ********************************************************************************
109 */
110 #include "gl_os.h"
111 #include "gl_kal.h"
112
113 #include "wlan_lib.h"
114 #include "debug.h"
115
116
117 /*******************************************************************************
118 *                              C O N S T A N T S
119 ********************************************************************************
120 */
121 #define PROC_MCR_ACCESS                         "mcr"
122 #define PROC_DRV_STATUS                         "status"
123 #define PROC_RX_STATISTICS                      "rx_statistics"
124 #define PROC_TX_STATISTICS                      "tx_statistics"
125 #define PROC_DBG_LEVEL                          "dbg_level"
126
127 #define PROC_MCR_ACCESS_MAX_USER_INPUT_LEN      20
128 #define PROC_RX_STATISTICS_MAX_USER_INPUT_LEN   10
129 #define PROC_TX_STATISTICS_MAX_USER_INPUT_LEN   10
130 #define PROC_DBG_LEVEL_MAX_USER_INPUT_LEN       20
131 #define PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN      30
132
133
134 /*******************************************************************************
135 *                             D A T A   T Y P E S
136 ********************************************************************************
137 */
138
139 /*******************************************************************************
140 *                            P U B L I C   D A T A
141 ********************************************************************************
142 */
143
144 /*******************************************************************************
145 *                           P R I V A T E   D A T A
146 ********************************************************************************
147 */
148 static UINT_32 u4McrOffset = 0;
149
150 /*******************************************************************************
151 *                                 M A C R O S
152 ********************************************************************************
153 */
154
155 /*******************************************************************************
156 *                   F U N C T I O N   D E C L A R A T I O N S
157 ********************************************************************************
158 */
159
160 /*******************************************************************************
161 *                              F U N C T I O N S
162 ********************************************************************************
163 */
164 /*----------------------------------------------------------------------------*/
165 /*!
166 * \brief The PROC function for reading MCR register to User Space, the offset of
167 *        the MCR is specified in u4McrOffset.
168 *
169 * \param[in] page       Buffer provided by kernel.
170 * \param[in out] start  Start Address to read(3 methods).
171 * \param[in] off        Offset.
172 * \param[in] count      Allowable number to read.
173 * \param[out] eof       End of File indication.
174 * \param[in] data       Pointer to the private data structure.
175 *
176 * \return number of characters print to the buffer from User Space.
177 */
178 /*----------------------------------------------------------------------------*/
179 static int
180 procMCRRead (
181     char *page,
182     char **start,
183     off_t off,
184     int count,
185     int *eof,
186     void *data
187     )
188 {
189     P_GLUE_INFO_T prGlueInfo; 
190     PARAM_CUSTOM_MCR_RW_STRUC_T rMcrInfo;
191     UINT_32 u4BufLen;
192     char *p = page;
193     UINT_32 u4Count;
194     WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
195
196
197     ASSERT(data);
198
199     // Kevin: Apply PROC read method 1.
200     if (off != 0) {
201         return 0; // To indicate end of file.
202     }
203
204     prGlueInfo = (P_GLUE_INFO_T) netdev_priv((struct net_device *)data);
205
206     rMcrInfo.u4McrOffset = u4McrOffset;
207
208     rStatus = kalIoctl(prGlueInfo,
209                         wlanoidQueryMcrRead,
210                         (PVOID)&rMcrInfo,
211                         sizeof(rMcrInfo),
212                         TRUE,
213                         TRUE,
214                         TRUE,
215                         FALSE,
216                         &u4BufLen);
217
218
219     SPRINTF(p, ("MCR (0x%08lxh): 0x%08lx\n",
220         rMcrInfo.u4McrOffset, rMcrInfo.u4McrData));
221
222     u4Count = (UINT_32)(p - page);
223
224     *eof = 1;
225
226     return (int)u4Count;
227
228 } /* end of procMCRRead() */
229
230
231 /*----------------------------------------------------------------------------*/
232 /*!
233 * \brief The PROC function for writing MCR register to HW or update u4McrOffset
234 *        for reading MCR later.
235 *
236 * \param[in] file   pointer to file.
237 * \param[in] buffer Buffer from user space.
238 * \param[in] count  Number of characters to write
239 * \param[in] data   Pointer to the private data structure.
240 *
241 * \return number of characters write from User Space.
242 */
243 /*----------------------------------------------------------------------------*/
244 static int
245 procMCRWrite (
246     struct file *file,
247     const char *buffer,
248     unsigned long count,
249     void *data
250     )
251 {
252     P_GLUE_INFO_T prGlueInfo; 
253     char acBuf[PROC_MCR_ACCESS_MAX_USER_INPUT_LEN + 1]; // + 1 for "\0"
254     int i4CopySize;
255     PARAM_CUSTOM_MCR_RW_STRUC_T rMcrInfo;
256     UINT_32 u4BufLen;
257     WLAN_STATUS rStatus = WLAN_STATUS_SUCCESS;
258
259
260     ASSERT(data);
261
262     i4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1);
263     if (copy_from_user(acBuf, buffer, i4CopySize)) {
264         return 0;
265     }
266     acBuf[i4CopySize] = '\0';
267
268     switch (sscanf(acBuf, "0x%lx 0x%lx",
269                    &rMcrInfo.u4McrOffset, &rMcrInfo.u4McrData)) {
270     case 2:
271         /* NOTE: Sometimes we want to test if bus will still be ok, after accessing
272          * the MCR which is not align to DW boundary.
273          */
274         //if (IS_ALIGN_4(rMcrInfo.u4McrOffset))
275         {
276             prGlueInfo = (P_GLUE_INFO_T) netdev_priv((struct net_device *)data);
277  
278             u4McrOffset = rMcrInfo.u4McrOffset;
279
280             //printk("Write 0x%lx to MCR 0x%04lx\n",
281                 //rMcrInfo.u4McrOffset, rMcrInfo.u4McrData);
282
283             rStatus = kalIoctl(prGlueInfo,
284                                 wlanoidSetMcrWrite,
285                                 (PVOID)&rMcrInfo,
286                                 sizeof(rMcrInfo),
287                                 FALSE,
288                                 FALSE,
289                                 TRUE,
290                                 FALSE,
291                                 &u4BufLen);
292
293         }
294         break;
295
296     case 1:
297         //if (IS_ALIGN_4(rMcrInfo.u4McrOffset))
298         {
299             u4McrOffset = rMcrInfo.u4McrOffset;
300         }
301         break;
302
303     default:
304         break;
305     }
306
307     return count;
308
309 } /* end of procMCRWrite() */
310
311 #if 0
312 /*----------------------------------------------------------------------------*/
313 /*!
314 * \brief The PROC function for reading Driver Status to User Space.
315 *
316 * \param[in] page       Buffer provided by kernel.
317 * \param[in out] start  Start Address to read(3 methods).
318 * \param[in] off        Offset.
319 * \param[in] count      Allowable number to read.
320 * \param[out] eof       End of File indication.
321 * \param[in] data       Pointer to the private data structure.
322 *
323 * \return number of characters print to the buffer from User Space.
324 */
325 /*----------------------------------------------------------------------------*/
326 static int
327 procDrvStatusRead (
328     char *page,
329     char **start,
330     off_t off,
331     int count,
332     int *eof,
333     void *data
334     )
335 {
336     P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv;
337     char *p = page;
338     UINT_32 u4Count;
339
340     GLUE_SPIN_LOCK_DECLARATION();
341
342
343     ASSERT(data);
344
345     // Kevin: Apply PROC read method 1.
346     if (off != 0) {
347         return 0; // To indicate end of file.
348     }
349
350
351     SPRINTF(p, ("GLUE LAYER STATUS:"));
352     SPRINTF(p, ("\n=================="));
353
354     SPRINTF(p, ("\n* Number of Pending Frames: %ld\n",
355         prGlueInfo->u4TxPendingFrameNum));
356
357     GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM);
358
359     wlanoidQueryDrvStatusForLinuxProc(prGlueInfo->prAdapter, p, &u4Count);
360
361     GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM);
362
363     u4Count += (UINT_32)(p - page);
364
365     *eof = 1;
366
367     return (int)u4Count;
368
369 } /* end of procDrvStatusRead() */
370
371
372 /*----------------------------------------------------------------------------*/
373 /*!
374 * \brief The PROC function for reading Driver RX Statistic Counters to User Space.
375 *
376 * \param[in] page       Buffer provided by kernel.
377 * \param[in out] start  Start Address to read(3 methods).
378 * \param[in] off        Offset.
379 * \param[in] count      Allowable number to read.
380 * \param[out] eof       End of File indication.
381 * \param[in] data       Pointer to the private data structure.
382 *
383 * \return number of characters print to the buffer from User Space.
384 */
385 /*----------------------------------------------------------------------------*/
386 static int
387 procRxStatisticsRead (
388     char *page,
389     char **start,
390     off_t off,
391     int count,
392     int *eof,
393     void *data
394     )
395 {
396     P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv;
397     char *p = page;
398     UINT_32 u4Count;
399
400     GLUE_SPIN_LOCK_DECLARATION();
401
402
403     ASSERT(data);
404
405     // Kevin: Apply PROC read method 1.
406     if (off != 0) {
407         return 0; // To indicate end of file.
408     }
409
410
411     SPRINTF(p, ("RX STATISTICS (Write 1 to clear):"));
412     SPRINTF(p, ("\n=================================\n"));
413
414     GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM);
415
416     wlanoidQueryRxStatisticsForLinuxProc(prGlueInfo->prAdapter, p, &u4Count);
417
418     GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM);
419
420     u4Count += (UINT_32)(p - page);
421
422     *eof = 1;
423
424     return (int)u4Count;
425
426 } /* end of procRxStatisticsRead() */
427
428
429 /*----------------------------------------------------------------------------*/
430 /*!
431 * \brief The PROC function for reset Driver RX Statistic Counters.
432 *
433 * \param[in] file   pointer to file.
434 * \param[in] buffer Buffer from user space.
435 * \param[in] count  Number of characters to write
436 * \param[in] data   Pointer to the private data structure.
437 *
438 * \return number of characters write from User Space.
439 */
440 /*----------------------------------------------------------------------------*/
441 static int
442 procRxStatisticsWrite (
443     struct file *file,
444     const char *buffer,
445     unsigned long count,
446     void *data
447     )
448 {
449     P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv;
450     char acBuf[PROC_RX_STATISTICS_MAX_USER_INPUT_LEN + 1]; // + 1 for "\0"
451     UINT_32 u4CopySize;
452     UINT_32 u4ClearCounter;
453
454     GLUE_SPIN_LOCK_DECLARATION();
455
456
457     ASSERT(data);
458
459     u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1);
460     copy_from_user(acBuf, buffer, u4CopySize);
461     acBuf[u4CopySize] = '\0';
462
463     if (sscanf(acBuf, "%ld", &u4ClearCounter) == 1) {
464         if (u4ClearCounter == 1) {
465             GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM);
466
467             wlanoidSetRxStatisticsForLinuxProc(prGlueInfo->prAdapter);
468
469             GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM);
470         }
471     }
472
473     return count;
474
475 } /* end of procRxStatisticsWrite() */
476
477
478 /*----------------------------------------------------------------------------*/
479 /*!
480 * \brief The PROC function for reading Driver TX Statistic Counters to User Space.
481 *
482 * \param[in] page       Buffer provided by kernel.
483 * \param[in out] start  Start Address to read(3 methods).
484 * \param[in] off        Offset.
485 * \param[in] count      Allowable number to read.
486 * \param[out] eof       End of File indication.
487 * \param[in] data       Pointer to the private data structure.
488 *
489 * \return number of characters print to the buffer from User Space.
490 */
491 /*----------------------------------------------------------------------------*/
492 static int
493 procTxStatisticsRead (
494     char *page,
495     char **start,
496     off_t off,
497     int count,
498     int *eof,
499     void *data
500     )
501 {
502     P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv;
503     char *p = page;
504     UINT_32 u4Count;
505
506     GLUE_SPIN_LOCK_DECLARATION();
507
508
509     ASSERT(data);
510
511     // Kevin: Apply PROC read method 1.
512     if (off != 0) {
513         return 0; // To indicate end of file.
514     }
515
516
517     SPRINTF(p, ("TX STATISTICS (Write 1 to clear):"));
518     SPRINTF(p, ("\n=================================\n"));
519
520     GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM);
521
522     wlanoidQueryTxStatisticsForLinuxProc(prGlueInfo->prAdapter, p, &u4Count);
523
524     GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM);
525
526     u4Count += (UINT_32)(p - page);
527
528     *eof = 1;
529
530     return (int)u4Count;
531
532 } /* end of procTxStatisticsRead() */
533
534
535 /*----------------------------------------------------------------------------*/
536 /*!
537 * \brief The PROC function for reset Driver TX Statistic Counters.
538 *
539 * \param[in] file   pointer to file.
540 * \param[in] buffer Buffer from user space.
541 * \param[in] count  Number of characters to write
542 * \param[in] data   Pointer to the private data structure.
543 *
544 * \return number of characters write from User Space.
545 */
546 /*----------------------------------------------------------------------------*/
547 static int
548 procTxStatisticsWrite (
549     struct file *file,
550     const char *buffer,
551     unsigned long count,
552     void *data
553     )
554 {
555     P_GLUE_INFO_T prGlueInfo = ((struct net_device *)data)->priv;
556     char acBuf[PROC_RX_STATISTICS_MAX_USER_INPUT_LEN + 1]; // + 1 for "\0"
557     UINT_32 u4CopySize;
558     UINT_32 u4ClearCounter;
559
560     GLUE_SPIN_LOCK_DECLARATION();
561
562
563     ASSERT(data);
564
565     u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1);
566     copy_from_user(acBuf, buffer, u4CopySize);
567     acBuf[u4CopySize] = '\0';
568
569     if (sscanf(acBuf, "%ld", &u4ClearCounter) == 1) {
570         if (u4ClearCounter == 1) {
571             GLUE_ACQUIRE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM);
572
573             wlanoidSetTxStatisticsForLinuxProc(prGlueInfo->prAdapter);
574
575             GLUE_RELEASE_SPIN_LOCK(prGlueInfo, SPIN_LOCK_FSM);
576         }
577     }
578
579     return count;
580
581 } /* end of procTxStatisticsWrite() */
582 #endif
583
584
585 #if DBG
586 static UINT_8 aucDbModuleName[][PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN] = {
587     "DBG_INIT_IDX",
588     "DBG_HAL_IDX",
589     "DBG_INTR_IDX",
590     "DBG_REQ_IDX",    
591     "DBG_TX_IDX",
592     "DBG_RX_IDX",
593     "DBG_RFTEST_IDX",
594     "DBG_EMU_IDX",    
595     "DBG_SW1_IDX",
596     "DBG_SW2_IDX",
597     "DBG_SW3_IDX",
598     "DBG_SW4_IDX",    
599     "DBG_HEM_IDX",
600     "DBG_AIS_IDX",
601     "DBG_RLM_IDX",
602     "DBG_MEM_IDX",
603     "DBG_CNM_IDX",    
604     "DBG_RSN_IDX",
605     "DBG_BSS_IDX",
606     "DBG_SCN_IDX",
607     "DBG_SAA_IDX",
608     "DBG_AAA_IDX",
609     "DBG_P2P_IDX",
610     "DBG_QM_IDX",
611     "DBG_SEC_IDX",
612     "DBG_BOW_IDX"
613     };
614     
615 extern UINT_8 aucDebugModule[];
616
617
618 /*----------------------------------------------------------------------------*/
619 /*!
620 * \brief The PROC function for displaying current Debug Level.
621 *
622 * \param[in] page       Buffer provided by kernel.
623 * \param[in out] start  Start Address to read(3 methods).
624 * \param[in] off        Offset.
625 * \param[in] count      Allowable number to read.
626 * \param[out] eof       End of File indication.
627 * \param[in] data       Pointer to the private data structure.
628 *
629 * \return number of characters print to the buffer from User Space.
630 */
631 /*----------------------------------------------------------------------------*/
632 static int
633 procDbgLevelRead (
634     char *page,
635     char **start,
636     off_t off,
637     int count,
638     int *eof,
639     void *data
640     )
641 {
642     char *p = page;
643     int i;
644
645
646
647     // Kevin: Apply PROC read method 1.
648     if (off != 0) {
649         return 0; // To indicate end of file.
650     }
651
652     for (i = 0; i < (sizeof(aucDbModuleName)/PROC_DBG_LEVEL_MAX_DISPLAY_STR_LEN); i++) {
653         SPRINTF(p, ("%c %-15s(0x%02x): %02x\n",
654             ((i == u4DebugModule) ? '*' : ' '),
655             &aucDbModuleName[i][0],
656             i,
657             aucDebugModule[i]));
658     }
659
660     *eof = 1;
661     return (int)(p - page);
662 }
663
664
665 /*----------------------------------------------------------------------------*/
666 /*!
667 * \brief The PROC function for adjusting Debug Level to turn on/off debugging message.
668 *
669 * \param[in] file   pointer to file.
670 * \param[in] buffer Buffer from user space.
671 * \param[in] count  Number of characters to write
672 * \param[in] data   Pointer to the private data structure.
673 *
674 * \return number of characters write from User Space.
675 */
676 /*----------------------------------------------------------------------------*/
677 static int
678 procDbgLevelWrite (
679     struct file *file,
680     const char *buffer,
681     unsigned long count,
682     void *data
683     )
684 {
685     char acBuf[PROC_DBG_LEVEL_MAX_USER_INPUT_LEN + 1]; // + 1 for "\0"
686     UINT_32 u4CopySize;
687     UINT_32 u4NewDbgModule, u4NewDbgLevel;
688
689
690     u4CopySize = (count < (sizeof(acBuf) - 1)) ? count : (sizeof(acBuf) - 1);
691     copy_from_user(acBuf, buffer, u4CopySize);
692     acBuf[u4CopySize] = '\0';
693
694     if (sscanf(acBuf, "0x%lx 0x%lx", &u4NewDbgModule, &u4NewDbgLevel) == 2) {
695         if (u4NewDbgModule < DBG_MODULE_NUM) {
696             u4DebugModule = u4NewDbgModule;
697             u4NewDbgLevel &= DBG_CLASS_MASK;
698             aucDebugModule[u4DebugModule] = (UINT_8)u4NewDbgLevel;
699         }
700     }
701
702     return count;
703 }
704 #endif /* DBG */
705
706
707 /*----------------------------------------------------------------------------*/
708 /*!
709 * \brief This function create a PROC fs in linux /proc/net subdirectory.
710 *
711 * \param[in] prDev      Pointer to the struct net_device.
712 * \param[in] pucDevName Pointer to the name of net_device.
713 *
714 * \return N/A
715 */
716 /*----------------------------------------------------------------------------*/
717 INT_32
718 procInitProcfs (
719     struct net_device *prDev,
720     char *pucDevName
721     )
722 {
723     P_GLUE_INFO_T prGlueInfo;
724     struct proc_dir_entry *prEntry;
725
726
727     ASSERT(prDev);
728
729     if (init_net.proc_net == (struct proc_dir_entry *)NULL) {
730         DBGLOG(INIT, INFO, ("init proc fs fail: proc_net == NULL\n"));
731         return -ENOENT;
732     }
733
734     prGlueInfo = (P_GLUE_INFO_T) netdev_priv(prDev);
735
736     if (!prGlueInfo) {
737         DBGLOG(INIT, WARN, ("The OS context is NULL\n"));
738         return -ENOENT;
739     }
740
741
742     /*
743     /proc/net/wlan0
744                |-- mcr              (PROC_MCR_ACCESS)
745                |-- status           (PROC_DRV_STATUS)
746                |-- rx_statistics    (PROC_RX_STATISTICS)
747                |-- tx_statistics    (PROC_TX_STATISTICS)
748                |-- dbg_level        (PROC_DBG_LEVEL)
749                |-- (end)
750      */
751
752     /*
753     * Directory: Root (/proc/net/wlan0)
754     */
755
756     prGlueInfo->pProcRoot = proc_mkdir(pucDevName, init_net.proc_net);
757     if (prGlueInfo->pProcRoot == NULL) {
758         return -ENOENT;
759     }
760
761     /* File Root/mcr (RW) */
762     prEntry = create_proc_entry(PROC_MCR_ACCESS, 0, prGlueInfo->pProcRoot);
763     if (prEntry) {
764         prEntry->read_proc = procMCRRead;
765         prEntry->write_proc = procMCRWrite;
766         prEntry->data = (void *)prDev;
767     }
768
769 #if 0
770     /* File Root/status (RW) */
771     prEntry = create_proc_read_entry(PROC_DRV_STATUS, 0, prGlueInfo->pProcRoot,
772                                      procDrvStatusRead, prDev);
773
774     /* File Root/rx_statistics (RW) */
775     prEntry = create_proc_entry(PROC_RX_STATISTICS, 0, prGlueInfo->pProcRoot);
776     if (prEntry) {
777         prEntry->read_proc = procRxStatisticsRead;
778         prEntry->write_proc = procRxStatisticsWrite;
779         prEntry->data = (void *)prDev;
780     }
781
782     /* File Root/tx_statistics (RW) */
783     prEntry = create_proc_entry(PROC_TX_STATISTICS, 0, prGlueInfo->pProcRoot);
784     if (prEntry) {
785         prEntry->read_proc = procTxStatisticsRead;
786         prEntry->write_proc = procTxStatisticsWrite;
787         prEntry->data = (void *)prDev;
788     }
789
790 #if DBG
791     /* File Root/dbg_level (RW) */
792     prEntry = create_proc_entry(PROC_DBG_LEVEL, 0644, prGlueInfo->pProcRoot);
793     if (prEntry) {
794         prEntry->read_proc = procDbgLevelRead;
795         prEntry->write_proc = procDbgLevelWrite;
796     }
797 #endif /* DBG */
798 #endif
799     return 0;
800
801 } /* end of procInitProcfs() */
802
803
804 /*----------------------------------------------------------------------------*/
805 /*!
806 * \brief This function clean up a PROC fs created by procInitProcfs().
807 *
808 * \param[in] prDev      Pointer to the struct net_device.
809 * \param[in] pucDevName Pointer to the name of net_device.
810 *
811 * \return N/A
812 */
813 /*----------------------------------------------------------------------------*/
814 INT_32
815 procRemoveProcfs (
816     struct net_device *prDev,
817     char *pucDevName
818     )
819 {
820     P_GLUE_INFO_T prGlueInfo = NULL;
821
822
823     ASSERT(prDev);
824
825     if (!prDev) {
826         return -ENOENT;
827     }
828
829     if (init_net.proc_net == (struct proc_dir_entry *)NULL) {
830         DBGLOG(INIT, WARN, ("remove proc fs fail: proc_net == NULL\n"));
831         return -ENOENT;
832     }
833
834     prGlueInfo = (P_GLUE_INFO_T) netdev_priv(prDev);
835     if (!prGlueInfo->pProcRoot) {
836         DBGLOG(INIT, WARN, ("The procfs root is NULL\n"));
837         return -ENOENT;
838     }
839 #if 0
840 #if DBG
841     remove_proc_entry(PROC_DBG_LEVEL,       prGlueInfo->pProcRoot);
842 #endif /* DBG */
843     remove_proc_entry(PROC_TX_STATISTICS,   prGlueInfo->pProcRoot);
844     remove_proc_entry(PROC_RX_STATISTICS,   prGlueInfo->pProcRoot);
845     remove_proc_entry(PROC_DRV_STATUS,      prGlueInfo->pProcRoot);
846 #endif
847     remove_proc_entry(PROC_MCR_ACCESS,      prGlueInfo->pProcRoot);
848
849     /* remove root directory (proc/net/wlan0) */
850     remove_proc_entry(pucDevName, init_net.proc_net);
851
852     return 0;
853
854 } /* end of procRemoveProcfs() */
855