2 * This file contains ioctl functions
5 #include <linux/ctype.h>
6 #include <linux/delay.h>
8 #include <linux/if_arp.h>
9 #include <linux/wireless.h>
11 #include <net/iw_handler.h>
12 #include <net/ieee80211.h>
22 #define MAX_SCAN_CELL_SIZE (IW_EV_ADDR_LEN + \
24 IW_EV_UINT_LEN + IW_EV_FREQ_LEN + \
25 IW_EV_QUAL_LEN + IW_ESSID_MAX_SIZE + \
26 IW_EV_PARAM_LEN + 40) /* 40 for WPAIE */
28 #define WAIT_FOR_SCAN_RRESULT_MAX_TIME (10 * HZ)
30 static int wlan_set_region(wlan_private
* priv
, u16 region_code
)
35 for (i
= 0; i
< MRVDRV_MAX_REGION_CODE
; i
++) {
36 // use the region code to search for the index
37 if (region_code
== libertas_region_code_to_index
[i
]) {
38 priv
->adapter
->regiontableindex
= (u16
) i
;
39 priv
->adapter
->regioncode
= region_code
;
44 // if it's unidentified region code
45 if (i
>= MRVDRV_MAX_REGION_CODE
) {
46 lbs_deb_ioctl("region Code not identified\n");
51 if (libertas_set_regiontable(priv
, priv
->adapter
->regioncode
, 0)) {
56 lbs_deb_leave_args(LBS_DEB_IOCTL
, "ret %d", ret
);
60 static inline int hex2int(char c
)
62 if (c
>= '0' && c
<= '9')
64 if (c
>= 'a' && c
<= 'f')
65 return (c
- 'a' + 10);
66 if (c
>= 'A' && c
<= 'F')
67 return (c
- 'A' + 10);
71 /* Convert a string representation of a MAC address ("xx:xx:xx:xx:xx:xx")
72 into binary format (6 bytes).
74 This function expects that each byte is represented with 2 characters
75 (e.g., 11:2:11:11:11:11 is invalid)
78 static char *eth_str2addr(char *ethstr
, u8
* addr
)
83 /* get rid of initial blanks */
84 while (*pos
== ' ' || *pos
== '\t')
87 for (i
= 0; i
< 6; i
++) {
88 val
= hex2int(*pos
++);
91 val2
= hex2int(*pos
++);
94 addr
[i
] = (val
* 16 + val2
) & 0xff;
96 if (i
< 5 && *pos
++ != ':')
102 /* this writes xx:xx:xx:xx:xx:xx into ethstr
103 (ethstr must have space for 18 chars) */
104 static int eth_addr2str(u8
* addr
, char *ethstr
)
109 for (i
= 0; i
< 6; i
++) {
110 sprintf(pos
, "%02x", addr
[i
] & 0xff);
119 * @brief Add an entry to the BT table
120 * @param priv A pointer to wlan_private structure
121 * @param req A pointer to ifreq structure
122 * @return 0 --success, otherwise fail
124 static int wlan_bt_add_ioctl(wlan_private
* priv
, struct ifreq
*req
)
126 struct iwreq
*wrq
= (struct iwreq
*)req
;
127 char ethaddrs_str
[18];
129 u8 ethaddr
[ETH_ALEN
];
132 lbs_deb_enter(LBS_DEB_IOCTL
);
134 if (copy_from_user(ethaddrs_str
, wrq
->u
.data
.pointer
,
135 sizeof(ethaddrs_str
)))
138 if ((pos
= eth_str2addr(ethaddrs_str
, ethaddr
)) == NULL
) {
139 lbs_pr_info("BT_ADD: Invalid MAC address\n");
143 lbs_deb_ioctl("BT: adding %s\n", ethaddrs_str
);
144 ret
= libertas_prepare_and_send_command(priv
, cmd_bt_access
,
145 cmd_act_bt_access_add
,
146 cmd_option_waitforrsp
, 0, ethaddr
);
147 lbs_deb_leave_args(LBS_DEB_IOCTL
, "ret %d", ret
);
152 * @brief Delete an entry from the BT table
153 * @param priv A pointer to wlan_private structure
154 * @param req A pointer to ifreq structure
155 * @return 0 --success, otherwise fail
157 static int wlan_bt_del_ioctl(wlan_private
* priv
, struct ifreq
*req
)
159 struct iwreq
*wrq
= (struct iwreq
*)req
;
160 char ethaddrs_str
[18];
161 u8 ethaddr
[ETH_ALEN
];
164 lbs_deb_enter(LBS_DEB_IOCTL
);
166 if (copy_from_user(ethaddrs_str
, wrq
->u
.data
.pointer
,
167 sizeof(ethaddrs_str
)))
170 if ((pos
= eth_str2addr(ethaddrs_str
, ethaddr
)) == NULL
) {
171 lbs_pr_info("Invalid MAC address\n");
175 lbs_deb_ioctl("BT: deleting %s\n", ethaddrs_str
);
177 return (libertas_prepare_and_send_command(priv
,
179 cmd_act_bt_access_del
,
180 cmd_option_waitforrsp
, 0, ethaddr
));
182 lbs_deb_leave(LBS_DEB_IOCTL
);
187 * @brief Reset all entries from the BT table
188 * @param priv A pointer to wlan_private structure
189 * @return 0 --success, otherwise fail
191 static int wlan_bt_reset_ioctl(wlan_private
* priv
)
193 lbs_deb_enter(LBS_DEB_IOCTL
);
195 lbs_pr_alert( "BT: resetting\n");
197 return (libertas_prepare_and_send_command(priv
,
199 cmd_act_bt_access_reset
,
200 cmd_option_waitforrsp
, 0, NULL
));
202 lbs_deb_leave(LBS_DEB_IOCTL
);
207 * @brief List an entry from the BT table
208 * @param priv A pointer to wlan_private structure
209 * @param req A pointer to ifreq structure
210 * @return 0 --success, otherwise fail
212 static int wlan_bt_list_ioctl(wlan_private
* priv
, struct ifreq
*req
)
216 struct iwreq
*wrq
= (struct iwreq
*)req
;
217 /* used to pass id and store the bt entry returned by the FW */
220 char addr1addr2
[2 * ETH_ALEN
];
222 static char outstr
[64];
226 lbs_deb_enter(LBS_DEB_IOCTL
);
228 if (copy_from_user(outstr
, wrq
->u
.data
.pointer
, sizeof(outstr
))) {
229 lbs_deb_ioctl("Copy from user failed\n");
232 param
.id
= simple_strtoul(outstr
, NULL
, 10);
233 pos
= sprintf(pbuf
, "%d: ", param
.id
);
236 ret
= libertas_prepare_and_send_command(priv
, cmd_bt_access
,
237 cmd_act_bt_access_list
,
238 cmd_option_waitforrsp
, 0,
242 addr1
= param
.addr1addr2
;
244 pos
= sprintf(pbuf
, "BT includes node ");
246 pos
= eth_addr2str(addr1
, pbuf
);
249 sprintf(pbuf
, "(null)");
253 wrq
->u
.data
.length
= strlen(outstr
);
254 if (copy_to_user(wrq
->u
.data
.pointer
, (char *)outstr
,
255 wrq
->u
.data
.length
)) {
256 lbs_deb_ioctl("BT_LIST: Copy to user failed!\n");
260 lbs_deb_leave(LBS_DEB_IOCTL
);
265 * @brief Sets inverted state of blacklist (non-zero if inverted)
266 * @param priv A pointer to wlan_private structure
267 * @param req A pointer to ifreq structure
268 * @return 0 --success, otherwise fail
270 static int wlan_bt_set_invert_ioctl(wlan_private
* priv
, struct ifreq
*req
)
273 struct iwreq
*wrq
= (struct iwreq
*)req
;
276 char addr1addr2
[2 * ETH_ALEN
];
279 lbs_deb_enter(LBS_DEB_IOCTL
);
281 param
.id
= SUBCMD_DATA(wrq
) ;
282 ret
= libertas_prepare_and_send_command(priv
, cmd_bt_access
,
283 cmd_act_bt_access_set_invert
,
284 cmd_option_waitforrsp
, 0,
288 lbs_deb_leave(LBS_DEB_IOCTL
);
293 * @brief Gets inverted state of blacklist (non-zero if inverted)
294 * @param priv A pointer to wlan_private structure
295 * @param req A pointer to ifreq structure
296 * @return 0 --success, otherwise fail
298 static int wlan_bt_get_invert_ioctl(wlan_private
* priv
, struct ifreq
*req
)
303 char addr1addr2
[2 * ETH_ALEN
];
306 lbs_deb_enter(LBS_DEB_IOCTL
);
308 ret
= libertas_prepare_and_send_command(priv
, cmd_bt_access
,
309 cmd_act_bt_access_get_invert
,
310 cmd_option_waitforrsp
, 0,
314 req
->ifr_data
= (char *)(le32_to_cpu(param
.id
));
318 lbs_deb_leave(LBS_DEB_IOCTL
);
323 * @brief Find the next parameter in an input string
324 * @param ptr A pointer to the input parameter string
325 * @return A pointer to the next parameter, or 0 if no parameters left.
327 static char * next_param(char * ptr
)
329 if (!ptr
) return NULL
;
330 while (*ptr
== ' ' || *ptr
== '\t') ++ptr
;
331 return (*ptr
== '\0') ? NULL
: ptr
;
335 * @brief Add an entry to the FWT table
336 * @param priv A pointer to wlan_private structure
337 * @param req A pointer to ifreq structure
338 * @return 0 --success, otherwise fail
340 static int wlan_fwt_add_ioctl(wlan_private
* priv
, struct ifreq
*req
)
342 struct iwreq
*wrq
= (struct iwreq
*)req
;
344 static struct cmd_ds_fwt_access fwt_access
;
348 lbs_deb_enter(LBS_DEB_IOCTL
);
350 if (copy_from_user(in_str
, wrq
->u
.data
.pointer
, sizeof(in_str
)))
353 if ((ptr
= eth_str2addr(in_str
, fwt_access
.da
)) == NULL
) {
354 lbs_pr_alert( "FWT_ADD: Invalid MAC address 1\n");
358 if ((ptr
= eth_str2addr(ptr
, fwt_access
.ra
)) == NULL
) {
359 lbs_pr_alert( "FWT_ADD: Invalid MAC address 2\n");
363 if ((ptr
= next_param(ptr
)))
365 cpu_to_le32(simple_strtoul(ptr
, &ptr
, 10));
367 fwt_access
.metric
= FWT_DEFAULT_METRIC
;
369 if ((ptr
= next_param(ptr
)))
370 fwt_access
.dir
= (u8
)simple_strtoul(ptr
, &ptr
, 10);
372 fwt_access
.dir
= FWT_DEFAULT_DIR
;
374 if ((ptr
= next_param(ptr
)))
375 fwt_access
.rate
= (u8
) simple_strtoul(ptr
, &ptr
, 10);
377 fwt_access
.rate
= FWT_DEFAULT_RATE
;
379 if ((ptr
= next_param(ptr
)))
381 cpu_to_le32(simple_strtoul(ptr
, &ptr
, 10));
383 fwt_access
.ssn
= FWT_DEFAULT_SSN
;
385 if ((ptr
= next_param(ptr
)))
387 cpu_to_le32(simple_strtoul(ptr
, &ptr
, 10));
389 fwt_access
.dsn
= FWT_DEFAULT_DSN
;
391 if ((ptr
= next_param(ptr
)))
392 fwt_access
.hopcount
= simple_strtoul(ptr
, &ptr
, 10);
394 fwt_access
.hopcount
= FWT_DEFAULT_HOPCOUNT
;
396 if ((ptr
= next_param(ptr
)))
397 fwt_access
.ttl
= simple_strtoul(ptr
, &ptr
, 10);
399 fwt_access
.ttl
= FWT_DEFAULT_TTL
;
401 if ((ptr
= next_param(ptr
)))
402 fwt_access
.expiration
=
403 cpu_to_le32(simple_strtoul(ptr
, &ptr
, 10));
405 fwt_access
.expiration
= FWT_DEFAULT_EXPIRATION
;
407 if ((ptr
= next_param(ptr
)))
408 fwt_access
.sleepmode
= (u8
)simple_strtoul(ptr
, &ptr
, 10);
410 fwt_access
.sleepmode
= FWT_DEFAULT_SLEEPMODE
;
412 if ((ptr
= next_param(ptr
)))
414 cpu_to_le32(simple_strtoul(ptr
, &ptr
, 10));
416 fwt_access
.snr
= FWT_DEFAULT_SNR
;
420 char ethaddr1_str
[18], ethaddr2_str
[18];
421 eth_addr2str(fwt_access
.da
, ethaddr1_str
);
422 eth_addr2str(fwt_access
.ra
, ethaddr2_str
);
423 lbs_deb_ioctl("FWT_ADD: adding (da:%s,%i,ra:%s)\n", ethaddr1_str
,
424 fwt_access
.dir
, ethaddr2_str
);
425 lbs_deb_ioctl("FWT_ADD: ssn:%u dsn:%u met:%u hop:%u ttl:%u exp:%u slp:%u snr:%u\n",
426 fwt_access
.ssn
, fwt_access
.dsn
, fwt_access
.metric
,
427 fwt_access
.hopcount
, fwt_access
.ttl
, fwt_access
.expiration
,
428 fwt_access
.sleepmode
, fwt_access
.snr
);
432 ret
= libertas_prepare_and_send_command(priv
, cmd_fwt_access
,
433 cmd_act_fwt_access_add
,
434 cmd_option_waitforrsp
, 0,
435 (void *)&fwt_access
);
437 lbs_deb_leave_args(LBS_DEB_IOCTL
, "ret %d", ret
);
442 * @brief Delete an entry from the FWT table
443 * @param priv A pointer to wlan_private structure
444 * @param req A pointer to ifreq structure
445 * @return 0 --success, otherwise fail
447 static int wlan_fwt_del_ioctl(wlan_private
* priv
, struct ifreq
*req
)
449 struct iwreq
*wrq
= (struct iwreq
*)req
;
451 static struct cmd_ds_fwt_access fwt_access
;
455 lbs_deb_enter(LBS_DEB_IOCTL
);
457 if (copy_from_user(in_str
, wrq
->u
.data
.pointer
, sizeof(in_str
)))
460 if ((ptr
= eth_str2addr(in_str
, fwt_access
.da
)) == NULL
) {
461 lbs_pr_alert( "FWT_DEL: Invalid MAC address 1\n");
465 if ((ptr
= eth_str2addr(ptr
, fwt_access
.ra
)) == NULL
) {
466 lbs_pr_alert( "FWT_DEL: Invalid MAC address 2\n");
470 if ((ptr
= next_param(ptr
)))
471 fwt_access
.dir
= (u8
)simple_strtoul(ptr
, &ptr
, 10);
473 fwt_access
.dir
= FWT_DEFAULT_DIR
;
477 char ethaddr1_str
[18], ethaddr2_str
[18];
478 lbs_deb_ioctl("FWT_DEL: line is %s\n", in_str
);
479 eth_addr2str(fwt_access
.da
, ethaddr1_str
);
480 eth_addr2str(fwt_access
.ra
, ethaddr2_str
);
481 lbs_deb_ioctl("FWT_DEL: removing (da:%s,ra:%s,dir:%d)\n", ethaddr1_str
,
482 ethaddr2_str
, fwt_access
.dir
);
486 ret
= libertas_prepare_and_send_command(priv
,
488 cmd_act_fwt_access_del
,
489 cmd_option_waitforrsp
, 0,
490 (void *)&fwt_access
);
491 lbs_deb_leave_args(LBS_DEB_IOCTL
, "ret %d", ret
);
497 * @brief Print route parameters
498 * @param fwt_access struct cmd_ds_fwt_access with route info
499 * @param buf destination buffer for route info
501 static void print_route(struct cmd_ds_fwt_access fwt_access
, char *buf
)
503 buf
+= sprintf(buf
, " ");
504 buf
+= eth_addr2str(fwt_access
.da
, buf
);
505 buf
+= sprintf(buf
, " ");
506 buf
+= eth_addr2str(fwt_access
.ra
, buf
);
507 buf
+= sprintf(buf
, " %u", fwt_access
.valid
);
508 buf
+= sprintf(buf
, " %u", le32_to_cpu(fwt_access
.metric
));
509 buf
+= sprintf(buf
, " %u", fwt_access
.dir
);
510 buf
+= sprintf(buf
, " %u", fwt_access
.rate
);
511 buf
+= sprintf(buf
, " %u", le32_to_cpu(fwt_access
.ssn
));
512 buf
+= sprintf(buf
, " %u", le32_to_cpu(fwt_access
.dsn
));
513 buf
+= sprintf(buf
, " %u", fwt_access
.hopcount
);
514 buf
+= sprintf(buf
, " %u", fwt_access
.ttl
);
515 buf
+= sprintf(buf
, " %u", le32_to_cpu(fwt_access
.expiration
));
516 buf
+= sprintf(buf
, " %u", fwt_access
.sleepmode
);
517 buf
+= sprintf(buf
, " %u ", le32_to_cpu(fwt_access
.snr
));
518 buf
+= eth_addr2str(fwt_access
.prec
, buf
);
522 * @brief Lookup an entry in the FWT table
523 * @param priv A pointer to wlan_private structure
524 * @param req A pointer to ifreq structure
525 * @return 0 --success, otherwise fail
527 static int wlan_fwt_lookup_ioctl(wlan_private
* priv
, struct ifreq
*req
)
529 struct iwreq
*wrq
= (struct iwreq
*)req
;
532 static struct cmd_ds_fwt_access fwt_access
;
533 static char out_str
[128];
536 lbs_deb_enter(LBS_DEB_IOCTL
);
538 if (copy_from_user(in_str
, wrq
->u
.data
.pointer
, sizeof(in_str
)))
541 if ((ptr
= eth_str2addr(in_str
, fwt_access
.da
)) == NULL
) {
542 lbs_pr_alert( "FWT_LOOKUP: Invalid MAC address\n");
548 char ethaddr1_str
[18];
549 lbs_deb_ioctl("FWT_LOOKUP: line is %s\n", in_str
);
550 eth_addr2str(fwt_access
.da
, ethaddr1_str
);
551 lbs_deb_ioctl("FWT_LOOKUP: looking for (da:%s)\n", ethaddr1_str
);
555 ret
= libertas_prepare_and_send_command(priv
,
557 cmd_act_fwt_access_lookup
,
558 cmd_option_waitforrsp
, 0,
559 (void *)&fwt_access
);
562 print_route(fwt_access
, out_str
);
564 sprintf(out_str
, "(null)");
566 wrq
->u
.data
.length
= strlen(out_str
);
567 if (copy_to_user(wrq
->u
.data
.pointer
, (char *)out_str
,
568 wrq
->u
.data
.length
)) {
569 lbs_deb_ioctl("FWT_LOOKUP: Copy to user failed!\n");
573 lbs_deb_leave(LBS_DEB_IOCTL
);
578 * @brief Reset all entries from the FWT table
579 * @param priv A pointer to wlan_private structure
580 * @return 0 --success, otherwise fail
582 static int wlan_fwt_reset_ioctl(wlan_private
* priv
)
584 lbs_deb_ioctl("FWT: resetting\n");
586 return (libertas_prepare_and_send_command(priv
,
588 cmd_act_fwt_access_reset
,
589 cmd_option_waitforrsp
, 0, NULL
));
593 * @brief List an entry from the FWT table
594 * @param priv A pointer to wlan_private structure
595 * @param req A pointer to ifreq structure
596 * @return 0 --success, otherwise fail
598 static int wlan_fwt_list_ioctl(wlan_private
* priv
, struct ifreq
*req
)
600 struct iwreq
*wrq
= (struct iwreq
*)req
;
602 static struct cmd_ds_fwt_access fwt_access
;
604 static char out_str
[128];
605 char *pbuf
= out_str
;
608 lbs_deb_enter(LBS_DEB_IOCTL
);
610 if (copy_from_user(in_str
, wrq
->u
.data
.pointer
, sizeof(in_str
)))
613 fwt_access
.id
= cpu_to_le32(simple_strtoul(ptr
, &ptr
, 10));
617 lbs_deb_ioctl("FWT_LIST: line is %s\n", in_str
);
618 lbs_deb_ioctl("FWT_LIST: listing id:%i\n", le32_to_cpu(fwt_access
.id
));
622 ret
= libertas_prepare_and_send_command(priv
, cmd_fwt_access
,
623 cmd_act_fwt_access_list
,
624 cmd_option_waitforrsp
, 0, (void *)&fwt_access
);
627 print_route(fwt_access
, pbuf
);
629 pbuf
+= sprintf(pbuf
, " (null)");
631 wrq
->u
.data
.length
= strlen(out_str
);
632 if (copy_to_user(wrq
->u
.data
.pointer
, (char *)out_str
,
633 wrq
->u
.data
.length
)) {
634 lbs_deb_ioctl("FWT_LIST: Copy to user failed!\n");
638 lbs_deb_leave(LBS_DEB_IOCTL
);
643 * @brief List an entry from the FRT table
644 * @param priv A pointer to wlan_private structure
645 * @param req A pointer to ifreq structure
646 * @return 0 --success, otherwise fail
648 static int wlan_fwt_list_route_ioctl(wlan_private
* priv
, struct ifreq
*req
)
650 struct iwreq
*wrq
= (struct iwreq
*)req
;
652 static struct cmd_ds_fwt_access fwt_access
;
654 static char out_str
[128];
655 char *pbuf
= out_str
;
658 lbs_deb_enter(LBS_DEB_IOCTL
);
660 if (copy_from_user(in_str
, wrq
->u
.data
.pointer
, sizeof(in_str
)))
663 fwt_access
.id
= cpu_to_le32(simple_strtoul(ptr
, &ptr
, 10));
667 lbs_deb_ioctl("FWT_LIST_ROUTE: line is %s\n", in_str
);
668 lbs_deb_ioctl("FWT_LIST_ROUTE: listing id:%i\n", le32_to_cpu(fwt_access
.id
));
672 ret
= libertas_prepare_and_send_command(priv
, cmd_fwt_access
,
673 cmd_act_fwt_access_list_route
,
674 cmd_option_waitforrsp
, 0, (void *)&fwt_access
);
677 pbuf
+= sprintf(pbuf
, " ");
678 pbuf
+= eth_addr2str(fwt_access
.da
, pbuf
);
679 pbuf
+= sprintf(pbuf
, " %u", le32_to_cpu(fwt_access
.metric
));
680 pbuf
+= sprintf(pbuf
, " %u", fwt_access
.dir
);
681 /* note that the firmware returns the nid in the id field */
682 pbuf
+= sprintf(pbuf
, " %u", le32_to_cpu(fwt_access
.id
));
683 pbuf
+= sprintf(pbuf
, " %u", le32_to_cpu(fwt_access
.ssn
));
684 pbuf
+= sprintf(pbuf
, " %u", le32_to_cpu(fwt_access
.dsn
));
685 pbuf
+= sprintf(pbuf
, " hop %u", fwt_access
.hopcount
);
686 pbuf
+= sprintf(pbuf
, " ttl %u", fwt_access
.ttl
);
687 pbuf
+= sprintf(pbuf
, " %u", le32_to_cpu(fwt_access
.expiration
));
689 pbuf
+= sprintf(pbuf
, " (null)");
691 wrq
->u
.data
.length
= strlen(out_str
);
692 if (copy_to_user(wrq
->u
.data
.pointer
, (char *)out_str
,
693 wrq
->u
.data
.length
)) {
694 lbs_deb_ioctl("FWT_LIST_ROUTE: Copy to user failed!\n");
698 lbs_deb_leave(LBS_DEB_IOCTL
);
703 * @brief List an entry from the FNT table
704 * @param priv A pointer to wlan_private structure
705 * @param req A pointer to ifreq structure
706 * @return 0 --success, otherwise fail
708 static int wlan_fwt_list_neighbor_ioctl(wlan_private
* priv
, struct ifreq
*req
)
710 struct iwreq
*wrq
= (struct iwreq
*)req
;
712 static struct cmd_ds_fwt_access fwt_access
;
714 static char out_str
[128];
715 char *pbuf
= out_str
;
718 lbs_deb_enter(LBS_DEB_IOCTL
);
720 if (copy_from_user(in_str
, wrq
->u
.data
.pointer
, sizeof(in_str
)))
723 memset(&fwt_access
, 0, sizeof(fwt_access
));
724 fwt_access
.id
= cpu_to_le32(simple_strtoul(ptr
, &ptr
, 10));
728 lbs_deb_ioctl("FWT_LIST_NEIGHBOR: line is %s\n", in_str
);
729 lbs_deb_ioctl("FWT_LIST_NEIGHBOR: listing id:%i\n", le32_to_cpu(fwt_access
.id
));
733 ret
= libertas_prepare_and_send_command(priv
, cmd_fwt_access
,
734 cmd_act_fwt_access_list_neighbor
,
735 cmd_option_waitforrsp
, 0,
736 (void *)&fwt_access
);
739 pbuf
+= sprintf(pbuf
, " ra ");
740 pbuf
+= eth_addr2str(fwt_access
.ra
, pbuf
);
741 pbuf
+= sprintf(pbuf
, " slp %u", fwt_access
.sleepmode
);
742 pbuf
+= sprintf(pbuf
, " snr %u", le32_to_cpu(fwt_access
.snr
));
743 pbuf
+= sprintf(pbuf
, " ref %u", le32_to_cpu(fwt_access
.references
));
745 pbuf
+= sprintf(pbuf
, " (null)");
747 wrq
->u
.data
.length
= strlen(out_str
);
748 if (copy_to_user(wrq
->u
.data
.pointer
, (char *)out_str
,
749 wrq
->u
.data
.length
)) {
750 lbs_deb_ioctl("FWT_LIST_NEIGHBOR: Copy to user failed!\n");
754 lbs_deb_leave(LBS_DEB_IOCTL
);
759 * @brief Cleans up the route (FRT) and neighbor (FNT) tables
760 * (Garbage Collection)
761 * @param priv A pointer to wlan_private structure
762 * @param req A pointer to ifreq structure
763 * @return 0 --success, otherwise fail
765 static int wlan_fwt_cleanup_ioctl(wlan_private
* priv
, struct ifreq
*req
)
767 struct iwreq
*wrq
= (struct iwreq
*)req
;
768 static struct cmd_ds_fwt_access fwt_access
;
771 lbs_deb_enter(LBS_DEB_IOCTL
);
773 lbs_deb_ioctl("FWT: cleaning up\n");
775 memset(&fwt_access
, 0, sizeof(fwt_access
));
777 ret
= libertas_prepare_and_send_command(priv
, cmd_fwt_access
,
778 cmd_act_fwt_access_cleanup
,
779 cmd_option_waitforrsp
, 0,
780 (void *)&fwt_access
);
783 wrq
->u
.param
.value
= le32_to_cpu(fwt_access
.references
);
787 lbs_deb_leave(LBS_DEB_IOCTL
);
792 * @brief Gets firmware internal time (debug purposes)
793 * @param priv A pointer to wlan_private structure
794 * @param req A pointer to ifreq structure
795 * @return 0 --success, otherwise fail
797 static int wlan_fwt_time_ioctl(wlan_private
* priv
, struct ifreq
*req
)
799 struct iwreq
*wrq
= (struct iwreq
*)req
;
800 static struct cmd_ds_fwt_access fwt_access
;
803 lbs_deb_enter(LBS_DEB_IOCTL
);
805 lbs_deb_ioctl("FWT: getting time\n");
807 memset(&fwt_access
, 0, sizeof(fwt_access
));
809 ret
= libertas_prepare_and_send_command(priv
, cmd_fwt_access
,
810 cmd_act_fwt_access_time
,
811 cmd_option_waitforrsp
, 0,
812 (void *)&fwt_access
);
815 wrq
->u
.param
.value
= le32_to_cpu(fwt_access
.references
);
819 lbs_deb_leave(LBS_DEB_IOCTL
);
824 * @brief Gets mesh ttl from firmware
825 * @param priv A pointer to wlan_private structure
826 * @param req A pointer to ifreq structure
827 * @return 0 --success, otherwise fail
829 static int wlan_mesh_get_ttl_ioctl(wlan_private
* priv
, struct ifreq
*req
)
831 struct iwreq
*wrq
= (struct iwreq
*)req
;
832 struct cmd_ds_mesh_access mesh_access
;
835 lbs_deb_enter(LBS_DEB_IOCTL
);
837 memset(&mesh_access
, 0, sizeof(mesh_access
));
839 ret
= libertas_prepare_and_send_command(priv
, cmd_mesh_access
,
840 cmd_act_mesh_get_ttl
,
841 cmd_option_waitforrsp
, 0,
842 (void *)&mesh_access
);
845 wrq
->u
.param
.value
= le32_to_cpu(mesh_access
.data
[0]);
849 lbs_deb_leave(LBS_DEB_IOCTL
);
854 * @brief Gets mesh ttl from firmware
855 * @param priv A pointer to wlan_private structure
856 * @param ttl New ttl value
857 * @return 0 --success, otherwise fail
859 static int wlan_mesh_set_ttl_ioctl(wlan_private
* priv
, int ttl
)
861 struct cmd_ds_mesh_access mesh_access
;
864 lbs_deb_enter(LBS_DEB_IOCTL
);
866 if( (ttl
> 0xff) || (ttl
< 0) )
869 memset(&mesh_access
, 0, sizeof(mesh_access
));
870 mesh_access
.data
[0] = ttl
;
872 ret
= libertas_prepare_and_send_command(priv
, cmd_mesh_access
,
873 cmd_act_mesh_set_ttl
,
874 cmd_option_waitforrsp
, 0,
875 (void *)&mesh_access
);
880 lbs_deb_leave(LBS_DEB_IOCTL
);
885 * @brief ioctl function - entry point
887 * @param dev A pointer to net_device structure
888 * @param req A pointer to ifreq structure
890 * @return 0--success, otherwise fail
892 int libertas_do_ioctl(struct net_device
*dev
, struct ifreq
*req
, int cmd
)
898 wlan_private
*priv
= dev
->priv
;
899 wlan_adapter
*adapter
= priv
->adapter
;
900 struct iwreq
*wrq
= (struct iwreq
*)req
;
902 lbs_deb_enter(LBS_DEB_IOCTL
);
904 lbs_deb_ioctl("libertas_do_ioctl: ioctl cmd = 0x%x\n", cmd
);
906 case WLAN_SETNONE_GETNONE
: /* set WPA mode on/off ioctl #20 */
907 switch (wrq
->u
.data
.flags
) {
908 case WLAN_SUBCMD_BT_RESET
: /* bt_reset */
909 wlan_bt_reset_ioctl(priv
);
911 case WLAN_SUBCMD_FWT_RESET
: /* fwt_reset */
912 wlan_fwt_reset_ioctl(priv
);
914 } /* End of switch */
917 case WLAN_SETONEINT_GETNONE
:
918 /* The first 4 bytes of req->ifr_data is sub-ioctl number
919 * after 4 bytes sits the payload.
921 subcmd
= wrq
->u
.data
.flags
;
923 subcmd
= (int)wrq
->u
.param
.value
;
927 idata
= SUBCMD_DATA(wrq
);
928 ret
= wlan_set_region(priv
, (u16
) idata
);
930 case WLAN_SUBCMD_MESH_SET_TTL
:
931 idata
= SUBCMD_DATA(wrq
);
932 ret
= wlan_mesh_set_ttl_ioctl(priv
, idata
);
935 case WLAN_SUBCMD_BT_SET_INVERT
:
936 ret
= wlan_bt_set_invert_ioctl(priv
, req
);
946 case WLAN_SET128CHAR_GET128CHAR
:
947 switch ((int)wrq
->u
.data
.flags
) {
948 case WLAN_SUBCMD_BT_ADD
:
949 ret
= wlan_bt_add_ioctl(priv
, req
);
951 case WLAN_SUBCMD_BT_DEL
:
952 ret
= wlan_bt_del_ioctl(priv
, req
);
954 case WLAN_SUBCMD_BT_LIST
:
955 ret
= wlan_bt_list_ioctl(priv
, req
);
957 case WLAN_SUBCMD_FWT_ADD
:
958 ret
= wlan_fwt_add_ioctl(priv
, req
);
960 case WLAN_SUBCMD_FWT_DEL
:
961 ret
= wlan_fwt_del_ioctl(priv
, req
);
963 case WLAN_SUBCMD_FWT_LOOKUP
:
964 ret
= wlan_fwt_lookup_ioctl(priv
, req
);
966 case WLAN_SUBCMD_FWT_LIST_NEIGHBOR
:
967 ret
= wlan_fwt_list_neighbor_ioctl(priv
, req
);
969 case WLAN_SUBCMD_FWT_LIST
:
970 ret
= wlan_fwt_list_ioctl(priv
, req
);
972 case WLAN_SUBCMD_FWT_LIST_ROUTE
:
973 ret
= wlan_fwt_list_route_ioctl(priv
, req
);
978 case WLAN_SETNONE_GETONEINT
:
979 switch (wrq
->u
.param
.value
) {
981 pdata
= (int *)wrq
->u
.name
;
982 *pdata
= (int)adapter
->regioncode
;
984 case WLAN_SUBCMD_FWT_CLEANUP
: /* fwt_cleanup */
985 ret
= wlan_fwt_cleanup_ioctl(priv
, req
);
988 case WLAN_SUBCMD_FWT_TIME
: /* fwt_time */
989 ret
= wlan_fwt_time_ioctl(priv
, req
);
992 case WLAN_SUBCMD_MESH_GET_TTL
:
993 ret
= wlan_mesh_get_ttl_ioctl(priv
, req
);
996 case WLAN_SUBCMD_BT_GET_INVERT
:
997 ret
= wlan_bt_get_invert_ioctl(priv
, req
);
1007 case WLAN_SET_GET_SIXTEEN_INT
:
1008 switch ((int)wrq
->u
.data
.flags
) {
1009 case WLAN_LED_GPIO_CTRL
:
1014 struct cmd_ds_802_11_led_ctrl ctrl
;
1015 struct mrvlietypes_ledgpio
*gpio
=
1016 (struct mrvlietypes_ledgpio
*) ctrl
.data
;
1018 memset(&ctrl
, 0, sizeof(ctrl
));
1019 if (wrq
->u
.data
.length
> MAX_LEDS
* 2)
1021 if ((wrq
->u
.data
.length
% 2) != 0)
1023 if (wrq
->u
.data
.length
== 0) {
1029 (data
, wrq
->u
.data
.pointer
,
1031 wrq
->u
.data
.length
)) {
1033 "Copy from user failed\n");
1040 ctrl
.numled
= cpu_to_le16(0);
1042 cpu_to_le16(TLV_TYPE_LED_GPIO
);
1043 gpio
->header
.len
= wrq
->u
.data
.length
;
1044 for (i
= 0; i
< wrq
->u
.data
.length
;
1046 gpio
->ledpin
[i
/ 2].led
=
1048 gpio
->ledpin
[i
/ 2].pin
=
1053 libertas_prepare_and_send_command(priv
,
1054 cmd_802_11_led_gpio_ctrl
,
1056 cmd_option_waitforrsp
,
1058 for (i
= 0; i
< gpio
->header
.len
; i
+= 2) {
1059 data
[i
] = gpio
->ledpin
[i
/ 2].led
;
1060 data
[i
+ 1] = gpio
->ledpin
[i
/ 2].pin
;
1062 if (copy_to_user(wrq
->u
.data
.pointer
, data
,
1064 gpio
->header
.len
)) {
1065 lbs_deb_ioctl("Copy to user failed\n");
1069 wrq
->u
.data
.length
= gpio
->header
.len
;
1080 lbs_deb_leave_args(LBS_DEB_IOCTL
, "ret %d", ret
);