我是靠谱客的博主 悦耳唇膏,最近开发中收集的这篇文章主要介绍记一次rk平台热点打开流程追踪记录记一次rk平台热点打开流程追踪记录,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

记一次rk平台热点打开流程追踪记录

问题描述

rk平台偶现热点打开失败,错误日志如下:

I/android.hardware.wifi@1.0-service: Starting legacy HAL
E/android.hardware.wifi@1.0-service: Could not set interface flags for wlan0 (Operation not permitted)
E/android.hardware.wifi@1.0-service: Failed to set WiFi interface up
E/android.hardware.wifi@1.0-service: Failed to start legacy HAL: UNKNOWN
E/HalDevMgr: executeChipReconfiguration: configureChip error: 9 (unknown)
E/WifiVendorHal: Failed to create AP iface
E/WifiNative: Failed to create AP iface in vendor HAL
E/SoftApManager: setup failure when creating ap interface.
V/WifiManager: SoftApCallbackProxy: onStateChanged: state=14, failureReason=0
E/WifiController: SoftAP start failed

故借此机会准备从Java层开始学习热点的打开流程

开始

1.首先,我们要打开热点,调用是ConnectivityManager中的如下方法:

	public void startTethering(int type, boolean showProvisioningUi,
            final OnStartTetheringCallback callback, Handler handler) {
        Preconditions.checkNotNull(callback, "OnStartTetheringCallback cannot be null.");

        ResultReceiver wrappedCallback = new ResultReceiver(handler) {
            @Override
            protected void onReceiveResult(int resultCode, Bundle resultData) {
                if (resultCode == TETHER_ERROR_NO_ERROR) {
                    callback.onTetheringStarted();
                } else {
                    callback.onTetheringFailed();
                }
            }
        };

        try {
            String pkgName = mContext.getOpPackageName();
            Log.i(TAG, "startTethering caller:" + pkgName);
            mService.startTethering(type, wrappedCallback, showProvisioningUi, pkgName);
        } catch (RemoteException e) {
            Log.e(TAG, "Exception trying to start tethering.", e);
            wrappedCallback.send(TETHER_ERROR_SERVICE_UNAVAIL, null);
        }
    }

此方法有四个参数:
type:热点类型,有三种TETHERING_WIFITETHERING_USBTETHERING_BLUETOOTH(一般我们用到的个人热点就是TETHERING_WIFI
showProvisioningUi:当设置为true是,将展示一个类似使用帮助的页面(需要厂商自己实现)
callback:热点打开结果的回调
handler:可以指定执行上面回调函数的线程

2.找到ConnectivityService的startTethering方法

	@Override
    public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi,
            String callerPkg) {
        ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);
        if (!isTetheringSupported()) {
            receiver.send(ConnectivityManager.TETHER_ERROR_UNSUPPORTED, null);
            return;
        }
        mTethering.startTethering(type, receiver, showProvisioningUi);
    }

显示权限检查,注释已经写的很明白了,之后判断是否支持热点,之后就调到了Tethering中的startTethering方法

	public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi) {
        if (!isTetherProvisioningRequired()) {//当没有定义热点UI时就会直接打开热点
            enableTetheringInternal(type, true, receiver);
            return;
        }

        if (showProvisioningUi) {
            runUiTetherProvisioningAndEnable(type, receiver);
        } else {
            runSilentTetherProvisioningAndEnable(type, receiver);
        }
    }

接下来看enableTetheringInternal方法

	/**
     * Enables or disables tethering for the given type. This should only be called once
     * provisioning has succeeded or is not necessary. It will also schedule provisioning rechecks
     * for the specified interface.
     */
    private void enableTetheringInternal(int type, boolean enable, ResultReceiver receiver) {
        boolean isProvisioningRequired = enable && isTetherProvisioningRequired();
        int result;
        switch (type) {
            case TETHERING_WIFI:
                result = setWifiTethering(enable);
                if (isProvisioningRequired && result == TETHER_ERROR_NO_ERROR) {
                    scheduleProvisioningRechecks(type);
                }
                sendTetherResult(receiver, result);
                break;
            case TETHERING_USB:
                result = setUsbTethering(enable);
                if (isProvisioningRequired && result == TETHER_ERROR_NO_ERROR) {
                    scheduleProvisioningRechecks(type);
                }
                sendTetherResult(receiver, result);
                break;
            case TETHERING_BLUETOOTH:
                setBluetoothTethering(enable, receiver);
                break;
            default:
                Log.w(TAG, "Invalid tether type.");
                sendTetherResult(receiver, TETHER_ERROR_UNKNOWN_IFACE);
        }
    }

