1 /*
2 * hdf_bdh_mac80211.c
3 *
4 * hdf driver
5 *
6 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 */
22
23 #include <net/cfg80211.h>
24 #include <net/regulatory.h>
25 #include <typedefs.h>
26 #include <ethernet.h>
27 #include <securec.h>
28 #include <linux/version.h>
29
30 #include "wifi_module.h"
31 #include "wifi_mac80211_ops.h"
32 #include "hdf_wlan_utils.h"
33 #include "hdf_wifi_event.h"
34 #include "net_bdh_adpater.h"
35 #include "hdf_wl_interface.h"
36 #include "hdf_public_ap6275s.h"
37 #include "bcmutils.h"
38 #include "wl_cfgp2p.h"
39 #include "eapol.h"
40
41 #define HDF_LOG_TAG BDH6Driver
42
43 struct NetDevice *get_real_netdev(NetDevice *netDev);
44 int32_t WalStopAp(NetDevice *hnetDev);
45 int32_t wl_cfg80211_abort_scan(struct wiphy *wiphy, struct wireless_dev *wdev);
46
get_linux_wiphy_ndev(struct net_device * ndev)47 struct wiphy *get_linux_wiphy_ndev(struct net_device *ndev)
48 {
49 if (ndev == NULL || ndev->ieee80211_ptr == NULL) {
50 return NULL;
51 }
52
53 return ndev->ieee80211_ptr->wiphy;
54 }
55
get_linux_wiphy_hdfdev(NetDevice * netDev)56 struct wiphy *get_linux_wiphy_hdfdev(NetDevice *netDev)
57 {
58 struct net_device *ndev = GetLinuxInfByNetDevice(netDev);
59 return get_linux_wiphy_ndev(ndev);
60 }
61
get_scan_ifidx(const char * ifname)62 int get_scan_ifidx(const char *ifname)
63 {
64 int i = 0;
65 struct NetDevice *p2p_hnetdev = NULL;
66 for (; i < HDF_INF_MAX; i ++) {
67 p2p_hnetdev = g_hdf_infmap[i].hnetdev;
68 if (p2p_hnetdev == NULL) {
69 continue;
70 }
71 if (strcmp(p2p_hnetdev->name, ifname) == 0) {
72 HDF_LOGE("get scan ifidx = %d, %s", i, ifname);
73 return i;
74 }
75 }
76 HDF_LOGI("get scan ifidx error %d, %s", i, ifname);
77 return 0;
78 }
79
BDH6WalSetMode(NetDevice * hnetDev,enum WlanWorkMode iftype)80 static int32_t BDH6WalSetMode(NetDevice *hnetDev, enum WlanWorkMode iftype)
81 {
82 int32_t retVal = 0;
83 struct net_device *netdev = NULL;
84 NetDevice *netDev = NULL;
85 struct wiphy *wiphy = NULL;
86 enum nl80211_iftype old_iftype = 0;
87 netDev = get_real_netdev(hnetDev);
88
89 netdev = GetLinuxInfByNetDevice(netDev);
90 if (!netdev) {
91 HDF_LOGE("%s: net_device is NULL", __func__);
92 return -1;
93 }
94
95 wiphy = get_linux_wiphy_ndev(netdev);
96 if (!wiphy) {
97 HDF_LOGE("%s: wiphy is NULL", __func__);
98 return -1;
99 }
100 old_iftype = netdev->ieee80211_ptr->iftype;
101
102 HDF_LOGI("%s: start... iftype=%d, oldiftype=%d", __func__, iftype, old_iftype);
103 if (old_iftype == NL80211_IFTYPE_AP && (int32_t)iftype != (int32_t)old_iftype) {
104 WalStopAp(netDev);
105 }
106
107 if ((int32_t)iftype == (int32_t)NL80211_IFTYPE_P2P_GO && old_iftype == NL80211_IFTYPE_P2P_GO) {
108 HDF_LOGE("%s: p2p go don't change mode", __func__);
109 return retVal;
110 }
111
112 rtnl_lock();
113 retVal = (int32_t)wl_cfg80211_ops.change_virtual_intf(wiphy, netdev,
114 (enum nl80211_iftype)iftype, NULL);
115 rtnl_unlock();
116 if (retVal < 0) {
117 HDF_LOGE("%s: set mode failed!", __func__);
118 }
119
120 return retVal;
121 }
122
BDH6WalAddKey(struct NetDevice * hnetDev,uint8_t keyIndex,bool pairwise,const uint8_t * macAddr,struct KeyParams * params)123 int32_t BDH6WalAddKey(struct NetDevice *hnetDev, uint8_t keyIndex, bool pairwise, const uint8_t *macAddr,
124 struct KeyParams *params)
125 {
126 int32_t retVal = 0;
127 struct NetDevice *netDev = NULL;
128 struct net_device *netdev = NULL;
129 struct wiphy *wiphy = NULL;
130
131 #if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 10, 0))
132 struct key_params keypm;
133 #endif
134 netDev = get_real_netdev(hnetDev);
135
136 netdev = GetLinuxInfByNetDevice(netDev);
137 if (!netdev) {
138 HDF_LOGE("%s: net_device is NULL", __func__);
139 return -1;
140 }
141
142 wiphy = get_linux_wiphy_ndev(netdev);
143 if (!wiphy) {
144 HDF_LOGE("%s: wiphy is NULL", __func__);
145 return -1;
146 }
147
148 HDF_LOGI("%s: start..., mac = %p, keyIndex = %u,pairwise = %d, cipher = 0x%x, seqlen = %d, keylen = %d",
149 __func__, macAddr, keyIndex, pairwise, params->cipher, params->seqLen, params->keyLen);
150 rtnl_lock();
151 bdh6_hdf_vxx_lock(netdev->ieee80211_ptr, 0);
152 #if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 10, 0))
153 memset_s(&keypm, sizeof(struct key_params), 0, sizeof(struct key_params));
154 keypm.key = params->key;
155 keypm.seq = params->seq;
156 keypm.key_len = params->keyLen;
157 keypm.seq_len = params->seqLen;
158 keypm.cipher = params->cipher;
159 keypm.vlan_id = 0;
160 retVal = (int32_t)wl_cfg80211_ops.add_key(wiphy, netdev, keyIndex, pairwise, macAddr, &keypm);
161 #else
162 retVal = (int32_t)wl_cfg80211_ops.add_key(wiphy, netdev, keyIndex, pairwise, macAddr, (struct key_params *)params);
163 #endif
164 bdh6_hdf_vxx_unlock(netdev->ieee80211_ptr, 0);
165 rtnl_unlock();
166 if (retVal < 0) {
167 HDF_LOGE("%s: add key failed!", __func__);
168 }
169
170 return retVal;
171 }
172
BDH6WalDelKey(struct NetDevice * hnetDev,uint8_t keyIndex,bool pairwise,const uint8_t * macAddr)173 int32_t BDH6WalDelKey(struct NetDevice *hnetDev, uint8_t keyIndex, bool pairwise, const uint8_t *macAddr)
174 {
175 int32_t retVal = 0;
176 struct NetDevice *netDev = NULL;
177 struct net_device *netdev = NULL;
178 struct wiphy *wiphy = NULL;
179 netDev = get_real_netdev(hnetDev);
180
181 netdev = GetLinuxInfByNetDevice(netDev);
182 if (!netdev) {
183 HDF_LOGE("%s: net_device is NULL", __func__);
184 return -1;
185 }
186
187 wiphy = get_linux_wiphy_ndev(netdev);
188 if (!wiphy) {
189 HDF_LOGE("%s: wiphy is NULL", __func__);
190 return -1;
191 }
192
193 HDF_LOGI("%s: start..., mac=%p, keyIndex=%u,pairwise=%d", __func__, macAddr, keyIndex, pairwise);
194
195 rtnl_lock();
196 bdh6_hdf_vxx_lock(netdev->ieee80211_ptr, 0);
197 retVal = (int32_t)wl_cfg80211_ops.del_key(wiphy, netdev, keyIndex, pairwise, macAddr);
198 bdh6_hdf_vxx_unlock(netdev->ieee80211_ptr, 0);
199 rtnl_unlock();
200 if (retVal < 0) {
201 HDF_LOGE("%s: delete key failed!", __func__);
202 }
203
204 return retVal;
205 }
206
BDH6WalSetDefaultKey(struct NetDevice * hnetDev,uint8_t keyIndex,bool unicast,bool multicas)207 int32_t BDH6WalSetDefaultKey(struct NetDevice *hnetDev, uint8_t keyIndex, bool unicast, bool multicas)
208 {
209 int32_t retVal = 0;
210 struct NetDevice *netDev = NULL;
211 struct net_device *netdev = NULL;
212 struct wiphy *wiphy = NULL;
213 netDev = get_real_netdev(hnetDev);
214
215 netdev = GetLinuxInfByNetDevice(netDev);
216 if (!netdev) {
217 HDF_LOGE("%s: net_device is NULL", __func__);
218 return -1;
219 }
220
221 wiphy = get_linux_wiphy_ndev(netdev);
222 if (!wiphy) {
223 HDF_LOGE("%s: wiphy is NULL", __func__);
224 return -1;
225 }
226 HDF_LOGI("%s: start..., keyIndex=%u,unicast=%d, multicas=%d", __func__, keyIndex, unicast, multicas);
227 rtnl_lock();
228 bdh6_hdf_vxx_lock(netdev->ieee80211_ptr, 0);
229 retVal = (int32_t)wl_cfg80211_ops.set_default_key(wiphy, netdev, keyIndex, unicast, multicas);
230 bdh6_hdf_vxx_unlock(netdev->ieee80211_ptr, 0);
231 rtnl_unlock();
232 if (retVal < 0) {
233 HDF_LOGE("%s: set default key failed!", __func__);
234 }
235
236 return retVal;
237 }
238
BDH6WalGetDeviceMacAddr(NetDevice * hnetDev,int32_t type,uint8_t * mac,uint8_t len)239 int32_t BDH6WalGetDeviceMacAddr(NetDevice *hnetDev, int32_t type, uint8_t *mac, uint8_t len)
240 {
241 struct NetDevice *netDev = NULL;
242 struct net_device *netdev = NULL;
243 netDev = get_real_netdev(hnetDev);
244 netdev = GetLinuxInfByNetDevice(netDev);
245 if (!netdev) {
246 HDF_LOGE("%s: net_device is NULL", __func__);
247 return -1;
248 }
249
250 (void)len;
251 (void)type;
252 (void)netDev;
253 HDF_LOGI("%s: start...", __func__);
254
255 memcpy_s(mac, len, netdev->dev_addr, netdev->addr_len);
256
257 return HDF_SUCCESS;
258 }
259
BDH6WalSetMacAddr(NetDevice * hnetDev,uint8_t * mac,uint8_t len)260 int32_t BDH6WalSetMacAddr(NetDevice *hnetDev, uint8_t *mac, uint8_t len)
261 {
262 int32_t retVal = 0;
263 struct NetDevice *netDev = NULL;
264 struct net_device *netdev = NULL;
265 struct sockaddr sa;
266 netDev = get_real_netdev(hnetDev);
267 netdev = GetLinuxInfByNetDevice(netDev);
268 if (!netdev) {
269 HDF_LOGE("%s: net_device is NULL", __func__);
270 return -1;
271 }
272
273 HDF_LOGI("%s: start...", __func__);
274 if (mac == NULL || len != ETH_ALEN) {
275 HDF_LOGE("%s: mac is error, len=%u", __func__, len);
276 return -1;
277 }
278 if (!is_valid_ether_addr(mac)) {
279 HDF_LOGE("%s: mac is invalid %02x:%02x:%02x:%02x:%02x:%02x", __func__,
280 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
281 return -1;
282 }
283
284 memcpy_s(sa.sa_data, ETH_ALEN, mac, len);
285
286 retVal = (int32_t)dhd_ops_pri.ndo_set_mac_address(netdev, (void *)&sa);
287 if (retVal < 0) {
288 HDF_LOGE("%s: set mac address failed!", __func__);
289 }
290 memcpy_s(hnetDev->macAddr, MAC_ADDR_SIZE, mac, len);
291 return retVal;
292 }
293
BDH6WalSetTxPower(NetDevice * hnetDev,int32_t power)294 int32_t BDH6WalSetTxPower(NetDevice *hnetDev, int32_t power)
295 {
296 int retVal = 0;
297 struct wiphy *wiphy = NULL;
298 struct NetDevice *netDev = NULL;
299 struct wireless_dev *wdev = NULL;
300 netDev = get_real_netdev(hnetDev);
301
302 // sync from net_device->ieee80211_ptr
303 wdev = GET_NET_DEV_CFG80211_WIRELESS(netDev);
304
305 wiphy = get_linux_wiphy_hdfdev(netDev);
306 if (!wiphy) {
307 HDF_LOGE("%s: wiphy is NULL", __func__);
308 return -1;
309 }
310
311 HDF_LOGI("%s: start...", __func__);
312 rtnl_lock();
313 retVal = (int32_t)wl_cfg80211_ops.set_tx_power(wiphy, wdev, NL80211_TX_POWER_FIXED, power);
314 rtnl_unlock();
315 if (retVal < 0) {
316 HDF_LOGE("%s: set_tx_power failed!", __func__);
317 }
318
319 return HDF_SUCCESS;
320 }
321
BDH6WalReleaseHwCapability(struct WlanHwCapability * self)322 void BDH6WalReleaseHwCapability(struct WlanHwCapability *self)
323 {
324 uint8_t i;
325 if (self == NULL) {
326 return;
327 }
328 for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
329 if (self->bands[i] != NULL) {
330 OsalMemFree(self->bands[i]);
331 self->bands[i] = NULL;
332 }
333 }
334 if (self->supportedRates != NULL) {
335 OsalMemFree(self->supportedRates);
336 self->supportedRates = NULL;
337 }
338 OsalMemFree(self);
339 }
340
GetBdh24GFreq(const struct ieee80211_regdomain * regdom,int32_t * freqs,uint32_t * num)341 static void GetBdh24GFreq(const struct ieee80211_regdomain *regdom, int32_t *freqs, uint32_t *num)
342 {
343 uint32_t channelNumber;
344 uint32_t freqIndex = 0;
345 uint32_t freqTmp;
346 uint32_t minFreq;
347 uint32_t maxFreq;
348
349 minFreq = regdom->reg_rules[0].freq_range.start_freq_khz / MHZ_TO_KHZ(1);
350 maxFreq = regdom->reg_rules[0].freq_range.end_freq_khz / MHZ_TO_KHZ(1);
351 for (channelNumber = 1; channelNumber <= WIFI_24G_CHANNEL_NUMS; channelNumber++) {
352 if (channelNumber < WAL_MAX_CHANNEL_2G) {
353 freqTmp = WAL_MIN_FREQ_2G + (channelNumber - 1) * WAL_FREQ_2G_INTERVAL;
354 } else if (channelNumber == WAL_MAX_CHANNEL_2G) {
355 freqTmp = WAL_MAX_FREQ_2G;
356 }
357 if (freqTmp < minFreq || freqTmp > maxFreq) {
358 continue;
359 }
360
361 HDF_LOGI("bdh6 2G %u: freq=%u\n", freqIndex, freqTmp);
362 freqs[freqIndex] = freqTmp;
363 freqIndex++;
364 }
365 *num = freqIndex;
366 }
367
Bdh6Fband(NetDevice * hnetDev,int32_t band,int32_t * freqs,uint32_t * num)368 int32_t Bdh6Fband(NetDevice *hnetDev, int32_t band, int32_t *freqs, uint32_t *num)
369 {
370 uint32_t freqIndex = 0;
371 struct wiphy* wiphy = NULL;
372 struct NetDevice *netDev = NULL;
373 struct ieee80211_supported_band *band5g = NULL;
374 int32_t max5GChNum = 0;
375 const struct ieee80211_regdomain *regdom = bdh6_get_regdomain();
376 if (regdom == NULL) {
377 HDF_LOGE("%s: wal_get_cfg_regdb failed!", __func__);
378 return HDF_FAILURE;
379 }
380 netDev = get_real_netdev(hnetDev);
381 wiphy = get_linux_wiphy_hdfdev(netDev);
382 if (!wiphy) {
383 HDF_LOGE("%s: wiphy is NULL", __func__);
384 return -1;
385 }
386 HDF_LOGI("%s: start..., band=%d", __func__, band);
387 switch (band) {
388 case WLAN_BAND_2G:
389 GetBdh24GFreq(regdom, freqs, num);
390 break;
391
392 case WLAN_BAND_5G:
393 band5g = wiphy->bands[IEEE80211_BAND_5GHZ];
394 if (band5g == NULL) {
395 return HDF_ERR_NOT_SUPPORT;
396 }
397 max5GChNum = min(band5g->n_channels, WIFI_24G_CHANNEL_NUMS);
398 for (freqIndex = 0; freqIndex < max5GChNum; freqIndex++) {
399 freqs[freqIndex] = band5g->channels[freqIndex].center_freq;
400 HDF_LOGI("bdh6 5G %u: freq=%u\n", freqIndex, freqs[freqIndex]);
401 }
402 *num = freqIndex;
403 break;
404
405 default:
406 HDF_LOGE("%s: no support band!", __func__);
407 return HDF_ERR_NOT_SUPPORT;
408 }
409 return HDF_SUCCESS;
410 }
411
FillBdhBandInfo(const struct ieee80211_supported_band * band,enum Ieee80211Band bnum,struct WlanHwCapability * hwCapability)412 static int32_t FillBdhBandInfo(const struct ieee80211_supported_band *band, enum Ieee80211Band bnum,
413 struct WlanHwCapability *hwCapability)
414 {
415 uint8_t loop = 0;
416 if (hwCapability->bands[bnum] == NULL) {
417 hwCapability->bands[bnum] =
418 OsalMemCalloc(sizeof(struct WlanBand) + (sizeof(struct WlanChannel) * band->n_channels));
419 if (hwCapability->bands[bnum] == NULL) {
420 BDH6WalReleaseHwCapability(hwCapability);
421 return HDF_FAILURE;
422 }
423 }
424
425 hwCapability->htCapability = band->ht_cap.cap;
426
427 hwCapability->bands[bnum]->channelCount = band->n_channels;
428 for (loop = 0; loop < band->n_channels; loop++) {
429 hwCapability->bands[bnum]->channels[loop].centerFreq = band->channels[loop].center_freq;
430 hwCapability->bands[bnum]->channels[loop].flags = band->channels[loop].flags;
431 hwCapability->bands[bnum]->channels[loop].channelId = band->channels[loop].hw_value;
432 HDF_LOGI("bdh6 %d band %u: centerFreq=%u, channelId=%u, flags=0x%08x\n", bnum, loop,
433 hwCapability->bands[bnum]->channels[loop].centerFreq,
434 hwCapability->bands[bnum]->channels[loop].channelId,
435 hwCapability->bands[bnum]->channels[loop].flags);
436 }
437
438 return HDF_SUCCESS;
439 }
440
FillBdhSupportedRates(const struct ieee80211_supported_band * band2g,const struct ieee80211_supported_band * band5g,struct WlanHwCapability * hwCapability)441 static int32_t FillBdhSupportedRates(const struct ieee80211_supported_band *band2g,
442 const struct ieee80211_supported_band *band5g, struct WlanHwCapability *hwCapability)
443 {
444 uint8_t loop = 0;
445 hwCapability->supportedRates = OsalMemCalloc(sizeof(uint16_t) * hwCapability->supportedRateCount);
446 if (hwCapability->supportedRates == NULL) {
447 HDF_LOGE("%s: oom!\n", __func__);
448 BDH6WalReleaseHwCapability(hwCapability);
449 return HDF_FAILURE;
450 }
451
452 for (loop = 0; loop < band2g->n_bitrates; loop++) {
453 hwCapability->supportedRates[loop] = band2g->bitrates[loop].bitrate;
454 HDF_LOGI("bdh6 2G supportedRates %u: %u\n", loop, hwCapability->supportedRates[loop]);
455 }
456
457 if (band5g) {
458 for (loop = band2g->n_bitrates; loop < hwCapability->supportedRateCount; loop++) {
459 hwCapability->supportedRates[loop] = band5g->bitrates[loop].bitrate;
460 HDF_LOGI("bdh6 5G supportedRates %u: %u\n", loop, hwCapability->supportedRates[loop]);
461 }
462 }
463
464 if (hwCapability->supportedRateCount > MAX_SUPPORTED_RATE) {
465 hwCapability->supportedRateCount = MAX_SUPPORTED_RATE;
466 }
467 return HDF_SUCCESS;
468 }
469
Bdh6Ghcap(struct NetDevice * hnetDev,struct WlanHwCapability ** capability)470 int32_t Bdh6Ghcap(struct NetDevice *hnetDev, struct WlanHwCapability **capability)
471 {
472 int32_t ret = 0;
473 struct wiphy *wiphy = NULL;
474 struct NetDevice *netDev = NULL;
475 struct ieee80211_supported_band *band2g = NULL;
476 struct ieee80211_supported_band *band5g = NULL;
477 struct WlanHwCapability *hwCapability = NULL;
478 uint16_t supportedRateCount = 0;
479 netDev = get_real_netdev(hnetDev);
480
481 wiphy = get_linux_wiphy_hdfdev(netDev);
482 if (!wiphy) {
483 HDF_LOGE("%s: wiphy is NULL", __func__);
484 return -1;
485 }
486
487 HDF_LOGI("%s: start...", __func__);
488 band2g = wiphy->bands[IEEE80211_BAND_2GHZ];
489 hwCapability = (struct WlanHwCapability *)OsalMemCalloc(sizeof(struct WlanHwCapability));
490 if (hwCapability == NULL) {
491 HDF_LOGE("%s: oom!\n", __func__);
492 return HDF_FAILURE;
493 }
494 hwCapability->Release = BDH6WalReleaseHwCapability;
495 supportedRateCount = band2g->n_bitrates;
496 ret = FillBdhBandInfo(band2g, IEEE80211_BAND_2GHZ, hwCapability);
497 if (ret != HDF_SUCCESS) {
498 HDF_LOGE("%s: FillBdh2GBandInfo failed", __func__);
499 return HDF_FAILURE;
500 }
501
502 if (wiphy->bands[IEEE80211_BAND_5GHZ]) { // Fill 5Ghz band
503 band5g = wiphy->bands[IEEE80211_BAND_5GHZ];
504 ret = FillBdhBandInfo(band5g, IEEE80211_BAND_5GHZ, hwCapability);
505 if (ret != HDF_SUCCESS) {
506 HDF_LOGE("%s: FillBdh5GBandInfo failed", __func__);
507 return HDF_FAILURE;
508 }
509
510 supportedRateCount += band5g->n_bitrates;
511 }
512
513 hwCapability->htCapability = band2g->ht_cap.cap;
514 HDF_LOGI("bdh6 htCapability= %u,%u; supportedRateCount= %u,%u,%u\n", hwCapability->htCapability,
515 band5g->ht_cap.cap, supportedRateCount, band2g->n_bitrates, band5g->n_bitrates);
516
517 hwCapability->supportedRateCount = supportedRateCount;
518 ret = FillBdhSupportedRates(band2g, band5g, hwCapability);
519
520 *capability = hwCapability;
521 return ret;
522 }
523
FillActionParamFreq(struct wiphy * wiphy,struct cfg80211_mgmt_tx_params * params)524 static int32_t FillActionParamFreq(struct wiphy *wiphy, struct cfg80211_mgmt_tx_params *params)
525 {
526 u32 center_freq = 0;
527 memset_s(params, sizeof(*params), 0, sizeof(*params));
528 params->wait = 0;
529 center_freq = p2p_remain_freq;
530 params->chan = ieee80211_get_channel_khz(wiphy, MHZ_TO_KHZ(center_freq));
531 if (params->chan == NULL) {
532 HDF_LOGE("%s: get center_freq %u faild", __func__, center_freq);
533 return -1;
534 }
535
536 return 0;
537 }
538
Bdh6SActionEntry(struct NetDevice * hhnetDev,WifiActionData * actionData)539 static int32_t Bdh6SActionEntry(struct NetDevice *hhnetDev, WifiActionData *actionData)
540 {
541 int retVal = 0;
542 struct net_device *netdev = NULL;
543 struct NetDevice *netDev = NULL;
544 struct wiphy *wiphy = NULL;
545 struct wireless_dev *wdev = NULL;
546 static u64 action_cookie = 0;
547 struct cfg80211_mgmt_tx_params params;
548 u8 *action_buf = NULL, *srcMac = NULL;
549 struct ieee80211_mgmt *mgmt = NULL;
550
551 g_mgmt_tx_event_ifidx = get_scan_ifidx(hhnetDev->name);
552 HDF_LOGI("%s: start %s... ifidx=%d", __func__, hhnetDev->name, g_mgmt_tx_event_ifidx);
553
554 netDev = get_real_netdev(hhnetDev);
555 netdev = GetLinuxInfByNetDevice(netDev);
556 if (!netdev) {
557 HDF_LOGE("%s: net_device is NULL", __func__);
558 return -1;
559 }
560 wiphy = get_linux_wiphy_ndev(netdev);
561 if (!wiphy) {
562 HDF_LOGE("%s: wiphy is NULL", __func__);
563 return -1;
564 }
565
566 if (strcmp(hhnetDev->name, "p2p0") == 0) {
567 wdev = g_hdf_infmap[HDF_INF_P2P0].wdev;
568 if (g_hdf_infmap[HDF_INF_P2P1].netdev)
569 srcMac = wdev->address;
570 else
571 srcMac = actionData->src;
572 } else {
573 wdev = netdev->ieee80211_ptr;
574 srcMac = actionData->src;
575 }
576 if (FillActionParamFreq(wiphy, ¶ms) != 0) {
577 return -1;
578 }
579
580 // build 802.11 action header
581 action_buf = (u8 *)OsalMemCalloc(MAC_80211_FRAME_LEN+actionData->dataLen);
582 mgmt = (struct ieee80211_mgmt *)action_buf;
583 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION);
584 memcpy_s(mgmt->da, ETH_ALEN, actionData->dst, ETH_ALEN);
585 memcpy_s(mgmt->sa, ETH_ALEN, srcMac, ETH_ALEN);
586 memcpy_s(mgmt->bssid, ETH_ALEN, actionData->bssid, ETH_ALEN);
587
588 /* 填充payload信息 */
589 if (actionData->dataLen > 0) {
590 memcpy_s(action_buf+MAC_80211_FRAME_LEN, actionData->dataLen, actionData->data, actionData->dataLen);
591 }
592 params.buf = action_buf;
593 params.len = (MAC_80211_FRAME_LEN + actionData->dataLen);
594 retVal = (int32_t)wl_cfg80211_ops.mgmt_tx(wiphy, wdev, ¶ms, &action_cookie);
595 OsalMemFree(action_buf);
596 return retVal;
597 }
598
Bdh6SAction(struct NetDevice * hhnetDev,WifiActionData * actionData)599 int32_t Bdh6SAction(struct NetDevice *hhnetDev, WifiActionData *actionData)
600 {
601 int retVal = 0;
602 rtnl_lock();
603 retVal = Bdh6SActionEntry(hhnetDev, actionData);
604 rtnl_unlock();
605 return retVal;
606 }
607
BDH6WalGetIftype(struct NetDevice * hnetDev,uint8_t * iftype)608 int32_t BDH6WalGetIftype(struct NetDevice *hnetDev, uint8_t *iftype)
609 {
610 struct NetDevice *netDev = NULL;
611 netDev = get_real_netdev(hnetDev);
612 iftype = (uint8_t *)(&(GET_NET_DEV_CFG80211_WIRELESS(netDev)->iftype));
613 HDF_LOGI("%s: start...", __func__);
614 return HDF_SUCCESS;
615 }
616
617 static struct HdfMac80211BaseOps g_bdh6_baseOps = {
618 .SetMode = BDH6WalSetMode,
619 .AddKey = BDH6WalAddKey,
620 .DelKey = BDH6WalDelKey,
621 .SetDefaultKey = BDH6WalSetDefaultKey,
622
623 .GetDeviceMacAddr = BDH6WalGetDeviceMacAddr,
624 .SetMacAddr = BDH6WalSetMacAddr,
625 .SetTxPower = BDH6WalSetTxPower,
626 .GetValidFreqsWithBand = Bdh6Fband,
627
628 .GetHwCapability = Bdh6Ghcap,
629 .SendAction = Bdh6SAction,
630 .GetIftype = BDH6WalGetIftype,
631
632 };
633
634 #define WIFI_SCAN_EXTRA_IE_LEN_MAX (512)
635 #define PTR_IEEE80211_CHANNEL_SIZE 8
636
GetChannelByFreq(const struct wiphy * wiphy,uint16_t center_freq)637 struct ieee80211_channel *GetChannelByFreq(const struct wiphy *wiphy, uint16_t center_freq)
638 {
639 enum Ieee80211Band band;
640 struct ieee80211_supported_band *currentBand = NULL;
641 int32_t loop;
642 for (band = (enum Ieee80211Band)0; band < IEEE80211_NUM_BANDS; band++) {
643 currentBand = wiphy->bands[band];
644 if (currentBand == NULL) {
645 continue;
646 }
647 for (loop = 0; loop < currentBand->n_channels; loop++) {
648 if (currentBand->channels[loop].center_freq == center_freq) {
649 return ¤tBand->channels[loop];
650 }
651 }
652 }
653 return NULL;
654 }
655
656
WifiScanSetSsid(const struct WlanScanRequest * params,struct cfg80211_scan_request * request)657 static int32_t WifiScanSetSsid(const struct WlanScanRequest *params, struct cfg80211_scan_request *request)
658 {
659 int32_t count = 0;
660 int32_t loop;
661
662 if (params->ssidCount > WPAS_MAX_SCAN_SSIDS) {
663 HDF_LOGE("%s:unexpected numSsids!numSsids=%u", __func__, params->ssidCount);
664 return HDF_FAILURE;
665 }
666
667 if (params->ssidCount == 0) {
668 HDF_LOGE("%s:ssid number is 0!", __func__);
669 return HDF_SUCCESS;
670 }
671
672 request->ssids = (struct cfg80211_ssid *)OsalMemCalloc(params->ssidCount * sizeof(struct cfg80211_ssid));
673 if (request->ssids == NULL) {
674 HDF_LOGE("%s: calloc request->ssids null", __func__);
675 return HDF_FAILURE;
676 }
677
678 for (loop = 0; loop < params->ssidCount; loop++) {
679 if (count >= DRIVER_MAX_SCAN_SSIDS) {
680 break;
681 }
682
683 if (params->ssids[loop].ssidLen > IEEE80211_MAX_SSID_LEN) {
684 continue;
685 }
686
687 request->ssids[count].ssid_len = params->ssids[loop].ssidLen;
688 if (memcpy_s(request->ssids[count].ssid, OAL_IEEE80211_MAX_SSID_LEN, params->ssids[loop].ssid,
689 params->ssids[loop].ssidLen) != EOK) {
690 continue;
691 }
692 count++;
693 }
694 request->n_ssids = count;
695
696 return HDF_SUCCESS;
697 }
698
WifiScanSetUserIe(const struct WlanScanRequest * params,struct cfg80211_scan_request * request)699 int32_t WifiScanSetUserIe(const struct WlanScanRequest *params, struct cfg80211_scan_request *request)
700 {
701 if (params->extraIEsLen > WIFI_SCAN_EXTRA_IE_LEN_MAX) {
702 HDF_LOGE("%s:unexpected extra len!extraIesLen=%d", __func__, params->extraIEsLen);
703 return HDF_FAILURE;
704 }
705 if ((params->extraIEs != NULL) && (params->extraIEsLen != 0)) {
706 request->ie = (uint8_t *)OsalMemCalloc(params->extraIEsLen);
707 if (request->ie == NULL) {
708 HDF_LOGE("%s: calloc request->ie null", __func__);
709 return HDF_FAILURE;
710 }
711 (void)memcpy_s((void *)request->ie, params->extraIEsLen, params->extraIEs, params->extraIEsLen);
712 request->ie_len = params->extraIEsLen;
713 }
714
715 return HDF_SUCCESS;
716 }
717
FillAllValidChannels(const struct wiphy * wiphy,int32_t channelTotal,struct cfg80211_scan_request * request)718 static int32_t FillAllValidChannels(const struct wiphy *wiphy, int32_t channelTotal,
719 struct cfg80211_scan_request *request)
720 {
721 int32_t loop;
722 int32_t count = 0;
723 enum Ieee80211Band band = IEEE80211_BAND_2GHZ;
724 struct ieee80211_channel *chan = NULL;
725
726 for (band = IEEE80211_BAND_2GHZ; band <= IEEE80211_BAND_5GHZ; band++) {
727 if (wiphy->bands[band] == NULL) {
728 HDF_LOGE("%s: wiphy->bands[band] = NULL!\n", __func__);
729 continue;
730 }
731
732 for (loop = 0; loop < (int32_t)wiphy->bands[band]->n_channels; loop++) {
733 if (count >= channelTotal) {
734 break;
735 }
736
737 chan = &wiphy->bands[band]->channels[loop];
738 if ((chan->flags & WIFI_CHAN_DISABLED) != 0) {
739 continue;
740 }
741 request->channels[count++] = chan;
742 }
743 }
744 return count;
745 }
746
WifiScanSetChannel(const struct wiphy * wiphy,const struct WlanScanRequest * params,struct cfg80211_scan_request * request)747 int32_t WifiScanSetChannel(const struct wiphy *wiphy, const struct WlanScanRequest *params,
748 struct cfg80211_scan_request *request)
749 {
750 int32_t loop;
751 int32_t count = 0;
752 struct ieee80211_channel *chan = NULL;
753
754 int32_t channelTotal = ieee80211_get_num_supported_channels((struct wiphy *)wiphy);
755
756 if ((params->freqs == NULL) || (params->freqsCount == 0)) {
757 count = FillAllValidChannels(wiphy, channelTotal, request);
758 } else {
759 for (loop = 0; loop < params->freqsCount; loop++) {
760 chan = GetChannelByFreq(wiphy, (uint16_t)(params->freqs[loop]));
761 if (chan == NULL) {
762 HDF_LOGE("%s: freq not found!freq=%d!\n", __func__, params->freqs[loop]);
763 continue;
764 }
765
766 if (count >= channelTotal) {
767 break;
768 }
769
770 request->channels[count++] = chan;
771 }
772 }
773
774 if (count == 0) {
775 HDF_LOGE("%s: invalid freq info!\n", __func__);
776 return HDF_FAILURE;
777 }
778 request->n_channels = count;
779
780 return HDF_SUCCESS;
781 }
782
WifiScanSetRequest(struct NetDevice * netdev,const struct WlanScanRequest * params,struct cfg80211_scan_request * request)783 int32_t WifiScanSetRequest(struct NetDevice *netdev, const struct WlanScanRequest *params,
784 struct cfg80211_scan_request *request)
785 {
786 if (netdev == NULL || netdev->ieee80211Ptr == NULL) {
787 return HDF_FAILURE;
788 }
789 request->wiphy = GET_NET_DEV_CFG80211_WIRELESS(netdev)->wiphy;
790 request->wdev = GET_NET_DEV_CFG80211_WIRELESS(netdev);
791 request->n_ssids = params->ssidCount;
792 if (WifiScanSetChannel(GET_NET_DEV_CFG80211_WIRELESS(netdev)->wiphy, params, request)) {
793 HDF_LOGE("%s: set channel failed!", __func__);
794 return HDF_FAILURE;
795 }
796 if (WifiScanSetSsid(params, request)) {
797 HDF_LOGE("%s: set ssid failed!", __func__);
798 return HDF_FAILURE;
799 }
800 if (WifiScanSetUserIe(params, request)) {
801 HDF_LOGE("%s: set user ie failed!", __func__);
802 return HDF_FAILURE;
803 }
804 memset_s(request->bssid, sizeof(request->bssid), 0xff, sizeof(request->bssid));
805 return HDF_SUCCESS;
806 }
807
WifiScanFree(struct cfg80211_scan_request ** request)808 void WifiScanFree(struct cfg80211_scan_request **request)
809 {
810 HDF_LOGI("%s: enter... !", __func__);
811
812 if (*request != NULL) {
813 if ((*request)->ie != NULL) {
814 OsalMemFree((void *)(*request)->ie);
815 (*request)->ie = NULL;
816 }
817 if ((*request)->ssids != NULL) {
818 OsalMemFree((void *)(*request)->ssids);
819 (*request)->ssids = NULL;
820 }
821 OsalMemFree((void *)*request);
822 *request = NULL;
823 }
824 }
825
HdfStartScanEntry(NetDevice * hhnetDev,struct WlanScanRequest * scanParam)826 static int32_t HdfStartScanEntry(NetDevice *hhnetDev, struct WlanScanRequest *scanParam)
827 {
828 int32_t ret = 0;
829 struct net_device *ndev = NULL;
830 struct wiphy *wiphy = NULL;
831 NetDevice *hnetdev = hhnetDev;
832 int32_t channelTotal;
833 struct NetDevice *netDev = NULL;
834 struct cfg80211_scan_request *request = NULL;
835
836 netDev = get_real_netdev(hhnetDev);
837 ndev = GetLinuxInfByNetDevice(netDev);
838 wiphy = get_linux_wiphy_ndev(ndev);
839 channelTotal = ieee80211_get_num_supported_channels(wiphy);
840 g_scan_event_ifidx = get_scan_ifidx(hnetdev->name);
841
842 request =
843 (struct cfg80211_scan_request *)OsalMemCalloc(
844 sizeof(struct cfg80211_scan_request) + (PTR_IEEE80211_CHANNEL_SIZE) * channelTotal);
845
846 HDF_LOGI("%s: enter hdfStartScan %s, channelTotal: %d, for %u", __func__, ndev->name,
847 channelTotal, (PTR_IEEE80211_CHANNEL_SIZE));
848
849 if (request == NULL) {
850 return HDF_FAILURE;
851 }
852 if (WifiScanSetRequest(netDev, scanParam, request) != HDF_SUCCESS) {
853 WifiScanFree(&request);
854 return HDF_FAILURE;
855 }
856 if (g_scan_event_ifidx == HDF_INF_P2P0 && g_hdf_infmap[HDF_INF_P2P0].wdev) {
857 request->wdev = g_hdf_infmap[HDF_INF_P2P0].wdev;
858 }
859
860 HDF_LOGI("%s: enter cfg80211_scan, n_ssids=%d !", __func__, request->n_ssids);
861 ret = wl_cfg80211_ops.scan(wiphy, request);
862 HDF_LOGI("%s: left cfg80211_scan %d!", __func__, ret);
863
864 if (ret != HDF_SUCCESS) {
865 WifiScanFree(&request);
866 }
867
868 return ret;
869 }
870
HdfStartScan(NetDevice * hhnetDev,struct WlanScanRequest * scanParam)871 int32_t HdfStartScan(NetDevice *hhnetDev, struct WlanScanRequest *scanParam)
872 {
873 int32_t ret = 0;
874 mutex_lock(&bdh6_reset_driver_lock);
875 rtnl_lock();
876 ret = HdfStartScanEntry(hhnetDev, scanParam);
877 rtnl_unlock();
878 mutex_unlock(&bdh6_reset_driver_lock);
879 return ret;
880 }
881
882
HdfAbortScan(NetDevice * hnetDev)883 int32_t HdfAbortScan(NetDevice *hnetDev)
884 {
885 struct net_device *ndev = NULL;
886 struct wireless_dev *wdev = NULL;
887 struct wiphy *wiphy = NULL;
888 struct NetDevice *netDev = NULL;
889 g_scan_event_ifidx = get_scan_ifidx(hnetDev->name);
890 netDev = get_real_netdev(hnetDev);
891 if (netDev == NULL) {
892 HDF_LOGE("%s:NULL ptr!", __func__);
893 return HDF_FAILURE;
894 }
895
896 HDF_LOGI("%s: enter", __func__);
897 ndev = GetLinuxInfByNetDevice(netDev);
898 wiphy = get_linux_wiphy_ndev(ndev);
899 if (ndev == NULL) {
900 HDF_LOGE("%s:NULL ptr!", __func__);
901 return HDF_FAILURE;
902 }
903 wdev = ndev->ieee80211_ptr;
904 if (!wdev || !wdev->wiphy) {
905 return HDF_FAILURE;
906 }
907 rtnl_lock();
908 wl_cfg80211_abort_scan(wiphy, wdev);
909 rtnl_unlock();
910 return HDF_SUCCESS;
911 }
912
WalGetChannel(struct wiphy * wiphy,int32_t freq)913 struct ieee80211_channel *WalGetChannel(struct wiphy *wiphy, int32_t freq)
914 {
915 int32_t loop;
916
917 enum Ieee80211Band band = IEEE80211_BAND_2GHZ;
918 struct ieee80211_supported_band *currentBand = NULL;
919
920 if (wiphy == NULL) {
921 HDF_LOGE("%s: capality is NULL!", __func__);
922 return NULL;
923 }
924
925 for (band = (enum Ieee80211Band)0; band < IEEE80211_NUM_BANDS; band++) {
926 currentBand = wiphy->bands[band];
927 if (currentBand == NULL) {
928 continue;
929 }
930
931 for (loop = 0; loop < currentBand->n_channels; loop++) {
932 if (currentBand->channels[loop].center_freq == freq) {
933 return ¤tBand->channels[loop];
934 }
935 }
936 }
937
938 return NULL;
939 }
940
941 #define BD0 0
942 #define BD1 1
943 #define BD2 2
944 #define BD3 3
945 #define BD4 4
946 #define BD5 5
947
FillCfg80211ConnectParams(const WlanConnectParams * param,struct cfg80211_connect_params * cfg80211_params)948 static void FillCfg80211ConnectParams(const WlanConnectParams *param, struct cfg80211_connect_params *cfg80211_params)
949 {
950 cfg80211_params->bssid = param->bssid;
951 cfg80211_params->ssid = param->ssid;
952 cfg80211_params->ie = param->ie;
953 cfg80211_params->ssid_len = param->ssidLen;
954 cfg80211_params->ie_len = param->ieLen;
955
956 cfg80211_params->crypto.wpa_versions = param->crypto.wpaVersions;
957 cfg80211_params->crypto.cipher_group = param->crypto.cipherGroup;
958 cfg80211_params->crypto.n_ciphers_pairwise = param->crypto.n_ciphersPairwise;
959
960 memcpy_s(cfg80211_params->crypto.ciphers_pairwise,
961 NL80211_MAX_NR_CIPHER_SUITES*sizeof(cfg80211_params->crypto.ciphers_pairwise[0]),
962 param->crypto.ciphersPairwise, NL80211_MAX_NR_CIPHER_SUITES*sizeof(param->crypto.ciphersPairwise[0]));
963
964 memcpy_s(cfg80211_params->crypto.akm_suites,
965 NL80211_MAX_NR_AKM_SUITES*sizeof(cfg80211_params->crypto.akm_suites[0]), param->crypto.akmSuites,
966 NL80211_MAX_NR_AKM_SUITES*sizeof(param->crypto.akmSuites[0]));
967
968 cfg80211_params->crypto.n_akm_suites = param->crypto.n_akmSuites;
969
970 if (param->crypto.controlPort) {
971 cfg80211_params->crypto.control_port = true;
972 } else {
973 cfg80211_params->crypto.control_port = false;
974 }
975
976 cfg80211_params->crypto.control_port_ethertype = param->crypto.controlPortEthertype;
977 cfg80211_params->crypto.control_port_no_encrypt = param->crypto.controlPortNoEncrypt;
978
979 cfg80211_params->key = param->key;
980 cfg80211_params->auth_type = (unsigned char)param->authType;
981 cfg80211_params->privacy = param->privacy;
982 cfg80211_params->key_len = param->keyLen;
983 cfg80211_params->key_idx = param->keyIdx;
984 cfg80211_params->mfp = (unsigned char)param->mfp;
985 }
986
HdfConnectEntry(NetDevice * hnetDev,WlanConnectParams * param)987 static int32_t HdfConnectEntry(NetDevice *hnetDev, WlanConnectParams *param)
988 {
989 int32_t ret = 0;
990 struct net_device *ndev = NULL;
991 struct wiphy *wiphy = NULL;
992 struct NetDevice *netDev = NULL;
993 struct cfg80211_connect_params cfg80211_params = { 0 };
994 g_conn_event_ifidx = get_scan_ifidx(hnetDev->name);
995 netDev = get_real_netdev(hnetDev);
996 if (netDev == NULL || param == NULL) {
997 HDF_LOGE("%s:NULL ptr!", __func__);
998 return HDF_FAILURE;
999 }
1000 ndev = GetLinuxInfByNetDevice(netDev);
1001 if (ndev == NULL) {
1002 HDF_LOGE("%s:NULL ptr!", __func__);
1003 return HDF_FAILURE;
1004 }
1005
1006 wiphy = get_linux_wiphy_ndev(ndev);
1007 if (!wiphy) {
1008 HDF_LOGE("%s: wiphy is NULL", __func__);
1009 return -1;
1010 }
1011
1012 if (param->centerFreq != WLAN_FREQ_NOT_SPECFIED) {
1013 cfg80211_params.channel = WalGetChannel(wiphy, param->centerFreq);
1014 if ((cfg80211_params.channel == NULL) || (cfg80211_params.channel->flags & WIFI_CHAN_DISABLED)) {
1015 HDF_LOGE("%s:illegal channel.flags=%u", __func__,
1016 (cfg80211_params.channel == NULL) ? 0 : cfg80211_params.channel->flags);
1017 return HDF_FAILURE;
1018 }
1019 }
1020 FillCfg80211ConnectParams(param, &cfg80211_params);
1021
1022 HDF_LOGI("%s: %s connect ssid: %s", __func__, netDev->name, cfg80211_params.ssid);
1023 HDF_LOGI("%s: cfg80211_params auth_type:%d--channelId:%d--centerFreq:%d--Mac:%02x:%02x:%02x:%02x:%02x:%02x",
1024 __func__, cfg80211_params.auth_type, cfg80211_params.channel->band, param->centerFreq,
1025 cfg80211_params.bssid[BD0], cfg80211_params.bssid[BD1], cfg80211_params.bssid[BD2],
1026 cfg80211_params.bssid[BD3], cfg80211_params.bssid[BD4], cfg80211_params.bssid[BD5]);
1027
1028 bdh6_hdf_vxx_lock(ndev->ieee80211_ptr, 0);
1029 ret = wl_cfg80211_ops.connect(wiphy, ndev, &cfg80211_params);
1030 bdh6_hdf_vxx_unlock(ndev->ieee80211_ptr, 0);
1031 if (ret < 0) {
1032 HDF_LOGE("%s: connect failed!\n", __func__);
1033 }
1034 return ret;
1035 }
1036
HdfConnect(NetDevice * hnetDev,WlanConnectParams * param)1037 int32_t HdfConnect(NetDevice *hnetDev, WlanConnectParams *param)
1038 {
1039 int32_t ret = 0;
1040 mutex_lock(&bdh6_reset_driver_lock);
1041 rtnl_lock();
1042 ret = HdfConnectEntry(hnetDev, param);
1043 rtnl_unlock();
1044 mutex_unlock(&bdh6_reset_driver_lock);
1045 return ret;
1046 }
1047
HdfDisconnect(NetDevice * hnetDev,uint16_t reasonCode)1048 int32_t HdfDisconnect(NetDevice *hnetDev, uint16_t reasonCode)
1049 {
1050 int32_t ret = 0;
1051 struct net_device *ndev = NULL;
1052 struct wiphy *wiphy = NULL;
1053 struct NetDevice *netDev = NULL;
1054 g_conn_event_ifidx = get_scan_ifidx(hnetDev->name);
1055 netDev = get_real_netdev(hnetDev);
1056
1057 HDF_LOGI("%s: start...", __func__);
1058 if (netDev == NULL) {
1059 HDF_LOGE("%s:NULL ptr!", __func__);
1060 return HDF_FAILURE;
1061 }
1062 ndev = GetLinuxInfByNetDevice(netDev);
1063 if (ndev == NULL) {
1064 HDF_LOGE("%s:NULL ptr!", __func__);
1065 return HDF_FAILURE;
1066 }
1067
1068 wiphy = get_linux_wiphy_ndev(ndev);
1069 if (!wiphy) {
1070 HDF_LOGE("%s: wiphy is NULL", __func__);
1071 return -1;
1072 }
1073
1074 rtnl_lock();
1075 bdh6_hdf_vxx_lock(ndev->ieee80211_ptr, 0);
1076 ret = wl_cfg80211_ops.disconnect(wiphy, ndev, reasonCode);
1077 bdh6_hdf_vxx_unlock(ndev->ieee80211_ptr, 0);
1078 rtnl_unlock();
1079 return ret;
1080 }
1081
HdfSetScanningMacAddress(NetDevice * hnetDev,unsigned char * mac,uint32_t len)1082 int32_t HdfSetScanningMacAddress(NetDevice *hnetDev, unsigned char *mac, uint32_t len)
1083 {
1084 struct NetDevice *netDev = NULL;
1085 netDev = get_real_netdev(hnetDev);
1086 (void)mac;
1087 (void)len;
1088 return HDF_ERR_NOT_SUPPORT;
1089 }
1090
1091 static struct HdfMac80211STAOps g_bdh6_staOps = {
1092 .Connect = HdfConnect,
1093 .Disconnect = HdfDisconnect,
1094 .StartScan = HdfStartScan,
1095 .AbortScan = HdfAbortScan,
1096 .SetScanningMacAddress = HdfSetScanningMacAddress,
1097 };
1098
1099 /*--------------------------------------------------------------------------------------------------*/
1100 /* public */
1101 /*--------------------------------------------------------------------------------------------------*/
1102 #define MAX_NUM_OF_ASSOCIATED_DEV 64
1103 #define WLC_GET_ASSOCLIST 159
1104 #define ETH_MAC_LEN 6
1105
1106 static struct cfg80211_ap_settings g_ap_setting_info;
1107
ChangDelSta(struct net_device * dev,const uint8_t * macAddr,uint8_t addrLen)1108 int ChangDelSta(struct net_device *dev, const uint8_t *macAddr, uint8_t addrLen)
1109 {
1110 int ret;
1111 struct NetDevice *netDev = GetHdfNetDeviceByLinuxInf(dev);
1112 ret = HdfWifiEventDelSta(netDev, macAddr, ETH_MAC_LEN);
1113 return ret;
1114 }
1115
ChangNewSta(struct net_device * dev,const uint8_t * macAddr,uint8_t addrLen,const struct station_info * info)1116 int ChangNewSta(struct net_device *dev, const uint8_t *macAddr, uint8_t addrLen,
1117 const struct station_info *info)
1118 {
1119 int ret;
1120 struct NetDevice *netDev = NULL;
1121 struct StationInfo Info = {0};
1122
1123 Info.assocReqIes = info->assoc_req_ies;
1124 Info.assocReqIesLen = info->assoc_req_ies_len;
1125 netDev = GetHdfNetDeviceByLinuxInf(dev);
1126 ret = HdfWifiEventNewSta(netDev, macAddr, addrLen, &Info);
1127 return ret;
1128 }
1129
wl_get_all_sta(struct net_device * ndev,uint32_t * num)1130 int32_t wl_get_all_sta(struct net_device *ndev, uint32_t *num)
1131 {
1132 int ret = 0;
1133 char mac_buf[MAX_NUM_OF_ASSOCIATED_DEV *
1134 sizeof(struct ether_addr) + sizeof(uint)] = {0};
1135 struct maclist *assoc_maclist = (struct maclist *)mac_buf;
1136 assoc_maclist->count = MAX_NUM_OF_ASSOCIATED_DEV;
1137 ret = wldev_ioctl_get(ndev, WLC_GET_ASSOCLIST,
1138 (void *)assoc_maclist, sizeof(mac_buf));
1139 *num = assoc_maclist->count;
1140 return 0;
1141 }
1142 #define MAX_NUM_OF_ASSOCLIST 64
1143
1144 #define RATE_OFFSET 2
1145 #define CAP_OFFSET 3
1146
bdh6_nl80211_check_ap_rate_selectors(struct cfg80211_ap_settings * params,const u8 * rates)1147 static void bdh6_nl80211_check_ap_rate_selectors(struct cfg80211_ap_settings *params,
1148 const u8 *rates)
1149 {
1150 int i;
1151 if (!rates)
1152 return;
1153
1154 for (i = 0; i < rates[1]; i++) {
1155 if (rates[RATE_OFFSET + i] == BSS_MEMBERSHIP_SELECTOR_HT_PHY)
1156 params->ht_required = true;
1157 if (rates[RATE_OFFSET + i] == BSS_MEMBERSHIP_SELECTOR_VHT_PHY)
1158 params->vht_required = true;
1159 #if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 10, 0))
1160 if (rates[RATE_OFFSET + i] == BSS_MEMBERSHIP_SELECTOR_HE_PHY)
1161 params->he_required = true;
1162 #endif
1163 }
1164 }
1165
bdh6_nl80211_calculate_ap_params(struct cfg80211_ap_settings * params)1166 void bdh6_nl80211_calculate_ap_params(struct cfg80211_ap_settings *params)
1167 {
1168 const struct cfg80211_beacon_data *bcn = ¶ms->beacon;
1169 size_t ies_len = bcn->tail_len;
1170 const u8 *ies = bcn->tail;
1171 const u8 *rates;
1172 const u8 *cap;
1173
1174 rates = cfg80211_find_ie(WLAN_EID_SUPP_RATES, ies, ies_len);
1175 HDF_LOGI("find beacon tail WLAN_EID_SUPP_RATES=%p", rates);
1176 bdh6_nl80211_check_ap_rate_selectors(params, rates);
1177
1178 rates = cfg80211_find_ie(WLAN_EID_EXT_SUPP_RATES, ies, ies_len);
1179 HDF_LOGI("find beacon tail WLAN_EID_EXT_SUPP_RATES=%p", rates);
1180 bdh6_nl80211_check_ap_rate_selectors(params, rates);
1181
1182 cap = cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies, ies_len);
1183 HDF_LOGI("find beacon tail WLAN_EID_HT_CAPABILITY=%p", cap);
1184 if (cap && cap[1] >= sizeof(*params->ht_cap))
1185 params->ht_cap = (void *)(cap + RATE_OFFSET);
1186 cap = cfg80211_find_ie(WLAN_EID_VHT_CAPABILITY, ies, ies_len);
1187 HDF_LOGI("find beacon tail WLAN_EID_VHT_CAPABILITY=%p", cap);
1188 if (cap && cap[1] >= sizeof(*params->vht_cap))
1189 params->vht_cap = (void *)(cap + RATE_OFFSET);
1190 #if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 10, 0))
1191 cap = cfg80211_find_ext_ie(WLAN_EID_EXT_HE_CAPABILITY, ies, ies_len);
1192 HDF_LOGI("find beacon tail WLAN_EID_EXT_HE_CAPABILITY=%p", cap);
1193 if (cap && cap[1] >= sizeof(*params->he_cap) + 1) {
1194 params->he_cap = (void *)(cap + CAP_OFFSET);
1195 }
1196 cap = cfg80211_find_ext_ie(WLAN_EID_EXT_HE_OPERATION, ies, ies_len);
1197 HDF_LOGI("find beacon tail WLAN_EID_EXT_HE_OPERATION=%p", cap);
1198 if (cap && cap[1] >= sizeof(*params->he_oper) + 1) {
1199 params->he_oper = (void *)(cap + CAP_OFFSET);
1200 }
1201 #endif
1202 }
1203
1204
1205 static struct ieee80211_channel g_ap_ieee80211_channel;
1206 static u8 g_ap_ssid[IEEE80211_MAX_SSID_LEN];
1207 static int start_ap_flag = 0;
1208
SetupWireLessDev(struct net_device * netDev,struct WlanAPConf * apSettings)1209 static int32_t SetupWireLessDev(struct net_device *netDev, struct WlanAPConf *apSettings)
1210 {
1211 struct wireless_dev *wdev = NULL;
1212 struct ieee80211_channel *chan = NULL;
1213
1214 wdev = netDev->ieee80211_ptr;
1215 if (wdev == NULL) {
1216 HDF_LOGE("%s: wdev is null", __func__);
1217 return -1;
1218 }
1219 HDF_LOGI("%s:%p, chan=%p, channel=%u, centfreq1=%u, centfreq2=%u, band=%u, width=%u", __func__,
1220 wdev, wdev->preset_chandef.chan,
1221 apSettings->channel, apSettings->centerFreq1, apSettings->centerFreq2, apSettings->band, apSettings->width);
1222
1223 wdev->iftype = NL80211_IFTYPE_AP;
1224 wdev->preset_chandef.width = (enum nl80211_channel_type)apSettings->width;
1225 wdev->preset_chandef.center_freq1 = apSettings->centerFreq1;
1226 wdev->preset_chandef.center_freq2 = apSettings->centerFreq2;
1227
1228 chan = ieee80211_get_channel(wdev->wiphy, apSettings->centerFreq1);
1229 if (chan) {
1230 wdev->preset_chandef.chan = chan;
1231 HDF_LOGI("%s: use valid channel %u", __func__, chan->center_freq);
1232 } else if (wdev->preset_chandef.chan == NULL) {
1233 wdev->preset_chandef.chan = &g_ap_ieee80211_channel;
1234 wdev->preset_chandef.chan->hw_value = apSettings->channel;
1235 wdev->preset_chandef.chan->band = apSettings->band; // IEEE80211_BAND_2GHZ;
1236 wdev->preset_chandef.chan->center_freq = apSettings->centerFreq1;
1237 HDF_LOGI("%s: fill new channel %u", __func__, wdev->preset_chandef.chan->center_freq);
1238 }
1239
1240 g_ap_setting_info.chandef = wdev->preset_chandef;
1241
1242 return HDF_SUCCESS;
1243 }
1244
1245 /*--------------------------------------------------------------------------------------------------*/
1246 /* HdfMac80211APOps */
1247 /*--------------------------------------------------------------------------------------------------*/
WalConfigApEntry(NetDevice * hnetDev,struct WlanAPConf * apConf)1248 static int32_t WalConfigApEntry(NetDevice *hnetDev, struct WlanAPConf *apConf)
1249 {
1250 int32_t ret = 0;
1251 struct net_device *netdev = NULL;
1252 struct NetDevice *netDev = NULL;
1253 struct wiphy *wiphy = NULL;
1254 netDev = get_real_netdev(hnetDev);
1255 netdev = GetLinuxInfByNetDevice(netDev);
1256 if (!netdev) {
1257 HDF_LOGE("%s: net_device is NULL", __func__);
1258 return -1;
1259 }
1260
1261 wiphy = get_linux_wiphy_ndev(netdev);
1262 if (!wiphy) {
1263 HDF_LOGE("%s: wiphy is NULL", __func__);
1264 return -1;
1265 }
1266
1267 memset_s(&g_ap_setting_info, sizeof(g_ap_setting_info), 0, sizeof(g_ap_setting_info));
1268 ret = SetupWireLessDev(netdev, apConf);
1269 if (ret != 0) {
1270 HDF_LOGE("%s: set up wireless device failed!", __func__);
1271 return HDF_FAILURE;
1272 }
1273
1274 HDF_LOGI("%s: before iftype = %d!", __func__, netdev->ieee80211_ptr->iftype);
1275 netdev->ieee80211_ptr->iftype = NL80211_IFTYPE_AP;
1276 HDF_LOGI("%s: after iftype = %d!", __func__, netdev->ieee80211_ptr->iftype);
1277
1278 g_ap_setting_info.ssid_len = apConf->ssidConf.ssidLen;
1279 memcpy_s(&g_ap_ssid[0], IEEE80211_MAX_SSID_LEN, &apConf->ssidConf.ssid[0], apConf->ssidConf.ssidLen);
1280 g_ap_setting_info.ssid = &g_ap_ssid[0];
1281 ret = (int32_t)wl_cfg80211_ops.change_virtual_intf(wiphy, netdev,
1282 (enum nl80211_iftype)netdev->ieee80211_ptr->iftype, NULL);
1283 if (ret < 0) {
1284 HDF_LOGE("%s: set mode failed!", __func__);
1285 }
1286
1287 return HDF_SUCCESS;
1288 }
1289
WalConfigAp(NetDevice * hnetDev,struct WlanAPConf * apConf)1290 int32_t WalConfigAp(NetDevice *hnetDev, struct WlanAPConf *apConf)
1291 {
1292 int32_t ret = 0;
1293 rtnl_lock();
1294 ret = WalConfigApEntry(hnetDev, apConf);
1295 rtnl_unlock();
1296 return ret;
1297 }
1298
InitCfg80211BeaconDataInfo(struct cfg80211_beacon_data * pInfo,const struct WlanBeaconConf * param)1299 static void InitCfg80211BeaconDataInfo(struct cfg80211_beacon_data *pInfo, const struct WlanBeaconConf *param)
1300 {
1301 memset_s(pInfo, sizeof(struct cfg80211_beacon_data), 0x00, sizeof(struct cfg80211_beacon_data));
1302 pInfo->head = param->headIEs;
1303 pInfo->head_len = (size_t)param->headIEsLength;
1304 pInfo->tail = param->tailIEs;
1305 pInfo->tail_len = (size_t)param->tailIEsLength;
1306
1307 pInfo->beacon_ies = NULL;
1308 pInfo->proberesp_ies = NULL;
1309 pInfo->assocresp_ies = NULL;
1310 pInfo->probe_resp = NULL;
1311 pInfo->beacon_ies_len = 0X00;
1312 pInfo->proberesp_ies_len = 0X00;
1313 pInfo->assocresp_ies_len = 0X00;
1314 pInfo->probe_resp_len = 0X00;
1315 }
1316
InitCfg80211ApSettingInfo(const struct WlanBeaconConf * param)1317 static void InitCfg80211ApSettingInfo(const struct WlanBeaconConf *param)
1318 {
1319 if (g_ap_setting_info.beacon.head != NULL) {
1320 OsalMemFree((uint8_t *)g_ap_setting_info.beacon.head);
1321 g_ap_setting_info.beacon.head = NULL;
1322 }
1323 if (g_ap_setting_info.beacon.tail != NULL) {
1324 OsalMemFree((uint8_t *)g_ap_setting_info.beacon.tail);
1325 g_ap_setting_info.beacon.tail = NULL;
1326 }
1327
1328 if (param->headIEs && param->headIEsLength > 0) {
1329 g_ap_setting_info.beacon.head = OsalMemCalloc(param->headIEsLength);
1330 memcpy_s((uint8_t *)g_ap_setting_info.beacon.head, param->headIEsLength, param->headIEs, param->headIEsLength);
1331 g_ap_setting_info.beacon.head_len = param->headIEsLength;
1332 }
1333
1334 if (param->tailIEs && param->tailIEsLength > 0) {
1335 g_ap_setting_info.beacon.tail = OsalMemCalloc(param->tailIEsLength);
1336 memcpy_s((uint8_t *)g_ap_setting_info.beacon.tail, param->tailIEsLength, param->tailIEs, param->tailIEsLength);
1337 g_ap_setting_info.beacon.tail_len = param->tailIEsLength;
1338 }
1339
1340 /* add beacon data for start ap */
1341 g_ap_setting_info.dtim_period = param->DTIMPeriod;
1342 g_ap_setting_info.hidden_ssid = param->hiddenSSID;
1343 g_ap_setting_info.beacon_interval = param->interval;
1344 HDF_LOGI("%s: dtim_period:%d---hidden_ssid:%d---beacon_interval:%d!",
1345 __func__, g_ap_setting_info.dtim_period, g_ap_setting_info.hidden_ssid, g_ap_setting_info.beacon_interval);
1346
1347 g_ap_setting_info.beacon.beacon_ies = NULL;
1348 g_ap_setting_info.beacon.proberesp_ies = NULL;
1349 g_ap_setting_info.beacon.assocresp_ies = NULL;
1350 g_ap_setting_info.beacon.probe_resp = NULL;
1351 g_ap_setting_info.beacon.beacon_ies_len = 0X00;
1352 g_ap_setting_info.beacon.proberesp_ies_len = 0X00;
1353 g_ap_setting_info.beacon.assocresp_ies_len = 0X00;
1354 g_ap_setting_info.beacon.probe_resp_len = 0X00;
1355
1356 bdh6_nl80211_calculate_ap_params(&g_ap_setting_info);
1357 }
1358
WalStartAp(NetDevice * hnetDev)1359 int32_t WalStartAp(NetDevice *hnetDev)
1360 {
1361 int32_t ret = 0;
1362 struct net_device *netdev = NULL;
1363 struct wiphy *wiphy = NULL;
1364 struct wireless_dev *wdev = NULL;
1365 struct NetDevice *netDev = NULL;
1366 netDev = get_real_netdev(hnetDev);
1367
1368 if (start_ap_flag) {
1369 WalStopAp(netDev);
1370 HDF_LOGE("do not start up, because start_ap_flag=%d", start_ap_flag);
1371 }
1372
1373 netdev = GetLinuxInfByNetDevice(netDev);
1374 if (!netdev) {
1375 HDF_LOGE("%s: net_device is NULL", __func__);
1376 return -1;
1377 }
1378
1379 wiphy = get_linux_wiphy_ndev(netdev);
1380 if (!wiphy) {
1381 HDF_LOGE("%s: wiphy is NULL", __func__);
1382 return -1;
1383 }
1384 rtnl_lock();
1385 bdh6_hdf_vxx_lock(netdev->ieee80211_ptr, 0);
1386 wdev = netdev->ieee80211_ptr;
1387 HDF_LOGI("%s: start...", __func__);
1388 ret = (int32_t)wl_cfg80211_ops.start_ap(wiphy, netdev, &g_ap_setting_info);
1389 if (ret < 0) {
1390 HDF_LOGE("%s: start_ap failed!", __func__);
1391 } else {
1392 wdev->preset_chandef = g_ap_setting_info.chandef;
1393 wdev->beacon_interval = g_ap_setting_info.beacon_interval;
1394 wdev->chandef = g_ap_setting_info.chandef;
1395 wdev->ssid_len = g_ap_setting_info.ssid_len;
1396 memcpy_s(wdev->ssid, wdev->ssid_len, g_ap_setting_info.ssid, wdev->ssid_len);
1397 start_ap_flag = 1;
1398 }
1399 bdh6_hdf_vxx_unlock(netdev->ieee80211_ptr, 0);
1400 rtnl_unlock();
1401 return ret;
1402 }
1403
WalChangeBeacon(NetDevice * hnetDev,struct WlanBeaconConf * param)1404 int32_t WalChangeBeacon(NetDevice *hnetDev, struct WlanBeaconConf *param)
1405 {
1406 int32_t ret = 0;
1407 struct cfg80211_beacon_data info;
1408 struct net_device *netdev = NULL;
1409 struct wiphy *wiphy = NULL;
1410 NetDevice *netDev = NULL;
1411 netDev = get_real_netdev(hnetDev);
1412 netdev = GetLinuxInfByNetDevice(netDev);
1413 if (!netdev) {
1414 HDF_LOGE("%s: net_device is NULL", __func__);
1415 return -1;
1416 }
1417
1418 wiphy = get_linux_wiphy_ndev(netdev);
1419 if (!wiphy) {
1420 HDF_LOGE("%s: wiphy is NULL", __func__);
1421 return -1;
1422 }
1423
1424 HDF_LOGI("%s: start...", __func__);
1425 if ((int)param->interval <= 0) {
1426 HDF_LOGE("%s: invalid beacon interval=%d, %d,%d", __func__,
1427 (int)param->interval, param->DTIMPeriod, (int)param->hiddenSSID);
1428 return 0;
1429 }
1430
1431 InitCfg80211BeaconDataInfo(&info, param);
1432 InitCfg80211ApSettingInfo(param);
1433
1434 HDF_LOGI("%s: headIEsLen:%d---tailIEsLen:%d!", __func__, param->headIEsLength, param->tailIEsLength);
1435 ret = WalStartAp(netDev);
1436 HDF_LOGI("call start_ap ret=%d", ret);
1437
1438 rtnl_lock();
1439 bdh6_hdf_vxx_lock(netdev->ieee80211_ptr, 0);
1440 ret = (int32_t)wl_cfg80211_ops.change_beacon(wiphy, netdev, &info);
1441 bdh6_hdf_vxx_unlock(netdev->ieee80211_ptr, 0);
1442 rtnl_unlock();
1443 if (ret < 0) {
1444 HDF_LOGE("%s: change_beacon failed!", __func__);
1445 }
1446
1447 return HDF_SUCCESS;
1448 }
1449
WalSetCountryCode(NetDevice * hnetDev,const char * code,uint32_t len)1450 int32_t WalSetCountryCode(NetDevice *hnetDev, const char *code, uint32_t len)
1451 {
1452 int32_t ret = 0;
1453 struct net_device *netdev = NULL;
1454 struct NetDevice *netDev = NULL;
1455 netDev = get_real_netdev(hnetDev);
1456 netdev = GetLinuxInfByNetDevice(netDev);
1457 if (!netdev) {
1458 HDF_LOGE("%s: net_device is NULL", __func__);
1459 return -1;
1460 }
1461
1462 rtnl_lock();
1463 ret = (int32_t)wl_cfg80211_set_country_code(netdev, (char*)code, false, true, len);
1464 rtnl_unlock();
1465 if (ret < 0) {
1466 HDF_LOGE("%s: set_country_code failed!", __func__);
1467 }
1468 return ret;
1469 }
1470
WalStopAp(NetDevice * hnetDev)1471 int32_t WalStopAp(NetDevice *hnetDev)
1472 {
1473 int32_t ret = 0;
1474 struct net_device *netdev = NULL;
1475 struct NetDevice *netDev = NULL;
1476 struct wiphy *wiphy = NULL;
1477 netDev = get_real_netdev(hnetDev);
1478 netdev = GetLinuxInfByNetDevice(netDev);
1479 if (!netdev) {
1480 HDF_LOGE("%s: net_device is NULL", __func__);
1481 return -1;
1482 }
1483
1484 wiphy = get_linux_wiphy_ndev(netdev);
1485 if (!wiphy) {
1486 HDF_LOGE("%s: wiphy is NULL", __func__);
1487 return -1;
1488 }
1489
1490 HDF_LOGI("%s: start...", __func__);
1491 rtnl_lock();
1492 bdh6_hdf_vxx_lock(netdev->ieee80211_ptr, 0);
1493 ret = (int32_t)wl_cfg80211_ops.stop_ap(wiphy, netdev);
1494 bdh6_hdf_vxx_unlock(netdev->ieee80211_ptr, 0);
1495 rtnl_unlock();
1496 return ret;
1497 }
1498
WalDelStation(NetDevice * hnetDev,const uint8_t * macAddr)1499 int32_t WalDelStation(NetDevice *hnetDev, const uint8_t *macAddr)
1500 {
1501 int32_t ret = 0;
1502 struct net_device *netdev = NULL;
1503 struct wiphy *wiphy = NULL;
1504 struct NetDevice *netDev = NULL;
1505 struct station_del_parameters del_param = {macAddr, 10, 0};
1506 netDev = get_real_netdev(hnetDev);
1507 netdev = GetLinuxInfByNetDevice(netDev);
1508 if (!netdev) {
1509 HDF_LOGE("%s: net_device is NULL", __func__);
1510 return -1;
1511 }
1512
1513 wiphy = get_linux_wiphy_ndev(netdev);
1514 if (!wiphy) {
1515 HDF_LOGE("%s: wiphy is NULL", __func__);
1516 return -1;
1517 }
1518
1519 (void)macAddr;
1520 HDF_LOGI("%s: start...", __func__);
1521
1522 ret = (int32_t)wl_cfg80211_ops.del_station(wiphy, netdev, &del_param);
1523 if (ret < 0) {
1524 HDF_LOGE("%s: del_station failed!", __func__);
1525 }
1526 return ret;
1527 }
1528
WalGetAssociatedStasCount(NetDevice * hnetDev,uint32_t * num)1529 int32_t WalGetAssociatedStasCount(NetDevice *hnetDev, uint32_t *num)
1530 {
1531 int32_t ret = 0;
1532 struct net_device *netdev = NULL;
1533 struct NetDevice *netDev = NULL;
1534 netDev = get_real_netdev(hnetDev);
1535 netdev = GetLinuxInfByNetDevice(netDev);
1536 if (!netdev) {
1537 HDF_LOGE("%s: net_device is NULL", __func__);
1538 return -1;
1539 }
1540
1541 rtnl_lock();
1542 ret = (int32_t)wl_get_all_sta(netdev, num);
1543 rtnl_unlock();
1544 if (ret < 0) {
1545 HDF_LOGE("%s: wl_get_all_sta failed!", __func__);
1546 }
1547 return ret;
1548 }
1549
WalGetAssociatedStasInfo(NetDevice * hnetDev,WifiStaInfo * staInfo,uint32_t num)1550 int32_t WalGetAssociatedStasInfo(NetDevice *hnetDev, WifiStaInfo *staInfo, uint32_t num)
1551 {
1552 struct net_device *netdev = NULL;
1553 struct NetDevice *netDev = NULL;
1554 int error = 0, i = 0;
1555 char mac_buf[MAX_NUM_OF_ASSOCLIST *sizeof(struct ether_addr) + sizeof(uint)] = {0};
1556 struct maclist *assoc_maclist = (struct maclist *)mac_buf;
1557 netDev = get_real_netdev(hnetDev);
1558 netdev = GetLinuxInfByNetDevice(netDev);
1559 if (!netdev) {
1560 HDF_LOGE("%s: net_device is NULL", __func__);
1561 return -1;
1562 }
1563 HDF_LOGI("%s: start..., num=%u", __func__, num);
1564 if (staInfo == NULL || num == 0) {
1565 HDF_LOGE("%s: invalid parameter staInfo=%p, num=%u", __func__);
1566 return -1;
1567 }
1568
1569 assoc_maclist->count = (MAX_NUM_OF_ASSOCLIST);
1570 rtnl_lock();
1571 error = wldev_ioctl_get(netdev, WLC_GET_ASSOCLIST, (void *)assoc_maclist, sizeof(mac_buf));
1572 rtnl_unlock();
1573 if (error) {
1574 HDF_LOGE("%s: WLC_GET_ASSOCLIST ret=%d", __func__, error);
1575 return -1;
1576 }
1577 if (num > assoc_maclist->count) {
1578 HDF_LOGE("%s: num=%u is larger than assoc_num=%u", __func__, num, assoc_maclist->count);
1579 num = assoc_maclist->count;
1580 }
1581 for (i = 0; i < num; i++) {
1582 memcpy_s(staInfo[i].mac, ETHER_ADDR_LEN, assoc_maclist->ea[i].octet, ETHER_ADDR_LEN);
1583 }
1584
1585 return HDF_SUCCESS;
1586 }
1587
1588 static struct HdfMac80211APOps g_bdh6_apOps = {
1589 .ConfigAp = WalConfigAp,
1590 .StartAp = WalStartAp,
1591 .StopAp = WalStopAp,
1592 .ConfigBeacon = WalChangeBeacon,
1593 .DelStation = WalDelStation,
1594 .SetCountryCode = WalSetCountryCode,
1595 .GetAssociatedStasCount = WalGetAssociatedStasCount,
1596 .GetAssociatedStasInfo = WalGetAssociatedStasInfo
1597 };
1598
1599 enum wl_management_type {
1600 WL_BEACON = 0x1,
1601 WL_PROBE_RESP = 0x2,
1602 WL_ASSOC_RESP = 0x4
1603 };
1604
1605
1606 #define HISI_DRIVER_FLAGS_AP 0x00000040
1607 #define HISI_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE 0x00000400
1608 #define HISI_DRIVER_FLAGS_P2P_CONCURRENT 0x00000200
1609 #define HISI_DRIVER_FLAGS_P2P_CAPABLE 0x00000800
1610
1611 #if defined(WL_CFG80211_P2P_DEV_IF)
ndev_to_cfg(struct net_device * ndev)1612 static inline void *ndev_to_cfg(struct net_device *ndev)
1613 {
1614 return ndev->ieee80211_ptr;
1615 }
1616 #else
ndev_to_cfg(struct net_device * ndev)1617 static inline void *ndev_to_cfg(struct net_device *ndev)
1618 {
1619 return ndev;
1620 }
1621 #endif
1622
1623 s32 wl_cfg80211_set_wps_p2p_ie(
1624 struct net_device *net, char *buf, int len, enum wl_management_type type);
1625
1626
1627 static u64 p2p_cookie = 0;
1628 u32 p2p_remain_freq = 0;
1629 int start_p2p_completed = 0;
1630
WalRemainOnChannel(struct NetDevice * hnetDev,WifiOnChannel * onChannel)1631 int32_t WalRemainOnChannel(struct NetDevice *hnetDev, WifiOnChannel *onChannel)
1632 {
1633 struct net_device *netdev = NULL;
1634 struct wiphy *wiphy = NULL;
1635 bcm_struct_cfgdev *cfgdev = NULL;
1636 struct ieee80211_channel *channel = NULL;
1637 unsigned int duration;
1638 struct NetDevice *netDev = NULL;
1639 int ret = 0;
1640
1641 netDev = get_real_netdev(hnetDev);
1642 netdev = GetLinuxInfByNetDevice(netDev);
1643 if (!netdev) {
1644 HDF_LOGE("%s: net_device is NULL", __func__);
1645 return -1;
1646 }
1647
1648 wiphy = get_linux_wiphy_ndev(netdev);
1649 if (!wiphy) {
1650 HDF_LOGE("%s: wiphy is NULL", __func__);
1651 return -1;
1652 }
1653 HDF_LOGI("%s: ifname=%s, freq=%u, duration=%u", __func__, hnetDev->name, onChannel->freq, onChannel->duration);
1654
1655 channel = OsalMemCalloc(sizeof(struct ieee80211_channel));
1656 cfgdev = ndev_to_cfg(netdev);
1657 channel->center_freq = onChannel->freq;
1658 duration = (unsigned int)onChannel->duration;
1659 p2p_remain_freq = channel->center_freq;
1660
1661 rtnl_lock();
1662 ret = wl_cfg80211_ops.remain_on_channel(wiphy, cfgdev, channel, duration, &p2p_cookie);
1663 rtnl_unlock();
1664 OsalMemFree(channel);
1665 return ret;
1666 }
1667
WalCancelRemainOnChannel(struct NetDevice * hnetDev)1668 int32_t WalCancelRemainOnChannel(struct NetDevice *hnetDev)
1669 {
1670 struct net_device *netdev = NULL;
1671 bcm_struct_cfgdev *cfgdev = NULL;
1672 struct wiphy *wiphy = NULL;
1673 struct NetDevice *netDev = NULL;
1674 int ret = 0;
1675
1676 netDev = get_real_netdev(hnetDev);
1677 netdev = GetLinuxInfByNetDevice(netDev);
1678 wiphy = get_linux_wiphy_ndev(netdev);
1679 if (!wiphy) {
1680 HDF_LOGE("%s: wiphy is NULL", __func__);
1681 return -1;
1682 }
1683
1684 HDF_LOGI("%s: ifname = %s", __func__, hnetDev->name);
1685 if (!netdev) {
1686 HDF_LOGE("%s: net_device is NULL", __func__);
1687 return -1;
1688 }
1689
1690 cfgdev = ndev_to_cfg(netdev);
1691 rtnl_lock();
1692 ret = wl_cfg80211_ops.cancel_remain_on_channel(wiphy, cfgdev, p2p_cookie);
1693 rtnl_unlock();
1694 return ret;
1695 }
1696
WalProbeReqReport(struct NetDevice * netDev,int32_t report)1697 int32_t WalProbeReqReport(struct NetDevice *netDev, int32_t report)
1698 {
1699 (void)report;
1700 HDF_LOGI("%s: ifname = %s, report=%d", __func__, netDev->name, report);
1701 return HDF_SUCCESS;
1702 }
1703
1704 #define M0 0
1705 #define M1 1
1706 #define M2 2
1707 #define M3 3
1708 #define M4 4
1709 #define M5 5
1710
WalAddIf(struct NetDevice * hnetDev,WifiIfAdd * ifAdd)1711 int32_t WalAddIf(struct NetDevice *hnetDev, WifiIfAdd *ifAdd)
1712 {
1713 struct wiphy *wiphy = NULL;
1714 struct wireless_dev *wdev = NULL;
1715 int ret = 0;
1716 struct net_device *p2p_netdev = NULL;
1717 struct NetDevice *p2p_hnetdev = NULL;
1718 struct NetDevice *netDev = NULL;
1719
1720 if (hnetDev == NULL || ifAdd == NULL) {
1721 HDF_LOGE("%s:NULL ptr!", __func__);
1722 return -1;
1723 }
1724
1725 HDF_LOGI("%s: ifname = %s, type=%u", __func__, hnetDev->name, ifAdd->type);
1726 netDev = get_real_netdev(hnetDev);
1727 if (g_hdf_infmap[HDF_INF_P2P1].hnetdev != NULL) {
1728 HDF_LOGE("%s: ifidx=%d was used, failed add if", __func__, HDF_INF_P2P1);
1729 return -1;
1730 }
1731
1732 ret = P2pInitNetdev(netDev, ifAdd, get_dhd_priv_data_size(), HDF_INF_P2P1);
1733 if (ret != 0) {
1734 HDF_LOGE("%s:P2pInitNetdev %s failed", __func__, ifAdd->ifName);
1735 return HDF_FAILURE;
1736 }
1737
1738 wiphy = get_linux_wiphy_hdfdev(netDev);
1739 if (wiphy == NULL) {
1740 HDF_LOGE("%s:get wlan0 wiphy failed", __func__);
1741 return HDF_FAILURE;
1742 }
1743
1744 p2p_hnetdev = get_hdf_netdev(g_hdf_ifidx);
1745 p2p_netdev = get_krn_netdev(g_hdf_ifidx);
1746
1747 wdev = wl_cfg80211_ops.add_virtual_intf(wiphy, p2p_hnetdev->name, NET_NAME_USER, ifAdd->type, NULL);
1748 if (wdev == NULL || wdev == ERR_PTR(-ENODEV)) {
1749 HDF_LOGE("%s:create wdev for %s %d failed", __func__, p2p_hnetdev->name, ifAdd->type);
1750 return HDF_FAILURE;
1751 }
1752 HDF_LOGI("%s:%s wdev->netdev=%p, %p", __func__, p2p_hnetdev->name, wdev->netdev, p2p_netdev);
1753 p2p_hnetdev->ieee80211Ptr = p2p_netdev->ieee80211_ptr;
1754
1755 // update mac addr to NetDevice object
1756 memcpy_s(p2p_hnetdev->macAddr, MAC_ADDR_SIZE, p2p_netdev->dev_addr, p2p_netdev->addr_len);
1757 HDF_LOGI("%s: %s mac: %02x:%02x:%02x:%02x:%02x:%02x", __func__, p2p_hnetdev->name,
1758 p2p_hnetdev->macAddr[M0],
1759 p2p_hnetdev->macAddr[M1],
1760 p2p_hnetdev->macAddr[M2],
1761 p2p_hnetdev->macAddr[M3],
1762 p2p_hnetdev->macAddr[M4],
1763 p2p_hnetdev->macAddr[M5]);
1764 return HDF_SUCCESS;
1765 }
1766
WalRemoveIf(struct NetDevice * hnetDev,WifiIfRemove * ifRemove)1767 int32_t WalRemoveIf(struct NetDevice *hnetDev, WifiIfRemove *ifRemove)
1768 {
1769 int i = HDF_INF_WLAN0;
1770 struct wiphy *wiphy = NULL;
1771 struct wireless_dev *wdev = NULL;
1772 struct NetDevice *p2p_hnetdev = NULL;
1773 int ret = 0;
1774 struct NetDevice *netDev = NULL;
1775 netDev = get_real_netdev(hnetDev);
1776
1777 wiphy = get_linux_wiphy_hdfdev(netDev);
1778 if (wiphy == NULL) {
1779 HDF_LOGE("%s:get wlan0 wiphy failed", __func__);
1780 return HDF_FAILURE;
1781 }
1782
1783 HDF_LOGI("%s: ifname=%s, primary netdev %s, remove ifname=%s", __func__,
1784 hnetDev->name, netDev->name, ifRemove->ifName);
1785 for (; i < HDF_INF_MAX; i ++) {
1786 p2p_hnetdev = g_hdf_infmap[i].hnetdev;
1787 if (p2p_hnetdev == NULL) {
1788 continue;
1789 }
1790
1791 if (strcmp(p2p_hnetdev->name, ifRemove->ifName) == 0) {
1792 // check safely
1793 if (i == HDF_INF_WLAN0) {
1794 HDF_LOGE("%s: don't remove master interface %s", __func__, ifRemove->ifName);
1795 continue;
1796 }
1797 if (i != HDF_INF_P2P1) {
1798 HDF_LOGE("%s: remove %s is not p2p interface (%d %d)", __func__, ifRemove->ifName, i, HDF_INF_P2P1);
1799 }
1800
1801 wdev = (struct wireless_dev *)p2p_hnetdev->ieee80211Ptr;
1802 ret = (int32_t)wl_cfg80211_ops.change_virtual_intf(wiphy, g_hdf_infmap[i].netdev,
1803 NL80211_IFTYPE_STATION, NULL);
1804 HDF_LOGI("%s: change %s mode %d --> %d, ret=%d", __func__, g_hdf_infmap[i].netdev->name,
1805 wdev->iftype, NL80211_IFTYPE_STATION, ret);
1806
1807 rtnl_lock();
1808 // clear private object
1809 DestroyEapolData(p2p_hnetdev);
1810 p2p_hnetdev->ieee80211Ptr = NULL;
1811 // This func free wdev object and call unregister_netdevice() and NetDeviceDeInit()
1812 ret = wl_cfg80211_ops.del_virtual_intf(wiphy, wdev);
1813
1814 g_hdf_infmap[i].hnetdev = NULL;
1815 g_hdf_infmap[i].netdev = NULL;
1816 g_hdf_infmap[i].wdev = NULL;
1817 g_hdf_ifidx = HDF_INF_WLAN0;
1818 g_event_ifidx = HDF_INF_P2P0;
1819 rtnl_unlock();
1820 break;
1821 }
1822 }
1823
1824 return ret;
1825 }
1826
WalSetApWpsP2pIe(struct NetDevice * hnetDev,WifiAppIe * appIe)1827 int32_t WalSetApWpsP2pIe(struct NetDevice *hnetDev, WifiAppIe *appIe)
1828 {
1829 struct net_device *netdev = NULL;
1830 enum wl_management_type type;
1831 struct NetDevice *netDev = NULL;
1832 int ret = 0;
1833
1834 netDev = get_real_netdev(hnetDev);
1835 netdev = GetLinuxInfByNetDevice(netDev);
1836 type = appIe->appIeType;
1837
1838 HDF_LOGI("%s: primary netdev %s, type=%d", __func__, netDev->name, type);
1839 if (!netdev) {
1840 HDF_LOGE("%s: net_device is NULL", __func__);
1841 return -1;
1842 }
1843
1844 if (appIe->ieLen > WLAN_WPS_IE_MAX_SIZE) {
1845 return -1;
1846 }
1847
1848 rtnl_lock();
1849 ret = wl_cfg80211_set_wps_p2p_ie(netdev, appIe->ie, appIe->ieLen, type);
1850 rtnl_unlock();
1851 return ret;
1852 }
1853
1854 void cfg80211_init_wdev(struct wireless_dev *wdev);
1855
hdf_start_p2p_device(void)1856 int hdf_start_p2p_device(void)
1857 {
1858 int ret = HDF_SUCCESS;
1859 struct wiphy *wiphy = NULL;
1860 struct wireless_dev *wdev = NULL;
1861 struct net_device *netdev = get_krn_netdev(HDF_INF_WLAN0);
1862
1863 if (start_p2p_completed == 1) {
1864 HDF_LOGE("%s:start p2p completed already", __func__);
1865 return 0;
1866 }
1867
1868 // create wdev object for p2p-dev-wlan0 device, refer nl80211_new_interface()
1869 wiphy = get_linux_wiphy_ndev(netdev);
1870 if (wiphy == NULL) {
1871 HDF_LOGE("%s:get wlan0 wiphy failed", __func__);
1872 return HDF_FAILURE;
1873 }
1874
1875 wdev = wl_cfg80211_ops.add_virtual_intf(wiphy, "p2p-dev-wlan0", NET_NAME_USER, NL80211_IFTYPE_P2P_DEVICE, NULL);
1876 if (wdev == NULL) {
1877 HDF_LOGE("%s:create wdev for p2p-dev-wlan0 %d failed", __func__, NL80211_IFTYPE_P2P_DEVICE);
1878 return HDF_FAILURE;
1879 }
1880 cfg80211_init_wdev(wdev);
1881 HDF_LOGI("%s:p2p-dev-wlan0 wdev->netdev=%p", __func__, wdev->netdev);
1882
1883 g_hdf_infmap[HDF_INF_P2P0].wdev = wdev; // free it for module released !!
1884
1885 ret = wl_cfg80211_ops.start_p2p_device(wiphy, NULL);
1886 HDF_LOGI("call start_p2p_device ret = %d", ret);
1887 g_event_ifidx = HDF_INF_P2P0;
1888 start_p2p_completed = 1;
1889
1890 return ret;
1891 }
1892
WalGetDriverFlag(struct NetDevice * netDev,WifiGetDrvFlags ** params)1893 int32_t WalGetDriverFlag(struct NetDevice *netDev, WifiGetDrvFlags **params)
1894 {
1895 struct wireless_dev *wdev = NULL;
1896 WifiGetDrvFlags *getDrvFlag = NULL;
1897 int iftype = 0;
1898 int ifidx = 0;
1899
1900 HDF_LOGI("%s: primary netdev %s", __func__, netDev->name);
1901 if (netDev == NULL || params == NULL) {
1902 HDF_LOGE("%s:NULL ptr!", __func__);
1903 return -1;
1904 }
1905 wdev = (struct wireless_dev*)((netDev)->ieee80211Ptr);
1906 getDrvFlag = (WifiGetDrvFlags *)OsalMemCalloc(sizeof(WifiGetDrvFlags));
1907 if (wdev) {
1908 iftype = wdev->iftype;
1909 } else {
1910 ifidx = get_scan_ifidx(netDev->name);
1911 if (ifidx == HDF_INF_P2P0)
1912 iftype = NL80211_IFTYPE_P2P_DEVICE;
1913 }
1914
1915 switch (iftype) {
1916 case NL80211_IFTYPE_P2P_CLIENT:
1917 /* fall-through */
1918 case NL80211_IFTYPE_P2P_GO:
1919 getDrvFlag->drvFlags = (unsigned int)(HISI_DRIVER_FLAGS_AP);
1920 g_event_ifidx = HDF_INF_P2P1;
1921 break;
1922 case NL80211_IFTYPE_P2P_DEVICE:
1923 getDrvFlag->drvFlags = (unsigned int)(HISI_DRIVER_FLAGS_P2P_DEDICATED_INTERFACE |
1924 HISI_DRIVER_FLAGS_P2P_CONCURRENT |
1925 HISI_DRIVER_FLAGS_P2P_CAPABLE);
1926 rtnl_lock();
1927 hdf_start_p2p_device();
1928 rtnl_unlock();
1929 break;
1930 default:
1931 getDrvFlag->drvFlags = 0;
1932 }
1933
1934 *params = getDrvFlag;
1935
1936 HDF_LOGI("%s: %s iftype=%d, drvflag=%lu", __func__, netDev->name, iftype, getDrvFlag->drvFlags);
1937 return HDF_SUCCESS;
1938 }
1939
1940 static struct HdfMac80211P2POps g_bdh6_p2pOps = {
1941 .RemainOnChannel = WalRemainOnChannel,
1942 .CancelRemainOnChannel = WalCancelRemainOnChannel,
1943 .ProbeReqReport = WalProbeReqReport,
1944 .AddIf = WalAddIf,
1945 .RemoveIf = WalRemoveIf,
1946 .SetApWpsP2pIe = WalSetApWpsP2pIe,
1947 .GetDriverFlag = WalGetDriverFlag,
1948 };
1949
BDH6Mac80211Init(struct HdfChipDriver * chipDriver)1950 void BDH6Mac80211Init(struct HdfChipDriver *chipDriver)
1951 {
1952 HDF_LOGI("%s: start...", __func__);
1953
1954 if (chipDriver == NULL) {
1955 HDF_LOGE("%s: input is NULL", __func__);
1956 return;
1957 }
1958
1959 chipDriver->ops = &g_bdh6_baseOps;
1960 chipDriver->staOps = &g_bdh6_staOps;
1961 chipDriver->apOps = &g_bdh6_apOps;
1962 chipDriver->p2pOps = &g_bdh6_p2pOps;
1963 }