diff --git a/en/device-dev/driver/driver-peripherals-external-des.md b/en/device-dev/driver/driver-peripherals-external-des.md index d2b681dcad9172b622cb261d81c9efdf3a0b86cc..04f0d7631555e55f7481da003d214a1715f5533d 100644 --- a/en/device-dev/driver/driver-peripherals-external-des.md +++ b/en/device-dev/driver/driver-peripherals-external-des.md @@ -3,164 +3,152 @@ ## Overview -### WLAN +### Function -The Wireless Local Area Network (WLAN) driver module is developed based on OpenHarmony Hardware Driver Foundation (HDF). It supports modular assembly and building, automatic adaptation to device differences, and cross-OS porting. +A wireless LAN (WLAN) allows users to easily connect to a wireless network to transmit and share data and move around within the area and remain connected to the network. The WLAN driver developed based on the Hardware Driver Foundation (HDF) shields hardware component differences and provides stable basic capability interfaces for upper-layer WLAN services, including starting a scan, associating with or disassociating from a hotspot, obtaining or setting MAC addresses, and obtaining link information. -### Working Principles - -You can modify your driver code based on the unified APIs provided by the WLAN module. The WLAN module provides: - -- APIs for the underlying layer to implement capabilities, such as opening or closing a WLAN hotspot, scanning hotspots, and connecting to or disconnecting from a hotspot. -- APIs for the Hardware Device Interface (HDI) layer to implement capabilities, such as setting or obtaining the device Media Access Control (MAC) address and setting the transmit power. - -The following figure shows the WLAN architecture. The WLAN driver module implements startup loading, parses configuration files, and provides bus abstraction APIs. The WLAN chip driver module provides the MAC Sublayer Management Entity (MLME). - - **Figure 1** WLAN architecture - - ![image](figures/WLAN_architecture.png "WLAN architecture") +### Basic Concepts - The following figure shows the WLAN driver architecture. +Before development, you need to understand the following basic concepts related to WLAN: - **Figure 2** WLAN driver architecture +- AP + + A wireless access point (AP) is a central node of a network that provides the wireless access service. Once connecting to the wireless network, the device can access data. - ![image](figures/WLAN_driver_architecture.png "WLAN driver architecture") +- STA + + A station (STA) is a basic component of a WLAN. Each terminal connected to a WLAN, such as a notebook and a personal digital assistant (PDA), is an STA. -The WLAN driver consists of the following modules: +- SSID + + A service set identifier (SSID) identifies a wireless network. Each WLAN has its SSID. -1. WLAN Message: provides an independent interface for each service or a composite service interface for multiple dependent services. It can run in the user mode, kernel mode, and MCU to implement complete decoupling between components. +- bssid + + A basic service set identifier (BSSID) is a 48-bit MAC address that uniquely identifies a basic service set on a WLAN. + +- Scan -2. WLAN Configuration Core: parses WLAN configuration files. + A terminal device scans the wireless network to obtain visible wireless network information, including the hotspot SSID, operating frequency band, and signal strength. -3. Access point (AP): allows devices to connect to the WLAN. +- Associate -4. Station (STA): a device that has access to the WLAN system and allows transmission and reception of data. + When a terminal device is associated with a valid hotspot, it can communicate with the AP. A device (STA) can set up a connection with only one AP at a time. -5. mac80211: defines MAC-layer APIs for underlying drivers. - -6. Bus: provides a unified bus abstract interface for the upper layer. It shields the differences between different kernels by calling the Secure Digital Input Output (SDIO) interfaces provided by the platform layer and encapsulating the adapted USB and PCIe interfaces. It also encapsulates different types of bus operations in a unified manner to shield differences between different chipsets. The complete bus driving capabilities provided by the bus module help simplify and streamline the development of different chip vendors. - -7. NetDevice: creates dedicated network devices to shield differences between OSs, provides unified interfaces for Wi-Fi drivers, unified HDF NetDevice data structure, and unified management, registration, and deregistration capabilities, and connects to the Linux network device layer on mini-, small-, standard, and large-system devices. - -8. NetBuf: encapsulates the unified data structure of the Linux or LiteOS native network data buffer and the operation interfaces for network data. +### Working Principles -9. FlowCtl: processes data based on the priority when the data volume is too large. +This document describes how to develop WLAN functions based on the HDF. The following figure shows the WLAN framework. -10. HCC-CFG: configures WLAN parameters, including the board configuration, driver configuration, and module configuration. +![image](figures/WLAN-driver-framework.png "WLAN Framework") -The relationships between the main modules are as follows: +1. The upper-layer service calls a hardware device interface (HDI) based on service requirements to deliver user-mode messages to the client through the Wi-Fi Protected Access (WPA) layer or hardware abstraction layer (HAL). The WPA layer provides interfaces for setting the encryption mode, associating with a hotspot, setting a channel, and hiding the hotspot. As a supplement to the WPA layer, the HAL provides APIs for setting the country code or MAC address and obtaining channel information. + +2. The Message module distributes user-mode messages to modules, such as the AP and STA, by component. + +3. Hdf_Mac80211 defines MAC-layer interfaces for underlying drivers. The command field is delivered to Hdf_Mac80211 and then sent to the WLAN chip firmware through the Bus module. + +4. The Bus module provides unified bus abstraction interfaces for the upper layer. It shields the differences between kernels by calling the Secure Digital Input Output (SDIO) interfaces provided by the platform layer and encapsulating the USB and PCIe interfaces. The Bus module also encapsulates different types of bus operations in a unified manner to shield differences between chipsets. The interfaces provided by the Bus module simplify and streamline the development of different chip vendors. + +5. Extensible Authentication Protocol (EAP) over LAN (EAPOL) is a LAN-based extended authentication protocol. It is used to transmit EAP packets between a client and a device (access device or server) so that EAP packets can be transmitted on a LAN to complete the authentication process and enable the device to go online. + +6. NetDevice creates dedicated network devices to shield differences between OSs. It provides unified interfaces for Wi-Fi drivers, unified HDF NetDevice data structs, and unified management, registration, and deregistration capabilities, and connects to the Linux network device layer on OpenHarmony devices. + +7. NetBuf encapsulates the unified data structure of the Linux or LiteOS native network data buffer and the operation interfaces for network data. + +8. The protocol stack works with the NetDevice and NetBuf modules to exchange data flows. -1. The WLAN driver works with HCC-CFG and WLAN Configuration Core to parse and load configuration files. +### Constraints -2. The WLAN Message module distributes user-mode messages to the AP and STA by component. +The WLAN driver provides basic capability interfaces for upper-layer WLAN services. The HDI interfaces apply to the standard system, and the HAL interfaces apply to mini and small systems. -3. Commands are delivered to mac80211, and then forwarded by the Bus module to the WLAN chip firmware. +## Development Guidelines -4. The protocol stack works with the NetDevice, NetBuf, and FlowCtl modules to exchange data flows. +### When to Use -## How to Develop +The WLAN driver provides basic capability interfaces for upper-layer WLAN services to ensure that users can easily access the wireless network and transmit and share data. Refer to the following when you adapt your WLAN module to OpenHarmony. ### Available APIs -The WLAN module provides the following types of APIs: +The WLAN module provides the following APIs: -1. HDI and Hardware Abstraction Layer (HAL) APIs for upper-layer services +1. HDI and HAL APIs for upper-layer services 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 module provides HAL APIs for upper-layer services (applicable to small and mini systems). **Table 1** and **Table 2** describe some APIs. +- This interfaces provided by the WLAN Driver module for upper-layer services can be used to create or destroy an IWiFi object, and set MAC addresses or transmit power. Table 1 and Table 2 list the C function interfaces generated based on the IDL interface description. For details about the interface declaration, see the IDL files (**/drivers/interface/wlan/v1_1/**). **Table 1** wifi_hal.h | API| Description| | -------- | -------- | - | 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.| + | 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 2** wifi_hal_base_feature.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 (\*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. **Table 3** describes some APIs. +- The WLAN Driver module also provides APIs that you need to fill in the implementation. These APIs can be used to initialize or deregister a network device, open or stop a network device, and obtain network device status. Table 3 describes some APIs. **Table 3** net_device.h | API| Description| | -------- | -------- | - | 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 network device.| - | int32_t (\*open)(struct NetDevice \*netDev)| Opens a network device.| - | int32_t (\*stop)(struct NetDevice \*netDev)| Stops a network device.| + | 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 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 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** struct of Lightweight IP (lwIP) and a **NetBuf**. - The following tables describe the APIs. + Tables 4 to 6 list the APIs that can be directly called. - **Table 4** wifi_module.h + **Table 4** wifi_module.h | 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**.| + | 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 5** wifi_mac80211_ops.h + **Table 5** wifi_mac80211_ops.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 (\*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 6** hdf_netbuf.h + **Table 6** 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.| - -### Development Procedure -#### WLAN Framework Adaptation - -The WLAN driver framework developed based on the HDF and Platform framework provides a unified driver model regardless of the OS and system on a chip (SoC). When developing your WLAN driver, you need to configure data based on the WLAN driver framework. -**Development Procedure** - -1. Configure hardware (such as modules and chips) parameters in the **wlan_platform.hcs** file. The HDF parses the file to generate structure objects with full configuration. - -2. Implement initialization and deinitialization of the WLAN module (such as initialize and deinitialize the WLAN chip and WLAN chip driver). + | 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.| -3. Implement the delivery of control flow commands. +### How to Develop -4. Implement event reporting. +The WLAN driver framework developed based on the HDF and Platform framework provides a unified driver model for vendors regardless of the OS and system on a chip (SoC). When developing your WLAN driver based on the WLAN driver framework, you need to make adaptation. The following uses the Hi3881 WLAN chip as an example. -**Development Example** +#### Configuring the HCS for the Driver -The following uses the Hi3881 WLAN chip as an example to describe how to initialize a WLAN module. - -1. Configure the HDF configuration source (HCS) for the driver. - - The HCS includes device configuration and component configuration. + The HDF configuration source (HCS) includes device configuration and component configuration. - Device configuration @@ -223,8 +211,9 @@ The following uses the Hi3881 WLAN chip as an example to describe how to initial } ``` -2. Hook the **init** and **deinit** functions of the WLAN chip and WLAN chip driver. - - Implementing the driver adaptation entry function +#### Initializing and deinitializing the WLAN Chip and WLAN Chip Driver + + - Implement the driver adaptation entry function Define a variable of the HdfDriverEntry type based on the chip to hook functions of **Bind()**, **Init()**, and **Release()**. Call **HDF_INIT** to register the driver entry with the HDF. During driver loading, the HDF calls the **Bind** function and then the **Init** function to load the driver. If **Init()** fails to be called, the HDF calls **Release()** to release driver resources. ```c @@ -239,7 +228,7 @@ The following uses the Hi3881 WLAN chip as an example to describe how to initial HDF_INIT(g_hdfHisiChipEntry); ``` - - Registering the functions for initializing the chip and chip driver + - Register the functions for initializing the chip and chip driver Hook the chip initialization function to **InitChip()** and the chip deinitialization function to **DeinitChip()**. @@ -278,296 +267,308 @@ The following uses the Hi3881 WLAN chip as an example to describe how to initial } ``` - - Initializing and deinitializing the chip - ```c - /* Function for initializing the WLAN chip. */ - 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; - } - - /* Function for 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; - } - ``` - - Initializing and deinitializing the chip driver - ```c - /* 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__); - 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; - } - - /* Release the WLAN chip driver. */ - 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); - } - - /* Function for 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) - { - int32_t ret; - (void)chipDriver; - 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 wal_deinit_drv_wlan_netdev(netDevice); - } - - ``` + 1. Initialize and deinitialize the chip. + + ```c + /* Function for initializing the WLAN chip. */ + 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; + } + + /* Function for 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; + } + ``` - 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**. + 2. Initialize and deinitialize the chip driver. + + ```c + /* 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__); + 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; + } + + /* Release the WLAN chip driver. */ + 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); + } + + /* Function for 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) + { + int32_t ret; + (void)chipDriver; + 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 wal_deinit_drv_wlan_netdev(netDevice); + } - ```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 { - /* Initialize the network device. */ - ret = wal_init_netdev(type, netdev); - if (ret != HI_SUCCESS) { - break; - } - - 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; - } + 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; + } + + do { + /* Initialize the network device. */ + ret = wal_init_netdev(type, netdev); + if (ret != HI_SUCCESS) { + break; + } + + 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; + } + + return HI_SUCCESS; + } + + /* 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, + .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, + + ...... + + }; + + 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; + } + ``` - return HI_SUCCESS; - } +#### Modifying the MAC Layer Interfaces - /* 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, - .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, - - ... +After the user-mode message is delivered to the driver, the driver calls the corresponding MAC-layer capability interfaces. - }; + ```c + /* Define the functions for implementing the basic capabilities in the MAC layer for the driver. */ + static struct HdfMac80211BaseOps g_baseOps = { + .SetMode = WalSetMode, + .AddKey = WalAddKey, + .DelKey = WalDelKey, + .SetDefaultKey = WalSetDefaultKey, + .GetDeviceMacAddr = WalGetDeviceMacAddr, + .SetMacAddr = WalSetMacAddr, + .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 = { + .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 = { + .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 + }; + + /* Initialize mac80211 and hook functions of the chip. */ + 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; + } + ``` - 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); +#### Configuring Event Reporting - ... +The WLAN framework provides interfaces for event reporting. For details, see **hdf_wifi_event.c**. - return HI_SUCCESS; - } - ``` +The following presents how to use **HdfWiFiEventNewSta()** to report information about a newly associated STA. -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. - - ```c - /* Implement the basic capabilities of the MAC layer. */ - static struct HdfMac80211BaseOps g_baseOps = { - .SetMode = WalSetMode, - .AddKey = WalAddKey, - .DelKey = WalDelKey, - .SetDefaultKey = WalSetDefaultKey, - .GetDeviceMacAddr = WalGetDeviceMacAddr, - .SetMacAddr = WalSetMacAddr, - .SetTxPower = WalSetTxPower, - .GetValidFreqsWithBand = WalGetValidFreqsWithBand, - .GetHwCapability = WalGetHwCapability - }; - - /* Implement the STA capabilities of the MAC layer. */ - static struct HdfMac80211STAOps g_staOps = { - .Connect = WalConnect, - .Disconnect = WalDisconnect, - .StartScan = WalStartScan, - .AbortScan = WalAbortScan, - .SetScanningMacAddress = WalSetScanningMacAddress, - }; - - /* Implement the AP capabilities of the MAC layer. */ - 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 - }; - - /* Initialize mac80211 and hook functions of the chip. */ - 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; - } - ``` + ```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; + } + ``` -4. Invoke the event reporting APIs.
The WLAN framework provides the event reporting APIs. For details, see hdf_wifi_event.c.
For example, call **HdfWiFiEventNewSta AP** to report information about the newly associated STA. +### Debugging and Verification - ```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** +#### Driver Adaptation 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. @@ -644,7 +645,9 @@ Develop test cases in the WLAN module unit test to verify the basic features of exit 0 ``` - - Create a **udhcpd.conf** file (used to start the **udhcpd**) and copy the following content to the file.
In the following, **opt dns** *x.x.x.x* *x.x.x.x* indicates two DNS servers configured. You can configure DNS servers as required. + - Create the **udhcpd.conf** file and copy the following content to the file. + + In the following example, "opt dns x.x.x.x x.x.x.x" indicates two DNS servers configured. You can configure DNS servers as required. ```text start 192.168.12.2 @@ -698,7 +701,7 @@ Develop test cases in the WLAN module unit test to verify the basic features of 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 that network name in the connected Wi-Fi list if the connection is successful. + 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 that network name in the connected Wi-Fi list if the connection is successful. 5. Ping the test terminal from the development board. @@ -706,11 +709,11 @@ Develop test cases in the WLAN module unit test to verify the basic features of 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 WLAN driver provides basic features normally. + In the command, xxx.xxx.xxx.xxx indicates the IP address of the test terminal. If the test terminal can be pinged, the WLAN driver provides basic features normally. - - Verify basic STA features. + - Verify basic STA functions - 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**. + 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: @@ -737,8 +740,9 @@ Develop test cases in the WLAN module unit test to verify the basic features of In the command, xxx.xxx.xxx.xxx indicates the IP address of the test terminal. If the test terminal can be pinged, the WLAN driver provides basic features normally. -#### **API Invocation** -The WLAN driver module provides two types of capability interfaces for the upper layer: HDI interface and HAL interface. +#### API Usage Example + +The WLAN Driver module provides two types of capability interfaces for the upper layer: HDI APIs and HAL APIs. - HDI API invocation The following uses **GetSupportFeature** as an example to describe the development procedure: @@ -753,7 +757,7 @@ The WLAN driver module provides two types of capability interfaces for the upper 5. Call **WlanInterfaceRelease()** to destroy the WLAN service instance. - The sample code is as follows: + Example: ```c #include "v1_0/iwlan_interface.h" #include "wlan_callback_impl.h" @@ -848,7 +852,7 @@ The WLAN driver module provides two types of capability interfaces for the upper 7. Call **WifiDestruct()** to destroy the **IWiFi** instance. - The sample code is as follows: + Example: ```c #include "wifi_hal.h" @@ -947,17 +951,16 @@ The WLAN driver module provides two types of capability interfaces for the upper - Code paths: - 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 WLAN FlowCtl component on LiteOS: **//drivers/hdf_core/adapter/khdf/liteos/model/network/wifi** - 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** + - Adaptation of HDF network model on LiteOS: **//drivers/hdf_core/adapter/khdf/liteos/model/network** - Core code for implementing the WLAN module: **//drivers/hdf_core/framework/model/network/wifi** + - 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** - External APIs of the WLAN module: **//drivers/hdf_core/framework/include/wifi** + - Core code for implementing the WLAN module: **//drivers/hdf_core/framework/model/network/wifi** - HDF network model APIs: **//drivers/hdf_core/framework/include/net** + - External APIs of the WLAN module: **//drivers/hdf_core/framework/include/wifi** - WLAN HDI server implementation: **//drivers/peripheral/wlan** + - HDF network model APIs: **//drivers/hdf_core/framework/include/net** + - WLAN HDI server implementation: **//drivers/peripheral/wlan** diff --git a/en/device-dev/driver/figures/WLAN-driver-framework.png b/en/device-dev/driver/figures/WLAN-driver-framework.png new file mode 100644 index 0000000000000000000000000000000000000000..4dbbe0b49a4e5a61993152d266fa21dad18014c7 Binary files /dev/null and b/en/device-dev/driver/figures/WLAN-driver-framework.png differ diff --git a/en/device-dev/driver/figures/WLAN_architecture.png b/en/device-dev/driver/figures/WLAN_architecture.png deleted file mode 100644 index 2479e5101bf555d57c0ed700d82e7671b868bc3a..0000000000000000000000000000000000000000 Binary files a/en/device-dev/driver/figures/WLAN_architecture.png and /dev/null differ diff --git a/en/device-dev/driver/figures/WLAN_driver_APIs.png b/en/device-dev/driver/figures/WLAN_driver_APIs.png deleted file mode 100644 index 19cee91371e94ae6c375c4011174f65b2e0f5664..0000000000000000000000000000000000000000 Binary files a/en/device-dev/driver/figures/WLAN_driver_APIs.png and /dev/null differ diff --git a/en/device-dev/driver/figures/WLAN_driver_architecture.png b/en/device-dev/driver/figures/WLAN_driver_architecture.png deleted file mode 100644 index a902741d5f92c6a3b80ad5e51cb2f9343ed91787..0000000000000000000000000000000000000000 Binary files a/en/device-dev/driver/figures/WLAN_driver_architecture.png and /dev/null differ