主要看TETHERING_WIFI

	private int setWifiTethering(final boolean enable) {
        int rval = TETHER_ERROR_MASTER_ERROR;
        final long ident = Binder.clearCallingIdentity();
        try {
            synchronized (mPublicSync) {
                mWifiTetherRequested = enable;
                final WifiManager mgr = getWifiManager();
                if ((enable && mgr.startSoftAp(null /* use existing wifi config */)) ||
                    (!enable && mgr.stopSoftAp())) {
                    rval = TETHER_ERROR_NO_ERROR;
                }
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
        return rval;
    }

3.找到startSoftAp的实现,在WifiServiceImpl.java中

frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiServiceImpl.java

	/**
     * see {@link android.net.wifi.WifiManager#startSoftAp(WifiConfiguration)}
     * @param wifiConfig SSID, security and channel details as part of WifiConfiguration
     * @return {@code true} if softap start was triggered
     * @throws SecurityException if the caller does not have permission to start softap
     */
    @Override
    public boolean startSoftAp(WifiConfiguration wifiConfig) {
        // NETWORK_STACK is a signature only permission.
        enforceNetworkStackPermission();

        mLog.info("startSoftAp uid=%").c(Binder.getCallingUid()).flush();

        synchronized (mLocalOnlyHotspotRequests)    {
            // If a tethering request comes in while we have LOHS running (or requested), call stop
            // for softap mode and restart softap with the tethering config.
            if (!mLocalOnlyHotspotRequests.isEmpty()) {
                stopSoftApInternal();
            }
            return startSoftApInternal(wifiConfig, WifiManager.IFACE_IP_MODE_TETHERED);
        }
    }
     /**
     * Internal method to start softap mode. Callers of this method should have already checked
     * proper permissions beyond the NetworkStack permission.
     */
    private boolean startSoftApInternal(WifiConfiguration wifiConfig, int mode) {
        mLog.trace("startSoftApInternal uid=% mode=%")
                .c(Binder.getCallingUid()).c(mode).flush();

        // null wifiConfig is a meaningful input for CMD_SET_AP
        if (wifiConfig == null || WifiApConfigStore.validateApWifiConfiguration(wifiConfig)) {
            SoftApModeConfiguration softApConfig = new SoftApModeConfiguration(mode, wifiConfig);
            mWifiController.sendMessage(CMD_SET_AP, 1, 0, softApConfig);
            return true;
        }
        Slog.e(TAG, "Invalid WifiConfiguration");
        return false;
    }

4.接着到WifiController.java这是个状态机,真正操作打开热点是在WifiStateMachinePrime.java中:

frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiStateMachinePrime.java

	/**
     * Method to enable soft ap for wifi hotspot.
     *
     * The supplied SoftApModeConfiguration includes the target softap WifiConfiguration (or null if
     * the persisted config is to be used) and the target operating mode (ex,
     * {@link WifiManager.IFACE_IP_MODE_TETHERED} {@link WifiManager.IFACE_IP_MODE_LOCAL_ONLY}).
     *
     * @param wifiConfig SoftApModeConfiguration for the hostapd softap
     */
    public void enterSoftAPMode(@NonNull SoftApModeConfiguration wifiConfig) {
        mHandler.post(() -> {
            startSoftAp(wifiConfig);
        });
    }
	private void startSoftAp(SoftApModeConfiguration softapConfig) {
        Log.d(TAG, "Starting SoftApModeManager");

        WifiConfiguration config = softapConfig.getWifiConfiguration();
        if (config != null && config.SSID != null) {
            Log.d(TAG, "Passing config to SoftApManager! " + config);
        } else {
            config = null;
        }

        SoftApCallbackImpl callback = new SoftApCallbackImpl();
        ActiveModeManager manager = mWifiInjector.makeSoftApManager(callback, softapConfig);
        callback.setActiveModeManager(manager);
        manager.start();
        mActiveModeManagers.add(manager);
        updateBatteryStatsWifiState(true);
    }

5.找到SoftApManager.java的start()方法:

frameworks/opt/net/wifi/service/java/com/android/server/wifi/SoftApManager.java

	/**
     * Start soft AP with the supplied config.
     */
    public void start() {
        mStateMachine.sendMessage(SoftApStateMachine.CMD_START, mApConfig);
    }

又一个状态机

	private class IdleState extends State {
            @Override
            public void enter() {
                mApInterfaceName = null;
                mIfaceIsUp = false;
            }

            @Override
            public boolean processMessage(Message message) {
                switch (message.what) {
                    case CMD_START:
                        Log.e(TAG, "CMD_START.");
                        mApInterfaceName = mWifiNative.setupInterfaceForSoftApMode(
                                mWifiNativeInterfaceCallback);
                        if (TextUtils.isEmpty(mApInterfaceName)) {
                            Log.e(TAG, "setup failure when creating ap interface.");
                            updateApState(WifiManager.WIFI_AP_STATE_FAILED,
                                    WifiManager.WIFI_AP_STATE_DISABLED,
                                    WifiManager.SAP_START_FAILURE_GENERAL);
                            mWifiMetrics.incrementSoftApStartResult(
                                    false, WifiManager.SAP_START_FAILURE_GENERAL);
                            break;
                        }
                        updateApState(WifiManager.WIFI_AP_STATE_ENABLING,
                                WifiManager.WIFI_AP_STATE_DISABLED, 0);
                        int result = startSoftAp((WifiConfiguration) message.obj);
                        if (result != SUCCESS) {
                            int failureReason = WifiManager.SAP_START_FAILURE_GENERAL;
                            if (result == ERROR_NO_CHANNEL) {
                                failureReason = WifiManager.SAP_START_FAILURE_NO_CHANNEL;
                            }
                            updateApState(WifiManager.WIFI_AP_STATE_FAILED,
                                          WifiManager.WIFI_AP_STATE_ENABLING,
                                          failureReason);
                            stopSoftAp();
                            mWifiMetrics.incrementSoftApStartResult(false, failureReason);
                            break;
                        }
                        transitionTo(mStartedState);
                        break;
                    default:
                        // Ignore all other commands.
                        break;
                }

                return HANDLED;
            }
        }

6.setupInterfaceForSoftApMode方法,此处就比较重要了,需要逐条分析:

frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java

	/**
     * Setup an interface for Soft AP mode operations.
     *
     * This method configures an interface in AP mode in all the native daemons
     * (wificond, wpa_supplicant & vendor HAL).
     *
     * @param interfaceCallback Associated callback for notifying status changes for the iface.
     * @return Returns the name of the allocated interface, will be null on failure.
     */
    public String setupInterfaceForSoftApMode(@NonNull InterfaceCallback interfaceCallback) {
        Log.e(TAG,"setupInterfaceForSoftApMode");
        synchronized (mLock) {
            if (!startHal()) {
                Log.e(TAG, "Failed to start Hal");
                mWifiMetrics.incrementNumSetupSoftApInterfaceFailureDueToHal();
                return null;
            }
            Log.e(TAG, "liyang Hal start success");
            Iface iface = mIfaceMgr.allocateIface(Iface.IFACE_TYPE_AP);
            if (iface == null) {
                Log.e(TAG, "Failed to allocate new AP iface");
                return null;
            }
            iface.externalListener = interfaceCallback;
            iface.name = createApIface(iface);
            if (TextUtils.isEmpty(iface.name)) {
                Log.e(TAG, "Failed to create AP iface in vendor HAL");
                mIfaceMgr.removeIface(iface.id);
                mWifiMetrics.incrementNumSetupSoftApInterfaceFailureDueToHal();
                return null;
            }
            if (mWificondControl.setupInterfaceForSoftApMode(iface.name) == null) {
                Log.e(TAG, "Failed to setup iface in wificond on " + iface);
                teardownInterface(iface.name);
                mWifiMetrics.incrementNumSetupSoftApInterfaceFailureDueToWificond();
                return null;
            }
            iface.networkObserver = new NetworkObserverInternal(iface.id);
            if (!registerNetworkObserver(iface.networkObserver)) {
                Log.e(TAG, "Failed to register network observer on " + iface);
                teardownInterface(iface.name);
                return null;
            }
            // Just to avoid any race conditions with interface state change callbacks,
            // update the interface state before we exit.
            onInterfaceStateChanged(iface, isInterfaceUp(iface.name));
            Log.i(TAG, "Successfully setup " + iface);
            return iface.name;
        }
    }

7先看startHal()方法:

	/** Helper method invoked to start supplicant if there were no ifaces */
    private boolean startHal() {
        synchronized (mLock) {
            if (!mIfaceMgr.hasAnyIface()) {
                if (mWifiVendorHal.isVendorHalSupported()) {
                    if (!mWifiVendorHal.startVendorHal()) {
                        Log.e(TAG, "Failed to start vendor HAL");
                        return false;
                    }
                } else {
                    Log.i(TAG, "Vendor Hal not supported, ignoring start.");
                }
            }
            return true;
        }
    }

首次进来,还未调用 allocateIface 方法,所以 mIfaceMgr.hasAnyIface()false
同时mWifiVendorHal.isVendorHalSupported()也必然为true,接着就到了WifiVendorHal.java中:
frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiVendorHal.java

	/**
     * Bring up the HIDL Vendor HAL and configure for AP (Access Point) mode
     *
     * @return true for success
     */
    public boolean startVendorHalAp() {
        synchronized (sLock) {
            if (!startVendorHal()) {
                return false;
            }
            if (TextUtils.isEmpty(createApIface(null))) {
                stopVendorHal();
                return false;
            }
            return true;
        }
    }
 	/**
     * Bring up the HIDL Vendor HAL.
     * @return true on success, false otherwise.
     */
    public boolean startVendorHal() {
        synchronized (sLock) {
            if (!mHalDeviceManager.start()) {
                mLog.err("Failed to start vendor HAL").flush();
                return false;
            }
            mLog.info("Vendor Hal started successfully").flush();
            return true;
        }
    }

frameworks/opt/net/wifi/service/java/com/android/server/wifi/HalDeviceManager.java

	/**
     * Attempts to start Wi-Fi (using HIDL). Returns the success (true) or failure (false) or
     * the start operation. Will also dispatch any registered ManagerStatusCallback.onStart() on
     * success.
     *
     * Note: direct call to HIDL.
     */
    public boolean start() {
        return startWifi();
    }
    private boolean startWifi() {
        if (VDBG) Log.d(TAG, "startWifi");

        synchronized (mLock) {
            try {
                if (mWifi == null) {
                    Log.w(TAG, "startWifi called but mWifi is null!?");
                    return false;
                } else {
                    int triedCount = 0;
                    while (triedCount <= START_HAL_RETRY_TIMES) {
                        WifiStatus status = mWifi.start();
                        if (status.code == WifiStatusCode.SUCCESS) {
                            initIWifiChipDebugListeners();
                            managerStatusListenerDispatch();
                            if (triedCount != 0) {
                                Log.d(TAG, "start IWifi succeeded after trying "
                                         + triedCount + " times");
                            }
                            return true;
                        } else if (status.code == WifiStatusCode.ERROR_NOT_AVAILABLE) {
                            // Should retry. Hal might still be stopping.
                            Log.e(TAG, "Cannot start IWifi: " + statusString(status)
                                    + ", Retrying...");
                            try {
                                Thread.sleep(START_HAL_RETRY_INTERVAL_MS);
                            } catch (InterruptedException ignore) {
                                // no-op
                            }
                            triedCount++;
                        } else {
                            // Should not retry on other failures.
                            Log.e(TAG, "Cannot start IWifi: " + statusString(status));
                            return false;
                        }
                    }
                    Log.e(TAG, "Cannot start IWifi after trying " + triedCount + " times");
                    return false;
                }
            } catch (RemoteException e) {
                Log.e(TAG, "startWifi exception: " + e);
                return false;
            }
        }
    }

mWifi.start() 开始就到了native层
hardware/interfaces/wifi/1.2/default/wifi.cpp

Return<void> Wifi::start(start_cb hidl_status_cb) {
    return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN,
                           &Wifi::startInternal, hidl_status_cb);
}
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");
    }
    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;
}
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);
}

