zoukankan      html  css  js  c++  java
  • qcom wlan kernel 解读 WCNSS_qcom_cfg.ini 文件

    CORE/HDD/src/wlan_hdd_main.c
    模块初始化:
    static int __init hdd_module_init ( void)
    {
       return hdd_driver_init();
    }
    
    static int hdd_driver_init( void)
    {
       VOS_STATUS status;
       v_CONTEXT_t pVosContext = NULL;
       struct device *dev = NULL;
       int ret_status = 0;
    #ifdef HAVE_WCNSS_CAL_DOWNLOAD
       int max_retries = 0;
    #endif
    #ifdef HAVE_CBC_DONE
       int max_cbc_retries = 0;
    #endif
    
    #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
       wlan_logging_sock_init_svc();
    #endif
    
       ENTER();
    
       vos_wake_lock_init(&wlan_wake_lock, "wlan");
    
       pr_info("%s: loading driver v%s
    ", WLAN_MODULE_NAME,
               QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
    
    #ifdef ANI_BUS_TYPE_PCI
    
       dev = wcnss_wlan_get_device();
    
    #endif // ANI_BUS_TYPE_PCI
    
    #ifdef ANI_BUS_TYPE_PLATFORM
    
    #ifdef HAVE_WCNSS_CAL_DOWNLOAD
       /* wait until WCNSS driver downloads NV */
       while (!wcnss_device_ready() && 10 >= ++max_retries) {
           msleep(1000);
       }
    
       if (max_retries >= 10) {
          hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WCNSS driver not ready", __func__);
          vos_wake_lock_destroy(&wlan_wake_lock);
    #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
          wlan_logging_sock_deinit_svc();
    #endif
    
          return -ENODEV;
       }
    #endif
    
    #ifdef HAVE_CBC_DONE
       while (!wcnss_cbc_complete() && 10 >= ++max_cbc_retries) {
           msleep(1000);
       }
       if (max_cbc_retries >= 10) {
          hddLog(VOS_TRACE_LEVEL_FATAL, "%s:CBC not completed", __func__);
       }
    #endif
    
       dev = wcnss_wlan_get_device();
    #endif // ANI_BUS_TYPE_PLATFORM
    
    
       do {
          if (NULL == dev) {
             hddLog(VOS_TRACE_LEVEL_FATAL, "%s: WLAN device not found!!",__func__);
             ret_status = -1;
             break;
       }
    
    #ifdef TIMER_MANAGER
          vos_timer_manager_init();
    #endif
    
          /* Preopen VOSS so that it is ready to start at least SAL */
          status = vos_preOpen(&pVosContext);
    
       if (!VOS_IS_STATUS_SUCCESS(status))
       {
             hddLog(VOS_TRACE_LEVEL_FATAL,"%s: Failed to preOpen VOSS", __func__);
             ret_status = -1;
             break;
       }
    
       hddTraceInit();
       hdd_register_debug_callback();
    
    #ifndef MODULE
          /* For statically linked driver, call hdd_set_conparam to update curr_con_mode
           */
          hdd_set_conparam((v_UINT_t)con_mode);
    #endif
    
          // Call our main init function
          if (hdd_wlan_startup(dev))
          {
             hddLog(VOS_TRACE_LEVEL_FATAL,"%s: WLAN Driver Initialization failed",
                    __func__);
             vos_preClose( &pVosContext );
             ret_status = -1;
             break;
          }
    
       } while (0);
    
       if (0 != ret_status)
       {
    #ifdef TIMER_MANAGER
          vos_timer_exit();
    #endif
    #ifdef MEMORY_DEBUG
          vos_mem_exit();
    #endif
          vos_wake_lock_destroy(&wlan_wake_lock);
    #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
          wlan_logging_sock_deinit_svc();
    #endif
    
          pr_err("%s: driver load failure
    ", WLAN_MODULE_NAME);
       }
       else
       {
          //Send WLAN UP indication to Nlink Service
          send_btc_nlink_msg(WLAN_MODULE_UP_IND, 0);
    
          pr_info("%s: driver loaded
    ", WLAN_MODULE_NAME);
       }
    
       EXIT();
    
       return ret_status;
    }
    
    int hdd_wlan_startup(struct device *dev )
    {
    	....
       // Read and parse the qcom_cfg.ini file
       status = hdd_parse_config_ini( pHddCtx );
       if ( VOS_STATUS_SUCCESS != status )
       {
          hddLog(VOS_TRACE_LEVEL_FATAL, "%s: error parsing %s",
                 __func__, WLAN_INI_FILE);
          goto err_config;
       }
    #ifdef MEMORY_DEBUG
       if (pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled)
          vos_mem_init();
    
       hddLog(VOS_TRACE_LEVEL_INFO, "%s: gEnableMemoryDebug=%d",
              __func__, pHddCtx->cfg_ini->IsMemoryDebugSupportEnabled);
    #endif
    
    ...
    	// 设置日志输出的等级
       // Update VOS trace levels based upon the cfg.ini
       hdd_vos_trace_enable(VOS_MODULE_ID_BAP,
                            pHddCtx->cfg_ini->vosTraceEnableBAP);
       hdd_vos_trace_enable(VOS_MODULE_ID_TL,
                            pHddCtx->cfg_ini->vosTraceEnableTL);
       hdd_vos_trace_enable(VOS_MODULE_ID_WDI,
                            pHddCtx->cfg_ini->vosTraceEnableWDI);
       hdd_vos_trace_enable(VOS_MODULE_ID_HDD,
                            pHddCtx->cfg_ini->vosTraceEnableHDD);
       hdd_vos_trace_enable(VOS_MODULE_ID_SME,
                            pHddCtx->cfg_ini->vosTraceEnableSME);
       hdd_vos_trace_enable(VOS_MODULE_ID_PE,
                            pHddCtx->cfg_ini->vosTraceEnablePE);
       hdd_vos_trace_enable(VOS_MODULE_ID_PMC,
                             pHddCtx->cfg_ini->vosTraceEnablePMC);
       hdd_vos_trace_enable(VOS_MODULE_ID_WDA,
                            pHddCtx->cfg_ini->vosTraceEnableWDA);
       hdd_vos_trace_enable(VOS_MODULE_ID_SYS,
                            pHddCtx->cfg_ini->vosTraceEnableSYS);
       hdd_vos_trace_enable(VOS_MODULE_ID_VOSS,
                            pHddCtx->cfg_ini->vosTraceEnableVOSS);
       hdd_vos_trace_enable(VOS_MODULE_ID_SAP,
                            pHddCtx->cfg_ini->vosTraceEnableSAP);
       hdd_vos_trace_enable(VOS_MODULE_ID_HDD_SOFTAP,
                            pHddCtx->cfg_ini->vosTraceEnableHDDSAP);
    
       // Update WDI trace levels based upon the cfg.ini
       hdd_wdi_trace_enable(eWLAN_MODULE_DAL,
                            pHddCtx->cfg_ini->wdiTraceEnableDAL);
       hdd_wdi_trace_enable(eWLAN_MODULE_DAL_CTRL,
                            pHddCtx->cfg_ini->wdiTraceEnableCTL);
       hdd_wdi_trace_enable(eWLAN_MODULE_DAL_DATA,
                            pHddCtx->cfg_ini->wdiTraceEnableDAT);
       hdd_wdi_trace_enable(eWLAN_MODULE_PAL,
                            pHddCtx->cfg_ini->wdiTraceEnablePAL);
    	...
    
    }
    
    static void hdd_vos_trace_enable(VOS_MODULE_ID moduleId, v_U32_t bitmask)
    {
       wpt_tracelevel level;
    
       /* if the bitmask is the default value, then a bitmask was not
          specified in cfg.ini, so leave the logging level alone (it
          will remain at the "compiled in" default value) */
       //	0xffff
       if (CFG_VOS_TRACE_ENABLE_DEFAULT == bitmask)
       {
          return;
       }
    
       /* a mask was specified.  start by disabling all logging */
       vos_trace_setValue(moduleId, VOS_TRACE_LEVEL_NONE, 0);
    
       /* now cycle through the bitmask until all "set" bits are serviced */
       level = VOS_TRACE_LEVEL_FATAL;
       while (0 != bitmask)
       {
          if (bitmask & 1)
          {
             vos_trace_setValue(moduleId, level, 1);
          }
          level++;
          bitmask >>= 1;
       }
    }
    
    
    CORE/HDD/src/wlan_hdd_cfg.c
    VOS_STATUS hdd_parse_config_ini(hdd_context_t* pHddCtx)
    {
       int status, i=0;
       /** Pointer for firmware image data */
       const struct firmware *fw = NULL;
       char *buffer, *line, *pTemp = NULL;
       size_t size;
       char *name, *value;
       /* cfgIniTable is static to avoid excess stack usage */
       //MAX_CFG_INI_ITEMS   512, 最多512条
       static tCfgIniEntry cfgIniTable[MAX_CFG_INI_ITEMS];
       VOS_STATUS vos_status = VOS_STATUS_SUCCESS;
    
       memset(cfgIniTable, 0, sizeof(cfgIniTable));
    
       status = request_firmware(&fw, WLAN_INI_FILE, pHddCtx->parent_dev);
    
       if(status)
       {
          hddLog(VOS_TRACE_LEVEL_FATAL, "%s: request_firmware failed %d",__func__, status);
          vos_status = VOS_STATUS_E_FAILURE;
          goto config_exit;
       }
       if(!fw || !fw->data || !fw->size)
       {
          hddLog(VOS_TRACE_LEVEL_FATAL, "%s: %s download failed",
                 __func__, WLAN_INI_FILE);
          vos_status = VOS_STATUS_E_FAILURE;
          goto config_exit;
       }
    
       hddLog(VOS_TRACE_LEVEL_INFO , "%s: qcom_cfg.ini Size %zu", __func__, fw->size);
    
       buffer = (char*)vos_mem_vmalloc(fw->size);
    
       if(NULL == buffer) {
          hddLog(VOS_TRACE_LEVEL_FATAL, "%s: kmalloc failure",__func__);
          release_firmware(fw);
          return VOS_STATUS_E_FAILURE;
       }
       pTemp = buffer;
    
       vos_mem_copy((void*)buffer,(void *)fw->data, fw->size);
       size = fw->size;
    
       while (buffer != NULL)
       {
          /*
           * get_next_line function used to modify the 
     and 
     delimiter
           * to  before returning, without checking if it is over parsing the
           * source buffer. So changed the function not to modify the buffer
           * passed to it and letting the calling/caller function to take
           * care of the return pointer validation and modification of the buffer.
           * So validating if the return pointer is not greater than the end
           * buffer address and modifying the buffer value.
           */
          line = get_next_line(buffer, (pTemp + (fw->size-1)));
          if(line >= (pTemp + fw->size)) {
             hddLog(VOS_TRACE_LEVEL_FATAL, "%s: INI file seems to be corrupted",
                      __func__);
             vos_status = VOS_STATUS_E_FAILURE;
             goto config_exit;
          }
          else if(line) {
             *(line - 1) = '';
          }
    
          buffer = i_trim(buffer);
    
          hddLog(LOG1, "%s: item", buffer);
    		// "#"注释不解读
          if(strlen((char*)buffer) == 0 || *buffer == '#')  {
             buffer = line;
             continue;
          }
    	  // 匹配到END退出解读ini文件
          else if(strncmp(buffer, "END", 3) == 0 ) {
             break;
          }
          else
          {
             name = buffer;
             while(*buffer != '=' && *buffer != '')
                buffer++;
             if(*buffer != '') {
                *buffer++ = '';
                i_trim(name);
                if(strlen (name) != 0) {
                   buffer = i_trim(buffer);
                   if(strlen(buffer)>0) {
                      value = buffer;
                      while(!i_isspace(*buffer) && *buffer != '')
                         buffer++;
                      *buffer = '';
                      cfgIniTable[i].name= name;
                      cfgIniTable[i++].value= value;
                      if(i >= MAX_CFG_INI_ITEMS) {
                         hddLog(LOGE,"%s: Number of items in %s > %d",
                            __func__, WLAN_INI_FILE, MAX_CFG_INI_ITEMS);
                         break;
                      }
                   }
                }
             }
          }
          buffer = line;
       }
    
       //Loop through the registry table and apply all these configs
       vos_status = hdd_apply_cfg_ini(pHddCtx, cfgIniTable, i);
    
    config_exit:
       release_firmware(fw);
       vos_mem_vfree(pTemp);
       return vos_status;
    }
    

    2018-8-13, Shenzhen

  • 相关阅读:
    《Effective C#》读书笔记——条目22:通过定义并实现接口替代继承<使用C#表达设计>
    《Effective C#》读书笔记——条目23:理解接口方法和虚方法的区别<使用C#表达设计>
    《Effective C#》读书笔记——条目27:让类型支持序列化<使用C#表达设计>
    《Effective C#》读书笔记——条目28:提供粗粒度的互联网API<使用C#表达设计>
    《Effective C#》读书笔记——条目21:限制类型的可见性<使用C#表达设计>
    《Effective C#》读书笔记——条目24:用委托实现回调<使用C#表达设计>
    C# 温故知新 基础篇(1) C#概述
    《Effective C#》读书笔记——条目26:避免返回对内部类对象的引用<使用C#表达设计>
    《有关程序员的性别、年龄、个性、编程方法的话题》(2010/01/31)
    《程序员应该掌握的实用编程技能2》(2010/01/23)
  • 原文地址:https://www.cnblogs.com/helloworldtoyou/p/9471767.html
Copyright © 2011-2022 走看看