From d40c475de2f7c7e655848a4078923ef0fd298cf4 Mon Sep 17 00:00:00 2001 From: chenbotong Date: Thu, 25 Aug 2022 17:56:32 +0800 Subject: [PATCH] =?UTF-8?q?docs=EF=BC=9AModify=20the=20wlan=20document?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: chenbotong --- .../driver/driver-peripherals-external-des.md | 1174 +++++++++++------ 1 file changed, 796 insertions(+), 378 deletions(-) diff --git a/zh-cn/device-dev/driver/driver-peripherals-external-des.md b/zh-cn/device-dev/driver/driver-peripherals-external-des.md index d4f00c0f6d..b0298ec862 100644 --- a/zh-cn/device-dev/driver/driver-peripherals-external-des.md +++ b/zh-cn/device-dev/driver/driver-peripherals-external-des.md @@ -65,48 +65,46 @@ WLAN Driver框架主要由如下模块组成: WLAN模块有三部分对外开放的API接口,如下图所示: -1. 驱动直接调用WLAN模块能力接口。 +1. 对上层服务提供HDI以及HAL能力接口。 2. 提供给各厂商实现的能力接口。 -3. 对HDI层提供的能力接口 - +3. 驱动直接调用WLAN模块能力接口。 **图3** WLAN驱动接口框架图 ![image](figures/WLAN驱动接口框架图.png "WLAN驱动接口框架图") -- WLAN驱动模块提供给驱动开发人员可直接调用的能力接口,主要功能有:创建/释放WifiModule、关联/取消关联、申请/释放NetBuf、lwip的pbuf和NetBuf的相互转换等。 - - 可直接调用的接口如表1、表2和表3所示。 +- WLAN驱动模块对上层服务提供的HDI能力接口(适用于标准系统),主要功能有:创建/销毁ifeature对象、设置/获取功率模式等。提供的部分接口说明如表1所示: - **表1** wifi_module.h + **表1** IWlanInterface.idl | 接口名称 | 功能描述 | | -------- | -------- | - | struct WifiModule \*WifiModuleCreate(const struct HdfConfigWifiModuleConfig \*config) | 基于HDF开发WLAN驱动时,创建一个WifiModule。 | - | void WifiModuleDelete(struct WifiModule \*module) | 基于HDF开发WLAN驱动时,删除并释放WifiModule所有数据。 | - | int32_t DelFeature(struct WifiModule \*module, uint16_t featureType) | 基于HDF开发WLAN驱动时,从WifiModule删除一个功能组件。 | - | int32_t AddFeature(struct WifiModule \*module, uint16_t featureType,
 struct WifiFeature \*featureData) | 基于HDF开发WLAN驱动时,注册一个功能组件到WifiModule。 | + | CreateFeature([in] int type, [out] struct HdfFeatureInfo ifeature); | 创建ifeature对象。 | + | DestroyFeature([in] struct HdfFeatureInfo ifeature); | 销毁ifeature对象。 | + | GetPowerMode([in] struct HdfFeatureInfo ifeature, [out] unsigned char mode); | 获取功率模式。 | + | SetPowerMode([in] struct HdfFeatureInfo ifeature, [in] unsigned char mode); | 设置功率模式。 | + +- WLAN驱动模块对上层服务提供的HAL能力接口(适用于小型系统及轻量系统),主要功能有:创建/销毁 IWiFi对象、设置MAC地址等。提供的部分接口说明如表2、表3所示: - **表2** wifi_mac80211_ops.h + **表2** wifi_hal.h | 接口名称 | 功能描述 | | -------- | -------- | - | int32_t (\*startAp)(NetDevice \*netDev) | 启动AP。 | - | int32_t (\*stopAp)(NetDevice \*netDev) | 停止AP。 | - | int32_t (\*connect)(NetDevice \*netDev, WifiConnectParams \*param) | 开始关联。 | - | int32_t (\*disconnect)(NetDevice \*netDev, uint16_t reasonCode) | 取消关联。 | + | int32_t WifiConstruct(struct IWiFi \*\*wifiInstance) | 创建IWiFi对象,提供IWiFi基本能力。 | + | int32_t WifiDestruct(struct IWiFi \*\*wifiInstance) | 销毁IWiFi对象。 | + | int32_t (\*start)(struct IWiFi \*) | 创建HAL和驱动之间的通道及获取驱动支持的网卡信息。 | + | int32_t (\*stop)(struct IWiFi \*) | 销毁通道。 | - **表3** hdf_netbuf.h + **表3** wifi_hal_base_feature.h | 接口名称 | 功能描述 | | -------- | -------- | - | static inline void NetBufQueueInit(struct NetBufQueue \*q) | 初始化NetBuf队列。 | - | struct NetBuf \*NetBufAlloc(uint32_t size) | 申请NetBuf。 | - | void NetBufFree(struct NetBuf \*nb) | 释放NetBuf | - | struct NetBuf \*Pbuf2NetBuf(const struct NetDevice \*netdev, struct pbuf \*lwipBuf) | lwip的pbuf转换为NetBuf。 | - | struct pbuf \*NetBuf2Pbuf(const struct NetBuf \*nb) | NetBuf转换为lwip的pbuf。 | + | int32_t (\*getFeatureType)(const struct IWiFiBaseFeature \*) | 获取特性的类型。 | + | int32_t (\*setMacAddress)(const struct IWiFiBaseFeature \*, unsigned char \*, uint8_t) | 设置MAC地址。 | + | int32_t (\*getDeviceMacAddress)(const struct IWiFiBaseFeature \*, unsigned char \*, uint8_t) | 获取设备持久化的MAC地址。 | + | int32_t (\*setTxPower)(const struct IWiFiBaseFeature \*, int32_t) | 设置发射功率。 | - WLAN驱动模块也提供了需要驱动开发人员自行去填充具体实现内容的能力接口,主要功能有:初始化/注销NetDevice、打开/关闭NetDevice、获取NetDevice的状态等。提供的部分接口说明如表4所示: @@ -121,428 +119,846 @@ WLAN模块有三部分对外开放的API接口,如下图所示: | int32_t (\*open)(struct NetDevice \*netDev) | 打开NetDevice。 | | int32_t (\*stop)(struct NetDevice \*netDev) | 关闭NetDevice。 | -- WLAN驱动模块对HDI层提供的能力接口,主要功能有:创建/销毁 IWiFi对象、设置MAC地址等。提供的部分接口说明如表5、表6所示: +- WLAN驱动模块提供给驱动开发人员可直接调用的能力接口,主要功能有:创建/释放WifiModule、关联/取消关联、申请/释放NetBuf、lwip的pbuf和NetBuf的相互转换等。 + + 可直接调用的接口如表5、表6和表7所示。 - **表5** wifi_hal.h + **表5** wifi_module.h | 接口名称 | 功能描述 | | -------- | -------- | - | int32_t WifiConstruct(struct IWiFi \*\*wifiInstance) | 创建IWiFi对象,提供IWiFi基本能力。 | - | int32_t WifiDestruct(struct IWiFi \*\*wifiInstance) | 销毁IWiFi对象。 | - | int32_t (\*start)(struct IWiFi \*) | 创建HAL和驱动之间的通道及获取驱动支持的网卡信息。 | - | int32_t (\*stop)(struct IWiFi \*) | 销毁通道。 | + | struct WifiModule \*WifiModuleCreate(const struct HdfConfigWifiModuleConfig \*config) | 基于HDF开发WLAN驱动时,创建一个WifiModule。 | + | void WifiModuleDelete(struct WifiModule \*module) | 基于HDF开发WLAN驱动时,删除并释放WifiModule所有数据。 | + | int32_t DelFeature(struct WifiModule \*module, uint16_t featureType) | 基于HDF开发WLAN驱动时,从WifiModule删除一个功能组件。 | + | int32_t AddFeature(struct WifiModule \*module, uint16_t featureType,
 struct WifiFeature \*featureData) | 基于HDF开发WLAN驱动时,注册一个功能组件到WifiModule。 | - **表6** wifi_hal_base_feature.h + **表6** wifi_mac80211_ops.h | 接口名称 | 功能描述 | | -------- | -------- | - | int32_t (\*getFeatureType)(const struct IWiFiBaseFeature \*) | 获取特性的类型。 | - | int32_t (\*setMacAddress)(const struct IWiFiBaseFeature \*, unsigned char \*, uint8_t) | 设置MAC地址。 | - | int32_t (\*getDeviceMacAddress)(const struct IWiFiBaseFeature \*, unsigned char \*, uint8_t) | 获取设备持久化的MAC地址。 | - | int32_t (\*setTxPower)(const struct IWiFiBaseFeature \*, int32_t) | 设置发射功率。 | + | int32_t (\*startAp)(NetDevice \*netDev) | 启动AP。 | + | int32_t (\*stopAp)(NetDevice \*netDev) | 停止AP。 | + | int32_t (\*connect)(NetDevice \*netDev, WifiConnectParams \*param) | 开始关联。 | + | int32_t (\*disconnect)(NetDevice \*netDev, uint16_t reasonCode) | 取消关联。 | + **表7** hdf_netbuf.h -### 开发步骤 + | 接口名称 | 功能描述 | + | -------- | -------- | + | static inline void NetBufQueueInit(struct NetBufQueue \*q) | 初始化NetBuf队列。 | + | struct NetBuf \*NetBufAlloc(uint32_t size) | 申请NetBuf。 | + | void NetBufFree(struct NetBuf \*nb) | 释放NetBuf | + | struct NetBuf \*Pbuf2NetBuf(const struct NetDevice \*netdev, struct pbuf \*lwipBuf) | lwip的pbuf转换为NetBuf。 | + | struct pbuf \*NetBuf2Pbuf(const struct NetBuf \*nb) | NetBuf转换为lwip的pbuf。 | -WLAN驱动基于HDF框架和PLATFORM框架开发,不区分OS和芯片平台,为不同厂商的WLAN模组提供统一的驱动模型,各WLAN模组厂商根据如下指导适配WLAN驱动框架。 +### 开发步骤 +WLAN驱动基于HDF框架和Platform框架开发,不区分OS和芯片平台,为不同厂商的WLAN模组提供统一的驱动模型,各WLAN模组厂商根据如下指导适配WLAN驱动框架。 -1. 通过wifi_config.hcs文件,配置硬件(例如module、芯片等)相关的参数。此配置文件通过HDF框架中对应的接口解析后,生成全量配置的结构体对象。 + 1. 配置硬件(例如module、芯片等)相关的参数。在wlan_platform.hcs文件中对参数进行配置,该文件会通过HDF框架中对应的接口解析后,生成全量配置的结构体对象。 -2. Module初始化,创建Module。 + 2. 初始化和去初始化WLAN模块相关适配(如WLAN芯片初始化和去初始化、WLAN芯片驱动初始化和去初始化)。 -3. 挂接Chip,初始化Chip。 + 3. 控制流命令下发的适配。 -4. 挂接上层WPA(Wi-Fi Protected Access)业务。 + 4. 事件上报的调用。 ### 开发实例 本例程提供WLAN模块初始化过程的完整使用流程。示例如下(以Hi3881WLAN芯片为例): - 1、根据硬件,修改配置参数。 - -``` -/* 根据硬件参数,通过wlan_platform.hcs配置相关参数,以下是WLAN平台配置的示例 */ -hisi :& deviceList { - device0 :: deviceInst { - deviceInstId = 0; - powers { - power0 { - powerSeqDelay = 0; /* 电源序列延时 */ - powerType = 1; /* 电源类型:0--总是打开;1--GPIO */ - gpioId = 1; /* GPIO管脚号 */ - activeLevel=1; /* 有效电平:0--低;1--高 */ +1. 根据硬件具体情况修改配置参数。 + + ```text + /* 根据硬件具体情况,在wlan_platform.hcs中配置相关参数,以下是WLAN平台配置的示例 */ + hisi :& deviceList { + device0 :: deviceInst { + deviceInstId = 0; + powers { + power0 { + powerSeqDelay = 0; /* 电源序列延时 */ + powerType = 1; /* 电源类型,0表示总是打开;1表示GPIO */ + gpioId = 1; /* GPIO管脚号 */ + activeLevel=1; /* 有效电平,0表示低电平有效;1表示高电平有效 */ + } + power1 { + powerSeqDelay = 0; /* 电源序列延时 */ + powerType = 0; /* 电源类型,0表示总是打开;1表示GPIO */ + } } - power1 { - powerSeqDelay = 0; /* 电源序列延时 */ - powerType = 0; /* 电源类型:0--总是打开;1--GPIO */ + reset { + resetType = 0; /* 复位类型,0表示不管理;1表示GPIO */ + gpioId = 2; /* GPIO管脚号 */ + activeLevel=1; /* 有效电平,0表示低电平有效;1表示高电平有效 */ + resetHoldTime = 30; /* 复位配置后的等待时间(ms) */ + } + bootUpTimeout = 30; /* 启动超时时间(ms) */ + bus { + busEnable = 1; /* bus总线是否初始化,0-表示不初始化; 1表示初始化 */ + busType = 0; /* 总线类型,0表示sdio */ + busId = 2; /* 总线号 */ + funcNum = [1]; /* SDIO功能号 */ + timeout = 1000; /* 读/写数据的超时时间 */ + blockSize = 512; /* 读/写数据的块大小 */ } - } - reset { - resetType = 0; /* 复位类型:0--不管理;1--GPIO */ - gpioId = 2; /* GPIO管脚号 */ - activeLevel=1; /* 有效电平:0--低;1--高 */ - resetHoldTime = 30; /* 复位配置后的等待时间(ms) */ - } - bootUpTimeout = 30; /* 启动超时时间(ms) */ - bus { - busType = 0; /* 总线类型:0-sdio */ - busId = 2; /* 总线号 */ - funcNum = [1]; /* SDIO功能号 */ - timeout = 1000; /* 读/写数据的超时时间 */ - blockSize = 512; /* 读/写数据的块大小 */ } } -} -/* 每一块芯片添加配置文件wlan_chip_<芯片名>.hcs(如:wlan_chip_hi3881.hcs),配置相关参数。以下是hi3881的配置示例 */ -root { - wlan_config { - hi3881 :& chipList { - chipHi3881 :: chipInst { - match_attr = "hdf_wlan_chips_hi3881"; /* 配置匹配标识 */ - chipName = "hi3881"; /* WLAN芯片的名称 */ - sdio { - vendorId = 0x0296; /* 厂商Id */ - deviceId = [0x5347]; /* 设备Id */ + /* 每一块芯片添加配置文件wlan_chip_<芯片名>.hcs(如:wlan_chip_hi3881.hcs),配置相关参数。以下是hi3881的配置示例 */ + root { + wlan_config { + hi3881 :& chipList { + chipHi3881 :: chipInst { + match_attr = "hdf_wlan_chips_hi3881"; /* 配置匹配标识 */ + chipName = "hi3881"; /* WLAN芯片的名称 */ + bus { + vendorId = 0x0296; /* 厂商ID */ + deviceId = [0x5347]; /* 设备ID */ + } } } } } -} -``` - - 2、适配挂接WLAN芯片的初始化和去初始化、WLAN芯片驱动的初始化和去初始化。 - -``` -/* WLAN初始化挂接流程 */ -#include "hdf_device_desc.h" -#include "hdf_wifi_product.h" -#include "hdf_log.h" -#include "osal_mem.h" -#include "hdf_wlan_chipdriver_manager.h" -#include "securec.h" -#include "wifi_module.h" -#include "hi_wifi_api.h" -#include "hi_types_base.h" - -#define HDF_LOG_TAG Hi3881Driver - -/* WLAN芯片的初始化和去初始化函数 */ -int32_t InitHi3881Chip(struct HdfWlanDevice *device); -int32_t DeinitHi3881Chip(struct HdfWlanDevice *device); -/* WLAN芯片驱动的初始化和去初始化函数 */ -int32_t Hi3881Deinit(struct HdfChipDriver* chipDriver, struct NetDevice *netDevice); -int32_t Hi3881Init(struct HdfChipDriver* chipDriver, struct NetDevice *netDevice); - -/* 初始化mac80211与芯片侧的函数挂接 */ -hi_void HiMac80211Init(struct HdfChipDriver *chipDriver); - -static const char* const HI3881_DRIVER_NAME = "hisi"; - -/* WLAN芯片驱动挂接以及mac80211与芯片侧的函数挂接 */ -static struct HdfChipDriver *BuildHi3881Driver(struct HdfWlanDevice *device, uint8_t ifIndex) -{ - struct HdfChipDriver *specificDriver = NULL; - if (device == NULL) { - HDF_LOGE("%s fail : channel is NULL", __func__); - return NULL; - } - (void)device; - (void)ifIndex; - specificDriver = (struct HdfChipDriver *)OsalMemCalloc(sizeof(struct HdfChipDriver)); - if (specificDriver == NULL) { - HDF_LOGE("%s fail: OsalMemCalloc fail!", __func__); - return NULL; - } - if (memset_s(specificDriver, sizeof(struct HdfChipDriver), 0, sizeof(struct HdfChipDriver)) != EOK) { - HDF_LOGE("%s fail: memset_s fail!", __func__); - OsalMemFree(specificDriver); - return NULL; + ``` + +2. 适配挂接WLAN芯片的初始化和去初始化、WLAN芯片驱动的初始化和去初始化。 + + ```c + #include "hdf_device_desc.h" + #include "hdf_wifi_product.h" + #include "hdf_log.h" + #include "osal_mem.h" + #include "hdf_wlan_chipdriver_manager.h" + #include "securec.h" + #include "wifi_module.h" + #include "hi_wifi_api.h" + #include "hi_types_base.h" + + #define HDF_LOG_TAG Hi3881Driver + + /* WLAN芯片的初始化和去初始化函数。 */ + int32_t InitHi3881Chip(struct HdfWlanDevice *device); + int32_t DeinitHi3881Chip(struct HdfWlanDevice *device); + /* WLAN芯片驱动的初始化和去初始化函数。 */ + int32_t Hi3881Deinit(struct HdfChipDriver* chipDriver, struct NetDevice *netDevice); + int32_t Hi3881Init(struct HdfChipDriver* chipDriver, struct NetDevice *netDevice); + + /* 初始化Mac80211与芯片侧的函数挂接。 */ + hi_void HiMac80211Init(struct HdfChipDriver *chipDriver); + + static const char* const HI3881_DRIVER_NAME = "hisi"; + + /* WLAN芯片驱动挂接以及Mac80211与芯片侧的函数挂接。 */ + static struct HdfChipDriver *BuildHi3881Driver(struct HdfWlanDevice *device, uint8_t ifIndex) + { + struct HdfChipDriver *specificDriver = NULL; + if (device == NULL) { + HDF_LOGE("%s fail: channel is NULL!", __func__); + return NULL; + } + (void)ifIndex; + specificDriver = (struct HdfChipDriver *)OsalMemCalloc(sizeof(struct HdfChipDriver)); + if (specificDriver == NULL) { + HDF_LOGE("%s fail: OsalMemCalloc fail!", __func__); + return NULL; + } + if (memset_s(specificDriver, sizeof(struct HdfChipDriver), 0, sizeof(struct HdfChipDriver)) != EOK) { + HDF_LOGE("%s fail: memset_s fail!", __func__); + OsalMemFree(specificDriver); + return NULL; + } + + if (strcpy_s(specificDriver->name, MAX_WIFI_COMPONENT_NAME_LEN, HI3881_DRIVER_NAME) != EOK) { + HDF_LOGE("%s fail: strcpy_s fail!", __func__); + OsalMemFree(specificDriver); + return NULL; + } + specificDriver->init = Hi3881Init; + specificDriver->deinit = Hi3881Deinit; + + HiMac80211Init(specificDriver); + + return specificDriver; } - if (strcpy_s(specificDriver->name, MAX_WIFI_COMPONENT_NAME_LEN, HI3881_DRIVER_NAME) != EOK) { - HDF_LOGE("%s fail : strcpy_s fail", __func__); - OsalMemFree(specificDriver); - return NULL; + /* 释放WLAN芯片驱动。 */ + static void ReleaseHi3881Driver(struct HdfChipDriver *chipDriver) + { + if (chipDriver == NULL) { + return; + } + if (strcmp(chipDriver->name, HI3881_DRIVER_NAME) != 0) { + HDF_LOGE("%s:Not my driver!", __func__); + return; + } + OsalMemFree(chipDriver); } - specificDriver->init = Hi3881Init; - specificDriver->deinit = Hi3881Deinit; - HiMac80211Init(specificDriver); + static uint8_t GetHi3881GetMaxIFCount(struct HdfChipDriverFactory *factory) { + (void)factory; + return 1; + } - return specificDriver; -} + /* WLAN芯片相关函数的注册。 */ + static int32_t HDFWlanRegHisiDriverFactory(void) + { + static struct HdfChipDriverFactory tmpFactory = { 0 }; + struct HdfChipDriverManager *driverMgr = NULL; + driverMgr = HdfWlanGetChipDriverMgr(); + if (driverMgr == NULL) { + HDF_LOGE("%s fail: driverMgr is NULL!", __func__); + return HDF_FAILURE; + } + tmpFactory.driverName = HI3881_DRIVER_NAME; + tmpFactory.GetMaxIFCount = GetHi3881GetMaxIFCount; + tmpFactory.InitChip = InitHi3881Chip; + tmpFactory.DeinitChip = DeinitHi3881Chip; + tmpFactory.Build = BuildHi3881Driver; + tmpFactory.Release = ReleaseHi3881Driver; + tmpFactory.ReleaseFactory = NULL; + if (driverMgr->RegChipDriver(&tmpFactory) != HDF_SUCCESS) { + HDF_LOGE("%s fail: driverMgr is NULL!", __func__); + return HDF_FAILURE; + } -/* 释放WLAN芯片驱动 */ -static void ReleaseHi3881Driver(struct HdfChipDriver *chipDriver) -{ - if (chipDriver == NULL) { - return; + return HDF_SUCCESS; } - if (strcmp(chipDriver->name, HI3881_DRIVER_NAME) != 0) { - HDF_LOGE("%s:Not my driver!", __func__); - return; + + static int32_t HdfWlanHisiChipDriverInit(struct HdfDeviceObject *device) + { + (void)device; + return HDFWlanRegHisiDriverFactory(); } - OsalMemFree(chipDriver); -} - -static uint8_t GetHi3881GetMaxIFCount(struct HdfChipDriverFactory *factory) { - (void)factory; - return 1; -} - -/* WLAN芯片相关函数的注册 */ -static int32_t HDFWlanRegHisiDriverFactory(void) -{ - static struct HdfChipDriverFactory tmpFactory = { 0 }; - struct HdfChipDriverManager *driverMgr = NULL; - driverMgr = HdfWlanGetChipDriverMgr(); - if (driverMgr == NULL && driverMgr->RegChipDriver != NULL) { - HDF_LOGE("%s fail: driverMgr is NULL!", __func__); - return HDF_FAILURE; + + struct HdfDriverEntry g_hdfHisiChipEntry = { + .moduleVersion = 1, + .Bind = HdfWlanHisiDriverBind, + .Init = HdfWlanHisiChipDriverInit, + .Release = HdfWlanHisiChipRelease, + .moduleName = "HDF_WLAN_CHIPS" + }; + + HDF_INIT(g_hdfHisiChipEntry); + ``` + + 芯片初始化和芯片驱动初始化相关内容详见hdfinit_3881.c,具体函数分解如下: + + ```c + #include "hdf_wifi_product.h" + #include "hi_wifi_api.h" + #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION) + #include "oal_thread.h" + #include "osal_time.h" + #endif + #include "wifi_mac80211_ops.h" + #include "wal_cfg80211.h" + #include "net_adapter.h" + #include "hdf_wlan_utils.h" + + #define HDF_LOG_TAG Hi3881Driver + + /* WLAN芯片的初始化函数。 */ + int32_t InitHi3881Chip(struct HdfWlanDevice *device) + { + uint8_t maxPortCount = 3; + int32_t ret = HI_SUCCESS; + uint8_t maxRetryCount = 3; + if (device == NULL || device->bus == NULL) { + HDF_LOGE("%s:NULL ptr!", __func__); + return HI_FAIL; + } + + do { + if (ret != HI_SUCCESS) { + if (device->reset != NULL && device->reset->Reset != NULL) { + device->reset->Reset(device->reset); + } + HDF_LOGE("%s:Retry init hi3881!last ret=%d", __func__, ret); + } + ret = hi_wifi_init(maxPortCount, device->bus); + } while (ret != 0 && --maxRetryCount > 0); + + if (ret != 0) { + HDF_LOGE("%s:Init hi3881 driver failed!", __func__); + return ret; + } + return HI_SUCCESS; } - tmpFactory.driverName = HI3881_DRIVER_NAME; - tmpFactory.GetMaxIFCount = GetHi3881GetMaxIFCount; - tmpFactory.InitChip = InitHi3881Chip; - tmpFactory.DeinitChip = DeinitHi3881Chip; - tmpFactory.Build = BuildHi3881Driver; - tmpFactory.Release = ReleaseHi3881Driver; - tmpFactory.ReleaseFactory = NULL; - if (driverMgr->RegChipDriver(&tmpFactory) != HDF_SUCCESS) { - HDF_LOGE("%s fail: driverMgr is NULL!", __func__); - return HDF_FAILURE; + + /* WLAN芯片的去初始化函数。 */ + int32_t DeinitHi3881Chip(struct HdfWlanDevice *device) + { + (void)device; + int32_t ret = hi_wifi_deinit(); + if (ret != 0) { + HDF_LOGE("%s:Deinit failed!ret=%d", __func__, ret); + } + return ret; } - return HDF_SUCCESS; -} - -static int32_t HdfWlanHisiChipDriverInit(struct HdfDeviceObject *device) -{ - (void)device; - return HDFWlanRegHisiDriverFactory(); -} - -struct HdfDriverEntry g_hdfHisiChipEntry = { - .moduleVersion = 1, - .Init = HdfWlanHisiChipDriverInit, - .moduleName = "HDF_WLAN_CHIPS" -}; - -HDF_INIT(g_hdfHisiChipEntry); -``` - - -``` -#include "hdf_wifi_product.h" -#include "hi_wifi_api.h" -#if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION) -#include "oal_thread.h" -#include "osal_time.h" -#endif -#include "wifi_mac80211_ops.h" -#include "wal_cfg80211.h" -#include "net_adapter.h" -#include "hdf_wlan_utils.h" - -#define HDF_LOG_TAG Hi3881Driver - -/* WLAN芯片的初始化函数 */ -int32_t InitHi3881Chip(struct HdfWlanDevice *device) -{ - uint8_t maxPortCount = 1; - int32_t ret = HI_SUCCESS; - uint8_t maxRetryCount = 2; - if (device == NULL) { - HDF_LOGE("%s:NULL ptr!", __func__); - return HI_FAIL; + /* WLAN芯片驱动的初始化函数。 */ + int32_t Hi3881Init(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice) + { + hi_u16 mode; + int32_t ret; + nl80211_iftype_uint8 type; + (void)chipDriver; + HDF_LOGI("%s: start...", __func__); + mode = wal_get_vap_mode(); + if (mode >= WAL_WIFI_MODE_BUTT) { + oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode); + return HI_FAIL; + } + if (mode == WAL_WIFI_MODE_STA) { + type = NL80211_IFTYPE_STATION; + #ifdef _PRE_WLAN_FEATURE_P2P + if (InitNetdev(netDevice, NL80211_IFTYPE_P2P_DEVICE) != HI_SUCCESS) { + return HI_FAIL; + } + #endif + } else if (mode == WAL_WIFI_MODE_AP) { + type = NL80211_IFTYPE_AP; + } else { + oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode); + return HI_FAIL; + } + ret = wal_init_drv_wlan_netdev(type, WAL_PHY_MODE_11N, netDevice); + if (ret != HI_SUCCESS) { + oam_error_log2(0, OAM_SF_ANY, "wal_init_drv_netdev %s failed.l_return:%d\n", netDevice->name, ret); + } + return ret; } - do { + /* WLAN芯片驱动的去初始化函数。 */ + int32_t Hi3881Deinit(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice) + { + int32_t ret; + (void)chipDriver; + ret = DeinitNetdev(NL80211_IFTYPE_P2P_DEVICE); if (ret != HI_SUCCESS) { - if (device->reset != NULL && device->reset->Reset != NULL) { - device->reset->Reset(device->reset); + oam_error_log1(0, OAM_SF_ANY, "Hi3881Deinit: DeinitNetdev p2p device fail, ret = %d\n", ret); + return ret; + } + return wal_deinit_drv_wlan_netdev(netDevice); + } + + ``` + + 在芯片侧初始化过程中调用netdev的init和add接口进行初始化netdev,并挂接netdev的一些函数指针。 + + ```c + hi_s32 wal_init_drv_wlan_netdev(nl80211_iftype_uint8 type, wal_phy_mode mode, oal_net_device_stru *netdev) + { + hi_char *ac_mode_str = NULL; + hi_s32 ret; + if (oal_unlikely(netdev == HI_NULL)) { + oam_error_log0(0, OAM_SF_ANY, "{netdev is null!}"); + return HI_ERR_CODE_PTR_NULL; + } + + do { + /* 初始化网络设备。 */ + ret = wal_init_netdev(type, netdev); + if (ret != HI_SUCCESS) { + break; } - HDF_LOGE("%s:Retry init hi3881!last ret=%d", __func__, ret); + + ret = wal_init_netif(type, netdev); + if (ret != HI_SUCCESS) { + break; + } + ac_mode_str = "11bgn"; + if (mode == WAL_PHY_MODE_11G) { + ac_mode_str = "11bg"; + } else if (mode == WAL_PHY_MODE_11B) { + ac_mode_str = "11b"; + } + + ret = wal_ioctl_set_mode(netdev, ac_mode_str); + } while (false); + + if (ret != HI_SUCCESS) { + wal_deinit_wlan_vap(netdev); + oal_net_unregister_netdev(netdev); + oal_net_clear_netdev(netdev); + return HI_FAIL; } - ret = hi_wifi_init(maxPortCount); - } while (ret != 0 && --maxRetryCount > 0); - if (ret != 0) { - HDF_LOGE("%s:Init hi3881 driver failed!", __func__); - return ret; + return HI_SUCCESS; } - return HI_SUCCESS; -} - -/* WLAN芯片的去初始化函数 */ -int32_t DeinitHi3881Chip(struct HdfWlanDevice *device) -{ - (void)device; - int32_t ret = hi_wifi_deinit(); - if (ret != 0) { - HDF_LOGE("%s:Deinit failed!ret=%d", __func__, ret); + + /* 挂接netdev的一些函数指针,详细挂接函数请参考NetDeviceInterFace。 */ + oal_net_device_ops_stru g_wal_net_dev_ops = + { + .getStats = wal_netdev_get_stats, + .open = wal_netdev_open, + .stop = wal_netdev_stop, + .xmit = hmac_bridge_vap_xmit, + .ioctl = wal_net_device_ioctl, + .changeMtu = oal_net_device_change_mtu, + .init = oal_net_device_init, + .deInit = oal_net_free_netdev, + #if (defined(_PRE_WLAN_FEATURE_FLOWCTL) || defined(_PRE_WLAN_FEATURE_OFFLOAD_FLOWCTL)) + .selectQueue = wal_netdev_select_queue, + #endif + .setMacAddr = wal_netdev_set_mac_addr, + #if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION) + .netifNotify = HI_NULL, + #endif + .specialEtherTypeProcess = SpecialEtherTypeProcess, + }; + + hi_s32 wal_init_netif(nl80211_iftype_uint8 type, oal_net_device_stru *netdev, const oal_wireless_dev *wdev) + { + /* 添加网络设备到协议栈。 */ + hi_u32 ret = NetDeviceAdd(netdev, (Protocol80211IfType)type); + + ...... + + return HI_SUCCESS; } - return ret; -} - -/* WLAN芯片驱动的初始化函数 */ -int32_t Hi3881Init(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice) -{ - HDF_LOGI("%s: start...", __func__); - hi_u16 mode = wal_get_vap_mode(); - int32_t ret; - nl80211_iftype_uint8 type; - (void)chipDriver; - - if (mode >= WAL_WIFI_MODE_BUTT) { - oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode); - return HI_FAIL; + ``` + +3. 命令下发绑定,包括具有公共能力的设置MAC地址、设置发射功率等;STA相关的连接、扫描等;AP相关的启动AP、设置国家码等。 + + ```c + /* 驱动需要实现的MAC层基本能力的控制接口。 */ + static struct HdfMac80211BaseOps g_baseOps = { + .SetMode = WalSetMode, + .AddKey = WalAddKey, + .DelKey = WalDelKey, + .SetDefaultKey = WalSetDefaultKey, + .GetDeviceMacAddr = WalGetDeviceMacAddr, + .SetMacAddr = WalSetMacAddr, + .SetTxPower = WalSetTxPower, + .GetValidFreqsWithBand = WalGetValidFreqsWithBand, + .GetHwCapability = WalGetHwCapability + }; + + /* 驱动需要实现的MAC层STA能力的控制接口。 */ + static struct HdfMac80211STAOps g_staOps = { + .Connect = WalConnect, + .Disconnect = WalDisconnect, + .StartScan = WalStartScan, + .AbortScan = WalAbortScan, + .SetScanningMacAddress = WalSetScanningMacAddress, + }; + + /* 驱动需要实现的MAC层AP能力的控制接口。 */ + static struct HdfMac80211APOps g_apOps = { + .ConfigAp = WalConfigAp, + .StartAp = WalStartAp, + .StopAp = WalStopAp, + .ConfigBeacon = WalChangeBeacon, + .DelStation = WalDelStation, + .SetCountryCode = WalSetCountryCode, + .GetAssociatedStasCount = WalGetAssociatedStasCount, + .GetAssociatedStasInfo = WalGetAssociatedStasInfo + }; + + static struct HdfMac80211P2POps g_p2pOps = { + .RemainOnChannel = WalRemainOnChannel, + .CancelRemainOnChannel = WalCancelRemainOnChannel, + .ProbeReqReport = WalProbeReqReport, + .AddIf = WalAddIf, + .RemoveIf = WalRemoveIf, + .SetApWpsP2pIe = WalSetApWpsP2pIe, + .GetDriverFlag = WalGetDriverFlag + }; + + /* 初始化Mac80211与芯片侧的函数挂接。 */ + void HiMac80211Init(struct HdfChipDriver *chipDriver) + { + if (chipDriver == NULL) { + HDF_LOGE("%s:input is NULL!", __func__); + return; + } + chipDriver->ops = &g_baseOps; + chipDriver->staOps = &g_staOps; + chipDriver->apOps = &g_apOps; + chipDriver->p2pOps = &g_p2pOps; } - - if (mode == WAL_WIFI_MODE_STA) { - type = NL80211_IFTYPE_STATION; - } else if (mode == WAL_WIFI_MODE_AP) { - type = NL80211_IFTYPE_AP; - } else { - oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode); - return HI_FAIL; + ``` + +4. 事件上报接口调用,WLAN框架提供了event事件的上报接口,详情见hdf_wifi_event.c,例:调用HdfWiFiEventNewSta AP上报新关联的某个STA的情况。 + + ```c + hi_u32 oal_cfg80211_new_sta(oal_net_device_stru *net_device, const hi_u8 *mac_addr, hi_u8 addr_len, + oal_station_info_stru *station_info, oal_gfp_enum_uint8 en_gfp) + { + #if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION) && !defined(_PRE_HDF_LINUX) + cfg80211_new_sta(net_device, mac_addr, station_info, en_gfp); + hi_unref_param(addr_len); + #elif (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION) || defined(_PRE_HDF_LINUX) + struct StationInfo info = { 0 }; + info.assocReqIes = station_info->assoc_req_ies; + info.assocReqIesLen = station_info->assoc_req_ies_len; + HdfWifiEventNewSta(net_device, mac_addr, WLAN_MAC_ADDR_LEN, &info); + hi_unref_param(en_gfp); + hi_unref_param(addr_len); + #endif + + return HI_SUCCESS; } + ``` +## 调测验证 + +驱动开发完成后,在WLAN模块单元测试里面开发自测试用例以及验证WLAN模块基本功能。测试环境采用开发者自测试平台(这里以Hi3516DV300标准系统为例)。 + +1. 测试验证环境准备。 + + - 新建hostapd.conf文件(启动AP配置文件)并将以下内容复制到该文件中。 + + ```text + interface=wlan0 + driver=hdf wifi + ctrl_interface=udp + #WiFi名称 + ssid=test + hw_mode=g + channel=1 + ignore_broadcast_ssid=0 + wpa=2 + rsn_pairwise=CCMP + # WiFi密码 + wpa_passphrase=12345678 + ``` + + - 新建wpa_supplicant.conf文件(启动STA配置文件)并将以下内容复制到该文件中。 + + ```text + country=GB + + network={ + #热点名称 + ssid="test" + #热点密码 + psk="12345678" + } + ``` + + - 新建dhcpc.sh文件(将UDHCPC分配的IP地址等写入到设备中)并将以下内容复制到该文件中。 + + ```shell + #!/system/bin/sh + [ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1 + + RESOLV_CONF="/etc/resolv.conf" + [ -n "$broadcast" ] && BROADCAST="broadcast $broadcast" + [ -n "$subnet" ] && NETMASK="netmask $subnet" + + case "$1" in + deconfig) + /system/bin/ifconfig $interface 0.0.0.0 + ;; + + renew|bound) + /system/bin/ifconfig $interface $ip $BROADCAST $NETMASK + + if [ -n "$router" ] ; then + echo "deleting routers" + while busybox route del default gw 0.0.0.0 dev $interface ; do + : + done + + for i in $router ; do + busybox route add default gw $i dev $interface + done + fi + + echo -n > $RESOLV_CONF + [ -n "$domain" ] && echo search $domain >> $RESOLV_CONF + for i in $dns ; do + echo adding dns $i + echo nameserver $i >> $RESOLV_CONF + done + ;; + esac + + exit 0 + ``` + + - 新建udhcpd.conf文件(启动UDHCPD配置文件)并将以下内容复制到该文件中。 + + ```text + start 192.168.12.2 + end 192.168.12.100 + interface wlan0 #default: eth0 + max_leases 20 #default: 254 + remaining yes #default: yes + auto_time 7200 #default: 7200 (2 hours) + decline_time 3600 #default: 3600 (1 hour) + conflict_time 3600 #default: 3600 (1 hour) + offer_time 60 #default: 60 (1 minute) + min_lease 60 #defult: 60 + lease_file /vendor/etc/udhcpd.leases + opt dns 10.221.0.11 8.8.8.8 + option subnet 255.255.255.0 + opt router 192.168.12.1 + ``` + + - 执行下列命令将测试所需文件推送到开发板。 - ret = wal_init_drv_wlan_netdev(type, WAL_PHY_MODE_11N, netDevice); - if (ret != HI_SUCCESS) { - oam_error_log2(0, OAM_SF_ANY, "wal_init_drv_netdev %s failed.l_return:%d\n", netDevice->name, ret); + ```shell + hdc shell "mount -o rw,remount /" + timeout /T 1 + hdc file send dhcpc.sh /system/lib/ + hdc shell "chmod 777 /system/lib/dhcpc.sh" + hdc file send wpa_supplicant.conf / + hdc shell "mount -o rw,remount /vendor" + hdc file send hostapd.conf / + hdc file send udhcpd.conf /vendor/etc + hdc shell "touch /vendor/etc/udhcpd.leases" + hdc shell "chmod 777 /vendor/etc/udhcpd.leases" + ``` + +2. 验证WiFi基本功能。 + + - 验证AP基本功能 + + 1. 开发板启动AP,测试终端(例如手机)打开WiFi开关(设置 -> WLAN -> 打开WiFi开关)。 + + 2. 使用cmd窗口输入如下命令。 + ```shell + hdc shell + hostapd ./hostapd.conf + ``` + + 3. 使用另一个cmd窗口执行下列命令。 + + ```shell + hdc shell + ifconfig wlan0 192.168.12.1 netmask 255.255.255.0 + busybox udhcpd /vendor/etc/udhcpd.conf + ``` + + 4. 在手机的WiFi列表中找到对应名称为test的网络,并输入密码(网络名称及密码均在在hostapd.conf中进行配置,成功连接后,手机上可看到已连接)。 + + 5. 使用开发板ping测试终端。 + + ```shell + busybox ping xxx.xxx.xxx.xxx + ``` + + 上述xxx.xxx.xxx.xxx为当前测试终端的IP地址,若测试能够ping通测试终端则表示,WLAN驱动基本功能正常。 + + - 验证STA基本功能 + + 1. 开发板启动STA,测试终端(例如手机)打开热点(网络名称及密码均在在hostapd.conf中进行配置,热点名称为test,密码为12345678)。 + + 2. 使用cmd窗口输入如下命令。 + + ```shell + hdc shell + wpa_supplicant -i wlan0 -d -c wpa_supplicant.conf + ``` + + 3. 使用另一个cmd窗口执行下列命令。 + + ```shell + hdc shell + mount -o rw,remount / + mount -o rw,remount /vendor + busybox udhcpc -i wlan0 -s system/lib/dhcpc.sh + ``` + 上述命令执行成功后,回显信息中可以看到单板及测试终端IP地址。 + + 4. 使用开发板ping测试终端。 + + ```shell + busybox ping xxx.xxx.xxx.xxx + ``` + + 上述xxx.xxx.xxx.xxx为当前测试终端的IP地址,若测试能够ping通测试终端则表示,WLAN驱动基本功能正常。 + +3. 验证单元测试用例 + + HDI模块用例开发步骤(需要测试HDI模块指定接口时,可采用下列步骤): + + - 使用WlanInterfaceGetInstance获取WLAN服务对象。 + + - 使用Start创建HAL和驱动之间的通道及获取驱动网卡信息。 + + - 通过GetSupportFeature获取该设备支持的WLAN特性。 + + - 调用Stop,销毁HAL和驱动之间的通道。 + + - 执行WlanInterfaceRelease销毁WLAN服务对象。 + + HDI模块用例开发实例: + + ```c + #include "v1_0/iwlan_interface.h" + #include "wlan_callback_impl.h" + #include "wlan_impl.h" + + #define PROTOCOL_80211_IFTYPE_NUM 11; + #define HDF_SUCCESS 0 + #define HDF_FAILURE (-1) + + static int32_t hdi_main() + { + int32_t rc; + const char *WLAN_SERVICE_NAME = "wlan_hal_c_service"; + static struct IWlanInterface *g_wlanObj = NULL; + uint8_t supType[PROTOCOL_80211_IFTYPE_NUM + 1] = {0}; + uint32_t supTypeLen = PROTOCOL_80211_IFTYPE_NUM + 1; + + /* 获取WLAN服务对象。*/ + g_wlanObj = WlanInterfaceGetInstance(WLAN_SERVICE_NAME); + if (g_wlanObj == NULL) + { + return HDF_FAILURE; + } + + /* 创建HAL和驱动之间的通道及获取驱动网卡信息。 */ + rc = g_wlanObj->Start(g_wlanObj); + if (rc != HDF_SUCCESS) + { + return HDF_FAILURE; + } + + /* 获取该设备支持的WLAN特性(不考虑当前的使用状态)。 */ + rc = g_wlanObj->GetSupportFeature(g_wlanObj, supType, &supTypeLen); + if (rc != HDF_SUCCESS) + { + return HDF_FAILURE; + } + + /* 销毁HAL和驱动之间的通道。 */ + rc = g_wlanObj->Stop(g_wlanObj); + if (rc != HDF_SUCCESS) + { + return HDF_FAILURE; + } + + /* 销毁WLAN服务对象。 */ + rc = WlanInterfaceRelease(g_wlanObj); + if (rc != HDF_SUCCESS) + { + return HDF_FAILURE; + } + return rc; } - return ret; -} - -/* WLAN芯片驱动的去初始化函数 */ -int32_t Hi3881Deinit(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice) -{ - (void)chipDriver; - int32_t ret = wal_deinit_drv_wlan_netdev(netDevice); - if (ret != HDF_SUCCESS) { + ``` + + HAL模块用例开发步骤(需要测试HAL模块指定接口时,可采用下列步骤): + + - 使用WifiConstruct创建一个WiFi实体。 + + - 用创建的WiFi实体调用start开启HAL和驱动之间的通道,获得驱动网卡的信息。 + + - 通过createFeature创建一个apFeature或者staFeature。后面可通过这些Feature去调用具体的实现接口,下面基于创建的apFeature为例进行介绍。 + + - 调用和使用相关接口:如setMacAddress设置MAC地址、getDeviceMacAddress获取设备的MAC地址等。 + + - 调用destroyFeature,销毁掉创建的apFeature。 + + - 调用stop销毁创建的通道。 + + - 执行WifiDestruct销毁创建的WiFi实体。 + + HAL模块用例开发实例: + + ```c + #include "wifi_hal.h" + #include "wifi_hal_sta_feature.h" + #include "wifi_hal_ap_feature.h" + #include "wifi_hal_cmd.h" + #include "wifi_hal_event.h" + + #define MAC_LEN 6 + #define HDF_SUCCESS 0 + #define HDF_FAILURE (-1) + + + static int32_t hal_main() + { + int32_t ret; + struct IWiFi *wifi; + + /* 创建一个wifi实体。 */ + ret = WifiConstruct(&wifi); + if (ret != HDF_SUCCESS || wifi == NULL) { + return HDF_FAILURE; + } + + /* 开启HAL和驱动之间的通道,获得驱动网卡的信息。 */ + ret = wifi->start(wifi); + if (ret != HDF_SUCCESS) { + return HDF_FAILURE; + } + + /* 创建apFeature。 */ + ret = wifi->createFeature(PROTOCOL_80211_IFTYPE_AP, (struct IWiFiBaseFeature **)&apFeature); + if (ret != HDF_SUCCESS) { + return HDF_FAILURE; + } + + /* 获取设备MAC地址。 */ + unsigned char mac[MAC_LEN] = {0}; + ret = apFeature->baseFeature.getDeviceMacAddress((struct IWiFiBaseFeature *)apFeature, mac, MAC_LEN); + if (ret != HDF_SUCCESS) { + return HDF_FAILURE; + } + + /* 销毁创建的apFeature。 */ + ret = wifi->destroyFeature((struct IWiFiBaseFeature *)apFeature); + if (ret != HDF_SUCCESS) { + return HDF_FAILURE; + } + + /* 销毁HAL和驱动之间的通道。 */ + ret = wifi->stop(wifi); + if (ret != HDF_SUCCESS) { + return HDF_FAILURE; + } + + /* 销毁创建的WiFi实体。 */ + ret = WifiDestruct(&wifi); + if (ret != HDF_SUCCESS) { + return HDF_FAILURE; + } return ret; } - return ReleasePlatformNetDevice(netDevice); -} -``` - - 3、在芯片侧初始化过程中调用netdev的init和add接口进行初始化netdev,并挂接netdev的一些函数指针。 - -``` -hi_s32 wal_init_drv_wlan_netdev(nl80211_iftype_uint8 type, wal_phy_mode mode, hi_char* ifname, hi_u32* len) -{ - oal_net_device_stru *netdev = HI_NULL; - - ...... - /* 初始化网络设备,获取对应的实例 */ - netdev = NetDeviceInit(ifname, *len, LITE_OS); - oal_wireless_dev *wdev = (oal_wireless_dev *)oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, sizeof(oal_wireless_dev)); - ret = wal_init_netif(type, netdev, wdev); - - ...... - - return HI_SUCCESS; -} -/* 挂接netdev的一些函数指针,详细挂接函数{@link NetDeviceInterFace} */ -oal_net_device_ops_stru g_wal_net_dev_ops = -{ - .getStats = wal_netdev_get_stats, - .open = wal_netdev_open, - .stop = wal_netdev_stop, - .xmit = hmac_bridge_vap_xmit, - .ioctl = wal_net_device_ioctl, - .changeMtu = oal_net_device_change_mtu, - .init = oal_net_device_init, - .deInit = oal_net_free_netdev, -#if (defined(_PRE_WLAN_FEATURE_FLOWCTL) || defined(_PRE_WLAN_FEATURE_OFFLOAD_FLOWCTL)) - .selectQueue = wal_netdev_select_queue, -#endif - .setMacAddr = wal_netdev_set_mac_addr, -#if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION) - .netifNotify = HI_NULL, -#endif - .specialEtherTypeProcess = SpecialEtherTypeProcess, -}; - -hi_s32 wal_init_netif(nl80211_iftype_uint8 type, oal_net_device_stru *netdev, const oal_wireless_dev *wdev) -{ - /* 添加网络设备到协议栈 */ - hi_u32 ret = NetDeviceAdd(netdev, (Protocol80211IfType)type); - - ...... - - return HI_SUCCESS; -} -``` - -4、WifiMac80211Ops中的函数挂接实现。 - - -``` -/* 挂接mac80211的一些函数指针 */ - -/* 驱动需要实现的MAC层基本能力的控制接口 */ -static struct HdfMac80211BaseOps g_baseOps = { - .SetMode = WalSetMode, - .AddKey = WalAddKey, - .DelKey = WalDelKey, - .SetDefaultKey = WalSetDefaultKey, - .GetDeviceMacAddr = WalGetDeviceMacAddr, - .SetMacAddr = WalSetMacAddr, - .SetTxPower = WalSetTxPower, - .GetValidFreqsWithBand = WalGetValidFreqsWithBand, - .GetHwCapability = WalGetHwCapability -}; - -/* 驱动需要实现的MAC层STA能力的控制接口 */ -static struct HdfMac80211STAOps g_staOps = { - .Connect = WalConnect, - .Disconnect = WalDisconnect, - .StartScan = WalStartScan, - .AbortScan = WalAbortScan, - .SetScanningMacAddress = WalSetScanningMacAddress, -}; - -/* 驱动需要实现的MAC层AP能力的控制接口 */ -static struct HdfMac80211APOps g_apOps = { - .ConfigAp = WalConfigAp, - .StartAp = WalStartAp, - .StopAp = WalStopAp, - .ConfigBeacon = WalChangeBeacon, - .DelStation = WalDelStation, - .SetCountryCode = WalSetCountryCode, - .GetAssociatedStasCount = WalGetAssociatedStasCount, - .GetAssociatedStasInfo = WalGetAssociatedStasInfo -}; - -/* 初始化mac80211与芯片侧的函数挂接 */ -hi_void HiMac80211Init(struct HdfChipDriver *chipDriver) -{ - if (chipDriver == NULL) { - oam_error_log(0, OAM_SF_ANY, "%s:input is NULL!", __func__); - return; - } - chipDriver->ops = &g_baseOps; - chipDriver->staOps = &g_staOps; - chipDriver->apOps = &g_apOps; -} -``` + ``` + +4. 验证测试用例方法如下 + 1. 将测试用例推送到单板。 + + ```shell + hdc file send /xxx /data + ``` + + xxx表示需要推送到单板根目录的测试用例路径。 + + 2. 修改测试用例权限并执行该用例。 + + ```shell + hdc shell + cd data + chmod 777 测试用例名称 + ./测试用例名称 + ``` + + 查看测试用例执行结果是否正确。 + ## 参考 - 代码仓库如下: - [drivers\_hdf\_core](https://gitee.com/openharmony/drivers_hdf_core) + **[drivers\_hdf\_core](https://gitee.com/openharmony/drivers_hdf_core)** [drivers\_peripheral](https://gitee.com/openharmony/drivers_peripheral) + [drivers\_interface](https://gitee.com/openharmony/drivers_interface) + - 代码路径如下: WLAN模块流控组件liteos适配://drivers/hdf_core/adapter/khdf/liteos/model/network/wifi HDF网络模型liteos适配://drivers/hdf_core/adapter/khdf/liteos/model/network - WLAN模块流控组件Linux适配、HDF WLAN模型及VENDOR WLAN驱动编译: + WLAN模块流控组件Linux适配、HDF WLAN模型、VENDOR WLAN驱动编译: //drivers/hdf_core/adapter/khdf/linux/model/network/wifi @@ -552,4 +968,6 @@ hi_void HiMac80211Init(struct HdfChipDriver *chipDriver) HDF网络模型接口://drivers/hdf_core/framework/include/net - WLAN HDI接口及具体实现://drivers/peripheral/wlan + WLAN HDI服务端实现://drivers/peripheral/wlan + + WLAN HDI对外接口://out/{product_name}/gen/drivers/interface/wlan/v1_0 -- GitLab