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