• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * hdf_bdh_mac80211.c
3  *
4  * hdf driver
5  *
6  * Copyright (c) 2022 Shenzhen Kaihong Digital Industry Development Co., Ltd.
7  *
8  * This software is licensed under the terms of the GNU General Public
9  * License version 2, as published by the Free Software Foundation, and
10  * may be copied, distributed, and modified under those terms.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  */
18 #include <net/cfg80211.h>
19 #include <net/regulatory.h>
20 #include <securec.h>
21 #include <linux/version.h>
22 
23 #include "wifi_module.h"
24 #include "wifi_mac80211_ops.h"
25 #include "hdf_wlan_utils.h"
26 #include "net_bdh_adpater.h"
27 #include "hdf_wl_interface.h"
28 #include "hdf_public_ap6256.h"
29 #include "hdf_mac80211_sta.h"
30 
31 #define HDF_LOG_TAG BDH6Driver
32 
33 struct NetDevice *get_real_netdev(NetDevice *netDev);
34 int32_t WalStopAp(NetDevice *netDev);
get_linux_wiphy_ndev(struct net_device * ndev)35 struct wiphy *get_linux_wiphy_ndev(struct net_device *ndev)
36 {
37     if (ndev == NULL || ndev->ieee80211_ptr == NULL) {
38         return NULL;
39     }
40 
41     return ndev->ieee80211_ptr->wiphy;
42 }
43 
get_linux_wiphy_hdfdev(NetDevice * netDev)44 struct wiphy *get_linux_wiphy_hdfdev(NetDevice *netDev)
45 {
46     struct net_device *ndev = GetLinuxInfByNetDevice(netDev);
47     return get_linux_wiphy_ndev(ndev);
48 }
49 
BDH6WalSetMode(NetDevice * hnetDev,enum WlanWorkMode iftype)50 int32_t BDH6WalSetMode(NetDevice *hnetDev, enum WlanWorkMode iftype)
51 {
52     int32_t retVal = 0;
53     struct net_device *netdev = NULL;
54     NetDevice *netDev = NULL;
55     struct wiphy *wiphy = NULL;
56     netDev = get_real_netdev(hnetDev);
57     enum nl80211_iftype old_iftype = 0;
58 
59     netdev = GetLinuxInfByNetDevice(netDev);
60     if (!netdev) {
61         HDF_LOGE("%s: net_device is NULL", __func__);
62         return -1;
63     }
64 
65     wiphy = get_linux_wiphy_ndev(netdev);
66     if (!wiphy) {
67         HDF_LOGE("%s: wiphy is NULL", __func__);
68         return -1;
69     }
70     old_iftype = netdev->ieee80211_ptr->iftype;
71 
72     HDF_LOGE("%s: start... iftype=%d, oldiftype=%d", __func__, iftype, old_iftype);
73     if (old_iftype == NL80211_IFTYPE_AP && iftype != old_iftype) {
74         WalStopAp(netDev);
75     }
76 
77     if (iftype == NL80211_IFTYPE_P2P_GO && old_iftype == NL80211_IFTYPE_P2P_GO) {
78         HDF_LOGE("%s: p2p go don't change mode", __func__);
79         return retVal;
80     }
81 
82     retVal = (int32_t)wl_cfg80211_ops.change_virtual_intf(wiphy, netdev,
83         (enum nl80211_iftype)iftype, NULL);
84     if (retVal < 0) {
85         HDF_LOGE("%s: set mode failed!", __func__);
86     }
87 
88     return retVal;
89 }
90 
BDH6WalAddKey(struct NetDevice * hnetDev,uint8_t keyIndex,bool pairwise,const uint8_t * macAddr,struct KeyParams * params)91 int32_t BDH6WalAddKey(struct NetDevice *hnetDev, uint8_t keyIndex, bool pairwise, const uint8_t *macAddr,
92     struct KeyParams *params)
93 {
94     int32_t retVal = 0;
95     struct NetDevice *netDev = NULL;
96     struct net_device *netdev = NULL;
97     struct wiphy *wiphy = NULL;
98     netDev = get_real_netdev(hnetDev);
99 
100 #if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 10, 0))
101     struct key_params keypm;
102 #endif
103 
104     netdev = GetLinuxInfByNetDevice(netDev);
105     if (!netdev) {
106         HDF_LOGE("%s: net_device is NULL", __func__);
107         return -1;
108     }
109 
110     wiphy = get_linux_wiphy_ndev(netdev);
111     if (!wiphy) {
112         HDF_LOGE("%s: wiphy is NULL", __func__);
113         return -1;
114     }
115 
116     HDF_LOGE("%s: start..., mac = %p, keyIndex = %u,pairwise = %d, cipher = 0x%x, seqlen = %d, keylen = %d",
117         __func__, macAddr, keyIndex, pairwise, params->cipher, params->seqLen, params->keyLen);
118     (void)netDev;
119 #if (LINUX_VERSION_CODE > KERNEL_VERSION(5, 10, 0))
120     memset_s(&keypm, sizeof(struct key_params), 0, sizeof(struct key_params));
121     keypm.key = params->key;
122     keypm.seq = params->seq;
123     keypm.key_len = params->keyLen;
124     keypm.seq_len = params->seqLen;
125     keypm.cipher = params->cipher;
126     keypm.vlan_id = 0;
127     retVal = (int32_t)wl_cfg80211_ops.add_key(wiphy, netdev, keyIndex, pairwise, macAddr, &keypm);
128 #else
129     retVal = (int32_t)wl_cfg80211_ops.add_key(wiphy, netdev, keyIndex, pairwise, macAddr, (struct key_params *)params);
130 #endif
131     if (retVal < 0) {
132         HDF_LOGE("%s: add key failed!", __func__);
133     }
134 
135     return retVal;
136 }
137 
BDH6WalDelKey(struct NetDevice * hnetDev,uint8_t keyIndex,bool pairwise,const uint8_t * macAddr)138 int32_t BDH6WalDelKey(struct NetDevice *hnetDev, uint8_t keyIndex, bool pairwise, const uint8_t *macAddr)
139 {
140     int32_t retVal = 0;
141     struct NetDevice *netDev = NULL;
142     struct net_device *netdev = NULL;
143     struct wiphy *wiphy = NULL;
144     netDev = get_real_netdev(hnetDev);
145 
146     netdev = GetLinuxInfByNetDevice(netDev);
147     if (!netdev) {
148         HDF_LOGE("%s: net_device is NULL", __func__);
149         return -1;
150     }
151 
152     wiphy = get_linux_wiphy_ndev(netdev);
153     if (!wiphy) {
154         HDF_LOGE("%s: wiphy is NULL", __func__);
155         return -1;
156     }
157 
158     HDF_LOGE("%s: start..., mac=%p, keyIndex=%u,pairwise=%d", __func__, macAddr, keyIndex, pairwise);
159 
160     (void)netDev;
161     retVal = (int32_t)wl_cfg80211_ops.del_key(wiphy, netdev, keyIndex, pairwise, macAddr);
162     if (retVal < 0) {
163         HDF_LOGE("%s: delete key failed!", __func__);
164     }
165 
166     return retVal;
167 }
168 
BDH6WalSetDefaultKey(struct NetDevice * hnetDev,uint8_t keyIndex,bool unicast,bool multicas)169 int32_t BDH6WalSetDefaultKey(struct NetDevice *hnetDev, uint8_t keyIndex, bool unicast, bool multicas)
170 {
171     int32_t retVal = 0;
172     struct NetDevice *netDev = NULL;
173     struct net_device *netdev = NULL;
174     struct wiphy *wiphy = NULL;
175     netDev = get_real_netdev(hnetDev);
176 
177     netdev = GetLinuxInfByNetDevice(netDev);
178     if (!netdev) {
179         HDF_LOGE("%s: net_device is NULL", __func__);
180         return -1;
181     }
182 
183     wiphy = get_linux_wiphy_ndev(netdev);
184     if (!wiphy) {
185         HDF_LOGE("%s: wiphy is NULL", __func__);
186         return -1;
187     }
188     HDF_LOGE("%s: start..., keyIndex=%u,unicast=%d, multicas=%d", __func__, keyIndex, unicast, multicas);
189     retVal = (int32_t)wl_cfg80211_ops.set_default_key(wiphy, netdev, keyIndex, unicast, multicas);
190     if (retVal < 0) {
191         HDF_LOGE("%s: set default key failed!", __func__);
192     }
193 
194     return retVal;
195 }
196 
BDH6WalGetDeviceMacAddr(NetDevice * hnetDev,int32_t type,uint8_t * mac,uint8_t len)197 int32_t BDH6WalGetDeviceMacAddr(NetDevice *hnetDev, int32_t type, uint8_t *mac, uint8_t len)
198 {
199     struct NetDevice *netDev = NULL;
200     netDev = get_real_netdev(hnetDev);
201     struct net_device *netdev = GetLinuxInfByNetDevice(netDev);
202     if (!netdev) {
203         HDF_LOGE("%s: net_device is NULL", __func__);
204         return -1;
205     }
206 
207     (void)len;
208     (void)type;
209     (void)netDev;
210     HDF_LOGE("%s: start...", __func__);
211 
212     memcpy_s(mac, len, netdev->dev_addr, netdev->addr_len);
213 
214     return HDF_SUCCESS;
215 }
216 
BDH6WalSetMacAddr(NetDevice * hnetDev,uint8_t * mac,uint8_t len)217 int32_t BDH6WalSetMacAddr(NetDevice *hnetDev, uint8_t *mac, uint8_t len)
218 {
219     int32_t retVal = 0;
220     struct NetDevice *netDev = NULL;
221     struct sockaddr sa;
222     netDev = get_real_netdev(hnetDev);
223     struct net_device *netdev = GetLinuxInfByNetDevice(netDev);
224     if (!netdev) {
225         HDF_LOGE("%s: net_device is NULL", __func__);
226         return -1;
227     }
228 
229     HDF_LOGE("%s: start...", __func__);
230     if (mac == NULL || len != ETH_ALEN) {
231         HDF_LOGE("%s: mac is error, len=%u", __func__, len);
232         return -1;
233     }
234     if (!is_valid_ether_addr(mac)) {
235         HDF_LOGE("%s: mac is invalid %02x:%02x:%02x:%02x:%02x:%02x", __func__,
236             mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
237         return -1;
238     }
239 
240     memcpy_s(sa.sa_data, ETH_ALEN, mac, len);
241 
242     retVal = (int32_t)dhd_ops_pri.ndo_set_mac_address(netdev, (void *)&sa);
243     if (retVal < 0) {
244         HDF_LOGE("%s: set mac address failed!", __func__);
245     }
246 
247     return retVal;
248 }
249 
BDH6WalSetTxPower(NetDevice * hnetDev,int32_t power)250 int32_t BDH6WalSetTxPower(NetDevice *hnetDev, int32_t power)
251 {
252     int retVal = 0;
253     struct wiphy *wiphy = NULL;
254     struct NetDevice *netDev = NULL;
255     netDev = get_real_netdev(hnetDev);
256 
257     // sync from net_device->ieee80211_ptr
258     struct wireless_dev *wdev = GET_NET_DEV_CFG80211_WIRELESS(netDev);
259 
260     wiphy = get_linux_wiphy_hdfdev(netDev);
261     if (!wiphy) {
262         HDF_LOGE("%s: wiphy is NULL", __func__);
263         return -1;
264     }
265 
266     HDF_LOGE("%s: start...", __func__);
267     retVal = (int32_t)wl_cfg80211_ops.set_tx_power(wiphy, wdev, NL80211_TX_POWER_FIXED, power);
268     if (retVal < 0) {
269         HDF_LOGE("%s: set_tx_power failed!", __func__);
270     }
271 
272     return HDF_SUCCESS;
273 }
274 
BDH6WalReleaseHwCapability(struct WlanHwCapability * self)275 void BDH6WalReleaseHwCapability(struct WlanHwCapability *self)
276 {
277     uint8_t i;
278     if (self == NULL) {
279         return;
280     }
281     for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
282         if (self->bands[i] != NULL) {
283             OsalMemFree(self->bands[i]);
284             self->bands[i] = NULL;
285         }
286     }
287     if (self->supportedRates != NULL) {
288         OsalMemFree(self->supportedRates);
289         self->supportedRates = NULL;
290     }
291     OsalMemFree(self);
292 }
293 
BDH6WalGetIftype(struct NetDevice * hnetDev,uint8_t * iftype)294 int32_t BDH6WalGetIftype(struct NetDevice *hnetDev, uint8_t *iftype)
295 {
296     struct NetDevice *netDev = NULL;
297     netDev = get_real_netdev(hnetDev);
298     iftype = (uint8_t *)(&(GET_NET_DEV_CFG80211_WIRELESS(netDev)->iftype));
299     HDF_LOGE("%s: start...", __func__);
300     return HDF_SUCCESS;
301 }
302 
303 static struct HdfMac80211BaseOps g_bdh6_baseOps = {
304     .SetMode = BDH6WalSetMode,
305     .AddKey = BDH6WalAddKey,
306     .DelKey = BDH6WalDelKey,
307     .SetDefaultKey = BDH6WalSetDefaultKey,
308 
309     .GetDeviceMacAddr = BDH6WalGetDeviceMacAddr,
310     .SetMacAddr = BDH6WalSetMacAddr,
311     .SetTxPower = BDH6WalSetTxPower,
312     .GetValidFreqsWithBand = Bdh6Fband,
313 
314     .GetHwCapability = Bdh6Ghcap,
315     .SendAction = Bdh6SAction,
316     .GetIftype = BDH6WalGetIftype,
317 
318 };
319 
BDH6Mac80211Init(struct HdfChipDriver * chipDriver)320 void BDH6Mac80211Init(struct HdfChipDriver *chipDriver)
321 {
322     HDF_LOGE("%s: start...", __func__);
323 
324     if (chipDriver == NULL) {
325         HDF_LOGE("%s: input is NULL", __func__);
326         return;
327     }
328 
329     chipDriver->ops = &g_bdh6_baseOps;
330     chipDriver->staOps = &g_bdh6_staOps;
331     chipDriver->apOps = &g_bdh6_apOps;
332     chipDriver->p2pOps = &g_bdh6_p2pOps;
333 }
334 
335