Skip to content

Commit 8e84c25

Browse files
Eugene Krasnikovlinvjw
authored andcommitted
wcn36xx: mac80211 driver for Qualcomm WCN3660/WCN3680 hardware
This is a mac80211 driver for Qualcomm WCN3660/WCN3680 devices. So far WCN3660/WCN3680 is available only on MSM platform. Firmware can be found here: https://www.codeaurora.org/cgit/external/hisense/platform/vendor/qcom-opensource/wlan/prima/tree/firmware_bin?h=8130_CS Wiki page is available here: http://wireless.kernel.org/en/users/Drivers/wcn36xx A lot people made a contribution to this driver. Here is the list in alphabetical order: Eugene Krasnikov <[email protected]> Kalle Valo <[email protected]> Olof Johansson <[email protected]> Pontus Fuchs <[email protected]> Yanbo Li <[email protected]> Signed-off-by: Eugene Krasnikov <[email protected]> Signed-off-by: John W. Linville <[email protected]>
1 parent c856197 commit 8e84c25

File tree

18 files changed

+10082
-0
lines changed

18 files changed

+10082
-0
lines changed

MAINTAINERS

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6816,6 +6816,14 @@ L: [email protected]
68166816
S: Supported
68176817
F: arch/hexagon/
68186818

6819+
QUALCOMM WCN36XX WIRELESS DRIVER
6820+
M: Eugene Krasnikov <[email protected]>
6821+
6822+
W: http://wireless.kernel.org/en/users/Drivers/wcn36xx
6823+
T: git git://github.com/KrasnikovEugene/wcn36xx.git
6824+
S: Supported
6825+
F: drivers/net/wireless/ath/wcn36xx/
6826+
68196827
QUICKCAM PARALLEL PORT WEBCAMS
68206828
M: Hans Verkuil <[email protected]>
68216829

drivers/net/wireless/ath/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,6 @@ source "drivers/net/wireless/ath/ath6kl/Kconfig"
3232
source "drivers/net/wireless/ath/ar5523/Kconfig"
3333
source "drivers/net/wireless/ath/wil6210/Kconfig"
3434
source "drivers/net/wireless/ath/ath10k/Kconfig"
35+
source "drivers/net/wireless/ath/wcn36xx/Kconfig"
3536

3637
endif

drivers/net/wireless/ath/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ obj-$(CONFIG_ATH6KL) += ath6kl/
55
obj-$(CONFIG_AR5523) += ar5523/
66
obj-$(CONFIG_WIL6210) += wil6210/
77
obj-$(CONFIG_ATH10K) += ath10k/
8+
obj-$(CONFIG_WCN36XX) += wcn36xx/
89

