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