• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &params) != 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, &params, &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 &currentBand->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 &currentBand->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 = &params->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 }