1 /*
2 * hdf_mac80211_sta.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/netlink.h>
20 #include <securec.h>
21 #include <linux/kernel.h>
22 #include <linux/skbuff.h>
23 #include <linux/slab.h>
24 #include <linux/printk.h>
25 #include <linux/in6.h>
26 #include <linux/wireless.h>
27
28 #include "osal_mem.h"
29 #include "net_device.h"
30 #include "net_device_impl.h"
31 #include "net_device_adapter.h"
32 #include "wifi_mac80211_ops.h"
33 #include "hdf_wifi_cmd.h"
34 #include "hdf_wifi_event.h"
35 #include "hdf_mac80211_sta_event.h"
36 #include "hdf_public_ap6256.h"
37 #include "hdf_mac80211_sta.h"
38
39 #define HDF_LOG_TAG BDH6Driver
40 #define WIFI_SCAN_EXTRA_IE_LEN_MAX (512)
41 #define BDH6_POINT_CHANNEL_SIZE (8)
GetChannelByFreq(const struct wiphy * wiphy,uint16_t center_freq)42 struct ieee80211_channel *GetChannelByFreq(const struct wiphy *wiphy, uint16_t center_freq)
43 {
44 enum Ieee80211Band band;
45 struct ieee80211_supported_band *currentBand = NULL;
46 int32_t loop;
47 for (band = (enum Ieee80211Band)0; band < IEEE80211_NUM_BANDS; band++) {
48 currentBand = wiphy->bands[band];
49 if (currentBand == NULL) {
50 continue;
51 }
52 for (loop = 0; loop < currentBand->n_channels; loop++) {
53 if (currentBand->channels[loop].center_freq == center_freq) {
54 return ¤tBand->channels[loop];
55 }
56 }
57 }
58 return NULL;
59 }
60
61
WifiScanSetSsid(const struct WlanScanRequest * params,struct cfg80211_scan_request * request)62 static int32_t WifiScanSetSsid(const struct WlanScanRequest *params, struct cfg80211_scan_request *request)
63 {
64 int32_t count = 0;
65 int32_t loop;
66
67 if (params->ssidCount > WPAS_MAX_SCAN_SSIDS) {
68 HDF_LOGE("%s:unexpected numSsids!numSsids=%u", __func__, params->ssidCount);
69 return HDF_FAILURE;
70 }
71
72 if (params->ssidCount == 0) {
73 HDF_LOGE("%s:ssid number is 0!", __func__);
74 return HDF_SUCCESS;
75 }
76
77 request->ssids = (struct cfg80211_ssid *)OsalMemCalloc(params->ssidCount * sizeof(struct cfg80211_ssid));
78 if (request->ssids == NULL) {
79 HDF_LOGE("%s: calloc request->ssids null", __func__);
80 return HDF_FAILURE;
81 }
82
83 for (loop = 0; loop < params->ssidCount; loop++) {
84 if (count >= DRIVER_MAX_SCAN_SSIDS) {
85 break;
86 }
87
88 if (params->ssids[loop].ssidLen > IEEE80211_MAX_SSID_LEN) {
89 continue;
90 }
91
92 request->ssids[count].ssid_len = params->ssids[loop].ssidLen;
93 if (memcpy_s(request->ssids[count].ssid, OAL_IEEE80211_MAX_SSID_LEN, params->ssids[loop].ssid,
94 params->ssids[loop].ssidLen) != EOK) {
95 continue;
96 }
97 count++;
98 }
99 request->n_ssids = count;
100
101 return HDF_SUCCESS;
102 }
103
WifiScanSetRequest(struct NetDevice * netdev,const struct WlanScanRequest * params,struct cfg80211_scan_request * request)104 int32_t WifiScanSetRequest(struct NetDevice *netdev, const struct WlanScanRequest *params,
105 struct cfg80211_scan_request *request)
106 {
107 if (netdev == NULL || netdev->ieee80211Ptr == NULL) {
108 return HDF_FAILURE;
109 }
110 request->wiphy = GET_NET_DEV_CFG80211_WIRELESS(netdev)->wiphy;
111 request->wdev = GET_NET_DEV_CFG80211_WIRELESS(netdev);
112 request->n_ssids = params->ssidCount;
113 if (WifiScanSetChannel(GET_NET_DEV_CFG80211_WIRELESS(netdev)->wiphy, params, request)) {
114 HDF_LOGE("%s: set channel failed!", __func__);
115 return HDF_FAILURE;
116 }
117 if (WifiScanSetSsid(params, request)) {
118 HDF_LOGE("%s: set ssid failed!", __func__);
119 return HDF_FAILURE;
120 }
121 if (WifiScanSetUserIe(params, request)) {
122 HDF_LOGE("%s: set user ie failed!", __func__);
123 return HDF_FAILURE;
124 }
125 memset_s(request->bssid, sizeof(request->bssid), 0xff, sizeof(request->bssid));
126 return HDF_SUCCESS;
127 }
128
WifiScanFree(struct cfg80211_scan_request ** request)129 void WifiScanFree(struct cfg80211_scan_request **request)
130 {
131 HDF_LOGE("%s: enter... !", __func__);
132
133 if (*request != NULL) {
134 if ((*request)->ie != NULL) {
135 OsalMemFree((void *)(*request)->ie);
136 (*request)->ie = NULL;
137 }
138 if ((*request)->ssids != NULL) {
139 OsalMemFree((void *)(*request)->ssids);
140 (*request)->ssids = NULL;
141 }
142 OsalMemFree((void *)*request);
143 *request = NULL;
144 }
145 }
146
get_scan_ifidx(const char * ifname)147 int get_scan_ifidx(const char *ifname)
148 {
149 int i = 0;
150 struct NetDevice *p2p_hnetdev = NULL;
151 for (; i < HDF_INF_MAX; i ++) {
152 p2p_hnetdev = g_hdf_infmap[i].hnetdev;
153 if (p2p_hnetdev == NULL) {
154 continue;
155 }
156 if (strcmp(p2p_hnetdev->name, ifname) == 0) {
157 HDF_LOGE("get scan ifidx = %d, %s", i, ifname);
158 return i;
159 }
160 }
161 HDF_LOGE("get scan ifidx error %d, %s", i, ifname);
162 return 0;
163 }
164
HdfAbortScan(NetDevice * hnetDev)165 int32_t HdfAbortScan(NetDevice *hnetDev)
166 {
167 struct net_device *ndev = NULL;
168 struct wireless_dev *wdev = NULL;
169 struct wiphy *wiphy = NULL;
170 struct NetDevice *netDev = NULL;
171 g_scan_event_ifidx = get_scan_ifidx(hnetDev->name);
172 netDev = get_real_netdev(hnetDev);
173 if (netDev == NULL) {
174 HDF_LOGE("%s:NULL ptr!", __func__);
175 return HDF_FAILURE;
176 }
177
178 HDF_LOGE("%s: enter", __func__);
179 ndev = GetLinuxInfByNetDevice(netDev);
180 wiphy = get_linux_wiphy_ndev(ndev);
181 if (ndev == NULL) {
182 HDF_LOGE("%s:NULL ptr!", __func__);
183 return HDF_FAILURE;
184 }
185 wdev = ndev->ieee80211_ptr;
186 if (!wdev || !wdev->wiphy) {
187 return HDF_FAILURE;
188 }
189 wl_cfg80211_abort_scan(wiphy, wdev);
190 return HDF_SUCCESS;
191 }
192
WalGetChannel(struct wiphy * wiphy,int32_t freq)193 struct ieee80211_channel *WalGetChannel(struct wiphy *wiphy, int32_t freq)
194 {
195 int32_t loop;
196
197 enum Ieee80211Band band = IEEE80211_BAND_2GHZ;
198 struct ieee80211_supported_band *currentBand = NULL;
199
200 if (wiphy == NULL) {
201 HDF_LOGE("%s: capality is NULL!", __func__);
202 return NULL;
203 }
204
205 for (band = (enum Ieee80211Band)0; band < IEEE80211_NUM_BANDS; band++) {
206 currentBand = wiphy->bands[band];
207 if (currentBand == NULL) {
208 continue;
209 }
210
211 for (loop = 0; loop < currentBand->n_channels; loop++) {
212 if (currentBand->channels[loop].center_freq == freq) {
213 return ¤tBand->channels[loop];
214 }
215 }
216 }
217
218 return NULL;
219 }
220
HdfDisconnect(NetDevice * hnetDev,uint16_t reasonCode)221 int32_t HdfDisconnect(NetDevice *hnetDev, uint16_t reasonCode)
222 {
223 int32_t ret = 0;
224 struct net_device *ndev = NULL;
225 struct wiphy *wiphy = NULL;
226 struct NetDevice *netDev = NULL;
227 g_conn_event_ifidx = get_scan_ifidx(hnetDev->name);
228 netDev = get_real_netdev(hnetDev);
229
230 HDF_LOGE("%s: start...", __func__);
231 if (netDev == NULL) {
232 HDF_LOGE("%s:NULL ptr!", __func__);
233 return HDF_FAILURE;
234 }
235 ndev = GetLinuxInfByNetDevice(netDev);
236 if (ndev == NULL) {
237 HDF_LOGE("%s:NULL ptr!", __func__);
238 return HDF_FAILURE;
239 }
240
241 wiphy = get_linux_wiphy_ndev(ndev);
242 if (!wiphy) {
243 HDF_LOGE("%s: wiphy is NULL", __func__);
244 return -1;
245 }
246
247 ret = wl_cfg80211_ops.disconnect(wiphy, ndev, reasonCode);
248
249 return ret;
250 }
251
HdfSetScanningMacAddress(NetDevice * hnetDev,unsigned char * mac,uint32_t len)252 int32_t HdfSetScanningMacAddress(NetDevice *hnetDev, unsigned char *mac, uint32_t len)
253 {
254 struct NetDevice *netDev = NULL;
255 netDev = get_real_netdev(hnetDev);
256 (void)mac;
257 (void)len;
258 return HDF_ERR_NOT_SUPPORT;
259 }
260
261 struct HdfMac80211STAOps g_bdh6_staOps = {
262 .Connect = HdfConnect,
263 .Disconnect = HdfDisconnect,
264 .StartScan = HdfStartScan,
265 .AbortScan = HdfAbortScan,
266 .SetScanningMacAddress = HdfSetScanningMacAddress,
267 };
268
269