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 <net/cfg80211.h>
10 #include <net/regulatory.h>
11
12 #include <securec.h>
13
14 #include "wifi_module.h"
15 #include "wifi_mac80211_ops.h"
16 #include "hdf_wlan_utils.h"
17
18 #include "net_bdh_adpater.h"
19 #include "hdf_public_ap6275s.h"
20
21 #define HDF_LOG_TAG BDH6Driver
22
23
24 typedef enum {
25 WLAN_BAND_2G,
26 WLAN_BAND_5G,
27 WLAN_BAND_BUTT
28 } wlan_channel_band_enum;
29
30 #define WIFI_24G_CHANNEL_NUMS (14)
31 #define WAL_MIN_CHANNEL_2G (1)
32 #define WAL_MAX_CHANNEL_2G (14)
33 #define WAL_MIN_FREQ_2G (2412 + 5*(WAL_MIN_CHANNEL_2G - 1))
34 #define WAL_MAX_FREQ_2G (2484)
35 #define WAL_FREQ_2G_INTERVAL (5)
36
37 #define BDH6_GROUP_SIZE (1)
38 #define BDH6_ROW_SIZE (16)
39
40
get_linux_wiphy_ndev(struct net_device * ndev)41 struct wiphy* get_linux_wiphy_ndev(struct net_device *ndev)
42 {
43 if (ndev == NULL || ndev->ieee80211_ptr == NULL) {
44 return NULL;
45 }
46
47 return ndev->ieee80211_ptr->wiphy;
48 }
49
get_linux_wiphy_hdfdev(NetDevice * netDev)50 struct wiphy* get_linux_wiphy_hdfdev(NetDevice *netDev)
51 {
52 struct net_device *ndev = GetLinuxInfByNetDevice(netDev);
53 return get_linux_wiphy_ndev(ndev);
54 }
55
BDH6WalSetMode(NetDevice * netDev,enum WlanWorkMode iftype)56 int32_t BDH6WalSetMode(NetDevice *netDev, enum WlanWorkMode iftype)
57 {
58 int32_t retVal = 0;
59 struct net_device *netdev = NULL;
60 struct wiphy *wiphy = NULL;
61
62 netdev = GetLinuxInfByNetDevice(netDev);
63 if (!netdev) {
64 HDF_LOGE("%s: net_device is NULL", __func__);
65 return -1;
66 }
67
68 wiphy = get_linux_wiphy_ndev(netdev);
69 if (!wiphy) {
70 HDF_LOGE("%s: wiphy is NULL", __func__);
71 return -1;
72 }
73
74 HDF_LOGE("%s: start... iftype=%d ", __func__, iftype);
75 retVal = (int32_t) wl_cfg80211_ops.change_virtual_intf(wiphy, netdev,
76 (enum nl80211_iftype) iftype, NULL);
77 if (retVal < 0) {
78 HDF_LOGE("%s: set mode failed!", __func__);
79 }
80
81 return retVal;
82 }
83
BDH6WalAddKey(struct NetDevice * netDev,uint8_t keyIndex,bool pairwise,const uint8_t * macAddr,struct KeyParams * params)84 int32_t BDH6WalAddKey(struct NetDevice *netDev, uint8_t keyIndex, bool pairwise, const uint8_t *macAddr,
85 struct KeyParams *params)
86 {
87 int32_t retVal = 0;
88 struct net_device *netdev = NULL;
89 struct wiphy *wiphy = NULL;
90
91 netdev = GetLinuxInfByNetDevice(netDev);
92 if (!netdev) {
93 HDF_LOGE("%s: net_device is NULL", __func__);
94 return -1;
95 }
96
97 wiphy = get_linux_wiphy_ndev(netdev);
98 if (!wiphy) {
99 HDF_LOGE("%s: wiphy is NULL", __func__);
100 return -1;
101 }
102
103 HDF_LOGE("%s: start..., mac=%p, keyIndex=%u, pairwise=%d, cipher=0x%x, seqlen=%d, keylen=%d",
104 __func__, macAddr, keyIndex, pairwise, params->cipher, params->seqLen, params->keyLen);
105 print_hex_dump(KERN_INFO, "key: ", DUMP_PREFIX_NONE, BDH6_ROW_SIZE, BDH6_GROUP_SIZE, params->key,
106 params->keyLen, true);
107
108 (void)netDev;
109 retVal = (int32_t)wl_cfg80211_ops.add_key(wiphy, netdev, keyIndex, pairwise, macAddr, (struct key_params *)params);
110 if (retVal < 0) {
111 HDF_LOGE("%s: add key failed!", __func__);
112 }
113
114 return retVal;
115 }
116
BDH6WalDelKey(struct NetDevice * netDev,uint8_t keyIndex,bool pairwise,const uint8_t * macAddr)117 int32_t BDH6WalDelKey(struct NetDevice *netDev, uint8_t keyIndex, bool pairwise, const uint8_t *macAddr)
118 {
119 int32_t retVal = 0;
120 struct net_device *netdev = NULL;
121 struct wiphy *wiphy = NULL;
122
123 netdev = GetLinuxInfByNetDevice(netDev);
124 if (!netdev) {
125 HDF_LOGE("%s: net_device is NULL", __func__);
126 return -1;
127 }
128
129 wiphy = get_linux_wiphy_ndev(netdev);
130 if (!wiphy) {
131 HDF_LOGE("%s: wiphy is NULL", __func__);
132 return -1;
133 }
134
135 HDF_LOGE("%s: start..., mac=%p, keyIndex=%u,pairwise=%d", __func__, macAddr, keyIndex, pairwise);
136
137 (void)netDev;
138 retVal = (int32_t)wl_cfg80211_ops.del_key(wiphy, netdev, keyIndex, pairwise, macAddr);
139 if (retVal < 0) {
140 HDF_LOGE("%s: delete key failed!", __func__);
141 }
142
143 return retVal;
144 }
145
BDH6WalSetDefaultKey(struct NetDevice * netDev,uint8_t keyIndex,bool unicast,bool multicas)146 int32_t BDH6WalSetDefaultKey(struct NetDevice *netDev, uint8_t keyIndex, bool unicast, bool multicas)
147 {
148 int32_t retVal = 0;
149 struct net_device *netdev = NULL;
150 struct wiphy *wiphy = NULL;
151
152 netdev = GetLinuxInfByNetDevice(netDev);
153 if (!netdev) {
154 HDF_LOGE("%s: net_device is NULL", __func__);
155 return -1;
156 }
157
158 wiphy = get_linux_wiphy_ndev(netdev);
159 if (!wiphy) {
160 HDF_LOGE("%s: wiphy is NULL", __func__);
161 return -1;
162 }
163
164 HDF_LOGE("%s: start..., keyIndex=%u,unicast=%d, multicas=%d", __func__, keyIndex, unicast, multicas);
165
166 retVal = (int32_t)wl_cfg80211_ops.set_default_key(wiphy, netdev, keyIndex, unicast, multicas);
167 if (retVal < 0) {
168 HDF_LOGE("%s: set default key failed!", __func__);
169 }
170
171 return retVal;
172 }
173
BDH6WalGetDeviceMacAddr(NetDevice * netDev,int32_t type,uint8_t * mac,uint8_t len)174 int32_t BDH6WalGetDeviceMacAddr(NetDevice *netDev, int32_t type, uint8_t *mac, uint8_t len)
175 {
176 struct net_device *netdev = GetLinuxInfByNetDevice(netDev);
177 if (!netdev) {
178 HDF_LOGE("%s: net_device is NULL", __func__);
179 return -1;
180 }
181
182 (void)len;
183 (void)type;
184 (void)netDev;
185 HDF_LOGE("%s: start...", __func__);
186
187 memcpy_s(mac, len, netdev->dev_addr, netdev->addr_len);
188
189 return HDF_SUCCESS;
190 }
191
BDH6WalSetMacAddr(NetDevice * netDev,uint8_t * mac,uint8_t len)192 int32_t BDH6WalSetMacAddr(NetDevice *netDev, uint8_t *mac, uint8_t len)
193 {
194 int32_t retVal = 0;
195 struct net_device *netdev = GetLinuxInfByNetDevice(netDev);
196 if (!netdev) {
197 HDF_LOGE("%s: net_device is NULL", __func__);
198 return -1;
199 }
200
201 (void)len;
202 (void)netDev;
203 HDF_LOGE("%s: start...", __func__);
204
205 retVal = (int32_t)dhd_ops_pri.ndo_set_mac_address(netdev, mac);
206 if (retVal < 0) {
207 HDF_LOGE("%s: set mac address failed!", __func__);
208 }
209
210 return retVal;
211 }
212
BDH6WalSetTxPower(NetDevice * netDev,int32_t power)213 int32_t BDH6WalSetTxPower(NetDevice *netDev, int32_t power)
214 {
215 int retVal = 0;
216 struct wiphy *wiphy = NULL;
217
218 // sync from net_device->ieee80211_ptr
219 struct wireless_dev *wdev = GET_NET_DEV_CFG80211_WIRELESS(netDev);
220
221 wiphy = get_linux_wiphy_hdfdev(netDev);
222 if (!wiphy) {
223 HDF_LOGE("%s: wiphy is NULL", __func__);
224 return -1;
225 }
226
227 HDF_LOGE("%s: start...", __func__);
228 retVal = (int32_t)wl_cfg80211_ops.set_tx_power(wiphy, wdev, NL80211_TX_POWER_FIXED, power);
229 if (retVal < 0) {
230 HDF_LOGE("%s: set_tx_power failed!", __func__);
231 }
232
233 return HDF_SUCCESS;
234 }
235
236 const struct ieee80211_regdomain* bdh6_get_regdomain(void);
237
238
BDH6WalGetValidFreqsWithBand(NetDevice * netDev,int32_t band,int32_t * freqs,uint32_t * num)239 int32_t BDH6WalGetValidFreqsWithBand(NetDevice *netDev, int32_t band, int32_t *freqs, uint32_t *num)
240 {
241 uint32_t freqIndex = 0;
242 uint32_t channelNumber;
243 uint32_t freqTmp;
244 uint32_t minFreq;
245 uint32_t maxFreq;
246
247 struct wiphy* wiphy = NULL;
248 struct ieee80211_supported_band *band5g = NULL;
249 int32_t max5GChNum = 0;
250 const struct ieee80211_regdomain *regdom = bdh6_get_regdomain();
251 if (regdom == NULL) {
252 return HDF_FAILURE;
253 }
254
255 wiphy = get_linux_wiphy_hdfdev(netDev);
256 if (!wiphy) {
257 return -1;
258 }
259
260 (void)netDev;
261
262 minFreq = regdom->reg_rules[0].freq_range.start_freq_khz / MHZ_TO_KHZ(1);
263 maxFreq = regdom->reg_rules[0].freq_range.end_freq_khz / MHZ_TO_KHZ(1);
264 switch (band) {
265 case WLAN_BAND_2G:
266 for (channelNumber = 1; channelNumber <= WIFI_24G_CHANNEL_NUMS; channelNumber++) {
267 if (channelNumber < WAL_MAX_CHANNEL_2G) {
268 freqTmp = WAL_MIN_FREQ_2G + (channelNumber - 1) * WAL_FREQ_2G_INTERVAL;
269 } else if (channelNumber == WAL_MAX_CHANNEL_2G) {
270 freqTmp = WAL_MAX_FREQ_2G;
271 }
272 if (freqTmp < minFreq || freqTmp > maxFreq) {
273 continue;
274 }
275
276 freqs[freqIndex] = freqTmp;
277 freqIndex++;
278 }
279 *num = freqIndex;
280 break;
281
282 case WLAN_BAND_5G:
283 band5g = wiphy->bands[IEEE80211_BAND_5GHZ];
284 if (band5g == NULL) {
285 return HDF_ERR_NOT_SUPPORT;
286 }
287
288 max5GChNum = min(band5g->n_channels, WIFI_24G_CHANNEL_NUMS);
289 for (freqIndex = 0; freqIndex < max5GChNum; freqIndex++) {
290 freqs[freqIndex] = band5g->channels[freqIndex].center_freq;
291 }
292 *num = freqIndex;
293 break;
294
295 default:
296 return HDF_ERR_NOT_SUPPORT;
297 }
298 return HDF_SUCCESS;
299 }
300
BDH6WalReleaseHwCapability(struct WlanHwCapability * self)301 void BDH6WalReleaseHwCapability(struct WlanHwCapability *self)
302 {
303 uint8_t i;
304 if (self == NULL) {
305 return;
306 }
307 for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
308 if (self->bands[i] != NULL) {
309 OsalMemFree(self->bands[i]);
310 self->bands[i] = NULL;
311 }
312 }
313 if (self->supportedRates != NULL) {
314 OsalMemFree(self->supportedRates);
315 self->supportedRates = NULL;
316 }
317 OsalMemFree(self);
318 }
319
BDH6GetHw5GCapability(struct wiphy * wiphy,struct ieee80211_supported_band * band5g,struct WlanHwCapability * hwCapability)320 static int32_t BDH6GetHw5GCapability(struct wiphy* wiphy, struct ieee80211_supported_band *band5g,
321 struct WlanHwCapability *hwCapability)
322 {
323 uint8_t loop = 0;
324 hwCapability->bands[IEEE80211_BAND_5GHZ] = OsalMemCalloc(sizeof(struct WlanBand) + \
325 (sizeof(struct WlanChannel) * band5g->n_channels));
326 if (hwCapability->bands[IEEE80211_BAND_5GHZ] == NULL) {
327 HDF_LOGE("%s: oom!\n", __func__);
328 BDH6WalReleaseHwCapability(hwCapability);
329 return HDF_FAILURE;
330 }
331
332 hwCapability->bands[IEEE80211_BAND_5GHZ]->channelCount = band5g->n_channels;
333 for (loop = 0; loop < band5g->n_channels; loop++) {
334 hwCapability->bands[IEEE80211_BAND_5GHZ]->channels[loop].centerFreq = band5g->channels[loop].center_freq;
335 hwCapability->bands[IEEE80211_BAND_5GHZ]->channels[loop].flags = band5g->channels[loop].flags;
336 hwCapability->bands[IEEE80211_BAND_5GHZ]->channels[loop].channelId = band5g->channels[loop].hw_value;
337 }
338
339 return HDF_SUCCESS;
340 }
341
BDH6WalGetSupportRate(struct WlanHwCapability * hwCapability,struct ieee80211_supported_band * band,struct ieee80211_supported_band * band5g,uint16_t supportedRateCount)342 static int32_t BDH6WalGetSupportRate(struct WlanHwCapability *hwCapability, struct ieee80211_supported_band *band,
343 struct ieee80211_supported_band *band5g, uint16_t supportedRateCount)
344 {
345 uint8_t loop = 0;
346 hwCapability->supportedRateCount = supportedRateCount;
347 hwCapability->supportedRates = OsalMemCalloc(sizeof(uint16_t) * supportedRateCount);
348 if (hwCapability->supportedRates == NULL) {
349 HDF_LOGE("%s: oom!\n", __func__);
350 BDH6WalReleaseHwCapability(hwCapability);
351 return HDF_FAILURE;
352 }
353
354 for (loop = 0; loop < band->n_bitrates; loop++) {
355 hwCapability->supportedRates[loop] = band->bitrates[loop].bitrate;
356 HDF_LOGE("bdh6 2G supportedRates %u: %u\n", loop, hwCapability->supportedRates[loop]);
357 }
358
359 if (band5g) {
360 for (loop = band->n_bitrates; loop < supportedRateCount; loop++) {
361 hwCapability->supportedRates[loop] = band5g->bitrates[loop].bitrate;
362 HDF_LOGE("bdh6 5G supportedRates %u: %u\n", loop, hwCapability->supportedRates[loop]);
363 }
364 }
365
366 if (hwCapability->supportedRateCount > MAX_SUPPORTED_RATE)
367 hwCapability->supportedRateCount = MAX_SUPPORTED_RATE;
368
369 return HDF_SUCCESS;
370 }
371
BDH6WalGetHwCapability(struct NetDevice * netDev,struct WlanHwCapability ** capability)372 int32_t BDH6WalGetHwCapability(struct NetDevice *netDev, struct WlanHwCapability **capability)
373 {
374 uint8_t loop = 0;
375 struct wiphy* wiphy = NULL;
376 struct ieee80211_supported_band *band = NULL;
377 struct ieee80211_supported_band *band5g = NULL;
378 struct WlanHwCapability *hwCapability = NULL;
379 uint16_t supportedRateCount = 0;
380
381 wiphy = get_linux_wiphy_hdfdev(netDev);
382 if (!wiphy) {
383 return -1;
384 }
385 band = wiphy->bands[IEEE80211_BAND_2GHZ];
386 hwCapability = (struct WlanHwCapability *)OsalMemCalloc(sizeof(struct WlanHwCapability));
387 if (hwCapability == NULL) {
388 return HDF_FAILURE;
389 }
390 hwCapability->Release = BDH6WalReleaseHwCapability;
391
392 if (hwCapability->bands[IEEE80211_BAND_2GHZ] == NULL) {
393 hwCapability->bands[IEEE80211_BAND_2GHZ] =
394 OsalMemCalloc(sizeof(struct WlanBand) + (sizeof(struct WlanChannel) * band->n_channels));
395 if (hwCapability->bands[IEEE80211_BAND_2GHZ] == NULL) {
396 BDH6WalReleaseHwCapability(hwCapability);
397 return HDF_FAILURE;
398 }
399 }
400
401 hwCapability->htCapability = band->ht_cap.cap;
402 supportedRateCount = band->n_bitrates;
403
404 hwCapability->bands[IEEE80211_BAND_2GHZ]->channelCount = band->n_channels;
405 for (loop = 0; loop < band->n_channels; loop++) {
406 hwCapability->bands[IEEE80211_BAND_2GHZ]->channels[loop].centerFreq = band->channels[loop].center_freq;
407 hwCapability->bands[IEEE80211_BAND_2GHZ]->channels[loop].flags = band->channels[loop].flags;
408 hwCapability->bands[IEEE80211_BAND_2GHZ]->channels[loop].channelId = band->channels[loop].hw_value;
409 }
410
411 if (wiphy->bands[IEEE80211_BAND_5GHZ]) { // Fill 5Ghz band
412 band5g = wiphy->bands[IEEE80211_BAND_5GHZ];
413 if (BDH6GetHw5GCapability(wiphy, band5g, hwCapability) != HDF_SUCCESS) {
414 return HDF_FAILURE;
415 }
416
417 supportedRateCount += band5g->n_bitrates;
418 }
419
420 if (BDH6WalGetSupportRate(hwCapability, band, band5g, supportedRateCount) != HDF_FAILURE) {
421 return HDF_FAILURE;
422 }
423 *capability = hwCapability;
424 return HDF_SUCCESS;
425 }
426
BDH6WalSendAction(struct NetDevice * netDev,WifiActionData * actionData)427 int32_t BDH6WalSendAction(struct NetDevice *netDev, WifiActionData *actionData)
428 {
429 (void)netDev;
430 (void)actionData;
431 HDF_LOGE("%s: start...", __func__);
432 return HDF_ERR_NOT_SUPPORT;
433 }
434
BDH6WalGetIftype(struct NetDevice * netDev,uint8_t * iftype)435 int32_t BDH6WalGetIftype(struct NetDevice *netDev, uint8_t *iftype)
436 {
437 iftype = (uint8_t *)(&(GET_NET_DEV_CFG80211_WIRELESS(netDev)->iftype));
438 HDF_LOGE("%s: start...", __func__);
439 return HDF_SUCCESS;
440 }
441
442 static struct HdfMac80211BaseOps g_bdh6_baseOps = {
443 .SetMode = BDH6WalSetMode,
444 .AddKey = BDH6WalAddKey,
445 .DelKey = BDH6WalDelKey,
446 .SetDefaultKey = BDH6WalSetDefaultKey,
447
448 .GetDeviceMacAddr = BDH6WalGetDeviceMacAddr,
449 .SetMacAddr = BDH6WalSetMacAddr,
450 .SetTxPower = BDH6WalSetTxPower,
451 .GetValidFreqsWithBand = BDH6WalGetValidFreqsWithBand,
452
453 .GetHwCapability = BDH6WalGetHwCapability,
454
455 /**
456 .RemainOnChannel = WalRemainOnChannel,
457 .CancelRemainOnChannel = WalCancelRemainOnChannel,
458 .ProbeReqReport = WalProbeReqReport,
459 .AddIf = WalAddIf,
460 .RemoveIf = WalRemoveIf,
461 .SetApWpsP2pIe = WalSetApWpsP2pIe,
462 .GetDriverFlag = WalGetDriverFlag,
463 */
464 .SendAction = BDH6WalSendAction,
465 .GetIftype = BDH6WalGetIftype,
466
467 };
468
469
BDH6Mac80211Init(struct HdfChipDriver * chipDriver)470 void BDH6Mac80211Init(struct HdfChipDriver *chipDriver)
471 {
472 HDF_LOGE("%s: start...", __func__);
473
474 if (chipDriver == NULL) {
475 HDF_LOGE("%s: input is NULL", __func__);
476 return;
477 }
478
479 chipDriver->ops = &g_bdh6_baseOps;
480 chipDriver->staOps = &g_bdh6_staOps;
481 chipDriver->apOps = &g_bdh6_apOps;
482 chipDriver->p2pOps = NULL;
483 }
484
485