hardware/interfaces/wifi/1.2/default/wifi_mode_controller.cpp

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

framework/opt/net/wifi/lbwifi_hal/driver_tool.cpp

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

frameworks/opt/net/wifi/libwifi_hal/wifi_hal_common.cpp

int wifi_load_driver() {
#ifdef WIFI_DRIVER_MODULE_PATH
	char* wifi_ko_path = NULL ;
	char* wifi_ko_arg =NULL;
	int i = 0;
	int count = 100;
	if (is_wifi_driver_loaded()) {
		return 0;
	}
	if (wifi_type[0] == 0) {
		check_wifi_chip_type_string(wifi_type);
		save_wifi_chip_type(wifi_type);
	}
	for (i=0; i< (int)(sizeof(module_list) / sizeof(module_list[0])); i++) {
		if (!strcmp(wifi_type , module_list[i].wifi_name)) {
			wifi_ko_path = module_list[i].wifi_module_path;
			wifi_ko_arg = module_list[i].wifi_module_arg;
			PLOG(ERROR) << "matched ko file path " << wifi_ko_path;
			break;
		}
	}
	if (wifi_ko_path == NULL) {
		PLOG(ERROR) << "falied to find wifi driver for type=" << wifi_type;
		return -1;
	}

	if (strstr(wifi_ko_path, MVL_DRIVER_MODULE_NAME)) {
		insmod(MLAN_DRIVER_MODULE_PATH, "");
	}

  if (insmod(wifi_ko_path, wifi_ko_arg) < 0) {
	  return -1;
  }
#endif

#ifdef WIFI_DRIVER_STATE_CTRL_PARAM
  if (is_wifi_driver_loaded()) {
    return 0;
  }

  if (wifi_change_driver_state(WIFI_DRIVER_STATE_ON) < 0) return -1;
#endif
  while (count-- > 0) {
	  if (is_wifi_driver_loaded()) {
		property_set(DRIVER_PROP_NAME, "ok");
		return 0;
	  }
	  usleep(200000);
  }
  property_set(DRIVER_PROP_NAME, "timeout");
  return -1;
}

这里面就开始加载wlan0模块,并通过检测/proc/net/dev节点中是否存在wlan0判断是否加载完成,具体模块的初始化在:
kernel/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux.c

