• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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