回复
OpenHarmony开发——WLAN开发实例
jiecho
发布于 2021-7-2 11:50
浏览
1收藏
WLAN开发实例
本例程提供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--高 */
}
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 {
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 */
}
}
}
}
}
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;
}
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;
}
/* 释放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);
}
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;
}
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;
}
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_adpater.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;
}
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);
} while (ret != 0 && --maxRetryCount > 0);
if (ret != 0) {
HDF_LOGE("%s:Init hi3881 driver failed!", __func__);
return ret;
}
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);
}
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;
}
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;
}
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;
}
/* 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) {
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;
}
已于2021-7-2 11:50:49修改
赞
收藏 1
回复
相关推荐