2 ******************************************************************************
6 * @brief iwpriv function definitions
8 * Copyright (C) ESWIN 2015-2020
10 ******************************************************************************
15 ******************************************************************************
17 #include <net/cfg80211.h>
18 #include <net/iw_handler.h>
19 #include "ecrnx_defs.h"
20 #include "eswin_utils.h"
22 #ifdef CONFIG_ECRNX_WIFO_CAIL
23 #include "ecrnx_amt.h"
27 #ifdef CONFIG_WIRELESS_EXT
29 * FUNCTION DEFINITIONS
30 ******************************************************************************
35 #ifdef CONFIG_WEXT_PRIV
36 /* This may be wrong. When using the new SIOCIWFIRSTPRIV range, we probably
37 * should use only "GET" ioctls (last bit set to 1). "SET" ioctls are root
38 * only and don't return the modified struct ifreq to the application which
39 * is usually a problem. - Jean II */
40 #ifdef CONFIG_ECRNX_WIFO_CAIL
41 #define IOCTL_IWPRIV_AMT (SIOCIWFIRSTPRIV + 1)
43 #define IOCTL_IWPRIV_WD (SIOCIWFIRSTPRIV + 3)
46 static int priv_set_int(IN struct net_device *prNetDev,
47 IN struct iw_request_info *prIwReqInfo,
48 IN union iwreq_data *prIwReqData, IN OUT char *pcExtra)
50 int *flag = (int*)pcExtra;
51 ECRNX_PRINT("cmd=%x, flags=%x\n",
52 prIwReqInfo->cmd, prIwReqInfo->flags);
53 ECRNX_PRINT("mode=%x, flags=%x\n",
54 prIwReqData->mode, prIwReqData->data.flags);
56 prIwReqData->param.value = 0x1230;
61 /*----------------------------------------------------------------------------*/
63 * \brief Private ioctl get int handler.
65 * \param[in] pDev Net device requested.
66 * \param[out] pIwReq Pointer to iwreq structure.
67 * \param[in] prIwReqData The ioctl req structure, use the field of sub-command.
68 * \param[out] pcExtra The buffer with put the return value
70 * \retval 0 For success.
71 * \retval -EOPNOTSUPP If cmd is not supported.
72 * \retval -EFAULT For fail.
75 /*----------------------------------------------------------------------------*/
76 static int priv_get_int(IN struct net_device *prNetDev,
77 IN struct iw_request_info *prIwReqInfo,
78 IN union iwreq_data *prIwReqData, IN OUT char *pcExtra)
81 prIwReqData->mode = 0xabcd;
83 } /* __priv_get_int */
85 static int priv_set_struct(IN struct net_device *prNetDev,
86 IN struct iw_request_info *prIwReqInfo,
87 IN union iwreq_data *prIwReqData, IN OUT char *pcExtra)
89 ECRNX_PRINT("cmd=%x, flags=%x\n",
90 prIwReqInfo->cmd, prIwReqInfo->flags);
91 ECRNX_PRINT("mode=%x, flags=%x\n",
92 prIwReqData->mode, prIwReqData->data.flags);
95 //return compat_priv(prNetDev, prIwReqInfo,
96 // prIwReqData, pcExtra, __priv_set_struct);
99 static int priv_get_struct(IN struct net_device *prNetDev,
100 IN struct iw_request_info *prIwReqInfo,
101 IN union iwreq_data *prIwReqData, IN OUT char *pcExtra)
103 ECRNX_PRINT("cmd=%x, flags=%x\n",
104 prIwReqInfo->cmd, prIwReqInfo->flags);
105 ECRNX_PRINT("mode=%x, flags=%x\n",
106 prIwReqData->mode, prIwReqData->data.flags);
108 prIwReqData->data.length = 6;
109 memcpy(pcExtra, "ecrnx", 6);
114 static int priv_get_mac(IN struct net_device *prNetDev,
115 IN struct iw_request_info *prIwReqInfo,
116 IN union iwreq_data *prIwReqData, IN OUT char *pcExtra)
118 struct sockaddr *dst = (struct sockaddr *) pcExtra;
119 struct ecrnx_vif *vif;
122 req.dbg_level = DBG_TYPE_D;
125 vif = netdev_priv(prNetDev);
127 ECRNX_PRINT("priv_get_mac: send cmd to slave \n");
128 host_send(&req, sizeof(dbg_req_t), TX_FLAG_IWPRIV_IE);
129 //wait for slave confirm
131 wait_event_interruptible_timeout(vif->rxdataq, vif->rxdatas, 2*HZ);
133 ECRNX_PRINT("priv_get_mac: rx_len:%d \n", vif->rxlen);
137 prIwReqData->data.length = vif->rxlen;
138 memcpy(dst->sa_data, vif->rxdata, vif->rxlen);
140 prIwReqData->data.length = 1;
145 static int priv_get_vers(IN struct net_device *prNetDev,
146 IN struct iw_request_info *prIwReqInfo,
147 IN union iwreq_data *prIwReqData, IN OUT char *pcExtra)
149 ECRNX_PRINT("get vers cmd=%x, flags=%x\n", prIwReqInfo->cmd, prIwReqInfo->flags);
150 ECRNX_PRINT("mode=%x, flags=%x\n", prIwReqData->mode, prIwReqData->data.flags);
152 memcpy(pcExtra, "1.0.1", 6);
153 prIwReqData->data.length = 6;
159 static int priv_set_debug_level(IN struct net_device *prNetDev,
160 IN struct iw_request_info *prIwReqInfo,
161 IN union iwreq_data *prIwReqData, IN OUT char *pcExtra)
163 ECRNX_PRINT("priv_set_debug_level cmd=%x, flags=%x\n",
164 prIwReqInfo->cmd, prIwReqInfo->flags);
165 ECRNX_PRINT("mode=%x, flags=%x\n",
166 prIwReqData->mode, prIwReqData->data.flags);
168 ECRNX_PRINT("param_value:%d \n", prIwReqData->param.value);
170 ecrnx_dbg_level = prIwReqData->param.value;
175 #ifdef CONFIG_ECRNX_WIFO_CAIL
176 static int priv_amt(IN struct net_device *prNetDev,
177 IN struct iw_request_info *prIwReqInfo,
178 IN union iwreq_data *prIwReqData, IN OUT char *pcExtra)
180 struct sockaddr *dst = (struct sockaddr *) pcExtra;
182 if (amt_mode == false) {
183 ECRNX_ERR(" The current mode does not support the AMT commands!!\n");
186 // printk("buff:%s, len:%d\n", prIwReqData->data.pointer, prIwReqData->data.length);
188 char *reqdata = kzalloc(prIwReqData->data.length, GFP_KERNEL);
192 if (copy_from_user(reqdata, prIwReqData->data.pointer, prIwReqData->data.length)) {
195 host_send(reqdata, prIwReqData->data.length, TX_FLAG_AMT_IWPRIV_IE);
198 //wait for slave confirm
202 wait_event_interruptible_timeout(amt_vif.rxdataq, amt_vif.rxdatas, 2*HZ);
204 ECRNX_PRINT("rxdatas: rx_len:%d, rxdata:[%s]\n", amt_vif.rxlen,amt_vif.rxdata);
205 if (!amt_vif.rxdatas){
209 prIwReqData->data.length = amt_vif.rxlen;
210 memcpy(dst->sa_data, amt_vif.rxdata, amt_vif.rxlen);
212 memcpy(pcExtra, amt_vif.rxdata, amt_vif.rxlen);
218 static struct ecrnx_vif *get_priv_vif(struct ecrnx_hw *ecrnx_hw)
220 return ecrnx_hw->vif_table[0];
223 void priv_copy_data_wakeup(struct ecrnx_hw *ecrnx_hw, struct sk_buff *skb)
225 struct ecrnx_vif* ecrnx_vif = get_priv_vif(ecrnx_hw);
227 ECRNX_PRINT("iw_cfm vif_start:%d, vif_monitor:%d \n", ecrnx_hw->vif_started, ecrnx_hw->monitor_vif);
228 //print_hex_dump(KERN_INFO, DBG_PREFIX_IW_CFM, DUMP_PREFIX_ADDRESS, 32, 1, skb->data, skb->len, false);
229 if (ECRNX_RXSIZE > skb->len) {
230 ecrnx_vif->rxlen = skb->len;
232 ecrnx_vif->rxlen = ECRNX_RXSIZE;
235 memcpy(ecrnx_vif->rxdata, skb->data, ecrnx_vif->rxlen);
236 ecrnx_vif->rxdatas = 1;
237 wake_up(&ecrnx_vif->rxdataq);
240 static int priv_wd(IN struct net_device *prNetDev,
241 IN struct iw_request_info *prIwReqInfo,
242 IN union iwreq_data *prIwReqData, IN OUT char *pcExtra)
244 struct sockaddr *dst = (struct sockaddr *) pcExtra;
245 struct ecrnx_vif *vif;
247 //printk("priv_wd:%s, len:%d\n", prIwReqData->data.pointer, prIwReqData->data.length);
249 char *reqdata = kzalloc(prIwReqData->data.length, GFP_KERNEL);
254 if (copy_from_user(reqdata, prIwReqData->data.pointer, prIwReqData->data.length)) {
257 host_send(reqdata, prIwReqData->data.length, TX_FLAG_IWPRIV_IE);
260 //wait for slave confirm
261 vif = netdev_priv(prNetDev);
262 vif = get_priv_vif(vif->ecrnx_hw);
264 wait_event_interruptible_timeout(vif->rxdataq, vif->rxdatas, 2*HZ);
269 ECRNX_PRINT("priv_wd: rx_len:%d rxdata:[%s]\n", vif->rxlen, vif->rxdata);
270 prIwReqData->data.length = vif->rxlen;
271 memcpy(dst->sa_data, vif->rxdata, vif->rxlen);
273 memcpy(pcExtra, vif->rxdata, vif->rxlen);
279 * Structures to export the Wireless Handlers
281 static const struct iw_priv_args ecrnx_wext_private_args[] = {
282 #ifdef CONFIG_ECRNX_WIFO_CAIL
283 {IOCTL_IWPRIV_AMT, IW_PRIV_TYPE_CHAR | 2000, IW_PRIV_TYPE_CHAR | 2000, "amt"},
285 {IOCTL_IWPRIV_WD, IW_PRIV_TYPE_CHAR | 2000, IW_PRIV_TYPE_CHAR | 2000, "wd"},
288 const iw_handler ecrnx_wext_private_handler[] = {
289 #ifdef CONFIG_ECRNX_WIFO_CAIL
290 [IOCTL_IWPRIV_AMT - SIOCIWFIRSTPRIV] = priv_amt,
292 [IOCTL_IWPRIV_WD - SIOCIWFIRSTPRIV] = priv_wd,
297 /*------------------------------------------------------------------*/
299 * Commit handler : called after a bunch of SET operations
301 static int ecrnx_wext_config_commit(struct net_device *dev,
302 struct iw_request_info *info, /* NULL */
303 void *zwrq, /* NULL */
304 char *extra) /* NULL */
309 static int ecrnx_wext_get_name(struct net_device *dev,
310 struct iw_request_info *info,
314 strcpy(cwrq, "IEEE 802.11");
318 /*------------------------------------------------------------------*/
320 * Wireless Handler : set frequency
322 static int ecrnx_wext_set_freq(struct net_device *dev,
323 struct iw_request_info *info,
324 struct iw_freq *fwrq,
327 int rc = -EINPROGRESS; /* Call commit handler */
328 ECRNX_PRINT("fwrq->e:%d, fwrq->m:%d \n", fwrq->e, fwrq->m);
332 /*------------------------------------------------------------------*/
334 * Wireless Handler : get frequency
336 static int ecrnx_wext_get_freq(struct net_device *dev,
337 struct iw_request_info *info,
338 struct iw_freq *fwrq,
347 /*------------------------------------------------------------------*/
349 * Wireless Handler : set Mode of Operation
351 static int ecrnx_wext_set_mode(struct net_device *dev,
352 struct iw_request_info *info,
356 ECRNX_PRINT("*uwrq:%d \n", *uwrq);
357 return -EINPROGRESS; /* Call commit handler */
360 /*------------------------------------------------------------------*/
362 * Wireless Handler : get Mode of Operation
364 static int ecrnx_wext_get_mode(struct net_device *dev,
365 struct iw_request_info *info,
373 static const iw_handler ecrnx_wext_handler[] =
375 (iw_handler) ecrnx_wext_config_commit, /* SIOCSIWCOMMIT */
376 (iw_handler) ecrnx_wext_get_name, /* SIOCGIWNAME */
377 (iw_handler) NULL, /* SIOCSIWNWID */
378 (iw_handler) NULL, /* SIOCGIWNWID */
379 (iw_handler) ecrnx_wext_set_freq, /* SIOCSIWFREQ */
380 (iw_handler) ecrnx_wext_get_freq, /* SIOCGIWFREQ */
381 (iw_handler) ecrnx_wext_set_mode, /* SIOCSIWMODE */
382 (iw_handler) ecrnx_wext_get_mode, /* SIOCGIWMODE */
385 const struct iw_handler_def ecrnx_wext_handler_def =
387 .num_standard = ARRAY_SIZE(ecrnx_wext_handler),
388 .standard = ecrnx_wext_handler,
389 #ifdef CONFIG_WEXT_PRIV
390 .num_private = ARRAY_SIZE(ecrnx_wext_private_handler),
391 .num_private_args = ARRAY_SIZE(ecrnx_wext_private_args),
392 .private = ecrnx_wext_private_handler,
393 .private_args = ecrnx_wext_private_args,