dhd_module_init(void)
{
	int err;
	int retry = 0;
	printf("%s: in %sn", __FUNCTION__, dhd_version);

	DHD_PERIM_RADIO_INIT();


	if (firmware_path[0] != '') {
		strncpy(fw_bak_path, firmware_path, MOD_PARAM_PATHLEN);
		fw_bak_path[MOD_PARAM_PATHLEN-1] = '';
	}

	if (nvram_path[0] != '') {
		strncpy(nv_bak_path, nvram_path, MOD_PARAM_PATHLEN);
		nv_bak_path[MOD_PARAM_PATHLEN-1] = '';
	}

	do {
		err = dhd_wifi_platform_register_drv();
		if (!err) {
			register_reboot_notifier(&dhd_reboot_notifier);
			break;
		} else {
			DHD_ERROR(("%s: Failed to load the driver, try cnt %dn",
				__FUNCTION__, retry));
			strncpy(firmware_path, fw_bak_path, MOD_PARAM_PATHLEN);
			firmware_path[MOD_PARAM_PATHLEN-1] = '';
			strncpy(nvram_path, nv_bak_path, MOD_PARAM_PATHLEN);
			nvram_path[MOD_PARAM_PATHLEN-1] = '';
		}
	} while (retry--);

	dhd_create_to_notifier_skt();

	if (err) {
		DHD_ERROR(("%s: Failed to load driver max retry reached**n", __FUNCTION__));
	} else {
		if (!dhd_download_fw_on_driverload) {
			dhd_driver_init_done = TRUE;
		}
	}

	printf("%s: Exit err=%dn", __FUNCTION__, err);
	return err;
}

当wlan0模块加载完成后,接着看legacy_hal_->initialize(),初始化hal函数:
hardware/interfaces/wifi/1.2/default/wifi_legacy_hal.cpp

wifi_error WifiLegacyHal::initialize() {
    LOG(ERROR) << "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_)) {
        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_);
    if (status != WIFI_SUCCESS) {
        LOG(ERROR) << "Failed to initialize legacy hal function table";
    }
    return status;
}

到此,初始化工作就完成了,下面回头看第 6 点中的 createApIface(iface) 方法

8.创建AP Iface

frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiNative.java

	/**
     * Helper function to handle creation of AP iface.
     * For devices which do not the support the HAL, this will bypass HalDeviceManager &
     * teardown any existing iface.
     */
    private String createApIface(@NonNull Iface iface) {
        synchronized (mLock) {
            if (mWifiVendorHal.isVendorHalSupported()) {
                return mWifiVendorHal.createApIface(
                        new InterfaceDestoyedListenerInternal(iface.id));
            } else {
                Log.i(TAG, "Vendor Hal not supported, ignoring createApIface.");
                return handleIfaceCreationWhenVendorHalNotSupported(iface);
            }
        }
    }

frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiVendorHal.java

 	/**
     * Create a AP iface using {@link HalDeviceManager}.
     *
     * @param destroyedListener Listener to be invoked when the interface is destroyed.
     * @return iface name on success, null otherwise.
     */
    public String createApIface(InterfaceDestroyedListener destroyedListener) {
        synchronized (sLock) {
            IWifiApIface iface = mHalDeviceManager.createApIface(
                    new ApInterfaceDestroyedListenerInternal(destroyedListener), null);
            if (iface == null) {
                mLog.err("Failed to create AP iface").flush();
                return stringResult(null);
            }
            String ifaceName = mHalDeviceManager.getName((IWifiIface) iface);
            if (TextUtils.isEmpty(ifaceName)) {
                mLog.err("Failed to get iface name").flush();
                return stringResult(null);
            }
            if (!retrieveWifiChip((IWifiIface) iface)) {
                mLog.err("Failed to get wifi chip").flush();
                return stringResult(null);
            }
            mIWifiApIfaces.put(ifaceName, iface);
            return ifaceName;
        }
    }

frameworks/opt/net/wifi/service/java/com/android/server/wifi/HalDeviceManager.java

	/**
     * Create AP interface if possible (see createStaIface doc).
     */
    public IWifiApIface createApIface(@Nullable InterfaceDestroyedListener destroyedListener,
            @Nullable Handler handler) {
        return (IWifiApIface) createIface(IfaceType.AP, false, destroyedListener, handler);
    }
	private IWifiIface createIface(int ifaceType, boolean lowPriority,
            InterfaceDestroyedListener destroyedListener, Handler handler) {
        if (mDbg) {
            Log.d(TAG, "createIface: ifaceType=" + ifaceType + ", lowPriority=" + lowPriority);
        }

        synchronized (mLock) {
            WifiChipInfo[] chipInfos = getAllChipInfo();
            if (chipInfos == null) {
                Log.e(TAG, "createIface: no chip info found");
                stopWifi(); // major error: shutting down
                return null;
            }

            if (!validateInterfaceCache(chipInfos)) {
                Log.e(TAG, "createIface: local cache is invalid!");
                stopWifi(); // major error: shutting down
                return null;
            }

            IWifiIface iface = createIfaceIfPossible(chipInfos, ifaceType, lowPriority,
                    destroyedListener, handler);
            if (iface != null) { // means that some configuration has changed
                if (!dispatchAvailableForRequestListeners()) {
                    return null; // catastrophic failure - shut down
                }
            }

            return iface;
        }
    }
	/**
     * Performs chip reconfiguration per the input:
     * - Removes the specified interfaces
     * - Reconfigures the chip to the new chip mode (if necessary)
     * - Creates the new interface
     *
     * Returns the newly created interface or a null on any error.
     */
    private IWifiIface executeChipReconfiguration(IfaceCreationData ifaceCreationData,
            int ifaceType) {
        if (mDbg) {
            Log.d(TAG, "executeChipReconfiguration: ifaceCreationData=" + ifaceCreationData
                    + ", ifaceType=" + ifaceType);
        }
        synchronized (mLock) {
            try {
                // is this a mode change?
                boolean isModeConfigNeeded = !ifaceCreationData.chipInfo.currentModeIdValid
                        || ifaceCreationData.chipInfo.currentModeId != ifaceCreationData.chipModeId;
                if (mDbg) Log.d(TAG, "isModeConfigNeeded=" + isModeConfigNeeded);

                // first delete interfaces/change modes
                if (isModeConfigNeeded) {
                    // remove all interfaces pre mode-change
                    // TODO: is this necessary? note that even if we don't want to explicitly
                    // remove the interfaces we do need to call the onDeleted callbacks - which
                    // this does
                    for (WifiIfaceInfo[] ifaceInfos: ifaceCreationData.chipInfo.ifaces) {
                        for (WifiIfaceInfo ifaceInfo: ifaceInfos) {
                            removeIfaceInternal(ifaceInfo.iface); // ignore return value
                        }
                    }

                    WifiStatus status = ifaceCreationData.chipInfo.chip.configureChip(
                            ifaceCreationData.chipModeId);
                    if (status.code != WifiStatusCode.SUCCESS) {
                        Log.e(TAG, "executeChipReconfiguration: configureChip error: "
                                + statusString(status));
                        return null;
                    }
                } else {
                    // remove all interfaces on the delete list
                    for (WifiIfaceInfo ifaceInfo: ifaceCreationData.interfacesToBeRemovedFirst) {
                        removeIfaceInternal(ifaceInfo.iface); // ignore return value
                    }
                }

                // create new interface
                Mutable<WifiStatus> statusResp = new Mutable<>();
                Mutable<IWifiIface> ifaceResp = new Mutable<>();
                switch (ifaceType) {
                    case IfaceType.STA:
                        ifaceCreationData.chipInfo.chip.createStaIface(
                                (WifiStatus status, IWifiStaIface iface) -> {
                                    statusResp.value = status;
                                    ifaceResp.value = iface;
                                });
                        break;
                    case IfaceType.AP:
                        ifaceCreationData.chipInfo.chip.createApIface(
                                (WifiStatus status, IWifiApIface iface) -> {
                                    statusResp.value = status;
                                    ifaceResp.value = iface;
                                });
                        break;
                    case IfaceType.P2P:
                        ifaceCreationData.chipInfo.chip.createP2pIface(
                                (WifiStatus status, IWifiP2pIface iface) -> {
                                    statusResp.value = status;
                                    ifaceResp.value = iface;
                                });
                        break;
                    case IfaceType.NAN:
                        ifaceCreationData.chipInfo.chip.createNanIface(
                                (WifiStatus status, IWifiNanIface iface) -> {
                                    statusResp.value = status;
                                    ifaceResp.value = iface;
                                });
                        break;
                }

                if (statusResp.value.code != WifiStatusCode.SUCCESS) {
                    Log.e(TAG, "executeChipReconfiguration: failed to create interface ifaceType="
                            + ifaceType + ": " + statusString(statusResp.value));
                    return null;
                }

                return ifaceResp.value;
            } catch (RemoteException e) {
                Log.e(TAG, "executeChipReconfiguration exception: " + e);
                return null;
            }
        }
    }

