提交 bb8d5764 编写于 作者: A Annie_wang

update docs

Signed-off-by: NAnnie_wang <annie.wangli@huawei.com>
上级 43d1aae5
......@@ -64,127 +64,136 @@ The relationships between the main modules are as follows:
The WLAN module provides the following types of APIs:
- WLAN APIs that can be directly called by drivers
1. Hardware Device Interface (HDI) and Hardware Abstraction Layer (HAL) APIs for upper-layer services
- APIs for vendors
- APIs for the HDI layer
2. APIs for vendors
3. WLAN APIs directly called by drivers
**Figure 3** WLAN driver APIs
![image](figures/WLAN_driver_APIs.png "WLAN Driver APIs")
- The WLAN Driver module provides APIs that you can directly use to create or release a **WifiModule**, connect to or disconnect from a WLAN hotspot, request or release a **NetBuf**, and convert between the **pbuf** structure of Lightweight IP (lwIP) and a **NetBuf**.
Tables 1 to 3 describe these APIs.
- The WLAN module provides HDI APIs for upper-layer services (applicable to the standard system). **Table 1** describes the major APIs.
**Table 1** wifi_module.h (HDF-based WLAN driver development)
**Table 1** IWlanInterface.idl
| API| Description|
| -------- | -------- |
| struct WifiModule \*WifiModuleCreate(const struct HdfConfigWifiModuleConfig \*config) | Creates a **WifiModule**.|
| void WifiModuleDelete(struct WifiModule \*module) | Deletes a **WifiModule** and releases its data.|
| int32_t DelFeature(struct WifiModule \*module, uint16_t featureType) | Deletes a feature from a **WifiModule**.|
| int32_t AddFeature(struct WifiModule \*module, uint16_t featureType, struct WifiFeature \*featureData) | Adds a feature to a **WifiModule**.|
| CreateFeature([in] int type, [out] struct HdfFeatureInfo ifeature);| Creates an **ifeature** instance.|
| DestroyFeature([in] struct HdfFeatureInfo ifeature);| Destroys an **ifeature** instance.|
| GetPowerMode([in] struct HdfFeatureInfo ifeature, [out] unsigned char mode);| Obtains the power mode.|
| SetPowerMode([in] struct HdfFeatureInfo ifeature, [in] unsigned char mode);| Sets the power mode.|
**Table 2** wifi_mac80211_ops.h
- The WLAN module provides HAL APIs for upper-layer services (applicable to small and mini systems). **Table 2** and **Table 3** describe some APIs.
**Table 2** wifi_hal.h
| API| Description|
| -------- | -------- |
| int32_t (\*startAp)(NetDevice \*netDev) | Starts an AP.|
| int32_t (\*stopAp)(NetDevice \*netDev) | Stops an AP.|
| int32_t (\*connect)(NetDevice \*netDev, WifiConnectParams \*param) | Connects to a hotspot.|
| int32_t (\*disconnect)(NetDevice \*netDev, uint16_t reasonCode) | Disconnects from a hotspot.|
| int32_t WifiConstruct(struct IWiFi \*\*wifiInstance)| Creates an **IWiFi** instance with basic capabilities.|
| int32_t WifiDestruct(struct IWiFi \*\*wifiInstance)| Destroys an **IWiFi** instance.|
| int32_t (\*start)(struct IWiFi \*)| Creates a channel between the HAL and the driver and obtains the NICs supported by the driver.|
| int32_t (\*stop)(struct IWiFi \*)| Stops the channel between the HAL and the driver.|
**Table 3** hdf_netbuf.h
**Table 3** wifi_hal_base_feature.h
| API| Description|
| -------- | -------- |
| static inline void NetBufQueueInit(struct NetBufQueue \*q) | Initializes a **NetBuf** queue.|
| struct NetBuf \*NetBufAlloc(uint32_t size) | Allocates a **NetBuf**.|
| void NetBufFree(struct NetBuf \*nb) | Releases a **NetBuf**.|
| struct NetBuf \*Pbuf2NetBuf(const struct NetDevice \*netdev, struct pbuf \*lwipBuf) | Converts the **pbuf** structure of lwIP to a **NetBuf**.|
| struct pbuf \*NetBuf2Pbuf(const struct NetBuf \*nb) | Converts a **NetBuf** to the **pbuf** structure of lwIP.|
| int32_t (\*getFeatureType)(const struct IWiFiBaseFeature \*)| Obtains the feature type.|
| int32_t (\*setMacAddress)(const struct IWiFiBaseFeature \*, unsigned char \*, uint8_t)| Sets the MAC address.|
| int32_t (\*getDeviceMacAddress)(const struct IWiFiBaseFeature \*, unsigned char \*, uint8_t)| Obtains the device MAC address.|
| int32_t (\*setTxPower)(const struct IWiFiBaseFeature \*, int32_t)| Sets the transmit power.|
- The WLAN Driver module also provides APIs that you need to fill in the implementation. This type of APIs can be used to initialize/deinitialize a **NetDevice**, opening/stopping a **NetDevice**, and obtaining the **NetDevice** status. Table 4 describes some of these APIs.
- The WLAN Driver module also provides APIs that you need to fill in the implementation. **Table 4** describes some APIs.
**Table 4** net_device.h
| API| Description|
| -------- | -------- |
| int32_t (\*init)(struct NetDevice \*netDev) | Initializes a **NetDevice**.|
| struct NetDevStats \*(\*getStats)(struct NetDevice \*netDev) | Obtains the state of a **NetDevice**.|
| int32_t (\*init)(struct NetDevice \*netDev) | Initializes a network device. |
| struct NetDevStats \*(\*getStats)(struct NetDevice \*netDev) | Obtains the state of a network device. |
| int32_t (\*setMacAddr)(struct NetDevice \*netDev, void \*addr) | Sets the MAC address.|
| void (\*deInit)(struct NetDevice \*netDev) | Deinitializes a **NetDevice**.|
| int32_t (\*open)(struct NetDevice \*netDev) | Opens a **NetDevice**.|
| int32_t (\*stop)(struct NetDevice \*netDev) | Stops a **NetDevice**.|
| void (\*deInit)(struct NetDevice \*netDev) | Deinitializes a network device. |
| int32_t (\*open)(struct NetDevice \*netDev) | Opens a network device. |
| int32_t (\*stop)(struct NetDevice \*netDev) | Stops a network device. |
- The WLAN Driver module provides APIs that you can directly use to create or release a **WifiModule**, connect to or disconnect from a WLAN hotspot, request or release a **NetBuf**, and convert between the **pbuf** structure of Lightweight IP (lwIP) and a **NetBuf**.
- The WLAN Driver module also provides APIs to the HDI layer for creating and destroying an **IWiFi** object and setting the MAC address. Tables 5 and 6 describe some of the APIs.
Tables 5 to 7 describe the APIs.
**Table 5** wifi_hal.h
**Table 5** wifi_module.h
| API| Description|
| -------- | -------- |
| int32_t WifiConstruct(struct IWiFi \*\*wifiInstance) | Creates an **IWiFi** object with basic capabilities.|
| int32_t WifiDestruct(struct IWiFi \*\*wifiInstance) | Destroys an **IWiFi** object.|
| int32_t (\*start)(struct IWiFi \*) | Creates a channel between the HAL and the driver and obtains the NICs supported by the driver.|
| int32_t (\*stop)(struct IWiFi \*) | Stops the channel between the HAL and the driver.|
| struct WifiModule \*WifiModuleCreate(const struct HdfConfigWifiModuleConfig \*config) | Creates a **WifiModule**.|
| void WifiModuleDelete(struct WifiModule \*module) | Deletes a **WifiModule** and releases its data.|
| int32_t DelFeature(struct WifiModule \*module, uint16_t featureType) | Deletes a feature from a **WifiModule**.|
| int32_t AddFeature(struct WifiModule \*module, uint16_t featureType, struct WifiFeature \*featureData) | Adds a feature to a **WifiModule**.|
**Table 6** wifi_hal_base_feature.h
**Table 6** wifi_mac80211_ops.h
| API| Description|
| -------- | -------- |
| int32_t (\*getFeatureType)(const struct IWiFiBaseFeature \*) | Obtains the feature type.|
| int32_t (\*setMacAddress)(const struct IWiFiBaseFeature \*, unsigned char \*, uint8_t) | Sets the MAC address.|
| int32_t (\*getDeviceMacAddress)(const struct IWiFiBaseFeature \*, unsigned char \*, uint8_t) | Obtains the device MAC address.|
| int32_t (\*setTxPower)(const struct IWiFiBaseFeature \*, int32_t) | Sets the transmit power.|
| int32_t (\*startAp)(NetDevice \*netDev) | Starts an AP.|
| int32_t (\*stopAp)(NetDevice \*netDev) | Stops an AP.|
| int32_t (\*connect)(NetDevice \*netDev, WifiConnectParams \*param) | Connects to a hotspot.|
| int32_t (\*disconnect)(NetDevice \*netDev, uint16_t reasonCode) | Disconnects from a hotspot.|
**Table 7** hdf_netbuf.h
| API| Description|
| -------- | -------- |
| static inline void NetBufQueueInit(struct NetBufQueue \*q) | Initializes a **NetBuf** queue.|
| struct NetBuf \*NetBufAlloc(uint32_t size) | Allocates a **NetBuf**.|
| void NetBufFree(struct NetBuf \*nb) | Releases a **NetBuf**.|
| struct NetBuf \*Pbuf2NetBuf(const struct NetDevice \*netdev, struct pbuf \*lwipBuf) | Converts the **pbuf** structure of lwIP to a **NetBuf**.|
| struct pbuf \*NetBuf2Pbuf(const struct NetBuf \*nb) | Converts a **NetBuf** to the **pbuf** structure of lwIP.|
### How to Develop
The WLAN driver module developed based on the HDF and Platform frameworks provides a unified driver model for WLAN modules of different vendors regardless of the OS and system on a chip (SoC).
1. Configure hardware (such as modules and chips) parameters in the **wlan_platform.hcs** file. This file can be parsed by the APIs in the HDF to generate structure objects with full configuration.
1. Configure hardware (such as modules and chips) parameters in the **wifi_config.hcs** file. This configuration file is parsed by the corresponding API in the HDF to generate a structure object for full configuration.
2. Implement initialization and deinitialization of the WLAN module (such as initialize and deinitialize the WLAN chip and WLAN chip driver).
2. Initialize and create a module.
3. Implement the delivery of control flow commands.
3. Attach and initialize the chip.
4. Implement the upper-layer Wi-Fi Protected Access (WPA) service.
4. Implement event reporting.
### Development Example
This example describes how to initialize a WLAN module. The following uses the Hi3881 WLAN chip as an example:
The following uses the Hi3881 WLAN chip as an example to describe how to initialize a WLAN module.
1. Set parameters for the WLAN module based on hardware attributes.
1. Configure hardware parameters.
```
/* Set parameters in the wlan_platform.hcs file based on hardware attributes. The following is an example of the WLAN platform configuration. */
hisi :& deviceList {
```text
/* Configure parameters in wlan_platform.hcs based on the hardware you use. The following is an example of WLAN platform configuration. */
hisi :& deviceList {
device0 :: deviceInst {
deviceInstId = 0;
powers {
power0 {
powerSeqDelay = 0; /* Power sequence delay. */
powerType = 1; /* Power supply type. The value 0 indicates that the device is always powered on, and 1 indicates power supply through general-purpose input/output (GPIO). */
powerType = 1; /* Power supply type. The value 0 indicates that the device is always on. The value 1 indicates power supply through GPIO. */
gpioId = 1; /* GPIO pin number. */
activeLevel=1; /* Active level. The value 0 indicates low level, and 1 indicates high level. */
}
power1 {
powerSeqDelay = 0; /* Power sequence delay. */
powerType = 0; /* The value 0 indicates that the device is always powered on, and 1 indicates power supply through GPIO. */
powerType = 0; /* Power supply type. The value 0 indicates that the device is always on. The value 1 indicates power supply through GPIO. */
}
}
reset {
resetType = 0; /* Reset type. The value 0 indicates that reset is dynamically determined, and value 1 indicates reset through GPIO. */
resetType = 0; /* Reset type. The value 0 indicates that reset is dynamically determined, and 1 indicates reset through GPIO. */
gpioId = 2; /* GPIO pin number. */
activeLevel=1; /* Active level. The value 0 indicates low level, and 1 indicates high level. */
resetHoldTime = 30; /* Hold time (ms) after a reset. */
}
bootUpTimeout = 30; /* Boot timeout duration (ms). */
bus {
busEnable = 1; /* Whether to initialize the bus. The value 1 means to initialize the bus; the value 0 means the opposite. */
busType = 0; /* Bus type. The value 0 indicates SDIO. */
busId = 2; /* Bus number. */
funcNum = [1]; /* SDIO function number. */
......@@ -192,61 +201,59 @@ hisi :& deviceList {
blockSize = 512; /* Size of the data block to read or write. */
}
}
}
/* Add the configuration file wlan_chip_<Chip name>.hcs (for example, wlan_chip_hi3881.hcs) for each chip and set parameters. The following uses the Hi3881 chip as an example. */
root {
}
/* Add the configuration file wlan_chip_<Chip name>.hcs (for example, wlan_chip_hi3881.hcs) for each chip and set parameters. The following uses the Hi3881 chip as an example. */
root {
wlan_config {
hi3881 :& chipList {
chipHi3881 :: chipInst {
match_attr = "hdf_wlan_chips_hi3881"; /* Attribute used to match the chip. */
chipName = "hi3881"; /* WLAN chip name. */
sdio {
bus {
vendorId = 0x0296; /* Vendor ID. */
deviceId = [0x5347]; /* Device ID. */
}
}
}
}
}
```
2. Hook the **init** and **deinit** functions of the WLAN chip and WLAN chip driver.
```
/* Process of implementing WLAN module initialization. */
#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
/* Functions for initializing and deinitializing a WLAN chip. */
int32_t InitHi3881Chip(struct HdfWlanDevice *device);
int32_t DeinitHi3881Chip(struct HdfWlanDevice *device);
/* Functions for initializing and deinitializing a WLAN chip driver. */
int32_t Hi3881Deinit(struct HdfChipDriver* chipDriver, struct NetDevice *netDevice);
int32_t Hi3881Init(struct HdfChipDriver* chipDriver, struct NetDevice *netDevice);
/* Initialize mac80211 by hooking the functions of the chip. */
hi_void HiMac80211Init(struct HdfChipDriver *chipDriver);
static const char* const HI3881_DRIVER_NAME = "hisi";
/* Hook the functions of the WLAN chip driver, mac80211, and chip. */
static struct HdfChipDriver *BuildHi3881Driver(struct HdfWlanDevice *device, uint8_t ifIndex)
{
}
```
2. Hook the **init** and **deinit** functions of the WLAN chip and WLAN chip driver.
```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
/* Functions for initializing and deinitializing a WLAN chip. */
int32_t InitHi3881Chip(struct HdfWlanDevice *device);
int32_t DeinitHi3881Chip(struct HdfWlanDevice *device);
/* Functions for initializing and deinitializing a WLAN chip driver. */
int32_t Hi3881Deinit(struct HdfChipDriver* chipDriver, struct NetDevice *netDevice);
int32_t Hi3881Init(struct HdfChipDriver* chipDriver, struct NetDevice *netDevice);
/* Initialize mac80211 by hooking the functions of the chip. */
hi_void HiMac80211Init(struct HdfChipDriver *chipDriver);
static const char* const HI3881_DRIVER_NAME = "hisi";
/* Hook the functions of the WLAN chip driver, mac80211, and chip. */
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__);
HDF_LOGE("%s fail: channel is NULL!", __func__);
return NULL;
}
(void)device;
(void)ifIndex;
specificDriver = (struct HdfChipDriver *)OsalMemCalloc(sizeof(struct HdfChipDriver));
if (specificDriver == NULL) {
......@@ -260,7 +267,7 @@ static struct HdfChipDriver *BuildHi3881Driver(struct HdfWlanDevice *device, uin
}
if (strcpy_s(specificDriver->name, MAX_WIFI_COMPONENT_NAME_LEN, HI3881_DRIVER_NAME) != EOK) {
HDF_LOGE("%s fail : strcpy_s fail", __func__);
HDF_LOGE("%s fail: strcpy_s fail!", __func__);
OsalMemFree(specificDriver);
return NULL;
}
......@@ -270,11 +277,11 @@ static struct HdfChipDriver *BuildHi3881Driver(struct HdfWlanDevice *device, uin
HiMac80211Init(specificDriver);
return specificDriver;
}
}
/* Release the WLAN chip driver. */
static void ReleaseHi3881Driver(struct HdfChipDriver *chipDriver)
{
/* Release the WLAN chip driver. */
static void ReleaseHi3881Driver(struct HdfChipDriver *chipDriver)
{
if (chipDriver == NULL) {
return;
}
......@@ -283,20 +290,20 @@ static void ReleaseHi3881Driver(struct HdfChipDriver *chipDriver)
return;
}
OsalMemFree(chipDriver);
}
}
static uint8_t GetHi3881GetMaxIFCount(struct HdfChipDriverFactory *factory) {
static uint8_t GetHi3881GetMaxIFCount(struct HdfChipDriverFactory *factory) {
(void)factory;
return 1;
}
}
/* Register WLAN chip functions. */
static int32_t HDFWlanRegHisiDriverFactory(void)
{
/* Register WLAN chip functions. */
static int32_t HDFWlanRegHisiDriverFactory(void)
{
static struct HdfChipDriverFactory tmpFactory = { 0 };
struct HdfChipDriverManager *driverMgr = NULL;
driverMgr = HdfWlanGetChipDriverMgr();
if (driverMgr == NULL && driverMgr->RegChipDriver != NULL) {
if (driverMgr == NULL) {
HDF_LOGE("%s fail: driverMgr is NULL!", __func__);
return HDF_FAILURE;
}
......@@ -313,45 +320,48 @@ static int32_t HDFWlanRegHisiDriverFactory(void)
}
return HDF_SUCCESS;
}
}
static int32_t HdfWlanHisiChipDriverInit(struct HdfDeviceObject *device)
{
static int32_t HdfWlanHisiChipDriverInit(struct HdfDeviceObject *device)
{
(void)device;
return HDFWlanRegHisiDriverFactory();
}
}
struct HdfDriverEntry g_hdfHisiChipEntry = {
struct HdfDriverEntry g_hdfHisiChipEntry = {
.moduleVersion = 1,
.Bind = HdfWlanHisiDriverBind,
.Init = HdfWlanHisiChipDriverInit,
.Release = HdfWlanHisiChipRelease,
.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
/* Function for initializing the WLAN chip. */
int32_t InitHi3881Chip(struct HdfWlanDevice *device)
{
uint8_t maxPortCount = 1;
};
HDF_INIT(g_hdfHisiChipEntry);
```
For details about initialization of the chip and chip driver, see hdfinit_3881.c. The functions are as follows:
```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
/* Initialize the WLAN chip. */
int32_t InitHi3881Chip(struct HdfWlanDevice *device)
{
uint8_t maxPortCount = 3;
int32_t ret = HI_SUCCESS;
uint8_t maxRetryCount = 2;
if (device == NULL) {
uint8_t maxRetryCount = 3;
if (device == NULL || device->bus == NULL) {
HDF_LOGE("%s:NULL ptr!", __func__);
return HI_FAIL;
}
......@@ -363,7 +373,7 @@ int32_t InitHi3881Chip(struct HdfWlanDevice *device)
}
HDF_LOGE("%s:Retry init hi3881!last ret=%d", __func__, ret);
}
ret = hi_wifi_init(maxPortCount);
ret = hi_wifi_init(maxPortCount, device->bus);
} while (ret != 0 && --maxRetryCount > 0);
if (ret != 0) {
......@@ -371,81 +381,112 @@ int32_t InitHi3881Chip(struct HdfWlanDevice *device)
return ret;
}
return HI_SUCCESS;
}
}
/* Function for deinitializing the WLAN chip. */
int32_t DeinitHi3881Chip(struct HdfWlanDevice *device)
{
/* Deinitializing the WLAN chip. */
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;
}
}
/* Function for initializing the WLAN chip driver. */
int32_t Hi3881Init(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice)
{
HDF_LOGI("%s: start...", __func__);
hi_u16 mode = wal_get_vap_mode();
/* Initializing the WLAN chip driver. */
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;
}
}
/* Function for deinitializing the WLAN chip driver. */
int32_t Hi3881Deinit(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice)
{
/* Deinitializing the WLAN chip driver. */
int32_t Hi3881Deinit(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice)
{
int32_t ret;
(void)chipDriver;
int32_t ret = wal_deinit_drv_wlan_netdev(netDevice);
if (ret != HDF_SUCCESS) {
ret = DeinitNetdev(NL80211_IFTYPE_P2P_DEVICE);
if (ret != HI_SUCCESS) {
oam_error_log1(0, OAM_SF_ANY, "Hi3881Deinit: DeinitNetdev p2p device fail, ret = %d\n", ret);
return ret;
}
return ReleasePlatformNetDevice(netDevice);
}
```
return wal_deinit_drv_wlan_netdev(netDevice);
}
```
During the chip initialization process, call **NetDeviceInit()** to initialize a network device, call **NetDeviceAdd()** to add the network device to a protocol stack, and hook function pointers of **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;
}
3. During the chip initialization process, call **NetDeviceInit()** to initialize a network device, call **NetDeviceAdd()** to add the network device to a protocol stack, and hook function pointers of **netdev**.
do {
/* Initialize the network device. */
ret = wal_init_netdev(type, netdev);
if (ret != HI_SUCCESS) {
break;
}
```
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;
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";
}
......
/* Initialize the network device and obtain the initialized instance. */
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);
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;
}
return HI_SUCCESS;
}
/* Hook pointers of NetDeviceInterFace(). */
oal_net_device_ops_stru g_wal_net_dev_ops =
{
}
/* Hook function pointers of netdev. For details, see NetDeviceInterFace. */
oal_net_device_ops_stru g_wal_net_dev_ops =
{
.getStats = wal_netdev_get_stats,
.open = wal_netdev_open,
.stop = wal_netdev_stop,
......@@ -454,35 +495,33 @@ oal_net_device_ops_stru g_wal_net_dev_ops =
.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))
#if (defined(_PRE_WLAN_FEATURE_FLOWCTL) || defined(_PRE_WLAN_FEATURE_OFFLOAD_FLOWCTL))
.selectQueue = wal_netdev_select_queue,
#endif
#endif
.setMacAddr = wal_netdev_set_mac_addr,
#if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
#if (_PRE_OS_VERSION_LITEOS == _PRE_OS_VERSION)
.netifNotify = HI_NULL,
#endif
#endif
.specialEtherTypeProcess = SpecialEtherTypeProcess,
};
};
hi_s32 wal_init_netif(nl80211_iftype_uint8 type, oal_net_device_stru *netdev, const oal_wireless_dev *wdev)
{
/* Add the network device to a protocol stack. */
hi_s32 wal_init_netif(nl80211_iftype_uint8 type, oal_net_device_stru *netdev, const oal_wireless_dev *wdev)
{
/* Add the network device to the protocol stack. */
hi_u32 ret = NetDeviceAdd(netdev, (Protocol80211IfType)type);
......
...
return HI_SUCCESS;
}
```
}
```
4. Hook functions of **WifiMac80211Ops**.
```
/* Hook function pointers of mac80211. */
3. Bind the commands to be delivered, including setting the MAC address and transmit power, implement STA connection and scan, start APs, and setting the country code.
/* Define the functions for implementing the basic capabilities in the MAC layer for the driver. */
static struct HdfMac80211BaseOps g_baseOps = {
```c
/* Implement the basic capabilities of the MAC layer. */
static struct HdfMac80211BaseOps g_baseOps = {
.SetMode = WalSetMode,
.AddKey = WalAddKey,
.DelKey = WalDelKey,
......@@ -492,19 +531,19 @@ static struct HdfMac80211BaseOps g_baseOps = {
.SetTxPower = WalSetTxPower,
.GetValidFreqsWithBand = WalGetValidFreqsWithBand,
.GetHwCapability = WalGetHwCapability
};
};
/* Define the functions for implementing the STA capabilities in the MAC layer for the driver. */
static struct HdfMac80211STAOps g_staOps = {
/* Implement the STA capabilities of the MAC layer. */
static struct HdfMac80211STAOps g_staOps = {
.Connect = WalConnect,
.Disconnect = WalDisconnect,
.StartScan = WalStartScan,
.AbortScan = WalAbortScan,
.SetScanningMacAddress = WalSetScanningMacAddress,
};
};
/* Define the functions for implementing the AP capabilities in the MAC layer for the driver. */
static struct HdfMac80211APOps g_apOps = {
/* Implement the AP capabilities of the MAC layer. */
static struct HdfMac80211APOps g_apOps = {
.ConfigAp = WalConfigAp,
.StartAp = WalStartAp,
.StopAp = WalStopAp,
......@@ -513,42 +552,438 @@ static struct HdfMac80211APOps g_apOps = {
.SetCountryCode = WalSetCountryCode,
.GetAssociatedStasCount = WalGetAssociatedStasCount,
.GetAssociatedStasInfo = WalGetAssociatedStasInfo
};
/* Initialize mac80211 and hook functions of the chip. */
hi_void HiMac80211Init(struct HdfChipDriver *chipDriver)
{
};
static struct HdfMac80211P2POps g_p2pOps = {
.RemainOnChannel = WalRemainOnChannel,
.CancelRemainOnChannel = WalCancelRemainOnChannel,
.ProbeReqReport = WalProbeReqReport,
.AddIf = WalAddIf,
.RemoveIf = WalRemoveIf,
.SetApWpsP2pIe = WalSetApWpsP2pIe,
.GetDriverFlag = WalGetDriverFlag
};
/* Initialize mac80211 and hook functions of the chip. */
void HiMac80211Init(struct HdfChipDriver *chipDriver)
{
if (chipDriver == NULL) {
oam_error_log(0, OAM_SF_ANY, "%s:input is NULL!", __func__);
HDF_LOGE("%s:input is NULL!", __func__);
return;
}
chipDriver->ops = &g_baseOps;
chipDriver->staOps = &g_staOps;
chipDriver->apOps = &g_apOps;
}
```
chipDriver->p2pOps = &g_p2pOps;
}
```
4. Invoke the event reporting APIs.
The WLAN framework provides the event reporting APIs. For example, call **HdfWiFiEventNewSta AP** to report information about the newly associated STA. For details, see **hdf_wifi_event.c**.
```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;
}
```
## Verification
Develop test cases in the WLAN module unit test to verify the basic features of the WLAN module. The following uses Hi3516D V300 standard system as an example.
1. Set up the test environment.
- Create a **hostapd.conf** file (used to start the AP) and copy the following content to the file:
```text
interface=wlan0
driver=hdf wifi
ctrl_interface=udp
#Wi-Fi name
ssid=test
hw_mode=g
channel=1
ignore_broadcast_ssid=0
wpa=2
rsn_pairwise=CCMP
# Wi-Fi password.
wpa_passphrase=12345678
```
- Create a **wpa_supplicant.conf** file (used to start the STA) and copy the following content to the file:
```text
country=GB
network={
#Hotspot name
ssid="test"
#Hotspot password
psk="12345678"
}
```
- Create a **dhcpc.sh** file (used to write the IP address allocated by the udhcpc to the device) and copy the following content to the file:
```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
```
- Create a **udhcpd.conf** file (used to start the **udhcpd**) and copy the following content to the file:
```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
```
- Run the following commands to push the files required for the test to the development board:
```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. Verify basic Wi-Fi features.
- Verify basic AP features.
1. Start the AP on the development board and enable Wi-Fi on the test terminal. For example, choose **Settings** > **WLAN** and turn on Wi-Fi on a mobile phone.
2. Run the following command in the **cmd** window:
```shell
hdc shell
hostapd ./hostapd.conf
```
3. Run the following commands in another **cmd** window:
```shell
hdc shell
ifconfig wlan0 192.168.12.1 netmask 255.255.255.0
busybox udhcpd /vendor/etc/udhcpd.conf
```
4. On the mobile phone, select the network named **test** in the available Wi-Fi list and enter the password.
The network name and password are configured in the **hostapd.conf** file. You can see the network name in the connected Wi-Fi list if the connection is successful.
5. Ping the test terminal from the development board.
```shell
busybox ping xxx.xxx.xxx.xxx
```
In the command, xxx.xxx.xxx.xxx indicates the IP address of the test terminal. If the test terminal can be pinged, the basic features of the WLAN driver are implemented successfully.
- Verify basic STA features.
1. Start the STA on the development board, and enable the hotspot on the test terminal. (The hotspot name and password are configured in the **hostapd.conf** file. The hotspot name is **test**, and the password is **12345678**.)
2. Run the following command in the **cmd** window:
```shell
hdc shell
wpa_supplicant -i wlan0 -d -c wpa_supplicant.conf
```
3. Run the following commands in another **cmd** window:
```shell
hdc shell
mount -o rw,remount /
mount -o rw,remount /vendor
busybox udhcpc -i wlan0 -s system/lib/dhcpc.sh
```
The IP addresses of the board and test terminal are displayed if the command is successful.
4. Ping the test terminal from the development board.
```shell
busybox ping xxx.xxx.xxx.xxx
```
In the command, xxx.xxx.xxx.xxx indicates the IP address of the test terminal. If the test terminal can be pinged, the basic features of the WLAN driver are implemented successfully.
3. Verify the unit test cases.
To test a specified interface of the HDI module, perform the following steps:
1. Call **WlanInterfaceGetInstance()** to obtain a WLAN service instance.
2. Call **Start()** to create a channel between the HAL and the driver and obtain information about the driver network interface card (NIC).
3. Call **GetSupportFeature()** to obtain the WLAN features supported by the device.
4. Call **Stop()** to destroy the channel between the HAL and the driver
5. Call **WlanInterfaceRelease()** to destroy the WLAN service instance.
The sample code is as follows:
```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;
/* Obtain the WLAN service instance. */
g_wlanObj = WlanInterfaceGetInstance(WLAN_SERVICE_NAME);
if (g_wlanObj == NULL)
{
return HDF_FAILURE;
}
/* Create a channel between the HAL and the driver and obtain the driver NIC information. */
rc = g_wlanObj->Start(g_wlanObj);
if (rc != HDF_SUCCESS)
{
return HDF_FAILURE;
}
/* Obtain the WLAN features supported by the device irrespective of the device status (AP, STA, or P2P).
rc = g_wlanObj->GetSupportFeature(g_wlanObj, supType, &supTypeLen);
if (rc != HDF_SUCCESS)
{
return HDF_FAILURE;
}
/* Destroy the channel between the HAL and the driver. */
rc = g_wlanObj->Stop(g_wlanObj);
if (rc != HDF_SUCCESS)
{
return HDF_FAILURE;
}
/* Destroy the WLAN service instance. */
rc = WlanInterfaceRelease(g_wlanObj);
if (rc != HDF_SUCCESS)
{
return HDF_FAILURE;
}
return rc;
}
```
To test a specified interface of the HAL module, perform the following steps:
1. Call **WifiConstruct()** to create an **IWiFi** instance.
2. Use the created **IWiFi** instance to call **start()** to create a channel between the HAL and the driver and obtain the driver NIC information.
3. Call **createFeature()** to create an **apFeature** or **staFeature**. These features can be used to invoke specific APIs. The following uses the **apFeature** instance as an example.
4. Call related APIs, for example, call **setMacAddress()** to set the MAC address and call **getDeviceMacAddress()** to obtain the device MAC address.
5. Call **destroyFeature()** to destroy the **apFeature** instance.
6. Call **stop()** to destroy the channel between the HAL and the driver.
7. Call **WifiDestruct()** to destroy the **IWiFi** instance.
The sample code is as follows:
```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;
/* Create an IWiFi instance. */
ret = WifiConstruct(&wifi);
if (ret != HDF_SUCCESS || wifi == NULL) {
return HDF_FAILURE;
}
/* Create a channel between the HAL and the driver and obtain the driver NIC information. */
ret = wifi->start(wifi);
if (ret != HDF_SUCCESS) {
return HDF_FAILURE;
}
/* Create an apFeature instance. */
ret = wifi->createFeature(PROTOCOL_80211_IFTYPE_AP, (struct IWiFiBaseFeature **)&apFeature);
if (ret != HDF_SUCCESS) {
return HDF_FAILURE;
}
/* Obtain the MAC address of the device. */
unsigned char mac[MAC_LEN] = {0};
ret = apFeature->baseFeature.getDeviceMacAddress((struct IWiFiBaseFeature *)apFeature, mac, MAC_LEN);
if (ret != HDF_SUCCESS) {
return HDF_FAILURE;
}
/* Destroy the apFeature instance. */
ret = wifi->destroyFeature((struct IWiFiBaseFeature *)apFeature);
if (ret != HDF_SUCCESS) {
return HDF_FAILURE;
}
/* Destroy the channel between the HAL and the driver. */
ret = wifi->stop(wifi);
if (ret != HDF_SUCCESS) {
return HDF_FAILURE;
}
/* Destroy the IWiFi instance. */
ret = WifiDestruct(&wifi);
if (ret != HDF_SUCCESS) {
return HDF_FAILURE;
}
return ret;
}
```
4. Verify the test cases.
1. Push the test cases to the development board.
```shell
hdc file send /xxx /data
```
In the command, xxx indicates the path of the test cases of the development board.
2. Modify the permissions on the test cases and execute the test cases.
```shell
hdc shell
cd data
chmod 777 Test_case_name
./ Test case name.
```
3. Check the test case execution result.
## Reference
- Code repositories:
[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)
- Code paths:
Adaptation of WLAN FlowCtl component on LiteOS: **//drivers/hdf_core/adapter/khdf/liteos/model/network/wifi**
- Adaptation of WLAN FlowCtl component on LiteOS:
**//drivers/hdf_core/adapter/khdf/liteos/model/network/wifi**
Adaptation of HDF network model on LiteOS: **//drivers/hdf_core/adapter/khdf/liteos/model/network**
- Adaptation of HDF network model on LiteOS:
Adaptation of WLAN FlowCtl component on Linux, build of the HDF WLAN model, and build of the vendor's WLAN driver:
**//drivers/hdf_core/adapter/khdf/liteos/model/network**
- Adaptation of WLAN FlowCtl component on Linux, build of the HDF WLAN model, and build of the vendor's WLAN driver:
**//drivers/hdf_core/adapter/khdf/linux/model/network/wifi**
Core code for implementing the WLAN module: **//drivers/hdf_core/framework/model/network/wifi**
- Core code for implementing the WLAN module:
**//drivers/hdf_core/framework/model/network/wifi**
- External APIs of the WLAN module:**//drivers/hdf_core/framework/include/wifi**
- HDF network model APIs:
**//drivers/hdf_core/framework/include/net**
- WLAN HDI server implementation:
External APIs of the WLAN module: **//drivers/hdf_core/framework/include/wifi**
**//drivers/peripheral/wlan**
HDF network model APIs: **//drivers/hdf_core/framework/include/net**
- External APIs of the WLAN HDI:
WLAN HDI APIs and implementation: **//drivers/peripheral/wlan**
**//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.
先完成此消息的编辑!
想要评论请 注册