1 /*
2 * Copyright (c) 2020-2023 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "hdf_wlan_utils.h"
10 #include <securec.h>
11 #include "hdf_log.h"
12 #include "wifi_module.h"
13 #include "hdf_wlan_chipdriver_manager.h"
14
15 #define HDF_LOG_TAG HDF_WIFI_CORE
16 const char * const HDF_WIFI_PLATFORM_DRIVER_NAME = "HDF_WIFI_PLATFORM_DRIVER";
17
GetPlatformDriverName(void)18 const char *GetPlatformDriverName(void)
19 {
20 return HDF_WIFI_PLATFORM_DRIVER_NAME;
21 }
22
GetPlatformData(const struct NetDevice * netDev)23 struct HdfWifiNetDeviceData *GetPlatformData(const struct NetDevice *netDev)
24 {
25 if (netDev == NULL) {
26 HDF_LOGE("%s: Input param is null!", __func__);
27 return NULL;
28 }
29
30 if (netDev->classDriverName != HDF_WIFI_PLATFORM_DRIVER_NAME) {
31 HDF_LOGE("%s: Unexpected classDriverName!", __func__);
32 return NULL;
33 }
34
35 return (struct HdfWifiNetDeviceData *)(netDev->classDriverPriv);
36 }
37
GetChipDriver(const struct NetDevice * netDev)38 struct HdfChipDriver *GetChipDriver(const struct NetDevice *netDev)
39 {
40 struct HdfWifiNetDeviceData *data = GetPlatformData(netDev);
41 if (data != NULL) {
42 return data->chipDriver;
43 }
44 HDF_LOGD("%s: The data is null!", __func__);
45 return NULL;
46 }
47
GetHwCapability(struct NetDevice * netDev)48 struct WlanHwCapability *GetHwCapability(struct NetDevice *netDev)
49 {
50 struct HdfChipDriver *chipDriver = GetChipDriver(netDev);
51 struct WlanHwCapability *capability = NULL;
52 int32_t ret;
53 if (chipDriver == NULL) {
54 HDF_LOGE("%s:bad net device found!", __func__);
55 return NULL;
56 }
57 if (chipDriver->ops == NULL || chipDriver->ops->GetHwCapability == NULL) {
58 HDF_LOGE("%s: chipdriver not implemented", __func__);
59 return NULL;
60 }
61 ret = chipDriver->ops->GetHwCapability(netDev, &capability);
62 if (ret != HDF_SUCCESS || capability == NULL) {
63 HDF_LOGE("%s:GetHwCapability failed!ifName=%s,ret=%d", __func__, netDev->name, ret);
64 return NULL;
65 }
66 HDF_LOGD("%s: GetHwCapability finished!", __func__);
67 return capability;
68 }
69
70 static uint32_t g_allocatedIfMap = 0;
71
72 #define SET_BIT(target, bit) (target) = ((target) | ((0x1) << (bit)))
73 #define CLEAR_BIT(target, bit) (target) = ((target) & (~((0x1) << (bit))))
74
RenewNetDevice(NetDevice ** netDev)75 int32_t RenewNetDevice(NetDevice **netDev)
76 {
77 char ifName[IFNAMSIZ] = "";
78 NetDevice *result = NULL;
79 struct HdfWifiNetDeviceData *data = NULL;
80 int32_t ret;
81 if (netDev == NULL || *netDev == NULL) {
82 HDF_LOGE("%s:RenewNetDevice netDev NULL ptr!", __func__);
83 return HDF_FAILURE;
84 }
85 if ((*netDev)->classDriverName != HDF_WIFI_PLATFORM_DRIVER_NAME) {
86 HDF_LOGE("%s:bad net device!", __func__);
87 return HDF_FAILURE;
88 }
89 if (strcpy_s(ifName, IFNAMSIZ, (*netDev)->name) != EOK) {
90 HDF_LOGE("%s:Copy ifName failed!", __func__);
91 return HDF_FAILURE;
92 }
93 data = GetPlatformData(*netDev);
94 if (data == NULL) {
95 HDF_LOGE("%s:GetPlatformData failed!", __func__);
96 return HDF_FAILURE;
97 }
98
99 ret = NetDeviceDeInit(*netDev);
100 if (ret != HDF_SUCCESS) {
101 return ret;
102 }
103 *netDev = NULL;
104 #ifdef _PRE_HDF_LINUX
105 result = NetDeviceInit(ifName, strlen(ifName), WIFI_LINK, FULL_OS);
106 #else
107 result = NetDeviceInit(ifName, strlen(ifName), WIFI_LINK, LITE_OS);
108 #endif
109 if (result == NULL) {
110 HDF_LOGE("%s:alloc NetDevice return NULL!", __func__);
111 if (data->device != NULL) {
112 CLEAR_BIT(data->device->netIfMap, data->netInterfaceId);
113 }
114 CLEAR_BIT(g_allocatedIfMap, data->netInterfaceId);
115 OsalMemFree(data);
116 *netDev = NULL;
117 return HDF_FAILURE;
118 }
119 result->classDriverName = HDF_WIFI_PLATFORM_DRIVER_NAME;
120 result->classDriverPriv = data;
121 *netDev = result;
122 return HDF_SUCCESS;
123 }
124
GetPlatformIfName(uint8_t id,char * ifName,uint32_t ifNameSize)125 int32_t GetPlatformIfName(uint8_t id, char *ifName, uint32_t ifNameSize)
126 {
127 if (ifName == NULL || ifNameSize == 0) {
128 HDF_LOGE("%s:para is null!", __func__);
129 return HDF_FAILURE;
130 }
131
132 if (snprintf_s(ifName, ifNameSize, ifNameSize - 1, "wlan%d", id) < 0) {
133 HDF_LOGE("%s:format ifName failed!netDevice id=%hhu", __func__, id);
134 return HDF_FAILURE;
135 }
136 return HDF_SUCCESS;
137 }
138
AllocPlatformNetDevice(struct HdfWlanDevice * device)139 struct NetDevice *AllocPlatformNetDevice(struct HdfWlanDevice *device)
140 {
141 uint8_t i;
142 int32_t ret;
143 uint8_t id = MAX_IF_COUNT;
144 struct NetDevice *result = NULL;
145 char ifName[IFNAMSIZ] = {0};
146 struct HdfWifiNetDeviceData *data = NULL;
147 if (device == NULL) {
148 HDF_LOGE("%s: Input param is null!", __func__);
149 return NULL;
150 }
151 HDF_LOGD("%s: AllocPlatformNetDevice starting...!", __func__);
152 data = (struct HdfWifiNetDeviceData *)OsalMemCalloc(sizeof(struct HdfWifiNetDeviceData));
153 if (data == NULL) {
154 HDF_LOGE("%s:AllocPlatformNetDevice data NULL ptr!", __func__);
155 return NULL;
156 }
157 do {
158 for (i = 0; i < MAX_IF_COUNT; i++) {
159 if (((g_allocatedIfMap >> i) & 0x1) != 0x1) {
160 id = i;
161 break;
162 }
163 }
164 if (id >= MAX_IF_COUNT) {
165 HDF_LOGE("%s: not enough if!map=%u", __func__, g_allocatedIfMap);
166 break;
167 }
168
169 ret = GetPlatformIfName(id, ifName, IFNAMSIZ);
170 if (ret != HDF_SUCCESS) {
171 break;
172 }
173 #ifdef _PRE_HDF_LINUX
174 result = NetDeviceInit(ifName, strlen(ifName), WIFI_LINK, FULL_OS);
175 #else
176 result = NetDeviceInit(ifName, strlen(ifName), WIFI_LINK, LITE_OS);
177 #endif
178 } while (false);
179 if (result == NULL) {
180 HDF_LOGE("%s:alloc NetDevice return NULL!", __func__);
181 OsalMemFree(data);
182 return result;
183 }
184 result->classDriverName = HDF_WIFI_PLATFORM_DRIVER_NAME;
185 result->classDriverPriv = data;
186 data->netInterfaceId = id;
187 SET_BIT(device->netIfMap, id);
188 SET_BIT(g_allocatedIfMap, id);
189 HDF_LOGD("%s: AllocPlatformNetDevice finished!", __func__);
190 return result;
191 }
192
ReleasePlatformNetDevice(struct NetDevice * netDev)193 int32_t ReleasePlatformNetDevice(struct NetDevice *netDev)
194 {
195 uint8_t id;
196 struct HdfWifiNetDeviceData *data = NULL;
197 int32_t ret;
198
199 if (netDev == NULL) {
200 HDF_LOGE("%s:ReleasePlatformNetDevice netDev NULL ptr!", __func__);
201 return HDF_FAILURE;
202 }
203 if (netDev->classDriverName != HDF_WIFI_PLATFORM_DRIVER_NAME) {
204 HDF_LOGE("%s:Wrong net device!", __func__);
205 return HDF_FAILURE;
206 }
207
208 data = GetPlatformData(netDev);
209 if (data == NULL) {
210 HDF_LOGE("%s:GetPlatformData failed!", __func__);
211 return HDF_FAILURE;
212 }
213 id = data->netInterfaceId;
214
215 ret = NetDeviceDeInit(netDev);
216 if (ret != HDF_SUCCESS) {
217 return ret;
218 }
219 if (data->device != NULL) {
220 CLEAR_BIT(data->device->netIfMap, id);
221 }
222 CLEAR_BIT(g_allocatedIfMap, id);
223 OsalMemFree(data);
224 HDF_LOGD("%s:ReleasePlatformNetDevice successful!", __func__);
225 return HDF_SUCCESS;
226 }
227
HdfWlanGetIfNames(const uint8_t chipId,uint8_t * ifNameCount)228 char *HdfWlanGetIfNames(const uint8_t chipId, uint8_t *ifNameCount)
229 {
230 struct HdfWlanDevice *wlanDevice = NULL;
231 uint32_t netIfMapTemp;
232 char *ifNames = NULL;
233 uint32_t bufferSize;
234 uint8_t i;
235 uint8_t j;
236 int32_t ret;
237 if (ifNameCount == NULL) {
238 HDF_LOGE("%s: para is NULL", __func__);
239 return NULL;
240 }
241
242 wlanDevice = HdfWlanGetWlanDevice(chipId);
243 if (wlanDevice == NULL) {
244 HDF_LOGE("%s:wlanDevice is NULL, not found!", __func__);
245 return NULL;
246 }
247 *ifNameCount = 0;
248 netIfMapTemp = wlanDevice->netIfMap;
249 for (i = 0; i < MAX_IF_COUNT; i++) {
250 if (((netIfMapTemp >> i) & 0x1) != 0) {
251 (*ifNameCount)++;
252 }
253 }
254 if (*ifNameCount == 0) {
255 // Never alloc 0 size
256 bufferSize = sizeof(char);
257 } else {
258 bufferSize = IFNAMSIZ * (uint32_t)(*ifNameCount);
259 }
260 ifNames = (char *)OsalMemCalloc(bufferSize);
261 if (ifNames == NULL) {
262 HDF_LOGE("%s:HdfWlanGetIfNames ifNames NULL ptr!", __func__);
263 return NULL;
264 }
265 if (*ifNameCount == 0) {
266 return ifNames;
267 }
268 for (i = 0, j = 0; i < MAX_IF_COUNT; i++) {
269 if (((netIfMapTemp >> i) & 0x1) == 0) {
270 continue;
271 }
272 ret = GetPlatformIfName(i, ifNames + (j * IFNAMSIZ), IFNAMSIZ);
273 if (ret != HDF_SUCCESS) {
274 HDF_LOGE("%s:Get ifName failed!ret=%d", __func__, ret);
275 OsalMemFree(ifNames);
276 return NULL;
277 }
278 j++;
279 }
280 HDF_LOGI("%s: Wlan get ifNames finished! ifNames=%s", __func__, ifNames);
281 return ifNames;
282 }
283