主要看里面的

 WifiStatus status = ifaceCreationData.chipInfo.chip.configureChip(
                            ifaceCreationData.chipModeId);

这里就又走到了native
hardware/interfaces/wifi/1.2/default/wifi_chip.cpp

Return<void> WifiChip::configureChip(ChipModeId mode_id,
                                     configureChip_cb hidl_status_cb) {
    return validateAndCallWithLock(
        this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
        &WifiChip::configureChipInternal, hidl_status_cb, mode_id);
}
WifiStatus WifiChip::configureChipInternal(
    /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
    ChipModeId mode_id) {
    LOG(INFO) << "configureChipInternal mode: " << mode_id << ", current mode: " << current_mode_id_;
    if (!isValidModeId(mode_id)) {
        return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
    }
    if (mode_id == current_mode_id_) {
        LOG(DEBUG) << "Already in the specified mode " << mode_id;
        return createWifiStatus(WifiStatusCode::SUCCESS);
    }
    WifiStatus status = handleChipConfiguration(lock, mode_id);
    if (status.code != WifiStatusCode::SUCCESS) {
        for (const auto& callback : event_cb_handler_.getCallbacks()) {
            if (!callback->onChipReconfigureFailure(status).isOk()) {
                LOG(ERROR)
                    << "Failed to invoke onChipReconfigureFailure callback";
            }
        }
        return status;
    }
    for (const auto& callback : event_cb_handler_.getCallbacks()) {
        if (!callback->onChipReconfigured(mode_id).isOk()) {
            LOG(ERROR) << "Failed to invoke onChipReconfigured callback";
        }
    }
    current_mode_id_ = mode_id;
    LOG(INFO) << "Configured chip in mode " << mode_id;
    return status;
}
WifiStatus WifiChip::handleChipConfiguration(
    /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
    ChipModeId mode_id) {
    LOG(INFO) << "handleChipConfiguration ";
    // If the chip is already configured in a different mode, stop
    // the legacy HAL and then start it after firmware mode change.
    if (isValidModeId(current_mode_id_)) {
        LOG(INFO) << "Reconfiguring chip from mode " << current_mode_id_
                  << " to mode " << mode_id;
        invalidateAndRemoveAllIfaces();
        legacy_hal::wifi_error legacy_status =
            legacy_hal_.lock()->stop(lock, []() {});
        if (legacy_status != legacy_hal::WIFI_SUCCESS) {
            LOG(ERROR) << "Failed to stop legacy HAL: "
                       << legacyErrorToString(legacy_status);
            return createWifiStatusFromLegacyError(legacy_status);
        }
    }
    // Firmware mode change not needed for V2 devices.
    bool success = true;
    if (mode_id == kV1StaChipModeId) {
        success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);
    } else if (mode_id == kV1ApChipModeId) {
        success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP);
    }
    if (!success) {
        return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
    }
    legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start();
    if (legacy_status != legacy_hal::WIFI_SUCCESS) {
        LOG(ERROR) << "Failed to start legacy HAL: "
                   << legacyErrorToString(legacy_status);
        return createWifiStatusFromLegacyError(legacy_status);
    }
    // Every time the HAL is restarted, we need to register the
    // radio mode change callback.
    WifiStatus status = registerRadioModeChangeCallback();
    if (status.code != WifiStatusCode::SUCCESS) {
        // This probably is not a critical failure?
        LOG(ERROR) << "Failed to register radio mode change callback";
    }
    return createWifiStatus(WifiStatusCode::SUCCESS);
}

hardware/interfaces/wifi/1.2/default/wifi_legacy_hal.cpp

wifi_error WifiLegacyHal::start() {
    // Ensure that we're starting in a good state.
    //CHECK(global_func_table_.wifi_initialize && !global_handle_ &&
    //      iface_name_to_handle_.empty() && !awaiting_event_loop_termination_);
    if (is_started_) {
        LOG(INFO) << "Legacy HAL already started";
        return WIFI_SUCCESS;
    }
    LOG(INFO) << "Waiting for the driver ready";
    wifi_error status = global_func_table_.wifi_wait_for_driver_ready();
    if (status == WIFI_ERROR_TIMED_OUT) {
        LOG(ERROR) << "Timed out awaiting driver ready";
        return status;
    }
    LOG(INFO) << "Starting legacy HAL";
    if (!iface_tool_.SetWifiUpState(true)) {
        LOG(ERROR) << "Failed to set WiFi interface up";
        return WIFI_ERROR_UNKNOWN;
    }
    status = global_func_table_.wifi_initialize(&global_handle_);
    if (status != WIFI_SUCCESS || !global_handle_) {
        LOG(ERROR) << "Failed to retrieve global handle";
        return status;
    }
    std::thread(&WifiLegacyHal::runEventLoop, this).detach();
    status = retrieveIfaceHandles();
    if (status != WIFI_SUCCESS || iface_name_to_handle_.empty()) {
        LOG(ERROR) << "Failed to retrieve wlan interface handle";
        return status;
    }
    LOG(INFO) << "Legacy HAL start complete";
    is_started_ = true;
    return WIFI_SUCCESS;
}

