forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/net/wireless/rockchip_wlan/cywdhd/bcmdhd/wldev_common.c
....@@ -1,15 +1,16 @@
1
-/* SPDX-License-Identifier: GPL-2.0 */
21 /*
32 * Common function shared by Linux WEXT, cfg80211 and p2p drivers
43 *
5
- * Copyright (C) 1999-2019, Broadcom Corporation
6
- *
4
+ * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation
5
+ *
6
+ * Copyright (C) 1999-2017, Broadcom Corporation
7
+ *
78 * Unless you and Broadcom execute a separate written software license
89 * agreement governing use of this software, this software is licensed to you
910 * under the terms of the GNU General Public License version 2 (the "GPL"),
1011 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
1112 * following added to such license:
12
- *
13
+ *
1314 * As a special exception, the copyright holders of this software give you
1415 * permission to link this software with independent modules, and to copy and
1516 * distribute the resulting executable under terms of your choice, provided that
....@@ -17,7 +18,7 @@
1718 * the license of that module. An independent module is a module which is not
1819 * derived from this software. The special exception does not apply to any
1920 * modifications of the software.
20
- *
21
+ *
2122 * Notwithstanding the above, under no circumstances may you combine this
2223 * software in any way with any other Broadcom software provided under a license
2324 * other than the GPL, without Broadcom's express prior written consent.
....@@ -25,7 +26,7 @@
2526 *
2627 * <<Broadcom-WL-IPTag/Open:>>
2728 *
28
- * $Id: wldev_common.c 674374 2017-10-20 07:38:00Z $
29
+ * $Id: wldev_common.c 698236 2017-05-08 19:41:09Z $
2930 */
3031
3132 #include <osl.h>
....@@ -35,6 +36,10 @@
3536
3637 #include <wldev_common.h>
3738 #include <bcmutils.h>
39
+#ifdef WL_CFG80211
40
+#include <wl_cfg80211.h>
41
+#include <wl_cfgscan.h>
42
+#endif /* WL_CFG80211 */
3843
3944 #define htod32(i) (i)
4045 #define htod16(i) (i)
....@@ -45,28 +50,58 @@
4550
4651 #define WLDEV_ERROR(args) \
4752 do { \
48
- printk(KERN_ERR "WLDEV-ERROR) %s : ", __func__); \
53
+ printk(KERN_ERR "WLDEV-ERROR) "); \
54
+ printk args; \
55
+ } while (0)
56
+
57
+#define WLDEV_INFO(args) \
58
+ do { \
59
+ printk(KERN_INFO "WLDEV-INFO) "); \
4960 printk args; \
5061 } while (0)
5162
5263 extern int dhd_ioctl_entry_local(struct net_device *net, wl_ioctl_t *ioc, int cmd);
5364
54
-s32 wldev_ioctl(
65
+static s32 wldev_ioctl(
5566 struct net_device *dev, u32 cmd, void *arg, u32 len, u32 set)
5667 {
5768 s32 ret = 0;
58
- struct wl_ioctl ioc;
59
-
69
+ struct wl_ioctl ioc;
6070
6171 memset(&ioc, 0, sizeof(ioc));
6272 ioc.cmd = cmd;
6373 ioc.buf = arg;
6474 ioc.len = len;
6575 ioc.set = set;
66
-
67
- ret = dhd_ioctl_entry_local(dev, &ioc, cmd);
76
+ ret = dhd_ioctl_entry_local(dev, (wl_ioctl_t *)&ioc, cmd);
6877
6978 return ret;
79
+}
80
+
81
+/*
82
+SET commands :
83
+cast buffer to non-const and call the GET function
84
+*/
85
+
86
+s32 wldev_ioctl_set(
87
+ struct net_device *dev, u32 cmd, const void *arg, u32 len)
88
+{
89
+
90
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
91
+#pragma GCC diagnostic push
92
+#pragma GCC diagnostic ignored "-Wcast-qual"
93
+#endif // endif
94
+ return wldev_ioctl(dev, cmd, (void *)arg, len, 1);
95
+#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__)
96
+#pragma GCC diagnostic pop
97
+#endif // endif
98
+
99
+}
100
+
101
+s32 wldev_ioctl_get(
102
+ struct net_device *dev, u32 cmd, void *arg, u32 len)
103
+{
104
+ return wldev_ioctl(dev, cmd, (void *)arg, len, 0);
70105 }
71106
72107 /* Format a iovar buffer, not bsscfg indexed. The bsscfg index will be
....@@ -74,7 +109,7 @@
74109 * wl_iw, wl_cfg80211 and wl_cfgp2p
75110 */
76111 static s32 wldev_mkiovar(
77
- const s8 *iovar_name, s8 *param, s32 paramlen,
112
+ const s8 *iovar_name, const s8 *param, s32 paramlen,
78113 s8 *iovar_buf, u32 buflen)
79114 {
80115 s32 iolen = 0;
....@@ -85,23 +120,37 @@
85120
86121 s32 wldev_iovar_getbuf(
87122 struct net_device *dev, s8 *iovar_name,
88
- void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync)
123
+ const void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync)
89124 {
90125 s32 ret = 0;
91126 if (buf_sync) {
92127 mutex_lock(buf_sync);
93128 }
94
- wldev_mkiovar(iovar_name, param, paramlen, buf, buflen);
95
- ret = wldev_ioctl(dev, WLC_GET_VAR, buf, buflen, FALSE);
129
+
130
+ if (buf && (buflen > 0)) {
131
+ /* initialize the response buffer */
132
+ memset(buf, 0, buflen);
133
+ } else {
134
+ ret = BCME_BADARG;
135
+ goto exit;
136
+ }
137
+
138
+ ret = wldev_mkiovar(iovar_name, param, paramlen, buf, buflen);
139
+
140
+ if (!ret) {
141
+ ret = BCME_BUFTOOSHORT;
142
+ goto exit;
143
+ }
144
+ ret = wldev_ioctl_get(dev, WLC_GET_VAR, buf, buflen);
145
+exit:
96146 if (buf_sync)
97147 mutex_unlock(buf_sync);
98148 return ret;
99149 }
100150
101
-
102151 s32 wldev_iovar_setbuf(
103152 struct net_device *dev, s8 *iovar_name,
104
- void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync)
153
+ const void *param, s32 paramlen, void *buf, s32 buflen, struct mutex* buf_sync)
105154 {
106155 s32 ret = 0;
107156 s32 iovar_len;
....@@ -110,7 +159,7 @@
110159 }
111160 iovar_len = wldev_mkiovar(iovar_name, param, paramlen, buf, buflen);
112161 if (iovar_len > 0)
113
- ret = wldev_ioctl(dev, WLC_SET_VAR, buf, iovar_len, TRUE);
162
+ ret = wldev_ioctl_set(dev, WLC_SET_VAR, buf, iovar_len);
114163 else
115164 ret = BCME_BUFTOOSHORT;
116165
....@@ -129,7 +178,6 @@
129178 return wldev_iovar_setbuf(dev, iovar, &val, sizeof(val), iovar_buf,
130179 sizeof(iovar_buf), NULL);
131180 }
132
-
133181
134182 s32 wldev_iovar_getint(
135183 struct net_device *dev, s8 *iovar, s32 *pval)
....@@ -153,7 +201,7 @@
153201 * wl_iw, wl_cfg80211 and wl_cfgp2p
154202 */
155203 s32 wldev_mkiovar_bsscfg(
156
- const s8 *iovar_name, s8 *param, s32 paramlen,
204
+ const s8 *iovar_name, const s8 *param, s32 paramlen,
157205 s8 *iovar_buf, s32 buflen, s32 bssidx)
158206 {
159207 const s8 *prefix = "bsscfg:";
....@@ -163,7 +211,7 @@
163211 u32 iolen;
164212
165213 /* initialize buffer */
166
- if (!iovar_buf || buflen == 0)
214
+ if (!iovar_buf || buflen <= 0)
167215 return BCME_BADARG;
168216 memset(iovar_buf, 0, buflen);
169217
....@@ -176,8 +224,7 @@
176224 namelen = (u32) strlen(iovar_name) + 1; /* lengh of iovar name + null */
177225 iolen = prefixlen + namelen + sizeof(u32) + paramlen;
178226
179
- if (buflen < 0 || iolen > (u32)buflen)
180
- {
227
+ if (iolen > (u32)buflen) {
181228 WLDEV_ERROR(("%s: buffer is too short\n", __FUNCTION__));
182229 return BCME_BUFTOOSHORT;
183230 }
....@@ -215,7 +262,7 @@
215262 }
216263
217264 wldev_mkiovar_bsscfg(iovar_name, param, paramlen, buf, buflen, bsscfg_idx);
218
- ret = wldev_ioctl(dev, WLC_GET_VAR, buf, buflen, FALSE);
265
+ ret = wldev_ioctl_get(dev, WLC_GET_VAR, buf, buflen);
219266 if (buf_sync) {
220267 mutex_unlock(buf_sync);
221268 }
....@@ -224,8 +271,9 @@
224271 }
225272
226273 s32 wldev_iovar_setbuf_bsscfg(
227
- struct net_device *dev, s8 *iovar_name,
228
- void *param, s32 paramlen, void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync)
274
+ struct net_device *dev, const s8 *iovar_name,
275
+ const void *param, s32 paramlen,
276
+ void *buf, s32 buflen, s32 bsscfg_idx, struct mutex* buf_sync)
229277 {
230278 s32 ret = 0;
231279 s32 iovar_len;
....@@ -234,7 +282,7 @@
234282 }
235283 iovar_len = wldev_mkiovar_bsscfg(iovar_name, param, paramlen, buf, buflen, bsscfg_idx);
236284 if (iovar_len > 0)
237
- ret = wldev_ioctl(dev, WLC_SET_VAR, buf, iovar_len, TRUE);
285
+ ret = wldev_ioctl_set(dev, WLC_SET_VAR, buf, iovar_len);
238286 else {
239287 ret = BCME_BUFTOOSHORT;
240288 }
....@@ -255,7 +303,6 @@
255303 return wldev_iovar_setbuf_bsscfg(dev, iovar, &val, sizeof(val), iovar_buf,
256304 sizeof(iovar_buf), bssidx, NULL);
257305 }
258
-
259306
260307 s32 wldev_iovar_getint_bsscfg(
261308 struct net_device *dev, s8 *iovar, s32 *pval, s32 bssidx)
....@@ -281,8 +328,8 @@
281328
282329 if (!plink_speed)
283330 return -ENOMEM;
284
- plink_speed = 0;
285
- error = wldev_ioctl(dev, WLC_GET_RATE, plink_speed, sizeof(int), 0);
331
+ *plink_speed = 0;
332
+ error = wldev_ioctl_get(dev, WLC_GET_RATE, plink_speed, sizeof(int));
286333 if (unlikely(error))
287334 return error;
288335
....@@ -299,8 +346,7 @@
299346 if (!scb_val)
300347 return -ENOMEM;
301348
302
- memset(scb_val, 0, sizeof(scb_val_t));
303
- error = wldev_ioctl(dev, WLC_GET_RSSI, scb_val, sizeof(scb_val_t), 0);
349
+ error = wldev_ioctl_get(dev, WLC_GET_RSSI, scb_val, sizeof(scb_val_t));
304350 if (unlikely(error))
305351 return error;
306352
....@@ -314,9 +360,8 @@
314360
315361 if (!pssid)
316362 return -ENOMEM;
317
-
318363 memset(pssid, 0, sizeof(wlc_ssid_t));
319
- error = wldev_ioctl(dev, WLC_GET_SSID, pssid, sizeof(wlc_ssid_t), 0);
364
+ error = wldev_ioctl_get(dev, WLC_GET_SSID, pssid, sizeof(wlc_ssid_t));
320365 if (unlikely(error))
321366 return error;
322367 pssid->SSID_len = dtoh32(pssid->SSID_len);
....@@ -328,7 +373,8 @@
328373 {
329374 int error;
330375
331
- error = wldev_ioctl(dev, WLC_GET_BAND, pband, sizeof(uint), 0);
376
+ *pband = 0;
377
+ error = wldev_ioctl_get(dev, WLC_GET_BAND, pband, sizeof(uint));
332378 return error;
333379 }
334380
....@@ -338,7 +384,7 @@
338384 int error = -1;
339385
340386 if ((band == WLC_BAND_AUTO) || (band == WLC_BAND_5G) || (band == WLC_BAND_2G)) {
341
- error = wldev_ioctl(dev, WLC_SET_BAND, &band, sizeof(band), true);
387
+ error = wldev_ioctl_set(dev, WLC_SET_BAND, &band, sizeof(band));
342388 if (!error)
343389 dhd_bus_band_set(dev, band);
344390 }
....@@ -348,7 +394,7 @@
348394 {
349395 int error = 0;
350396
351
- error = wldev_ioctl(dev, WLC_GET_RATE, datarate, sizeof(int), false);
397
+ error = wldev_ioctl_get(dev, WLC_GET_RATE, datarate, sizeof(int));
352398 if (error) {
353399 return -1;
354400 } else {
....@@ -362,27 +408,30 @@
362408 wl_chspec_driver_to_host(chanspec_t chanspec);
363409 #define WL_EXTRA_BUF_MAX 2048
364410 int wldev_get_mode(
365
- struct net_device *dev, uint8 *cap)
411
+ struct net_device *dev, uint8 *cap, uint8 caplen)
366412 {
367413 int error = 0;
368414 int chanspec = 0;
369415 uint16 band = 0;
370416 uint16 bandwidth = 0;
371417 wl_bss_info_t *bss = NULL;
372
- char* buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
418
+ char* buf = NULL;
419
+
420
+ buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
373421 if (!buf) {
374
- WLDEV_ERROR(("%s:NOMEM\n", __FUNCTION__));
422
+ WLDEV_ERROR(("%s:ENOMEM\n", __FUNCTION__));
375423 return -ENOMEM;
376424 }
425
+
377426 *(u32*) buf = htod32(WL_EXTRA_BUF_MAX);
378
- error = wldev_ioctl(dev, WLC_GET_BSS_INFO, (void*)buf, WL_EXTRA_BUF_MAX, false);
427
+ error = wldev_ioctl_get(dev, WLC_GET_BSS_INFO, (void*)buf, WL_EXTRA_BUF_MAX);
379428 if (error) {
380429 WLDEV_ERROR(("%s:failed:%d\n", __FUNCTION__, error));
381430 kfree(buf);
382431 buf = NULL;
383432 return error;
384433 }
385
- bss = (struct wl_bss_info *)(buf + 4);
434
+ bss = (wl_bss_info_t*)(buf + 4);
386435 chanspec = wl_chspec_driver_to_host(bss->chanspec);
387436
388437 band = chanspec & WL_CHANSPEC_BAND_MASK;
....@@ -390,21 +439,21 @@
390439
391440 if (band == WL_CHANSPEC_BAND_2G) {
392441 if (bss->n_cap)
393
- strcpy(cap, "n");
442
+ strncpy(cap, "n", caplen);
394443 else
395
- strcpy(cap, "bg");
444
+ strncpy(cap, "bg", caplen);
396445 } else if (band == WL_CHANSPEC_BAND_5G) {
397446 if (bandwidth == WL_CHANSPEC_BW_80)
398
- strcpy(cap, "ac");
447
+ strncpy(cap, "ac", caplen);
399448 else if ((bandwidth == WL_CHANSPEC_BW_40) || (bandwidth == WL_CHANSPEC_BW_20)) {
400449 if ((bss->nbss_cap & 0xf00) && (bss->n_cap))
401
- strcpy(cap, "n|ac");
450
+ strncpy(cap, "n|ac", caplen);
402451 else if (bss->n_cap)
403
- strcpy(cap, "n");
452
+ strncpy(cap, "n", caplen);
404453 else if (bss->vht_cap)
405
- strcpy(cap, "ac");
454
+ strncpy(cap, "ac", caplen);
406455 else
407
- strcpy(cap, "a");
456
+ strncpy(cap, "a", caplen);
408457 } else {
409458 WLDEV_ERROR(("%s:Mode get failed\n", __FUNCTION__));
410459 error = BCME_ERROR;
....@@ -422,6 +471,11 @@
422471 wl_country_t cspec = {{0}, 0, {0}};
423472 scb_val_t scbval;
424473 char smbuf[WLC_IOCTL_SMLEN];
474
+#ifdef WL_CFG80211
475
+ struct wireless_dev *wdev = ndev_to_wdev(dev);
476
+ struct wiphy *wiphy = wdev->wiphy;
477
+ struct bcm_cfg80211 *cfg = wiphy_priv(wiphy);
478
+#endif /* WL_CFG80211 */
425479
426480 if (!country_code)
427481 return error;
....@@ -434,12 +488,19 @@
434488 }
435489
436490 if ((error < 0) ||
437
- dhd_force_country_change(dev) ||
438
- (strncmp(country_code, cspec.country_abbrev, WLC_CNTRY_BUF_SZ) != 0)) {
491
+#ifdef OEM_ANDROID
492
+ dhd_force_country_change(dev) ||
493
+#endif /* OEM_ANDROID */
494
+ (strncmp(country_code, cspec.ccode, WLC_CNTRY_BUF_SZ) != 0)) {
439495
496
+#ifdef WL_CFG80211
497
+ if ((user_enforced) && (wl_get_drv_status(cfg, CONNECTED, dev))) {
498
+#else
440499 if (user_enforced) {
500
+#endif /* WL_CFG80211 */
441501 bzero(&scbval, sizeof(scb_val_t));
442
- error = wldev_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t), true);
502
+ error = wldev_ioctl_set(dev, WLC_DISASSOC,
503
+ &scbval, sizeof(scb_val_t));
443504 if (error < 0) {
444505 WLDEV_ERROR(("%s: set country failed due to Disassoc error %d\n",
445506 __FUNCTION__, error));
....@@ -447,9 +508,11 @@
447508 }
448509 }
449510
511
+ wl_cfg80211_scan_abort(cfg);
512
+
450513 cspec.rev = revinfo;
451
- memcpy(cspec.country_abbrev, country_code, WLC_CNTRY_BUF_SZ);
452
- memcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ);
514
+ strlcpy(cspec.country_abbrev, country_code, WLC_CNTRY_BUF_SZ);
515
+ strlcpy(cspec.ccode, country_code, WLC_CNTRY_BUF_SZ);
453516 dhd_get_customized_country_code(dev, (char *)&cspec.country_abbrev, &cspec);
454517 error = wldev_iovar_setbuf(dev, "country", &cspec, sizeof(cspec),
455518 smbuf, sizeof(smbuf), NULL);
....@@ -459,7 +522,7 @@
459522 return error;
460523 }
461524 dhd_bus_country_set(dev, &cspec, notify);
462
- WLDEV_ERROR(("%s: set country for %s as %s rev %d\n",
525
+ WLDEV_INFO(("%s: set country for %s as %s rev %d\n",
463526 __FUNCTION__, country_code, cspec.ccode, cspec.rev));
464527 }
465528 return 0;