1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include <linux/module.h>
17#include <linux/netdevice.h>
18
19#include <rtw_android.h>
20#include <osdep_service.h>
21#include <rtw_debug.h>
22#include <rtw_ioctl_set.h>
23
24static const char *android_wifi_cmd_str[ANDROID_WIFI_CMD_MAX] = {
25 "START",
26 "STOP",
27 "SCAN-ACTIVE",
28 "SCAN-PASSIVE",
29 "RSSI",
30 "LINKSPEED",
31 "RXFILTER-START",
32 "RXFILTER-STOP",
33 "RXFILTER-ADD",
34 "RXFILTER-REMOVE",
35 "BTCOEXSCAN-START",
36 "BTCOEXSCAN-STOP",
37 "BTCOEXMODE",
38 "SETSUSPENDOPT",
39 "P2P_DEV_ADDR",
40 "SETFWPATH",
41 "SETBAND",
42 "GETBAND",
43 "COUNTRY",
44 "P2P_SET_NOA",
45 "P2P_GET_NOA",
46 "P2P_SET_PS",
47 "SET_AP_WPS_P2P_IE",
48 "MACADDR",
49 "BLOCK",
50 "WFD-ENABLE",
51 "WFD-DISABLE",
52 "WFD-SET-TCPPORT",
53 "WFD-SET-MAXTPUT",
54 "WFD-SET-DEVTYPE",
55};
56
57struct android_wifi_priv_cmd {
58 const char __user *buf;
59 int used_len;
60 int total_len;
61};
62
63
64
65
66
67
68
69
70
71static int g_wifi_on = true;
72
73int rtw_android_cmdstr_to_num(char *cmdstr)
74{
75 int cmd_num;
76
77 for (cmd_num = 0; cmd_num < ANDROID_WIFI_CMD_MAX; cmd_num++)
78 if (0 == strncasecmp(cmdstr, android_wifi_cmd_str[cmd_num],
79 strlen(android_wifi_cmd_str[cmd_num])))
80 break;
81 return cmd_num;
82}
83
84static int rtw_android_get_rssi(struct net_device *net, char *command,
85 int total_len)
86{
87 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(net);
88 struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
89 struct wlan_network *pcur_network = &pmlmepriv->cur_network;
90 int bytes_written = 0;
91
92 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
93 bytes_written += snprintf(&command[bytes_written], total_len,
94 "%s rssi %d",
95 pcur_network->network.Ssid.Ssid,
96 padapter->recvpriv.rssi);
97 }
98 return bytes_written;
99}
100
101static int rtw_android_get_link_speed(struct net_device *net, char *command,
102 int total_len)
103{
104 struct adapter *padapter = (struct adapter *)rtw_netdev_priv(net);
105 u16 link_speed;
106
107 link_speed = rtw_get_cur_max_rate(padapter) / 10;
108 return snprintf(command, total_len, "LinkSpeed %d",
109 link_speed);
110}
111
112static int rtw_android_get_macaddr(struct net_device *net, char *command,
113 int total_len)
114{
115 return snprintf(command, total_len, "Macaddr = %pM",
116 net->dev_addr);
117}
118
119static int android_set_cntry(struct net_device *net, char *command,
120 int total_len)
121{
122 struct adapter *adapter = (struct adapter *)rtw_netdev_priv(net);
123 char *country_code = command + strlen(android_wifi_cmd_str[ANDROID_WIFI_CMD_COUNTRY]) + 1;
124 int ret;
125
126 ret = rtw_set_country(adapter, country_code);
127 return (ret == _SUCCESS) ? 0 : -1;
128}
129
130static int android_get_p2p_addr(struct net_device *net, char *command,
131 int total_len)
132{
133
134 memcpy(command, net->dev_addr, ETH_ALEN);
135 return ETH_ALEN;
136}
137
138static int rtw_android_set_block(struct net_device *net, char *command,
139 int total_len)
140{
141 return 0;
142}
143
144int rtw_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
145{
146 int ret = 0;
147 char *command;
148 int cmd_num;
149 int bytes_written = 0;
150 struct android_wifi_priv_cmd priv_cmd;
151
152 if (!ifr->ifr_data)
153 return -EINVAL;
154 if (copy_from_user(&priv_cmd, ifr->ifr_data, sizeof(priv_cmd)))
155 return -EFAULT;
156 if (priv_cmd.total_len < 1)
157 return -EINVAL;
158 command = memdup_user(priv_cmd.buf, priv_cmd.total_len);
159 if (IS_ERR(command))
160 return PTR_ERR(command);
161 command[priv_cmd.total_len - 1] = 0;
162 DBG_88E("%s: Android private cmd \"%s\" on %s\n",
163 __func__, command, ifr->ifr_name);
164 cmd_num = rtw_android_cmdstr_to_num(command);
165 switch (cmd_num) {
166 case ANDROID_WIFI_CMD_START:
167 goto response;
168 case ANDROID_WIFI_CMD_SETFWPATH:
169 goto response;
170 }
171 if (!g_wifi_on) {
172 DBG_88E("%s: Ignore private cmd \"%s\" - iface %s is down\n",
173 __func__, command, ifr->ifr_name);
174 ret = 0;
175 goto free;
176 }
177 switch (cmd_num) {
178 case ANDROID_WIFI_CMD_STOP:
179 break;
180 case ANDROID_WIFI_CMD_SCAN_ACTIVE:
181 break;
182 case ANDROID_WIFI_CMD_SCAN_PASSIVE:
183 break;
184 case ANDROID_WIFI_CMD_RSSI:
185 bytes_written = rtw_android_get_rssi(net, command,
186 priv_cmd.total_len);
187 break;
188 case ANDROID_WIFI_CMD_LINKSPEED:
189 bytes_written = rtw_android_get_link_speed(net, command,
190 priv_cmd.total_len);
191 break;
192 case ANDROID_WIFI_CMD_MACADDR:
193 bytes_written = rtw_android_get_macaddr(net, command,
194 priv_cmd.total_len);
195 break;
196 case ANDROID_WIFI_CMD_BLOCK:
197 bytes_written = rtw_android_set_block(net, command,
198 priv_cmd.total_len);
199 break;
200 case ANDROID_WIFI_CMD_RXFILTER_START:
201 break;
202 case ANDROID_WIFI_CMD_RXFILTER_STOP:
203 break;
204 case ANDROID_WIFI_CMD_RXFILTER_ADD:
205 break;
206 case ANDROID_WIFI_CMD_RXFILTER_REMOVE:
207 break;
208 case ANDROID_WIFI_CMD_BTCOEXSCAN_START:
209
210 break;
211 case ANDROID_WIFI_CMD_BTCOEXSCAN_STOP:
212
213 break;
214 case ANDROID_WIFI_CMD_BTCOEXMODE:
215 break;
216 case ANDROID_WIFI_CMD_SETSUSPENDOPT:
217 break;
218 case ANDROID_WIFI_CMD_SETBAND:
219 break;
220 case ANDROID_WIFI_CMD_GETBAND:
221 break;
222 case ANDROID_WIFI_CMD_COUNTRY:
223 bytes_written = android_set_cntry(net, command,
224 priv_cmd.total_len);
225 break;
226 case ANDROID_WIFI_CMD_P2P_DEV_ADDR:
227 bytes_written = android_get_p2p_addr(net, command,
228 priv_cmd.total_len);
229 break;
230 case ANDROID_WIFI_CMD_P2P_SET_NOA:
231 break;
232 case ANDROID_WIFI_CMD_P2P_GET_NOA:
233 break;
234 case ANDROID_WIFI_CMD_P2P_SET_PS:
235 break;
236 default:
237 DBG_88E("Unknown PRIVATE command %s - ignored\n", command);
238 snprintf(command, 3, "OK");
239 bytes_written = strlen("OK");
240 }
241
242response:
243 if (bytes_written >= 0) {
244 if ((bytes_written == 0) && (priv_cmd.total_len > 0))
245 command[0] = '\0';
246 if (bytes_written >= priv_cmd.total_len) {
247 DBG_88E("%s: bytes_written = %d\n", __func__,
248 bytes_written);
249 bytes_written = priv_cmd.total_len;
250 } else {
251 bytes_written++;
252 }
253 priv_cmd.used_len = bytes_written;
254 if (copy_to_user((char __user *)priv_cmd.buf, command,
255 bytes_written)) {
256 DBG_88E("%s: failed to copy data to user buffer\n",
257 __func__);
258 ret = -EFAULT;
259 }
260 } else {
261 ret = bytes_written;
262 }
263free:
264 kfree(command);
265 return ret;
266}
267