frameworks/opt/net/wifi/libwifi_system_iface/interface_tool.cpp

bool InterfaceTool::SetWifiUpState(bool request_up) {
  return SetUpState(kWlan0InterfaceName, request_up);
}
bool InterfaceTool::SetUpState(const char* if_name, bool request_up) {
  base::unique_fd sock(socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0));
  if (sock.get() < 0) {
    LOG(ERROR) << "Failed to open socket to set up/down state ("
               << strerror(errno) << ")";
    return false;
  }

  struct ifreq ifr;
  if (!GetIfState(if_name, sock.get(), &ifr)) {
    return false;  // logging done internally
  }

  const bool currently_up = ifr.ifr_flags & IFF_UP;
  if (currently_up == request_up) {
    return true;
  }

  if (request_up) {
    ifr.ifr_flags |= IFF_UP;
  } else {
    ifr.ifr_flags &= ~IFF_UP;
  }

  if (TEMP_FAILURE_RETRY(ioctl(sock.get(), SIOCSIFFLAGS, &ifr)) != 0) {
    LOG(ERROR) << "Could not set interface flags for " << if_name
               << " (" << strerror(errno) << ")";
    return false;
  }

  return true;
}

这里通过ioctl调到了kernel中,具体过程不看了,直接找到实现的位置
kernel/drivers/net/wireless/rockchip_wlan/rkwifi/bcmdhd/dhd_linux.c

