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