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