static int
dhd_open(struct net_device *net)
{
	dhd_info_t *dhd = DHD_DEV_INFO(net);
#ifdef TOE
	uint32 toe_ol;
#endif
#ifdef BCM_FD_AGGR
	char iovbuf[WLC_IOCTL_SMLEN];
	dbus_config_t config;
	uint32 agglimit = 0;
	uint32 rpc_agg = BCM_RPC_TP_DNGL_AGG_DPC; /* host aggr not enabled yet */
#endif /* BCM_FD_AGGR */
	int ifidx;
	int32 ret = 0;
#if defined(OOB_INTR_ONLY)
	uint32 bus_type = -1;
	uint32 bus_num = -1;
	uint32 slot_num = -1;
	wifi_adapter_info_t *adapter = NULL;
#endif
#if defined(WL_EXT_IAPSTA) && defined(ISAM_PREINIT)
	int bytes_written = 0;
	struct dhd_conf *conf;
#endif

	if (!dhd_download_fw_on_driverload) {
		if (!dhd_driver_init_done) {
			DHD_ERROR(("%s: WLAN driver is not initializedn", __FUNCTION__));
			return -1;
		}
	}
	printf("%s: Enter %pn", __FUNCTION__, net);
	DHD_MUTEX_LOCK();
	/* Init wakelock */
	if (!dhd_download_fw_on_driverload) {
		if (!(dhd->dhd_state & DHD_ATTACH_STATE_WAKELOCKS_INIT)) {
			DHD_OS_WAKE_LOCK_INIT(dhd);
			dhd->dhd_state |= DHD_ATTACH_STATE_WAKELOCKS_INIT;
		}
#ifdef SHOW_LOGTRACE
		skb_queue_head_init(&dhd->evt_trace_queue);

		if (!(dhd->dhd_state & DHD_ATTACH_LOGTRACE_INIT)) {
			ret = dhd_init_logstrs_array(dhd->pub.osh, &dhd->event_data);
			if (ret == BCME_OK) {
				dhd_init_static_strs_array(dhd->pub.osh, &dhd->event_data,
					st_str_file_path, map_file_path);
				dhd_init_static_strs_array(dhd->pub.osh, &dhd->event_data,
					rom_st_str_file_path, rom_map_file_path);
				dhd->dhd_state |= DHD_ATTACH_LOGTRACE_INIT;
			}
		}
#endif /* SHOW_LOGTRACE */
	}

#if defined(PREVENT_REOPEN_DURING_HANG)
	/* WAR : to prevent calling dhd_open abnormally in quick succession after hang event */
	if (dhd->pub.hang_was_sent == 1) {
		DHD_ERROR(("%s: HANG was sent up earliern", __FUNCTION__));
		/* Force to bring down WLAN interface in case dhd_stop() is not called
		 * from the upper layer when HANG event is triggered.
		 */
		if (!dhd_download_fw_on_driverload && dhd->pub.up == 1) {
			DHD_ERROR(("%s: WLAN interface is not brought downn", __FUNCTION__));
			dhd_stop(net);
		} else {
			return -1;
		}
	}
#endif /* PREVENT_REOPEN_DURING_HANG */


	DHD_OS_WAKE_LOCK(&dhd->pub);
	DHD_PERIM_LOCK(&dhd->pub);
	dhd->pub.dongle_trap_occured = 0;
	dhd->pub.hang_was_sent = 0;
	dhd->pub.hang_reason = 0;
	dhd->pub.iovar_timeout_occured = 0;
#ifdef PCIE_FULL_DONGLE
	dhd->pub.d3ack_timeout_occured = 0;
#endif /* PCIE_FULL_DONGLE */

#ifdef DHD_LOSSLESS_ROAMING
	dhd->pub.dequeue_prec_map = ALLPRIO;
#endif
#if 0
	/*
	 * Force start if ifconfig_up gets called before START command
	 *  We keep WEXT's wl_control_wl_start to provide backward compatibility
	 *  This should be removed in the future
	 */
	ret = wl_control_wl_start(net);
	if (ret != 0) {
		DHD_ERROR(("%s: failed with code %dn", __FUNCTION__, ret));
		ret = -1;
		goto exit;
	}
#endif

	ifidx = dhd_net2idx(dhd, net);
	DHD_TRACE(("%s: ifidx %dn", __FUNCTION__, ifidx));

	if (ifidx < 0) {
		DHD_ERROR(("%s: Error: called with invalid IFn", __FUNCTION__));
		ret = -1;
		goto exit;
	}

	if (!dhd->iflist[ifidx]) {
		DHD_ERROR(("%s: Error: called when IF already deletedn", __FUNCTION__));
		ret = -1;
		goto exit;
	}

	if (ifidx == 0) {
		atomic_set(&dhd->pend_8021x_cnt, 0);
		if (!dhd_download_fw_on_driverload) {
			DHD_ERROR(("n%sn", dhd_version));
#ifdef WL_EXT_IAPSTA
			wl_ext_iapsta_attach_netdev(net, ifidx, dhd->iflist[ifidx]->bssidx);
#endif
#if defined(USE_INITIAL_SHORT_DWELL_TIME)
			g_first_broadcast_scan = TRUE;
#endif 
#if defined(BT_OVER_SDIO)
			ret = dhd_bus_get(&dhd->pub, WLAN_MODULE);
			wl_android_set_wifi_on_flag(TRUE);
#else
			ret = wl_android_wifi_on(net);
#endif /* BT_OVER_SDIO */
			if (ret != 0) {
				DHD_ERROR(("%s : wl_android_wifi_on failed (%d)n",
					__FUNCTION__, ret));
				ret = -1;
				goto exit;
			}
#if defined(WL_EXT_IAPSTA) && defined(ISAM_PREINIT)
			conf = dhd_get_conf(net);
			if (conf) {
				wl_android_ext_priv_cmd(net, conf->isam_init, 0, &bytes_written);
				wl_android_ext_priv_cmd(net, conf->isam_config, 0, &bytes_written);
				wl_android_ext_priv_cmd(net, conf->isam_enable, 0, &bytes_written);
			}
#endif
		}
#ifdef FIX_CPU_MIN_CLOCK
		if (dhd_get_fw_mode(dhd) == DHD_FLAG_HOSTAP_MODE) {
			dhd_init_cpufreq_fix(dhd);
			dhd_fix_cpu_freq(dhd);
		}
#endif /* FIX_CPU_MIN_CLOCK */
#if defined(OOB_INTR_ONLY)
		if (dhd->pub.conf->dpc_cpucore >= 0) {
			dhd_bus_get_ids(dhd->pub.bus, &bus_type, &bus_num, &slot_num);
			adapter = dhd_wifi_platform_get_adapter(bus_type, bus_num, slot_num);
			if (adapter) {
				printf("%s: set irq affinity hit %dn", __FUNCTION__, dhd->pub.conf->dpc_cpucore);
				irq_set_affinity_hint(adapter->irq_num, cpumask_of(dhd->pub.conf->dpc_cpucore));
			}
		}
#endif

		if (dhd->pub.busstate != DHD_BUS_DATA) {
#ifdef BCMDBUS
			dhd_set_path(&dhd->pub);
			DHD_MUTEX_UNLOCK();
			wait_event_interruptible_timeout(dhd->adapter->status_event,
				wifi_get_adapter_status(dhd->adapter, WIFI_STATUS_FW_READY),
				msecs_to_jiffies(DHD_FW_READY_TIMEOUT));
			DHD_MUTEX_LOCK();
			if ((ret = dbus_up(dhd->pub.bus)) != 0) {
				DHD_ERROR(("%s: failed to dbus_up with code %dn", __FUNCTION__, ret));
				goto exit;
			} else {
				dhd->pub.busstate = DHD_BUS_DATA;
			}
			if ((ret = dhd_sync_with_dongle(&dhd->pub)) < 0) {
				DHD_ERROR(("%s: failed with code %dn", __FUNCTION__, ret));
				goto exit;
			}
#else
			/* try to bring up bus */
			DHD_PERIM_UNLOCK(&dhd->pub);
			ret = dhd_bus_start(&dhd->pub);
			DHD_PERIM_LOCK(&dhd->pub);
			if (ret) {
				DHD_ERROR(("%s: failed with code %dn", __FUNCTION__, ret));
				ret = -1;
				goto exit;
			}
#endif /* !BCMDBUS */

		}
#ifdef WL_EXT_IAPSTA
		wl_ext_iapsta_attach_name(net, ifidx);
#endif
		if (dhd_download_fw_on_driverload) {
			if (dhd->pub.conf->deepsleep)
				dhd_deepsleep(dhd, 0);
		}

#ifdef BCM_FD_AGGR
		config.config_id = DBUS_CONFIG_ID_AGGR_LIMIT;


		memset(iovbuf, 0, sizeof(iovbuf));
		bcm_mkiovar("rpc_dngl_agglimit", (char *)&agglimit, 4,
			iovbuf, sizeof(iovbuf));

		if (!dhd_wl_ioctl_cmd(&dhd->pub, WLC_GET_VAR, iovbuf, sizeof(iovbuf), FALSE, 0)) {
			agglimit = *(uint32 *)iovbuf;
			config.aggr_param.maxrxsf = agglimit >> BCM_RPC_TP_AGG_SF_SHIFT;
			config.aggr_param.maxrxsize = agglimit & BCM_RPC_TP_AGG_BYTES_MASK;
			DHD_ERROR(("rpc_dngl_agglimit %x : sf_limit %d bytes_limit %dn",
				agglimit, config.aggr_param.maxrxsf, config.aggr_param.maxrxsize));
			if (bcm_rpc_tp_set_config(dhd->pub.info->rpc_th, &config)) {
				DHD_ERROR(("set tx/rx queue size and buffersize failedn"));
			}
		} else {
			DHD_ERROR(("get rpc_dngl_agglimit failedn"));
			rpc_agg &= ~BCM_RPC_TP_DNGL_AGG_DPC;
		}

		/* Set aggregation for TX */
		bcm_rpc_tp_agg_set(dhd->pub.info->rpc_th, BCM_RPC_TP_HOST_AGG_MASK,
			rpc_agg & BCM_RPC_TP_HOST_AGG_MASK);

		/* Set aggregation for RX */
		memset(iovbuf, 0, sizeof(iovbuf));
		bcm_mkiovar("rpc_agg", (char *)&rpc_agg, sizeof(rpc_agg), iovbuf, sizeof(iovbuf));
		if (!dhd_wl_ioctl_cmd(&dhd->pub, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0)) {
			dhd->pub.info->fdaggr = 0;
			if (rpc_agg & BCM_RPC_TP_HOST_AGG_MASK)
				dhd->pub.info->fdaggr |= BCM_FDAGGR_H2D_ENABLED;
			if (rpc_agg & BCM_RPC_TP_DNGL_AGG_MASK)
				dhd->pub.info->fdaggr |= BCM_FDAGGR_D2H_ENABLED;
		} else {
			DHD_ERROR(("%s(): Setting RX aggregation failed %dn", __FUNCTION__, ret));
		}
#endif /* BCM_FD_AGGR */

#ifdef BT_OVER_SDIO
		if (dhd->pub.is_bt_recovery_required) {
			DHD_ERROR(("%s: Send Hang Notification 2 to BTn", __FUNCTION__));
			bcmsdh_btsdio_process_dhd_hang_notification(TRUE);
		}
		dhd->pub.is_bt_recovery_required = FALSE;
#endif

		/* dhd_sync_with_dongle has been called in dhd_bus_start or wl_android_wifi_on */
		memcpy(net->dev_addr, dhd->pub.mac.octet, ETHER_ADDR_LEN);

#ifdef TOE
		/* Get current TOE mode from dongle */
		if (dhd_toe_get(dhd, ifidx, &toe_ol) >= 0 && (toe_ol & TOE_TX_CSUM_OL) != 0) {
			dhd->iflist[ifidx]->net->features |= NETIF_F_IP_CSUM;
		} else {
			dhd->iflist[ifidx]->net->features &= ~NETIF_F_IP_CSUM;
		}
#endif /* TOE */

#if defined(DHD_LB_RXP)
		__skb_queue_head_init(&dhd->rx_pend_queue);
		if (dhd->rx_napi_netdev == NULL) {
			dhd->rx_napi_netdev = dhd->iflist[ifidx]->net;
			memset(&dhd->rx_napi_struct, 0, sizeof(struct napi_struct));
			netif_napi_add(dhd->rx_napi_netdev, &dhd->rx_napi_struct,
				dhd_napi_poll, dhd_napi_weight);
			DHD_INFO(("%s napi<%p> enabled ifp->net<%p,%s>n",
				__FUNCTION__, &dhd->rx_napi_struct, net, net->name));
			napi_enable(&dhd->rx_napi_struct);
			DHD_INFO(("%s load balance init rx_napi_structn", __FUNCTION__));
			skb_queue_head_init(&dhd->rx_napi_queue);
		} /* rx_napi_netdev == NULL */
#endif /* DHD_LB_RXP */

#if defined(DHD_LB_TXP)
		/* Use the variant that uses locks */
		skb_queue_head_init(&dhd->tx_pend_queue);
#endif /* DHD_LB_TXP */

#if defined(WL_CFG80211)
		if (unlikely(wl_cfg80211_up(net))) {
			DHD_ERROR(("%s: failed to bring up cfg80211n", __FUNCTION__));
			ret = -1;
			goto exit;
		}
		if (!dhd_download_fw_on_driverload) {
#ifdef ARP_OFFLOAD_SUPPORT
			dhd->pend_ipaddr = 0;
			if (!dhd_inetaddr_notifier_registered) {
				dhd_inetaddr_notifier_registered = TRUE;
				register_inetaddr_notifier(&dhd_inetaddr_notifier);
			}
#endif /* ARP_OFFLOAD_SUPPORT */
#if defined(CONFIG_IPV6) && defined(IPV6_NDO_SUPPORT)
			if (!dhd_inet6addr_notifier_registered) {
				dhd_inet6addr_notifier_registered = TRUE;
				register_inet6addr_notifier(&dhd_inet6addr_notifier);
			}
#endif /* CONFIG_IPV6 && IPV6_NDO_SUPPORT */
		}

		argos_register_notifier_init(net);
#if defined(NUM_SCB_MAX_PROBE)
		dhd_set_scb_probe(&dhd->pub);
#endif /* NUM_SCB_MAX_PROBE */
#endif /* WL_CFG80211 */
	}

	/* Allow transmit calls */
	netif_start_queue(net);
	dhd->pub.up = 1;

	OLD_MOD_INC_USE_COUNT;

#ifdef BCMDBGFS
	dhd_dbgfs_init(&dhd->pub);
#endif

exit:
	if (ret) {
		dhd_stop(net);
	}

	DHD_PERIM_UNLOCK(&dhd->pub);
	DHD_OS_WAKE_UNLOCK(&dhd->pub);
	DHD_MUTEX_UNLOCK();

	printf("%s: Exit ret=%dn", __FUNCTION__, ret);
	return ret;
}

