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