910
obj-$(CONFIG_ATH_COMMON) += ath.o
1011

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
config WCN36XX
2+
tristate "Qualcomm Atheros WCN3660/3680 support"
3+
depends on MAC80211 && HAS_DMA
4+
---help---
5+
This module adds support for wireless adapters based on
6+
Qualcomm Atheros WCN3660 and WCN3680 mobile chipsets.
7+
8+
If you choose to build a module, it'll be called wcn36xx.
9+
10+
config WCN36XX_DEBUGFS
11+
bool "WCN36XX debugfs support"
12+
depends on WCN36XX
13+
---help---
14+
Enabled debugfs support
15+
16+
If unsure, say Y to make it easier to debug problems.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
obj-$(CONFIG_WCN36XX) := wcn36xx.o
2+
wcn36xx-y += main.o \
3+
dxe.o \
4+
txrx.o \
5+
smd.o \
6+
pmc.o \
7+
debug.o
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
/*
2+
* Copyright (c) 2013 Eugene Krasnikov <[email protected]>
3+
*
4+
* Permission to use, copy, modify, and/or distribute this software for any
5+
* purpose with or without fee is hereby granted, provided that the above
6+
* copyright notice and this permission notice appear in all copies.
7+
*
8+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9+
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10+
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11+
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12+
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13+
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14+
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15+
*/
16+
17+
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
18+
19+
#include <linux/debugfs.h>
20+
#include <linux/uaccess.h>
21+
#include "wcn36xx.h"
22+
#include "debug.h"
23+
#include "pmc.h"
24+
25+
#ifdef CONFIG_WCN36XX_DEBUGFS
26+
27+
static int wcn36xx_debugfs_open(struct inode *inode, struct file *file)
28+
{
29+
file->private_data = inode->i_private;
30+
31+
return 0;
32+
}
33+
34+
static ssize_t read_file_bool_bmps(struct file *file, char __user *user_buf,
35+
size_t count, loff_t *ppos)
36+
{
37+
struct wcn36xx *wcn = file->private_data;
38+
struct wcn36xx_vif *vif_priv = NULL;
39+
struct ieee80211_vif *vif = NULL;
40+
char buf[3];
41+
42+
list_for_each_entry(vif_priv, &wcn->vif_list, list) {
43+
vif = container_of((void *)vif_priv,
44+
struct ieee80211_vif,
45+
drv_priv);
46+
if (NL80211_IFTYPE_STATION == vif->type) {
47+
if (vif_priv->pw_state == WCN36XX_BMPS)
48+
buf[0] = '1';
49+
else
50+
buf[0] = '0';
51+
break;
52+
}
53+
}
54+
buf[1] = '\n';
55+
buf[2] = 0x00;
56+
57+
return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
58+
}
59+
60+
static ssize_t write_file_bool_bmps(struct file *file,
61+
const char __user *user_buf,
62+
size_t count, loff_t *ppos)
63+
{
64+
struct wcn36xx *wcn = file->private_data;
65+
struct wcn36xx_vif *vif_priv = NULL;
66+
struct ieee80211_vif *vif = NULL;
67+
68+
char buf[32];
69+
int buf_size;
70+
71+
buf_size = min(count, (sizeof(buf)-1));
72+
if (copy_from_user(buf, user_buf, buf_size))
73+
return -EFAULT;
74+
75+
switch (buf[0]) {
76+
case 'y':
77+
case 'Y':
78+
case '1':
79+
list_for_each_entry(vif_priv, &wcn->vif_list, list) {
80+
vif = container_of((void *)vif_priv,
81+
struct ieee80211_vif,
82+
drv_priv);
83+
if (NL80211_IFTYPE_STATION == vif->type) {
84+
wcn36xx_enable_keep_alive_null_packet(wcn, vif);
85+
wcn36xx_pmc_enter_bmps_state(wcn, vif);
86+
}
87+
}
88+
break;
89+
case 'n':
90+
case 'N':
91+
case '0':
92+
list_for_each_entry(vif_priv, &wcn->vif_list, list) {
93+
vif = container_of((void *)vif_priv,
94+
struct ieee80211_vif,
95+
drv_priv);
96+
if (NL80211_IFTYPE_STATION == vif->type)
97+
wcn36xx_pmc_exit_bmps_state(wcn, vif);
98+
}
99+
break;
100+
}
101+
102+
return count;
103+
}
104+
105+
static const struct file_operations fops_wcn36xx_bmps = {
106+
.open = wcn36xx_debugfs_open,
107+
.read = read_file_bool_bmps,
108+
.write = write_file_bool_bmps,
109+
};
110+
111+
static ssize_t write_file_dump(struct file *file,
112+
const char __user *user_buf,
113+
size_t count, loff_t *ppos)
114+
{
115+
struct wcn36xx *wcn = file->private_data;
116+
char buf[255], *tmp;
117+
int buf_size;
118+
u32 arg[WCN36xx_MAX_DUMP_ARGS];
119+
int i;
120+
121+
memset(buf, 0, sizeof(buf));
122+
memset(arg, 0, sizeof(arg));
123+
124+
buf_size = min(count, (sizeof(buf) - 1));
125+
if (copy_from_user(buf, user_buf, buf_size))
126+
return -EFAULT;
127+
128+
tmp = buf;
129+
130+
for (i = 0; i < WCN36xx_MAX_DUMP_ARGS; i++) {
131+
char *begin;
132+
begin = strsep(&tmp, " ");
133+
if (begin == NULL)
134+
break;
135+
136+
if (kstrtoul(begin, 0, (unsigned long *)(arg + i)) != 0)
137+
break;
138+
}
139+
140+
wcn36xx_info("DUMP args is %d %d %d %d %d\n", arg[0], arg[1], arg[2],
141+
arg[3], arg[4]);
142+
wcn36xx_smd_dump_cmd_req(wcn, arg[0], arg[1], arg[2], arg[3], arg[4]);
143+
144+
return count;
145+
}
146+
147+
static const struct file_operations fops_wcn36xx_dump = {
148+
.open = wcn36xx_debugfs_open,
149+
.write = write_file_dump,
150+
};
151+
152+
#define ADD_FILE(name, mode, fop, priv_data) \
153+
do { \
154+
struct dentry *d; \
155+
d = debugfs_create_file(__stringify(name), \
156+
mode, dfs->rootdir, \
157+
priv_data, fop); \
158+
dfs->file_##name.dentry = d; \
159+
if (IS_ERR(d)) { \
160+
wcn36xx_warn("Create the debugfs entry failed");\
161+
dfs->file_##name.dentry = NULL; \
162+
} \
163+
} while (0)
164+
165+
166+
void wcn36xx_debugfs_init(struct wcn36xx *wcn)
167+
{
168+
struct wcn36xx_dfs_entry *dfs = &wcn->dfs;
169+
170+
dfs->rootdir = debugfs_create_dir(KBUILD_MODNAME,
171+
wcn->hw->wiphy->debugfsdir);
172+
if (IS_ERR(dfs->rootdir)) {
173+
wcn36xx_warn("Create the debugfs failed\n");
174+
dfs->rootdir = NULL;
175+
}
176+
177+
ADD_FILE(bmps_switcher, S_IRUSR | S_IWUSR,
178+
&fops_wcn36xx_bmps, wcn);
179+
ADD_FILE(dump, S_IWUSR, &fops_wcn36xx_dump, wcn);
180+
}
181+
182+
void wcn36xx_debugfs_exit(struct wcn36xx *wcn)
183+
{
184+
struct wcn36xx_dfs_entry *dfs = &wcn->dfs;
185+
debugfs_remove_recursive(dfs->rootdir);
186+
}
187+
188+
#endif /* CONFIG_WCN36XX_DEBUGFS */
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright (c) 2013 Eugene Krasnikov <[email protected]>
3+
*
4+
* Permission to use, copy, modify, and/or distribute this software for any
5+
* purpose with or without fee is hereby granted, provided that the above
6+
* copyright notice and this permission notice appear in all copies.
7+
*
8+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9+
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10+
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11+
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12+
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13+
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14+
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15+
*/
16+
17+
#ifndef _WCN36XX_DEBUG_H_
18+
#define _WCN36XX_DEBUG_H_
19+
20+
#include <linux/kernel.h>
21+
22+
#define WCN36xx_MAX_DUMP_ARGS 5
23+
24+
#ifdef CONFIG_WCN36XX_DEBUGFS
25+
struct wcn36xx_dfs_file {
26+
struct dentry *dentry;
27+
u32 value;
28+
};
29+
30+
struct wcn36xx_dfs_entry {
31+
struct dentry *rootdir;
32+
struct wcn36xx_dfs_file file_bmps_switcher;
33+
struct wcn36xx_dfs_file file_dump;
34+
};
35+
36+
void wcn36xx_debugfs_init(struct wcn36xx *wcn);
37+
void wcn36xx_debugfs_exit(struct wcn36xx *wcn);
38+
39+
#else
40+
static inline void wcn36xx_debugfs_init(struct wcn36xx *wcn)
41+
{
42+
}
43+
static inline void wcn36xx_debugfs_exit(struct wcn36xx *wcn)
44+
{
45+
}
46+
47+
#endif /* CONFIG_WCN36XX_DEBUGFS */
48+
49+
#endif /* _WCN36XX_DEBUG_H_ */

0 commit comments

Comments
 (0)