这个方法是真的长,到此就找到了上面热点打不开报错的位置:

	if (!dhd_download_fw_on_driverload) {
		if (!dhd_driver_init_done) {
			DHD_ERROR(("%s: WLAN driver is not initializedn", __FUNCTION__));
			return -1;
		}
	}

那么dhd_driver_init_done是在什么时候被设置为true的呢,看这个类里面的dhd_module_init方法,也就是说在第7点startHal()方法;流程中被置为true的,而之前有分析了,startHal()成功的判断条件是/proc/net/dev节点中存在wlan0,那么什么时候开始这个判断成立的呢,看dhd_module_init(void)register_reboot_notifier(&dhd_reboot_notifier),在这个方法流程中就会初始化wlan0,那么这就导致了,同步问题,wlan0虽然初始化完成了,但dhd_driver_init_done还未被设置,导致上面的报错

解决办法

为 **dhd_module_init(void)dhd_open(struct net_device *net)**这两个方法添加互斥锁,已解决同步问题,如下:

DEFINE_MUTEX(_wlan_init_mutex_lock_);
#define WLAN_MUTEX_LOCK() 
    do { 
        if (mutex_is_locked(&_wlan_init_mutex_lock_) == 0) { 
            printf("%s : no wlan mutex held. set lockn", __FUNCTION__); 
        } else { 
            printf("%s : wlan mutex is locked!. wait for unlockingn", __FUNCTION__); 
        } 
        mutex_lock(&_wlan_init_mutex_lock_); 
    } while (0)

#define WLAN_MUTEX_UNLOCK() 
    do { 
        mutex_unlock(&_wlan_init_mutex_lock_); 
        printf("%s : the wlan lock is released.n", __FUNCTION__); 
    } while (0)
    if (!dhd_download_fw_on_driverload) {
        WLAN_MUTEX_LOCK();
        if (!dhd_driver_init_done) {
            DHD_ERROR(("%s: WLAN driver is not initializedn", __FUNCTION__));
            WLAN_MUTEX_UNLOCK();
            return -1;
        }else{
            WLAN_MUTEX_UNLOCK();
        }
    }
static int
dhd_module_init(void)
{
	int err;
	int retry = 0;
    WLAN_MUTEX_LOCK();
	printf("%s: in %sn", __FUNCTION__, dhd_version);
	DHD_PERIM_RADIO_INIT();
	............
	............
	............
	printf("%s: Exit err=%dn", __FUNCTION__, err);
	WLAN_MUTEX_UNLOCK();
	return err;
}

最后

以上就是悦耳唇膏为你收集整理的记一次rk平台热点打开流程追踪记录记一次rk平台热点打开流程追踪记录的全部内容,希望文章能够帮你解决记一次rk平台热点打开流程追踪记录记一次rk平台热点打开流程追踪记录所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(67)

评论列表共有 0 条评论

立即
投稿
返回
顶部