1 /*
2 * hdf_comm.c
3 *
4 * hdf driver
5 *
6 * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd.
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19 #include <net/cfg80211.h>
20 #include <net/regulatory.h>
21 #include <securec.h>
22 #include <linux/version.h>
23 #include <linux/skbuff.h>
24 #include <linux/slab.h>
25 #include <linux/printk.h>
26 #include <linux/in6.h>
27 #include <linux/wireless.h>
28
29 #include "wifi_module.h"
30 #include "wifi_mac80211_ops.h"
31 #include "hdf_wlan_utils.h"
32 #include "net_bdh_adpater.h"
33 #include "hdf_wl_interface.h"
34 #include "hdf_public_ap6256.h"
35
36 #include <typedefs.h>
37 #include <ethernet.h>
38 #include <bcmutils.h>
39
40 #include "osal_mem.h"
41 #include "hdf_log.h"
42
43 #include "net_device.h"
44 #include "net_device_impl.h"
45 #include "net_device_adapter.h"
46 #include "hdf_wifi_cmd.h"
47 #include "hdf_wifi_event.h"
48 #include "hdf_mac80211_sta_event.h"
49 #include "hdf_mac80211_sta.h"
50 #include <net/netlink.h>
51
52 #include <uapi/linux/nl80211.h>
53 #include <asm/byteorder.h>
54 #include <linux/kernel.h>
55
56 #include "hdf_wifi_product.h"
57 #define HDF_LOG_TAG BDH6Driver
58 #define WIFI_SCAN_EXTRA_IE_LEN_MAX (512)
59 #define BDH6_POINT_CHANNEL_SIZE (8)
60 int dhd_module_init(void);
61 struct bcm_cfg80211;
62 s32 wl_get_vif_macaddr(struct bcm_cfg80211 *cfg, u16 wl_iftype, u8 *mac_addr);
63 extern struct cfg80211_ap_settings g_ap_setting_info;
64
HdfInfMapInit(void)65 static void HdfInfMapInit(void)
66 {
67 int32_t i = 0;
68
69 memset_s(g_hdf_infmap, sizeof(g_hdf_infmap), 0, sizeof(g_hdf_infmap));
70 for (i = 0; i < HDF_INF_MAX; i++) {
71 INIT_WORK(&g_hdf_infmap[i].eapolEvent.eapol_report,
72 eapol_report_handler);
73 NetBufQueueInit(&g_hdf_infmap[i].eapolEvent.eapolQueue);
74 g_hdf_infmap[i].eapolEvent.idx = i;
75 }
76 g_hdf_ifidx = HDF_INF_WLAN0; // master interface
77 }
78
Bdh6Fband(NetDevice * hnetDev,int32_t band,int32_t * freqs,uint32_t * num)79 int32_t Bdh6Fband(NetDevice *hnetDev, int32_t band, int32_t *freqs,
80 uint32_t *num)
81 {
82 uint32_t freqIndex = 0;
83 uint32_t channelNumber;
84 uint32_t freqTmp;
85 uint32_t minFreq;
86 uint32_t maxFreq;
87
88 struct wiphy *wiphy = NULL;
89 struct NetDevice *netDev = NULL;
90 struct ieee80211_supported_band *band5g = NULL;
91 int32_t max5GChNum = 0;
92 const struct ieee80211_regdomain *regdom = bdh6_get_regdomain();
93 if (regdom == NULL) {
94 HDF_LOGE("%s: wal_get_cfg_regdb failed!", __func__);
95 return HDF_FAILURE;
96 }
97
98 netDev = get_real_netdev(hnetDev);
99 wiphy = get_linux_wiphy_hdfdev(netDev);
100 if (!wiphy) {
101 HDF_LOGE("%s: wiphy is NULL", __func__);
102 return -1;
103 }
104
105 (void)netDev;
106 HDF_LOGE("%s: start..., band=%d", __func__, band);
107
108 minFreq = regdom->reg_rules[0].freq_range.start_freq_khz / MHZ_TO_KHZ(1);
109 maxFreq = regdom->reg_rules[0].freq_range.end_freq_khz / MHZ_TO_KHZ(1);
110 switch (band) {
111 case WLAN_BAND_2G:
112 for (channelNumber = 1; channelNumber <= WIFI_24G_CHANNEL_NUMS;
113 channelNumber++) {
114 if (channelNumber < WAL_MAX_CHANNEL_2G) {
115 freqTmp = WAL_MIN_FREQ_2G +
116 (channelNumber - 1) * WAL_FREQ_2G_INTERVAL;
117 } else if (channelNumber == WAL_MAX_CHANNEL_2G) {
118 freqTmp = WAL_MAX_FREQ_2G;
119 }
120 if (freqTmp < minFreq || freqTmp > maxFreq) {
121 continue;
122 }
123
124 HDF_LOGE("bdh6 2G %u: freq=%u\n", freqIndex, freqTmp);
125 freqs[freqIndex] = freqTmp;
126 freqIndex++;
127 }
128 *num = freqIndex;
129 break;
130
131 case WLAN_BAND_5G:
132 band5g = wiphy->bands[IEEE80211_BAND_5GHZ];
133 if (band5g == NULL) {
134 return HDF_ERR_NOT_SUPPORT;
135 }
136
137 max5GChNum = min(band5g->n_channels, WIFI_24G_CHANNEL_NUMS);
138 for (freqIndex = 0; freqIndex < max5GChNum; freqIndex++) {
139 freqs[freqIndex] = band5g->channels[freqIndex].center_freq;
140 HDF_LOGE("bdh6 5G %u: freq=%u\n", freqIndex, freqs[freqIndex]);
141 }
142 *num = freqIndex;
143 break;
144 default:
145 HDF_LOGE("%s: no support band!", __func__);
146 return HDF_ERR_NOT_SUPPORT;
147 }
148 return HDF_SUCCESS;
149 }
150
Bdh6Ghcap(struct NetDevice * hnetDev,struct WlanHwCapability ** capability)151 int32_t Bdh6Ghcap(struct NetDevice *hnetDev,
152 struct WlanHwCapability **capability)
153 {
154 uint8_t loop = 0;
155 struct wiphy *wiphy = NULL;
156 struct NetDevice *netDev = NULL;
157 struct ieee80211_supported_band *band = NULL;
158 struct ieee80211_supported_band *band5g = NULL;
159 struct WlanHwCapability *hwCapability = NULL;
160 uint16_t supportedRateCount = 0;
161 netDev = get_real_netdev(hnetDev);
162
163 wiphy = get_linux_wiphy_hdfdev(netDev);
164 if (!wiphy) {
165 HDF_LOGE("%s: wiphy is NULL", __func__);
166 return -1;
167 }
168
169 HDF_LOGE("%s: start...", __func__);
170 band = wiphy->bands[IEEE80211_BAND_2GHZ];
171 hwCapability = (struct WlanHwCapability *)OsalMemCalloc(
172 sizeof(struct WlanHwCapability));
173 if (hwCapability == NULL) {
174 HDF_LOGE("%s: oom!\n", __func__);
175 return HDF_FAILURE;
176 }
177 hwCapability->Release = BDH6WalReleaseHwCapability;
178
179 if (hwCapability->bands[IEEE80211_BAND_2GHZ] == NULL) {
180 hwCapability->bands[IEEE80211_BAND_2GHZ] =
181 OsalMemCalloc(sizeof(struct WlanBand) +
182 (sizeof(struct WlanChannel) * band->n_channels));
183 if (hwCapability->bands[IEEE80211_BAND_2GHZ] == NULL) {
184 BDH6WalReleaseHwCapability(hwCapability);
185 return HDF_FAILURE;
186 }
187 }
188
189 hwCapability->htCapability = band->ht_cap.cap;
190 supportedRateCount = band->n_bitrates;
191
192 hwCapability->bands[IEEE80211_BAND_2GHZ]->channelCount = band->n_channels;
193 for (loop = 0; loop < band->n_channels; loop++) {
194 hwCapability->bands[IEEE80211_BAND_2GHZ]->channels[loop].centerFreq =
195 band->channels[loop].center_freq;
196 hwCapability->bands[IEEE80211_BAND_2GHZ]->channels[loop].flags =
197 band->channels[loop].flags;
198 hwCapability->bands[IEEE80211_BAND_2GHZ]->channels[loop].channelId =
199 band->channels[loop].hw_value;
200 HDF_LOGE(
201 "bdh6 2G band %u: centerFreq=%u, channelId=%u, flags=0x%08x\n",
202 loop,
203 hwCapability->bands[IEEE80211_BAND_2GHZ]->channels[loop].centerFreq,
204 hwCapability->bands[IEEE80211_BAND_2GHZ]->channels[loop].channelId,
205 hwCapability->bands[IEEE80211_BAND_2GHZ]->channels[loop].flags);
206 }
207
208 if (wiphy->bands[IEEE80211_BAND_5GHZ]) { // Fill 5Ghz band
209 band5g = wiphy->bands[IEEE80211_BAND_5GHZ];
210 hwCapability->bands[IEEE80211_BAND_5GHZ] =
211 OsalMemCalloc(sizeof(struct WlanBand) +
212 (sizeof(struct WlanChannel) * band5g->n_channels));
213 if (hwCapability->bands[IEEE80211_BAND_5GHZ] == NULL) {
214 HDF_LOGE("%s: oom!\n", __func__);
215 BDH6WalReleaseHwCapability(hwCapability);
216 return HDF_FAILURE;
217 }
218
219 hwCapability->bands[IEEE80211_BAND_5GHZ]->channelCount =
220 band5g->n_channels;
221 for (loop = 0; loop < band5g->n_channels; loop++) {
222 hwCapability->bands[IEEE80211_BAND_5GHZ]
223 ->channels[loop]
224 .centerFreq = band5g->channels[loop].center_freq;
225 hwCapability->bands[IEEE80211_BAND_5GHZ]->channels[loop].flags =
226 band5g->channels[loop].flags;
227 hwCapability->bands[IEEE80211_BAND_5GHZ]->channels[loop].channelId =
228 band5g->channels[loop].hw_value;
229 }
230
231 supportedRateCount += band5g->n_bitrates;
232 }
233 HDF_LOGE("bdh6 htCapability= %u,%u; supportedRateCount= %u,%u,%u\n",
234 hwCapability->htCapability, band5g->ht_cap.cap, supportedRateCount,
235 band->n_bitrates, band5g->n_bitrates);
236
237 hwCapability->supportedRateCount = supportedRateCount;
238 hwCapability->supportedRates =
239 OsalMemCalloc(sizeof(uint16_t) * supportedRateCount);
240 if (hwCapability->supportedRates == NULL) {
241 HDF_LOGE("%s: oom!\n", __func__);
242 BDH6WalReleaseHwCapability(hwCapability);
243 return HDF_FAILURE;
244 }
245
246 for (loop = 0; loop < band->n_bitrates; loop++) {
247 hwCapability->supportedRates[loop] = band->bitrates[loop].bitrate;
248 HDF_LOGE("bdh6 2G supportedRates %u: %u\n", loop,
249 hwCapability->supportedRates[loop]);
250 }
251
252 if (band5g) {
253 for (loop = band->n_bitrates; loop < supportedRateCount; loop++) {
254 hwCapability->supportedRates[loop] = band5g->bitrates[loop].bitrate;
255 HDF_LOGE("bdh6 5G supportedRates %u: %u\n", loop,
256 hwCapability->supportedRates[loop]);
257 }
258 }
259
260 if (hwCapability->supportedRateCount > MAX_SUPPORTED_RATE) {
261 hwCapability->supportedRateCount = MAX_SUPPORTED_RATE;
262 }
263
264 *capability = hwCapability;
265 return HDF_SUCCESS;
266 }
267
Bdh6SAction(struct NetDevice * hhnetDev,WifiActionData * actionData)268 int32_t Bdh6SAction(struct NetDevice *hhnetDev, WifiActionData *actionData)
269 {
270 int retVal = 0;
271 struct NetDevice *hnetdev = NULL;
272 struct net_device *netdev = NULL;
273 struct NetDevice *netDev = NULL;
274 struct wiphy *wiphy = NULL;
275 struct wireless_dev *wdev = NULL;
276 static u64 action_cookie = 0;
277 struct cfg80211_mgmt_tx_params params;
278 u32 center_freq = 0;
279 u8 *action_buf = NULL;
280 struct ieee80211_mgmt *mgmt = NULL;
281 u8 *srcMac = NULL;
282 hnetdev = hhnetDev; // backup it
283
284 g_mgmt_tx_event_ifidx = get_scan_ifidx(hnetdev->name);
285 HDF_LOGE("%s: start %s... ifidx=%d", __func__, hnetdev->name,
286 g_mgmt_tx_event_ifidx);
287
288 netDev = get_real_netdev(hhnetDev);
289 netdev = GetLinuxInfByNetDevice(netDev);
290 if (!netdev) {
291 HDF_LOGE("%s: net_device is NULL", __func__);
292 return -1;
293 }
294 wiphy = get_linux_wiphy_ndev(netdev);
295 if (!wiphy) {
296 HDF_LOGE("%s: wiphy is NULL", __func__);
297 return -1;
298 }
299
300 if (strcmp(hnetdev->name, "p2p0") == 0) {
301 wdev = g_hdf_infmap[HDF_INF_P2P0].wdev;
302 if (g_hdf_infmap[HDF_INF_P2P1].netdev) {
303 srcMac = wdev->address;
304 } else {
305 srcMac = actionData->src;
306 }
307 } else {
308 wdev = netdev->ieee80211_ptr;
309 srcMac = actionData->src;
310 }
311 memset_s(¶ms, sizeof(params), 0, sizeof(params));
312 params.wait = actionData->wait;
313 params.no_cck = (bool)actionData->noCck;
314 center_freq = actionData->freq;
315 params.chan = ieee80211_get_channel_khz(wiphy, MHZ_TO_KHZ(center_freq));
316 if (params.chan == NULL) {
317 HDF_LOGE("%s: get center_freq %u faild", __func__, center_freq);
318 return -1;
319 }
320
321 // build 802.11 action header
322 action_buf = (u8 *)OsalMemCalloc(MAC_80211_FRAME_LEN + actionData->dataLen);
323 mgmt = (struct ieee80211_mgmt *)action_buf;
324 mgmt->frame_control =
325 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION);
326 memcpy_s(mgmt->da, ETH_ALEN, actionData->dst, ETH_ALEN);
327 memcpy_s(mgmt->sa, ETH_ALEN, srcMac, ETH_ALEN);
328 memcpy_s(mgmt->bssid, ETH_ALEN, actionData->bssid, ETH_ALEN);
329
330 /* 填充payload信息 */
331 if (actionData->dataLen > 0) {
332 memcpy_s(action_buf + MAC_80211_FRAME_LEN, actionData->dataLen,
333 actionData->data, actionData->dataLen);
334 }
335 params.buf = action_buf;
336 params.len = (MAC_80211_FRAME_LEN + actionData->dataLen);
337 retVal =
338 (int32_t)wl_cfg80211_ops.mgmt_tx(wiphy, wdev, ¶ms, &action_cookie);
339 OsalMemFree(action_buf);
340 return retVal;
341 }
342
InitCfg80211BeaconDataInfo(struct cfg80211_beacon_data * pInfo,const struct WlanBeaconConf * param)343 static void InitCfg80211BeaconDataInfo(struct cfg80211_beacon_data *pInfo,
344 const struct WlanBeaconConf *param)
345 {
346 memset_s(pInfo, sizeof(struct cfg80211_beacon_data), 0x00,
347 sizeof(struct cfg80211_beacon_data));
348 pInfo->head = param->headIEs;
349 pInfo->head_len = (size_t)param->headIEsLength;
350 pInfo->tail = param->tailIEs;
351 pInfo->tail_len = (size_t)param->tailIEsLength;
352
353 pInfo->beacon_ies = NULL;
354 pInfo->proberesp_ies = NULL;
355 pInfo->assocresp_ies = NULL;
356 pInfo->probe_resp = NULL;
357 pInfo->beacon_ies_len = 0X00;
358 pInfo->proberesp_ies_len = 0X00;
359 pInfo->assocresp_ies_len = 0X00;
360 pInfo->probe_resp_len = 0X00;
361 }
362
InitCfg80211ApSettingInfo(const struct WlanBeaconConf * param)363 static void InitCfg80211ApSettingInfo(const struct WlanBeaconConf *param)
364 {
365 if (g_ap_setting_info.beacon.head != NULL) {
366 OsalMemFree((uint8_t *)g_ap_setting_info.beacon.head);
367 g_ap_setting_info.beacon.head = NULL;
368 }
369 if (g_ap_setting_info.beacon.tail != NULL) {
370 OsalMemFree((uint8_t *)g_ap_setting_info.beacon.tail);
371 g_ap_setting_info.beacon.tail = NULL;
372 }
373
374 if (param->headIEs && param->headIEsLength > 0) {
375 g_ap_setting_info.beacon.head = OsalMemCalloc(param->headIEsLength);
376 memcpy_s((uint8_t *)g_ap_setting_info.beacon.head, param->headIEsLength,
377 param->headIEs, param->headIEsLength);
378 g_ap_setting_info.beacon.head_len = param->headIEsLength;
379 }
380
381 if (param->tailIEs && param->tailIEsLength > 0) {
382 g_ap_setting_info.beacon.tail = OsalMemCalloc(param->tailIEsLength);
383 memcpy_s((uint8_t *)g_ap_setting_info.beacon.tail, param->tailIEsLength,
384 param->tailIEs, param->tailIEsLength);
385 g_ap_setting_info.beacon.tail_len = param->tailIEsLength;
386 }
387
388 /* add beacon data for start ap */
389 g_ap_setting_info.dtim_period = param->DTIMPeriod;
390 g_ap_setting_info.hidden_ssid = param->hiddenSSID;
391 g_ap_setting_info.beacon_interval = param->interval;
392 HDF_LOGE("%s: dtim_period:%d---hidden_ssid:%d---beacon_interval:%d!",
393 __func__, g_ap_setting_info.dtim_period,
394 g_ap_setting_info.hidden_ssid, g_ap_setting_info.beacon_interval);
395
396 g_ap_setting_info.beacon.beacon_ies = NULL;
397 g_ap_setting_info.beacon.proberesp_ies = NULL;
398 g_ap_setting_info.beacon.assocresp_ies = NULL;
399 g_ap_setting_info.beacon.probe_resp = NULL;
400 g_ap_setting_info.beacon.beacon_ies_len = 0X00;
401 g_ap_setting_info.beacon.proberesp_ies_len = 0X00;
402 g_ap_setting_info.beacon.assocresp_ies_len = 0X00;
403 g_ap_setting_info.beacon.probe_resp_len = 0X00;
404
405 bdh6_nl80211_calculate_ap_params(&g_ap_setting_info);
406 }
407
WalChangeBeacon(NetDevice * hnetDev,struct WlanBeaconConf * param)408 int32_t WalChangeBeacon(NetDevice *hnetDev, struct WlanBeaconConf *param)
409 {
410 int32_t ret = 0;
411 struct cfg80211_beacon_data info;
412 struct net_device *netdev = NULL;
413 struct wiphy *wiphy = NULL;
414 struct NetDevice *netDev = NULL;
415 netDev = get_real_netdev(hnetDev);
416 netdev = GetLinuxInfByNetDevice(netDev);
417 if (!netdev) {
418 HDF_LOGE("%s: net_device is NULL", __func__);
419 return -1;
420 }
421
422 wiphy = get_linux_wiphy_ndev(netdev);
423 if (!wiphy) {
424 HDF_LOGE("%s: wiphy is NULL", __func__);
425 return -1;
426 }
427
428 HDF_LOGE("%s: start...", __func__);
429 if ((int)param->interval <= 0) {
430 HDF_LOGE("%s: invalid beacon interval=%d, %d,%d", __func__,
431 (int)param->interval, param->DTIMPeriod,
432 (int)param->hiddenSSID);
433 return 0;
434 }
435
436 InitCfg80211BeaconDataInfo(&info, param);
437 InitCfg80211ApSettingInfo(param);
438
439 HDF_LOGE("%s: headIEsLen:%d---tailIEsLen:%d!", __func__,
440 param->headIEsLength, param->tailIEsLength);
441 ret = WalStartAp(netDev);
442 HDF_LOGE("call start_ap ret=%d", ret);
443 ret = (int32_t)wl_cfg80211_ops.change_beacon(wiphy, netdev, &info);
444 if (ret < 0) {
445 HDF_LOGE("%s: change_beacon failed!", __func__);
446 }
447
448 return HDF_SUCCESS;
449 }
450
__HdfConnect(NetDevice * hnetDev,WlanConnectParams * param)451 static int32_t __HdfConnect(NetDevice *hnetDev, WlanConnectParams *param)
452 {
453 int32_t ret = 0;
454 struct net_device *ndev = NULL;
455 struct wiphy *wiphy = NULL;
456 struct NetDevice *netDev = NULL;
457 struct cfg80211_connect_params cfg80211_params = {0};
458 g_conn_event_ifidx = get_scan_ifidx(hnetDev->name);
459 netDev = get_real_netdev(hnetDev);
460 if (netDev == NULL || param == NULL) {
461 HDF_LOGE("%s:NULL ptr!", __func__);
462 return HDF_FAILURE;
463 }
464 ndev = GetLinuxInfByNetDevice(netDev);
465 if (ndev == NULL) {
466 HDF_LOGE("%s:NULL ptr!", __func__);
467 return HDF_FAILURE;
468 }
469
470 wiphy = get_linux_wiphy_ndev(ndev);
471 if (!wiphy) {
472 HDF_LOGE("%s: wiphy is NULL", __func__);
473 return -1;
474 }
475
476 if (param->centerFreq != WLAN_FREQ_NOT_SPECFIED) {
477 cfg80211_params.channel = WalGetChannel(wiphy, param->centerFreq);
478 if ((cfg80211_params.channel == NULL) ||
479 (cfg80211_params.channel->flags & WIFI_CHAN_DISABLED)) {
480 HDF_LOGE("%s:illegal channel.flags=%u", __func__,
481 (cfg80211_params.channel == NULL)
482 ? 0
483 : cfg80211_params.channel->flags);
484 return HDF_FAILURE;
485 }
486 }
487
488 cfg80211_params.bssid = param->bssid;
489 cfg80211_params.ssid = param->ssid;
490 cfg80211_params.ie = param->ie;
491 cfg80211_params.ssid_len = param->ssidLen;
492 cfg80211_params.ie_len = param->ieLen;
493
494 cfg80211_params.crypto.wpa_versions = param->crypto.wpaVersions;
495 cfg80211_params.crypto.cipher_group = param->crypto.cipherGroup;
496 cfg80211_params.crypto.n_ciphers_pairwise = param->crypto.n_ciphersPairwise;
497
498 memcpy_s(cfg80211_params.crypto.ciphers_pairwise,
499 NL80211_MAX_NR_CIPHER_SUITES *
500 sizeof(cfg80211_params.crypto.ciphers_pairwise[0]),
501 param->crypto.ciphersPairwise,
502 NL80211_MAX_NR_CIPHER_SUITES *
503 sizeof(param->crypto.ciphersPairwise[0]));
504
505 memcpy_s(cfg80211_params.crypto.akm_suites,
506 NL80211_MAX_NR_AKM_SUITES *
507 sizeof(cfg80211_params.crypto.akm_suites[0]),
508 param->crypto.akmSuites,
509 NL80211_MAX_NR_AKM_SUITES * sizeof(param->crypto.akmSuites[0]));
510
511 cfg80211_params.crypto.n_akm_suites = param->crypto.n_akmSuites;
512
513 if (param->crypto.controlPort) {
514 cfg80211_params.crypto.control_port = true;
515 } else {
516 cfg80211_params.crypto.control_port = false;
517 }
518
519 cfg80211_params.crypto.control_port_ethertype =
520 param->crypto.controlPortEthertype;
521 cfg80211_params.crypto.control_port_no_encrypt =
522 param->crypto.controlPortNoEncrypt;
523
524 cfg80211_params.key = param->key;
525 cfg80211_params.auth_type = (unsigned char)param->authType;
526 cfg80211_params.privacy = param->privacy;
527 cfg80211_params.key_len = param->keyLen;
528 cfg80211_params.key_idx = param->keyIdx;
529 cfg80211_params.mfp = (unsigned char)param->mfp;
530
531 HDF_LOGE("%s: %s connect ssid: %s", __func__, netDev->name,
532 cfg80211_params.ssid);
533 HDF_LOGE("%s: cfg80211_params "
534 "auth_type:%d--channelId:%d--centerFreq:%d--Mac:%02x:%02x:%02x:%"
535 "02x:%02x:%02x",
536 __func__, cfg80211_params.auth_type, cfg80211_params.channel->band,
537 param->centerFreq, cfg80211_params.bssid[0],
538 cfg80211_params.bssid[1], cfg80211_params.bssid[0x2],
539 cfg80211_params.bssid[0x3], cfg80211_params.bssid[0x4],
540 cfg80211_params.bssid[0x5]);
541
542 ret = wl_cfg80211_ops.connect(wiphy, ndev, &cfg80211_params);
543 if (ret < 0) {
544 HDF_LOGE("%s: connect failed!\n", __func__);
545 }
546
547 return ret;
548 }
549
HdfConnect(NetDevice * hnetDev,WlanConnectParams * param)550 int32_t HdfConnect(NetDevice *hnetDev, WlanConnectParams *param)
551 {
552 int32_t ret = 0;
553 mutex_lock(&bdh6_reset_driver_lock);
554 rtnl_lock();
555 ret = __HdfConnect(hnetDev, param);
556 rtnl_unlock();
557 mutex_unlock(&bdh6_reset_driver_lock);
558 return ret;
559 }
560
__HdfStartScan(NetDevice * hhnetDev,struct WlanScanRequest * scanParam)561 static int32_t __HdfStartScan(NetDevice *hhnetDev,
562 struct WlanScanRequest *scanParam)
563 {
564 int32_t ret = 0;
565 struct net_device *ndev = NULL;
566 struct wiphy *wiphy = NULL;
567 NetDevice *hnetdev = hhnetDev;
568 int32_t channelTotal;
569 struct NetDevice *netDev = NULL;
570
571 netDev = get_real_netdev(hhnetDev);
572 ndev = GetLinuxInfByNetDevice(netDev);
573 wiphy = get_linux_wiphy_ndev(ndev);
574 channelTotal = ieee80211_get_num_supported_channels(wiphy);
575 g_scan_event_ifidx = get_scan_ifidx(hnetdev->name);
576
577 struct cfg80211_scan_request *request =
578 (struct cfg80211_scan_request *)OsalMemCalloc(
579 sizeof(struct cfg80211_scan_request) +
580 sizeof(struct ieeee80211_channel *) * channelTotal);
581
582 HDF_LOGE("%s: enter hdfStartScan %s, channelTotal: %d, for %u", __func__,
583 ndev->name, channelTotal, sizeof(struct ieeee80211_channel *));
584
585 if (request == NULL) {
586 return HDF_FAILURE;
587 }
588 if (WifiScanSetRequest(netDev, scanParam, request) != HDF_SUCCESS) {
589 WifiScanFree(&request);
590 return HDF_FAILURE;
591 }
592 if (g_scan_event_ifidx == HDF_INF_P2P0 && g_hdf_infmap[HDF_INF_P2P0].wdev) {
593 request->wdev = g_hdf_infmap[HDF_INF_P2P0].wdev;
594 }
595
596 HDF_LOGE("%s: enter cfg80211_scan, n_ssids=%d !", __func__,
597 request->n_ssids);
598 ret = wl_cfg80211_ops.scan(wiphy, request);
599 HDF_LOGE("%s: left cfg80211_scan %d!", __func__, ret);
600
601 if (ret != HDF_SUCCESS) {
602 WifiScanFree(&request);
603 }
604
605 return ret;
606 }
607
HdfStartScan(NetDevice * hhnetDev,struct WlanScanRequest * scanParam)608 int32_t HdfStartScan(NetDevice *hhnetDev, struct WlanScanRequest *scanParam)
609 {
610 int32_t ret = 0;
611 mutex_lock(&bdh6_reset_driver_lock);
612 rtnl_lock();
613 ret = __HdfStartScan(hhnetDev, scanParam);
614 rtnl_unlock();
615 mutex_unlock(&bdh6_reset_driver_lock);
616 return ret;
617 }
618
WifiScanSetUserIe(const struct WlanScanRequest * params,struct cfg80211_scan_request * request)619 int32_t WifiScanSetUserIe(const struct WlanScanRequest *params,
620 struct cfg80211_scan_request *request)
621 {
622 if (params->extraIEsLen > WIFI_SCAN_EXTRA_IE_LEN_MAX) {
623 HDF_LOGE("%s:unexpected extra len!extraIesLen=%d", __func__,
624 params->extraIEsLen);
625 return HDF_FAILURE;
626 }
627 if ((params->extraIEs != NULL) && (params->extraIEsLen != 0)) {
628 request->ie = (uint8_t *)OsalMemCalloc(params->extraIEsLen);
629 if (request->ie == NULL) {
630 HDF_LOGE("%s: calloc request->ie null", __func__);
631 goto fail;
632 }
633 (void)memcpy_s((void *)request->ie, params->extraIEsLen,
634 params->extraIEs, params->extraIEsLen);
635 request->ie_len = params->extraIEsLen;
636 }
637
638 return HDF_SUCCESS;
639
640 fail:
641 if (request->ie != NULL) {
642 OsalMemFree((void *)request->ie);
643 request->ie = NULL;
644 }
645
646 return HDF_FAILURE;
647 }
648
WifiScanSetChannel(const struct wiphy * wiphy,const struct WlanScanRequest * params,struct cfg80211_scan_request * request)649 int32_t WifiScanSetChannel(const struct wiphy *wiphy,
650 const struct WlanScanRequest *params,
651 struct cfg80211_scan_request *request)
652 {
653 int32_t loop;
654 int32_t count = 0;
655 enum Ieee80211Band band = IEEE80211_BAND_2GHZ;
656 struct ieee80211_channel *chan = NULL;
657
658 int32_t channelTotal =
659 ieee80211_get_num_supported_channels((struct wiphy *)wiphy);
660
661 if ((params->freqs == NULL) || (params->freqsCount == 0)) {
662 for (band = IEEE80211_BAND_2GHZ; band <= IEEE80211_BAND_5GHZ; band++) {
663 if (wiphy->bands[band] == NULL) {
664 HDF_LOGE("%s: wiphy->bands[band] = NULL!\n", __func__);
665 continue;
666 }
667
668 for (loop = 0; loop < (int32_t)wiphy->bands[band]->n_channels;
669 loop++) {
670 if (count >= channelTotal) {
671 break;
672 }
673
674 chan = &wiphy->bands[band]->channels[loop];
675 if ((chan->flags & WIFI_CHAN_DISABLED) != 0) {
676 continue;
677 }
678
679 request->channels[count++] = chan;
680 }
681 }
682 } else {
683 for (loop = 0; loop < params->freqsCount; loop++) {
684 chan = GetChannelByFreq(wiphy, (uint16_t)(params->freqs[loop]));
685 if (chan == NULL) {
686 HDF_LOGE("%s: freq not found!freq=%d!\n", __func__,
687 params->freqs[loop]);
688 continue;
689 }
690
691 if (count >= channelTotal) {
692 break;
693 }
694
695 request->channels[count++] = chan;
696 }
697 }
698
699 if (count == 0) {
700 HDF_LOGE("%s: invalid freq info!\n", __func__);
701 return HDF_FAILURE;
702 }
703 request->n_channels = count;
704
705 return HDF_SUCCESS;
706 }
707
708 #define HDF_ETHER_ADDR_LEN (6)
HdfConnectResultEventCallback(struct net_device * ndev,uint8_t * bssid,uint8_t * reqIe,uint8_t * rspIe,uint32_t reqIeLen,uint32_t rspIeLen,uint16_t connectStatus,uint16_t freq)709 int32_t HdfConnectResultEventCallback(struct net_device *ndev, uint8_t *bssid,
710 uint8_t *reqIe, uint8_t *rspIe,
711 uint32_t reqIeLen, uint32_t rspIeLen,
712 uint16_t connectStatus, uint16_t freq)
713 {
714 int32_t retVal = 0;
715 NetDevice *netDev = GetHdfNetDeviceByLinuxInf(ndev);
716 struct ConnetResult connResult;
717 // for check p2p0 report
718 netDev = get_hdf_netdev(g_conn_event_ifidx);
719
720 HDF_LOGE("%s: enter", __func__);
721
722 if (netDev == NULL || bssid == NULL || rspIe == NULL || reqIe == NULL) {
723 HDF_LOGE("%s: netDev / bssid / rspIe / reqIe null!", __func__);
724 return -1;
725 }
726
727 memcpy_s(&connResult.bssid[0], HDF_ETHER_ADDR_LEN, bssid,
728 HDF_ETHER_ADDR_LEN);
729
730 connResult.rspIe = rspIe;
731 connResult.rspIeLen = rspIeLen;
732 connResult.reqIe = reqIe;
733 connResult.reqIeLen = reqIeLen;
734 connResult.connectStatus = connectStatus;
735 connResult.freq = freq;
736 connResult.statusCode = connectStatus;
737
738 retVal = HdfWifiEventConnectResult(netDev, &connResult);
739 if (retVal < 0) {
740 HDF_LOGE("%s: hdf wifi event inform connect result failed!", __func__);
741 }
742 return retVal;
743 }
744
HdfInformBssFrameEventCallback(struct net_device * ndev,struct ieee80211_channel * channel,int32_t signal,int16_t freq,struct ieee80211_mgmt * mgmt,uint32_t mgmtLen)745 void HdfInformBssFrameEventCallback(struct net_device *ndev,
746 struct ieee80211_channel *channel,
747 int32_t signal, int16_t freq,
748 struct ieee80211_mgmt *mgmt,
749 uint32_t mgmtLen)
750 {
751 int32_t retVal = 0;
752 NetDevice *netDev = GetHdfNetDeviceByLinuxInf(ndev);
753 struct ScannedBssInfo bssInfo;
754 struct WlanChannel hdfchannel;
755
756 if (channel == NULL || netDev == NULL || mgmt == NULL) {
757 HDF_LOGE("%s: inform_bss_frame channel = null or netDev = null!",
758 __func__);
759 return;
760 }
761 netDev = get_hdf_netdev(g_scan_event_ifidx);
762 bssInfo.signal = signal;
763 bssInfo.freq = freq;
764 bssInfo.mgmtLen = mgmtLen;
765 bssInfo.mgmt = (struct Ieee80211Mgmt *)mgmt;
766
767 hdfchannel.flags = channel->flags;
768 hdfchannel.channelId = channel->hw_value;
769 hdfchannel.centerFreq = channel->center_freq;
770 retVal = HdfWifiEventInformBssFrame(netDev, &hdfchannel, &bssInfo);
771 if (retVal < 0) {
772 HDF_LOGE("%s: hdf wifi event inform bss frame failed!", __func__);
773 }
774 }
775
BDH6Init(struct HdfChipDriver * chipDriver,struct NetDevice * netDevice)776 int32_t BDH6Init(struct HdfChipDriver *chipDriver, struct NetDevice *netDevice)
777 {
778 int32_t ret = 0;
779 struct HdfWifiNetDeviceData *data = NULL;
780 struct net_device *netdev = NULL;
781 int private_data_size = 0;
782 struct wiphy *wiphy = NULL;
783 struct net_device *p2p_netdev = NULL;
784 struct NetDevice *p2p_hnetdev = NULL;
785 struct bcm_cfg80211 *cfg = NULL;
786
787 (void)chipDriver;
788 HDF_LOGW("bdh6: call BDH6Init");
789 HdfInfMapInit();
790
791 if (netDevice == NULL) {
792 HDF_LOGE("%s netdevice is null!", __func__);
793 return HDF_FAILURE;
794 }
795
796 netdev = GetLinuxInfByNetDevice(netDevice);
797 if (netdev == NULL) {
798 HDF_LOGE("%s net_device is null!", __func__);
799 return HDF_FAILURE;
800 }
801
802 data = GetPlatformData(netDevice);
803 if (data == NULL) {
804 HDF_LOGE("%s:netdevice data null!", __func__);
805 return HDF_FAILURE;
806 }
807
808 hdf_bdh6_netdev_init(netDevice);
809 netDevice->classDriverPriv = data;
810 private_data_size = get_dhd_priv_data_size(); // create bdh6 private object
811 netDevice->mlPriv = kzalloc(private_data_size, GFP_KERNEL);
812 if (netDevice->mlPriv == NULL) {
813 HDF_LOGE("%s:kzalloc mlPriv failed", __func__);
814 return HDF_FAILURE;
815 }
816
817 set_krn_netdev(netDevice, netdev, g_hdf_ifidx);
818 dhd_module_init();
819 ret = hdf_bdh6_netdev_open(netDevice);
820 if (ret != 0) {
821 HDF_LOGE("%s:open netdev %s failed", __func__, netDevice->name);
822 }
823
824 ret = BDH6InitNetdev(netDevice, sizeof(void *), NL80211_IFTYPE_P2P_DEVICE,
825 HDF_INF_P2P0);
826 if (ret != 0) {
827 HDF_LOGE("%s:BDH6InitNetdev p2p0 failed", __func__);
828 return HDF_FAILURE;
829 }
830 wiphy = get_linux_wiphy_ndev(netdev);
831 if (wiphy == NULL) {
832 HDF_LOGE("%s:get wlan0 wiphy failed", __func__);
833 return HDF_FAILURE;
834 }
835 p2p_hnetdev = get_hdf_netdev(g_hdf_ifidx);
836 p2p_netdev = get_krn_netdev(g_hdf_ifidx);
837 p2p_netdev->ieee80211_ptr = NULL;
838 p2p_hnetdev->ieee80211Ptr = p2p_netdev->ieee80211_ptr;
839 cfg = wiphy_priv(wiphy); // update mac from wdev address
840 wl_get_vif_macaddr(cfg, 7, p2p_hnetdev->macAddr); // WL_IF_TYPE_P2P_DISC = 7
841 memcpy_s(p2p_netdev->dev_addr, p2p_netdev->addr_len, p2p_hnetdev->macAddr,
842 MAC_ADDR_SIZE);
843 p2p_hnetdev->netDeviceIf = wal_get_net_p2p_ops(); // reset netdev_ops
844 hdf_cfgp2p_register_ndev(p2p_netdev, netdev, wiphy);
845 ret = NetDeviceAdd(p2p_hnetdev); // Call linux register_netdev()
846 HDF_LOGE("NetDeviceAdd %s ret = %d", p2p_hnetdev->name, ret);
847
848 if (bdh6_reset_driver_flag) {
849 p2p_hnetdev->netDeviceIf->open(p2p_hnetdev);
850 rtnl_lock();
851 dev_open(netdev, NULL);
852 rtnl_unlock();
853 rtnl_lock();
854 dev_open(p2p_netdev, NULL);
855 rtnl_unlock();
856 if (start_p2p_completed) {
857 start_p2p_completed = 0;
858 hdf_start_p2p_device();
859 }
860 bdh6_reset_driver_flag = 0;
861 HDF_LOGE("%s: reset driver ok", __func__);
862 }
863 return HDF_SUCCESS;
864 }
865