wifi-加载驱动

IWifi.hal 驱动加载和函数映射(HIDL)

WifiService(java进程)通过IWifi.hal HIDL接口调用到C++端的Wifi.cpp

 驱动加载时序

驱动加载代码流程:

Wifi.cpp-start->startInternal

WifiStatus Wifi::startInternal() {
    if (run_state_ == RunState::STARTED) {
        return createWifiStatus(WifiStatusCode::SUCCESS);
    } else if (run_state_ == RunState::STOPPING) {
        return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE,
                                "HAL is stopping");
    }

//初始化WifiModeController和LegacyHal
    WifiStatus wifi_status = initializeModeControllerAndLegacyHal();
    if (wifi_status.code == WifiStatusCode::SUCCESS) {
        // Create the chip instance once the HAL is started.
        chip_ = new WifiChip(kChipId, legacy_hal_, mode_controller_,
                             feature_flags_);

        run_state_ = RunState::STARTED;
        for (const auto& callback : event_cb_handler_.getCallbacks()) {
            if (!callback->onStart().isOk()) {
                LOG(ERROR) << "Failed to invoke onStart callback";
            };
        }
        LOG(INFO) << "Wifi HAL started";
    } else {
        for (const auto& callback : event_cb_handler_.getCallbacks()) {
            if (!callback->onFailure(wifi_status).isOk()) {
                LOG(ERROR) << "Failed to invoke onFailure callback";
            }
        }
        LOG(ERROR) << "Wifi HAL start failed";
    }
    return wifi_status;
}

initializeModeControllerAndLegacyHal -mode_controller_->initialize 和legacy_hal_->initialize()

WifiStatus Wifi::initializeModeControllerAndLegacyHal() {
    if (!mode_controller_->initialize()) {
        LOG(ERROR) << "Failed to initialize firmware mode controller";
        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
    }
    legacy_hal::wifi_error legacy_status = legacy_hal_->initialize();
    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
        LOG(ERROR) << "Failed to initialize legacy HAL: "
                   << legacyErrorToString(legacy_status);
        return createWifiStatusFromLegacyError(legacy_status);
    }
    return createWifiStatus(WifiStatusCode::SUCCESS);
}

WifiModeController 的initialize

bool WifiModeController::initialize() {
    if (!driver_tool_->LoadDriver()) {
        LOG(ERROR) << "Failed to load WiFi driver";
        return false;
    }
    return true;
}

 

bool DriverTool::LoadDriver() {
  return ::wifi_load_driver() == 0;
}

 

wifi_hal_common.cpp

int wifi_unload_driver() {
  if (!is_wifi_driver_loaded()) {//检查driver是否有加载
    return 0;
  }
  usleep(200000); /* allow to finish interface down */
#ifdef WIFI_DRIVER_MODULE_PATH
  if (rmmod(DRIVER_MODULE_NAME) == 0) {
    int count = 20; /* wait at most 10 seconds for completion */
    while (count-- > 0) {
      if (!is_wifi_driver_loaded()) break;
      usleep(500000);
    }
    usleep(500000); /* allow card removal */
    if (count) {
      return 0;
    }
    return -1;
  } else
    return -1;
#else
#ifdef WIFI_DRIVER_STATE_CTRL_PARAM
  if (is_wifi_driver_loaded()) {
    if (wifi_change_driver_state(WIFI_DRIVER_STATE_OFF) < 0) return -1;
  }
#endif
  property_set(DRIVER_PROP_NAME, "unloaded");
  return 0;
#endif
}

int is_wifi_driver_loaded() {
  char driver_status[PROPERTY_VALUE_MAX];
#ifdef WIFI_DRIVER_MODULE_PATH
  FILE *proc;
  char line[sizeof(DRIVER_MODULE_TAG) + 10];
#endif

  if (!property_get(DRIVER_PROP_NAME, driver_status, NULL) ||
      strcmp(driver_status, "ok") != 0) {

    return 0; /* driver not loaded */
  }
#ifdef WIFI_DRIVER_MODULE_PATH
  /*
   * If the property says the driver is loaded, check to
   * make sure that the property setting isn't just left
   * over from a previous manual shutdown or a runtime
   * crash.
   */
  if ((proc = fopen(MODULE_FILE, "r")) == NULL) {
    PLOG(WARNING) << "Could not open " << MODULE_FILE;
    property_set(DRIVER_PROP_NAME, "unloaded");
    return 0;
  }
  while ((fgets(line, sizeof(line), proc)) != NULL) {
    if (strncmp(line, DRIVER_MODULE_TAG, strlen(DRIVER_MODULE_TAG)) == 0) {
      fclose(proc);
      return 1;
    }
  }
  fclose(proc);
  property_set(DRIVER_PROP_NAME, "unloaded");
  return 0;
#else
  return 1;
#endif
}

WifiLegacyHal initialize

wifi_error WifiLegacyHal::initialize() {
    LOG(DEBUG) << "Initialize legacy HAL";
    // TODO: Add back the HAL Tool if we need to. All we need from the HAL tool
    // for now is this function call which we can directly call.
    if (!initHalFuncTableWithStubs(&global_func_table_)) { //wifi_legacy_hal_stubs.cpp加载函数列表
        LOG(ERROR)
            << "Failed to initialize legacy hal function table with stubs";
        return WIFI_ERROR_UNKNOWN;
    }
    wifi_error status = init_wifi_vendor_hal_func_table(&global_func_table_);///hardware/qcom/wlan/qcwcn/wifi_hal/wifi_hal.cpp 中加载函数列表     if (status != WIFI_SUCCESS) {         LOG(ERROR) << "Failed to initialize legacy hal function table";     }     return status; }