未验证 提交 0834d4a9 编写于 作者: O openharmony_ci 提交者: Gitee

!8667 docs:Modify the wlan document

Merge pull request !8667 from 陈博通/master
...@@ -65,48 +65,46 @@ WLAN Driver框架主要由如下模块组成: ...@@ -65,48 +65,46 @@ WLAN Driver框架主要由如下模块组成:
WLAN模块有三部分对外开放的API接口,如下图所示: WLAN模块有三部分对外开放的API接口,如下图所示:
1. 驱动直接调用WLAN模块能力接口。 1. 对上层服务提供HDI以及HAL能力接口。
2. 提供给各厂商实现的能力接口。 2. 提供给各厂商实现的能力接口。
3. 对HDI层提供的能力接口 3. 驱动直接调用WLAN模块能力接口。
**图3** WLAN驱动接口框架图 **图3** WLAN驱动接口框架图
![image](figures/WLAN驱动接口框架图.png "WLAN驱动接口框架图") ![image](figures/WLAN驱动接口框架图.png "WLAN驱动接口框架图")
- WLAN驱动模块提供给驱动开发人员可直接调用的能力接口,主要功能有:创建/释放WifiModule、关联/取消关联、申请/释放NetBuf、lwip的pbuf和NetBuf的相互转换等。 - WLAN驱动模块对上层服务提供的HDI能力接口(适用于标准系统),主要功能有:创建/销毁ifeature对象、设置/获取功率模式等。提供的部分接口说明如表1所示:
可直接调用的接口如表1、表2和表3所示。
**表1** wifi_module.h **表1** IWlanInterface.idl
| 接口名称 | 功能描述 | | 接口名称 | 功能描述 |
| -------- | -------- | | -------- | -------- |
| struct WifiModule \*WifiModuleCreate(const struct HdfConfigWifiModuleConfig \*config) | 基于HDF开发WLAN驱动时,创建一个WifiModule。 | | CreateFeature([in] int type, [out] struct HdfFeatureInfo ifeature); | 创建ifeature对象。 |
| void WifiModuleDelete(struct WifiModule \*module) | 基于HDF开发WLAN驱动时,删除并释放WifiModule所有数据。 | | DestroyFeature([in] struct HdfFeatureInfo ifeature); | 销毁ifeature对象。 |
| int32_t DelFeature(struct WifiModule \*module, uint16_t featureType) | 基于HDF开发WLAN驱动时,从WifiModule删除一个功能组件。 | | GetPowerMode([in] struct HdfFeatureInfo ifeature, [out] unsigned char mode); | 获取功率模式。 |
| int32_t&nbsp;AddFeature(struct&nbsp;WifiModule&nbsp;\*module,&nbsp;uint16_t&nbsp;featureType,<br>&nbsp;struct&nbsp;WifiFeature&nbsp;\*featureData) | 基于HDF开发WLAN驱动时,注册一个功能组件到WifiModule。 | | SetPowerMode([in]&nbsp;struct&nbsp;HdfFeatureInfo&nbsp;ifeature,&nbsp;[in]&nbsp;unsigned&nbsp;char&nbsp;mode); | 设置功率模式。 |
- WLAN驱动模块对上层服务提供的HAL能力接口(适用于小型系统及轻量系统),主要功能有:创建/销毁 IWiFi对象、设置MAC地址等。提供的部分接口说明如表2、表3所示:
**表2** wifi_mac80211_ops.h **表2** wifi_hal.h
| 接口名称 | 功能描述 | | 接口名称 | 功能描述 |
| -------- | -------- | | -------- | -------- |
| int32_t&nbsp;(\*startAp)(NetDevice&nbsp;\*netDev) | 启动AP。 | | int32_t&nbsp;WifiConstruct(struct&nbsp;IWiFi&nbsp;\*\*wifiInstance) | 创建IWiFi对象,提供IWiFi基本能力。 |
| int32_t&nbsp;(\*stopAp)(NetDevice&nbsp;\*netDev) | 停止AP。 | | int32_t&nbsp;WifiDestruct(struct&nbsp;IWiFi&nbsp;\*\*wifiInstance) | 销毁IWiFi对象。 |
| int32_t&nbsp;(\*connect)(NetDevice&nbsp;\*netDev,&nbsp;WifiConnectParams&nbsp;\*param) | 开始关联。 | | int32_t&nbsp;(\*start)(struct&nbsp;IWiFi&nbsp;\*) | 创建HAL和驱动之间的通道及获取驱动支持的网卡信息。 |
| int32_t&nbsp;(\*disconnect)(NetDevice&nbsp;\*netDev,&nbsp;uint16_t&nbsp;reasonCode) | 取消关联。 | | int32_t&nbsp;(\*stop)(struct&nbsp;IWiFi&nbsp;\*) | 销毁通道。 |
**表3** hdf_netbuf.h **表3** wifi_hal_base_feature.h
| 接口名称 | 功能描述 | | 接口名称 | 功能描述 |
| -------- | -------- | | -------- | -------- |
| static&nbsp;inline&nbsp;void&nbsp;NetBufQueueInit(struct&nbsp;NetBufQueue&nbsp;\*q) | 初始化NetBuf队列。 | | int32_t&nbsp;(\*getFeatureType)(const&nbsp;struct&nbsp;IWiFiBaseFeature&nbsp;\*) | 获取特性的类型。 |
| struct&nbsp;NetBuf&nbsp;\*NetBufAlloc(uint32_t&nbsp;size) | 申请NetBuf。 | | int32_t&nbsp;(\*setMacAddress)(const&nbsp;struct&nbsp;IWiFiBaseFeature&nbsp;\*,&nbsp;unsigned&nbsp;char&nbsp;\*,&nbsp;uint8_t) | 设置MAC地址。 |
| void&nbsp;NetBufFree(struct&nbsp;NetBuf&nbsp;\*nb) | 释放NetBuf | | int32_t&nbsp;(\*getDeviceMacAddress)(const&nbsp;struct&nbsp;IWiFiBaseFeature&nbsp;\*,&nbsp;unsigned&nbsp;char&nbsp;\*,&nbsp;uint8_t) | 获取设备持久化的MAC地址。 |
| struct&nbsp;NetBuf&nbsp;\*Pbuf2NetBuf(const&nbsp;struct&nbsp;NetDevice&nbsp;\*netdev,&nbsp;struct&nbsp;pbuf&nbsp;\*lwipBuf) | lwip的pbuf转换为NetBuf。 | | int32_t&nbsp;(\*setTxPower)(const&nbsp;struct&nbsp;IWiFiBaseFeature&nbsp;\*,&nbsp;int32_t) | 设置发射功率。 |
| struct&nbsp;pbuf&nbsp;\*NetBuf2Pbuf(const&nbsp;struct&nbsp;NetBuf&nbsp;\*nb) | NetBuf转换为lwip的pbuf。 |
- WLAN驱动模块也提供了需要驱动开发人员自行去填充具体实现内容的能力接口,主要功能有:初始化/注销NetDevice、打开/关闭NetDevice、获取NetDevice的状态等。提供的部分接口说明如表4所示: - WLAN驱动模块也提供了需要驱动开发人员自行去填充具体实现内容的能力接口,主要功能有:初始化/注销NetDevice、打开/关闭NetDevice、获取NetDevice的状态等。提供的部分接口说明如表4所示:
...@@ -121,428 +119,846 @@ WLAN模块有三部分对外开放的API接口,如下图所示: ...@@ -121,428 +119,846 @@ WLAN模块有三部分对外开放的API接口,如下图所示:
| int32_t&nbsp;(\*open)(struct&nbsp;NetDevice&nbsp;\*netDev) | 打开NetDevice。 | | int32_t&nbsp;(\*open)(struct&nbsp;NetDevice&nbsp;\*netDev) | 打开NetDevice。 |
| int32_t&nbsp;(\*stop)(struct&nbsp;NetDevice&nbsp;\*netDev) | 关闭NetDevice。 | | int32_t&nbsp;(\*stop)(struct&nbsp;NetDevice&nbsp;\*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&nbsp;WifiConstruct(struct&nbsp;IWiFi&nbsp;\*\*wifiInstance) | 创建IWiFi对象,提供IWiFi基本能力。 | | struct&nbsp;WifiModule&nbsp;\*WifiModuleCreate(const&nbsp;struct&nbsp;HdfConfigWifiModuleConfig&nbsp;\*config) | 基于HDF开发WLAN驱动时,创建一个WifiModule。 |
| int32_t&nbsp;WifiDestruct(struct&nbsp;IWiFi&nbsp;\*\*wifiInstance) | 销毁IWiFi对象。 | | void&nbsp;WifiModuleDelete(struct&nbsp;WifiModule&nbsp;\*module) | 基于HDF开发WLAN驱动时,删除并释放WifiModule所有数据。 |
| int32_t&nbsp;(\*start)(struct&nbsp;IWiFi&nbsp;\*) | 创建HAL和驱动之间的通道及获取驱动支持的网卡信息。 | | int32_t&nbsp;DelFeature(struct&nbsp;WifiModule&nbsp;\*module,&nbsp;uint16_t&nbsp;featureType) | 基于HDF开发WLAN驱动时,从WifiModule删除一个功能组件。 |
| int32_t&nbsp;(\*stop)(struct&nbsp;IWiFi&nbsp;\*) | 销毁通道。 | | int32_t&nbsp;AddFeature(struct&nbsp;WifiModule&nbsp;\*module,&nbsp;uint16_t&nbsp;featureType,<br>&nbsp;struct&nbsp;WifiFeature&nbsp;\*featureData) | 基于HDF开发WLAN驱动时,注册一个功能组件到WifiModule。 |
**表6** wifi_hal_base_feature.h **表6** wifi_mac80211_ops.h
| 接口名称 | 功能描述 | | 接口名称 | 功能描述 |
| -------- | -------- | | -------- | -------- |
| int32_t&nbsp;(\*getFeatureType)(const&nbsp;struct&nbsp;IWiFiBaseFeature&nbsp;\*) | 获取特性的类型。 | | int32_t&nbsp;(\*startAp)(NetDevice&nbsp;\*netDev) | 启动AP。 |
| int32_t&nbsp;(\*setMacAddress)(const&nbsp;struct&nbsp;IWiFiBaseFeature&nbsp;\*,&nbsp;unsigned&nbsp;char&nbsp;\*,&nbsp;uint8_t) | 设置MAC地址。 | | int32_t&nbsp;(\*stopAp)(NetDevice&nbsp;\*netDev) | 停止AP。 |
| int32_t&nbsp;(\*getDeviceMacAddress)(const&nbsp;struct&nbsp;IWiFiBaseFeature&nbsp;\*,&nbsp;unsigned&nbsp;char&nbsp;\*,&nbsp;uint8_t) | 获取设备持久化的MAC地址。 | | int32_t&nbsp;(\*connect)(NetDevice&nbsp;\*netDev,&nbsp;WifiConnectParams&nbsp;\*param) | 开始关联。 |
| int32_t&nbsp;(\*setTxPower)(const&nbsp;struct&nbsp;IWiFiBaseFeature&nbsp;\*,&nbsp;int32_t) | 设置发射功率。 | | int32_t&nbsp;(\*disconnect)(NetDevice&nbsp;\*netDev,&nbsp;uint16_t&nbsp;reasonCode) | 取消关联。 |
**表7** hdf_netbuf.h
### 开发步骤 | 接口名称 | 功能描述 |
| -------- | -------- |
| static&nbsp;inline&nbsp;void&nbsp;NetBufQueueInit(struct&nbsp;NetBufQueue&nbsp;\*q) | 初始化NetBuf队列。 |
| struct&nbsp;NetBuf&nbsp;\*NetBufAlloc(uint32_t&nbsp;size) | 申请NetBuf。 |
| void&nbsp;NetBufFree(struct&nbsp;NetBuf&nbsp;\*nb) | 释放NetBuf |
| struct&nbsp;NetBuf&nbsp;\*Pbuf2NetBuf(const&nbsp;struct&nbsp;NetDevice&nbsp;\*netdev,&nbsp;struct&nbsp;pbuf&nbsp;\*lwipBuf) | lwip的pbuf转换为NetBuf。 |
| struct&nbsp;pbuf&nbsp;\*NetBuf2Pbuf(const&nbsp;struct&nbsp;NetBuf&nbsp;\*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芯片为例): 本例程提供WLAN模块初始化过程的完整使用流程。示例如下(以Hi3881WLAN芯片为例):
1、根据硬件,修改配置参数。 1. 根据硬件具体情况修改配置参数。
``` ```text
/* 根据硬件参数,通过wlan_platform.hcs配置相关参数,以下是WLAN平台配置的示例 */ /* 根据硬件具体情况,在wlan_platform.hcs中配置相关参数,以下是WLAN平台配置的示例 */
hisi :& deviceList { hisi :& deviceList {
device0 :: deviceInst { device0 :: deviceInst {
deviceInstId = 0; deviceInstId = 0;
powers { powers {
power0 { power0 {
powerSeqDelay = 0; /* 电源序列延时 */ powerSeqDelay = 0; /* 电源序列延时 */
powerType = 1; /* 电源类型:0--总是打开;1--GPIO */ powerType = 1; /* 电源类型,0表示总是打开;1表示GPIO */
gpioId = 1; /* GPIO管脚号 */ gpioId = 1; /* GPIO管脚号 */
activeLevel=1; /* 有效电平:0--低;1--高 */ activeLevel=1; /* 有效电平,0表示低电平有效;1表示高电平有效 */
}
power1 {
powerSeqDelay = 0; /* 电源序列延时 */
powerType = 0; /* 电源类型,0表示总是打开;1表示GPIO */
}
} }
power1 { reset {
powerSeqDelay = 0; /* 电源序列延时 */ resetType = 0; /* 复位类型,0表示不管理;1表示GPIO */
powerType = 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的配置示例 */
/* 每一块芯片添加配置文件wlan_chip_<芯片名>.hcs(如:wlan_chip_hi3881.hcs),配置相关参数。以下是hi3881的配置示例 */ root {
root { wlan_config {
wlan_config { hi3881 :& chipList {
hi3881 :& chipList { chipHi3881 :: chipInst {
chipHi3881 :: chipInst { match_attr = "hdf_wlan_chips_hi3881"; /* 配置匹配标识 */
match_attr = "hdf_wlan_chips_hi3881"; /* 配置匹配标识 */ chipName = "hi3881"; /* WLAN芯片的名称 */
chipName = "hi3881"; /* WLAN芯片的名称 */ bus {
sdio { vendorId = 0x0296; /* 厂商ID */
vendorId = 0x0296; /* 厂商Id */ deviceId = [0x5347]; /* 设备ID */
deviceId = [0x5347]; /* 设备Id */ }
} }
} }
} }
} }
} ```
```
2. 适配挂接WLAN芯片的初始化和去初始化、WLAN芯片驱动的初始化和去初始化。
2、适配挂接WLAN芯片的初始化和去初始化、WLAN芯片驱动的初始化和去初始化。
```c
``` #include "hdf_device_desc.h"
/* WLAN初始化挂接流程 */ #include "hdf_wifi_product.h"
#include "hdf_device_desc.h" #include "hdf_log.h"
#include "hdf_wifi_product.h" #include "osal_mem.h"
#include "hdf_log.h" #include "hdf_wlan_chipdriver_manager.h"
#include "osal_mem.h" #include "securec.h"
#include "hdf_wlan_chipdriver_manager.h" #include "wifi_module.h"
#include "securec.h" #include "hi_wifi_api.h"
#include "wifi_module.h" #include "hi_types_base.h"
#include "hi_wifi_api.h"
#include "hi_types_base.h" #define HDF_LOG_TAG Hi3881Driver
#define HDF_LOG_TAG Hi3881Driver /* WLAN芯片的初始化和去初始化函数。 */
int32_t InitHi3881Chip(struct HdfWlanDevice *device);
/* WLAN芯片的初始化和去初始化函数 */ int32_t DeinitHi3881Chip(struct HdfWlanDevice *device);
int32_t InitHi3881Chip(struct HdfWlanDevice *device); /* WLAN芯片驱动的初始化和去初始化函数。 */
int32_t DeinitHi3881Chip(struct HdfWlanDevice *device); int32_t Hi3881Deinit(struct HdfChipDriver* chipDriver, struct NetDevice *netDevice);
/* WLAN芯片驱动的初始化和去初始化函数 */ int32_t Hi3881Init(struct HdfChipDriver* chipDriver, struct NetDevice *netDevice);
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);
/* 初始化mac80211与芯片侧的函数挂接 */
hi_void HiMac80211Init(struct HdfChipDriver *chipDriver); static const char* const HI3881_DRIVER_NAME = "hisi";
static const char* const HI3881_DRIVER_NAME = "hisi"; /* WLAN芯片驱动挂接以及Mac80211与芯片侧的函数挂接。 */
static struct HdfChipDriver *BuildHi3881Driver(struct HdfWlanDevice *device, uint8_t ifIndex)
/* WLAN芯片驱动挂接以及mac80211与芯片侧的函数挂接 */ {
static struct HdfChipDriver *BuildHi3881Driver(struct HdfWlanDevice *device, uint8_t ifIndex) struct HdfChipDriver *specificDriver = NULL;
{ if (device == NULL) {
struct HdfChipDriver *specificDriver = NULL; HDF_LOGE("%s fail: channel is NULL!", __func__);
if (device == NULL) { return NULL;
HDF_LOGE("%s fail : channel is NULL", __func__); }
return NULL; (void)ifIndex;
} specificDriver = (struct HdfChipDriver *)OsalMemCalloc(sizeof(struct HdfChipDriver));
(void)device; if (specificDriver == NULL) {
(void)ifIndex; HDF_LOGE("%s fail: OsalMemCalloc fail!", __func__);
specificDriver = (struct HdfChipDriver *)OsalMemCalloc(sizeof(struct HdfChipDriver)); return NULL;
if (specificDriver == NULL) { }
HDF_LOGE("%s fail: OsalMemCalloc fail!", __func__); if (memset_s(specificDriver, sizeof(struct HdfChipDriver), 0, sizeof(struct HdfChipDriver)) != EOK) {
return NULL; HDF_LOGE("%s fail: memset_s fail!", __func__);
} OsalMemFree(specificDriver);
if (memset_s(specificDriver, sizeof(struct HdfChipDriver), 0, sizeof(struct HdfChipDriver)) != EOK) { return NULL;
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) { /* 释放WLAN芯片驱动。 */
HDF_LOGE("%s fail : strcpy_s fail", __func__); static void ReleaseHi3881Driver(struct HdfChipDriver *chipDriver)
OsalMemFree(specificDriver); {
return NULL; 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芯片驱动 */ return HDF_SUCCESS;
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__); static int32_t HdfWlanHisiChipDriverInit(struct HdfDeviceObject *device)
return; {
(void)device;
return HDFWlanRegHisiDriverFactory();
} }
OsalMemFree(chipDriver);
} struct HdfDriverEntry g_hdfHisiChipEntry = {
.moduleVersion = 1,
static uint8_t GetHi3881GetMaxIFCount(struct HdfChipDriverFactory *factory) { .Bind = HdfWlanHisiDriverBind,
(void)factory; .Init = HdfWlanHisiChipDriverInit,
return 1; .Release = HdfWlanHisiChipRelease,
} .moduleName = "HDF_WLAN_CHIPS"
};
/* WLAN芯片相关函数的注册 */
static int32_t HDFWlanRegHisiDriverFactory(void) HDF_INIT(g_hdfHisiChipEntry);
{ ```
static struct HdfChipDriverFactory tmpFactory = { 0 };
struct HdfChipDriverManager *driverMgr = NULL; 芯片初始化和芯片驱动初始化相关内容详见hdfinit_3881.c,具体函数分解如下:
driverMgr = HdfWlanGetChipDriverMgr();
if (driverMgr == NULL && driverMgr->RegChipDriver != NULL) { ```c
HDF_LOGE("%s fail: driverMgr is NULL!", __func__); #include "hdf_wifi_product.h"
return HDF_FAILURE; #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; /* WLAN芯片的去初始化函数。 */
tmpFactory.InitChip = InitHi3881Chip; int32_t DeinitHi3881Chip(struct HdfWlanDevice *device)
tmpFactory.DeinitChip = DeinitHi3881Chip; {
tmpFactory.Build = BuildHi3881Driver; (void)device;
tmpFactory.Release = ReleaseHi3881Driver; int32_t ret = hi_wifi_deinit();
tmpFactory.ReleaseFactory = NULL; if (ret != 0) {
if (driverMgr->RegChipDriver(&tmpFactory) != HDF_SUCCESS) { HDF_LOGE("%s:Deinit failed!ret=%d", __func__, ret);
HDF_LOGE("%s fail: driverMgr is NULL!", __func__); }
return HDF_FAILURE; return ret;
} }
return HDF_SUCCESS; /* WLAN芯片驱动的初始化函数。 */
} int32_t Hi3881Init(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice)
{
static int32_t HdfWlanHisiChipDriverInit(struct HdfDeviceObject *device) hi_u16 mode;
{ int32_t ret;
(void)device; nl80211_iftype_uint8 type;
return HDFWlanRegHisiDriverFactory(); (void)chipDriver;
} HDF_LOGI("%s: start...", __func__);
mode = wal_get_vap_mode();
struct HdfDriverEntry g_hdfHisiChipEntry = { if (mode >= WAL_WIFI_MODE_BUTT) {
.moduleVersion = 1, oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode);
.Init = HdfWlanHisiChipDriverInit, return HI_FAIL;
.moduleName = "HDF_WLAN_CHIPS" }
}; if (mode == WAL_WIFI_MODE_STA) {
type = NL80211_IFTYPE_STATION;
HDF_INIT(g_hdfHisiChipEntry); #ifdef _PRE_WLAN_FEATURE_P2P
``` if (InitNetdev(netDevice, NL80211_IFTYPE_P2P_DEVICE) != HI_SUCCESS) {
return HI_FAIL;
}
``` #endif
#include "hdf_wifi_product.h" } else if (mode == WAL_WIFI_MODE_AP) {
#include "hi_wifi_api.h" type = NL80211_IFTYPE_AP;
#if (_PRE_OS_VERSION_LINUX == _PRE_OS_VERSION) } else {
#include "oal_thread.h" oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode);
#include "osal_time.h" return HI_FAIL;
#endif }
#include "wifi_mac80211_ops.h" ret = wal_init_drv_wlan_netdev(type, WAL_PHY_MODE_11N, netDevice);
#include "wal_cfg80211.h" if (ret != HI_SUCCESS) {
#include "net_adapter.h" oam_error_log2(0, OAM_SF_ANY, "wal_init_drv_netdev %s failed.l_return:%d\n", netDevice->name, ret);
#include "hdf_wlan_utils.h" }
return ret;
#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;
} }
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 (ret != HI_SUCCESS) {
if (device->reset != NULL && device->reset->Reset != NULL) { oam_error_log1(0, OAM_SF_ANY, "Hi3881Deinit: DeinitNetdev p2p device fail, ret = %d\n", ret);
device->reset->Reset(device->reset); 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) { return HI_SUCCESS;
HDF_LOGE("%s:Init hi3881 driver failed!", __func__);
return ret;
} }
return HI_SUCCESS;
} /* 挂接netdev的一些函数指针,详细挂接函数请参考NetDeviceInterFace。 */
oal_net_device_ops_stru g_wal_net_dev_ops =
/* WLAN芯片的去初始化函数 */ {
int32_t DeinitHi3881Chip(struct HdfWlanDevice *device) .getStats = wal_netdev_get_stats,
{ .open = wal_netdev_open,
(void)device; .stop = wal_netdev_stop,
int32_t ret = hi_wifi_deinit(); .xmit = hmac_bridge_vap_xmit,
if (ret != 0) { .ioctl = wal_net_device_ioctl,
HDF_LOGE("%s:Deinit failed!ret=%d", __func__, ret); .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; ```
}
3. 命令下发绑定,包括具有公共能力的设置MAC地址、设置发射功率等;STA相关的连接、扫描等;AP相关的启动AP、设置国家码等。
/* WLAN芯片驱动的初始化函数 */
int32_t Hi3881Init(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice) ```c
{ /* 驱动需要实现的MAC层基本能力的控制接口。 */
HDF_LOGI("%s: start...", __func__); static struct HdfMac80211BaseOps g_baseOps = {
hi_u16 mode = wal_get_vap_mode(); .SetMode = WalSetMode,
int32_t ret; .AddKey = WalAddKey,
nl80211_iftype_uint8 type; .DelKey = WalDelKey,
(void)chipDriver; .SetDefaultKey = WalSetDefaultKey,
.GetDeviceMacAddr = WalGetDeviceMacAddr,
if (mode >= WAL_WIFI_MODE_BUTT) { .SetMacAddr = WalSetMacAddr,
oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode); .SetTxPower = WalSetTxPower,
return HI_FAIL; .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; 4. 事件上报接口调用,WLAN框架提供了event事件的上报接口,详情见hdf_wifi_event.c,例:调用HdfWiFiEventNewSta AP上报新关联的某个STA的情况。
} else if (mode == WAL_WIFI_MODE_AP) {
type = NL80211_IFTYPE_AP; ```c
} else { hi_u32 oal_cfg80211_new_sta(oal_net_device_stru *net_device, const hi_u8 *mac_addr, hi_u8 addr_len,
oam_error_log1(0, 0, "wal_init_drv_netdev:: invalid mode[%d]", mode); oal_station_info_stru *station_info, oal_gfp_enum_uint8 en_gfp)
return HI_FAIL; {
#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); ```shell
if (ret != HI_SUCCESS) { hdc shell "mount -o rw,remount /"
oam_error_log2(0, OAM_SF_ANY, "wal_init_drv_netdev %s failed.l_return:%d\n", netDevice->name, ret); 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; ```
}
HAL模块用例开发步骤(需要测试HAL模块指定接口时,可采用下列步骤):
/* WLAN芯片驱动的去初始化函数 */
int32_t Hi3881Deinit(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice) - 使用WifiConstruct创建一个WiFi实体。
{
(void)chipDriver; - 用创建的WiFi实体调用start开启HAL和驱动之间的通道,获得驱动网卡的信息。
int32_t ret = wal_deinit_drv_wlan_netdev(netDevice);
if (ret != HDF_SUCCESS) { - 通过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 ret;
} }
return ReleasePlatformNetDevice(netDevice); ```
}
``` 4. 验证测试用例方法如下
1. 将测试用例推送到单板。
3、在芯片侧初始化过程中调用netdev的init和add接口进行初始化netdev,并挂接netdev的一些函数指针。
```shell
``` hdc file send /xxx /data
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; xxx表示需要推送到单板根目录的测试用例路径。
...... 2. 修改测试用例权限并执行该用例。
/* 初始化网络设备,获取对应的实例 */
netdev = NetDeviceInit(ifname, *len, LITE_OS); ```shell
oal_wireless_dev *wdev = (oal_wireless_dev *)oal_mem_alloc(OAL_MEM_POOL_ID_LOCAL, sizeof(oal_wireless_dev)); hdc shell
ret = wal_init_netif(type, netdev, wdev); cd data
chmod 777 测试用例名称
...... ./测试用例名称
```
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;
}
```
## 参考 ## 参考
- 代码仓库如下: - 代码仓库如下:
[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\_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 WLAN模块流控组件liteos适配://drivers/hdf_core/adapter/khdf/liteos/model/network/wifi
HDF网络模型liteos适配://drivers/hdf_core/adapter/khdf/liteos/model/network 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 //drivers/hdf_core/adapter/khdf/linux/model/network/wifi
...@@ -552,4 +968,6 @@ hi_void HiMac80211Init(struct HdfChipDriver *chipDriver) ...@@ -552,4 +968,6 @@ hi_void HiMac80211Init(struct HdfChipDriver *chipDriver)
HDF网络模型接口://drivers/hdf_core/framework/include/net 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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册