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