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 setrxantenna(wlan_private * priv, int mode)
33 wlan_adapter *adapter = priv->adapter;
35 if (mode != RF_ANTENNA_1 && mode != RF_ANTENNA_2
36 && mode != RF_ANTENNA_AUTO) {
40 adapter->rxantennamode = mode;
42 lbs_pr_debug(1, "SET RX Antenna mode to 0x%04x\n", adapter->rxantennamode);
44 ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_antenna,
46 cmd_option_waitforrsp, 0,
47 &adapter->rxantennamode);
51 static int settxantenna(wlan_private * priv, int mode)
54 wlan_adapter *adapter = priv->adapter;
56 if ((mode != RF_ANTENNA_1) && (mode != RF_ANTENNA_2)
57 && (mode != RF_ANTENNA_AUTO)) {
61 adapter->txantennamode = mode;
63 lbs_pr_debug(1, "SET TX Antenna mode to 0x%04x\n", adapter->txantennamode);
65 ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_antenna,
67 cmd_option_waitforrsp, 0,
68 &adapter->txantennamode);
73 static int getrxantenna(wlan_private * priv, char *buf)
76 wlan_adapter *adapter = priv->adapter;
78 // clear it, so we will know if the value
79 // returned below is correct or not.
80 adapter->rxantennamode = 0;
82 ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_antenna,
84 cmd_option_waitforrsp, 0, NULL);
91 lbs_pr_debug(1, "Get Rx Antenna mode:0x%04x\n", adapter->rxantennamode);
93 return sprintf(buf, "0x%04x", adapter->rxantennamode) + 1;
96 static int gettxantenna(wlan_private * priv, char *buf)
99 wlan_adapter *adapter = priv->adapter;
101 // clear it, so we will know if the value
102 // returned below is correct or not.
103 adapter->txantennamode = 0;
105 ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_antenna,
107 cmd_option_waitforrsp, 0, NULL);
114 lbs_pr_debug(1, "Get Tx Antenna mode:0x%04x\n", adapter->txantennamode);
116 return sprintf(buf, "0x%04x", adapter->txantennamode) + 1;
119 static int wlan_set_region(wlan_private * priv, u16 region_code)
123 for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
124 // use the region code to search for the index
125 if (region_code == libertas_region_code_to_index[i]) {
126 priv->adapter->regiontableindex = (u16) i;
127 priv->adapter->regioncode = region_code;
132 // if it's unidentified region code
133 if (i >= MRVDRV_MAX_REGION_CODE) {
134 lbs_pr_debug(1, "region Code not identified\n");
139 if (libertas_set_regiontable(priv, priv->adapter->regioncode, 0)) {
148 * @brief Get/Set Firmware wakeup method
150 * @param priv A pointer to wlan_private structure
151 * @param wrq A pointer to user data
152 * @return 0--success, otherwise fail
154 static int wlan_txcontrol(wlan_private * priv, struct iwreq *wrq)
156 wlan_adapter *adapter = priv->adapter;
160 if ((int)wrq->u.data.length == 0) {
162 (wrq->u.data.pointer, &adapter->pkttxctrl, sizeof(u32))) {
163 lbs_pr_alert("copy_to_user failed!\n");
167 if ((int)wrq->u.data.length > 1) {
168 lbs_pr_alert("ioctl too many args!\n");
171 if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
172 lbs_pr_alert("Copy from user failed\n");
176 adapter->pkttxctrl = (u32) data;
179 wrq->u.data.length = 1;
186 * @brief Get/Set NULL Package generation interval
188 * @param priv A pointer to wlan_private structure
189 * @param wrq A pointer to user data
190 * @return 0--success, otherwise fail
192 static int wlan_null_pkt_interval(wlan_private * priv, struct iwreq *wrq)
194 wlan_adapter *adapter = priv->adapter;
198 if ((int)wrq->u.data.length == 0) {
199 data = adapter->nullpktinterval;
201 if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) {
202 lbs_pr_alert( "copy_to_user failed!\n");
206 if ((int)wrq->u.data.length > 1) {
207 lbs_pr_alert( "ioctl too many args!\n");
210 if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
211 lbs_pr_debug(1, "Copy from user failed\n");
215 adapter->nullpktinterval = data;
218 wrq->u.data.length = 1;
224 static int wlan_get_rxinfo(wlan_private * priv, struct iwreq *wrq)
226 wlan_adapter *adapter = priv->adapter;
229 data[0] = adapter->SNR[TYPE_RXPD][TYPE_NOAVG];
230 data[1] = adapter->rxpd_rate;
231 if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * 2)) {
232 lbs_pr_debug(1, "Copy to user failed\n");
235 wrq->u.data.length = 2;
240 static int wlan_get_snr(wlan_private * priv, struct iwreq *wrq)
243 wlan_adapter *adapter = priv->adapter;
247 memset(data, 0, sizeof(data));
248 if (wrq->u.data.length) {
249 if (copy_from_user(data, wrq->u.data.pointer,
250 min_t(size_t, wrq->u.data.length, 4) * sizeof(int)))
253 if ((wrq->u.data.length == 0) || (data[0] == 0) || (data[0] == 1)) {
254 if (adapter->connect_status == libertas_connected) {
255 ret = libertas_prepare_and_send_command(priv,
258 cmd_option_waitforrsp,
268 if (wrq->u.data.length == 0) {
269 data[0] = adapter->SNR[TYPE_BEACON][TYPE_NOAVG];
270 data[1] = adapter->SNR[TYPE_BEACON][TYPE_AVG];
271 data[2] = adapter->SNR[TYPE_RXPD][TYPE_NOAVG];
272 data[3] = adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
273 if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * 4))
275 wrq->u.data.length = 4;
276 } else if (data[0] == 0) {
277 data[0] = adapter->SNR[TYPE_BEACON][TYPE_NOAVG];
278 if (copy_to_user(wrq->u.data.pointer, data, sizeof(int)))
280 wrq->u.data.length = 1;
281 } else if (data[0] == 1) {
282 data[0] = adapter->SNR[TYPE_BEACON][TYPE_AVG];
283 if (copy_to_user(wrq->u.data.pointer, data, sizeof(int)))
285 wrq->u.data.length = 1;
286 } else if (data[0] == 2) {
287 data[0] = adapter->SNR[TYPE_RXPD][TYPE_NOAVG];
288 if (copy_to_user(wrq->u.data.pointer, data, sizeof(int)))
290 wrq->u.data.length = 1;
291 } else if (data[0] == 3) {
292 data[0] = adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
293 if (copy_to_user(wrq->u.data.pointer, data, sizeof(int)))
295 wrq->u.data.length = 1;
303 static int wlan_beacon_interval(wlan_private * priv, struct iwreq *wrq)
306 wlan_adapter *adapter = priv->adapter;
308 if (wrq->u.data.length > 0) {
309 if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int)))
312 lbs_pr_debug(1, "WLAN SET BEACON INTERVAL: %d\n", data);
313 if ((data > MRVDRV_MAX_BEACON_INTERVAL)
314 || (data < MRVDRV_MIN_BEACON_INTERVAL))
316 adapter->beaconperiod = data;
318 data = adapter->beaconperiod;
319 if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int)))
322 wrq->u.data.length = 1;
327 static int wlan_get_rssi(wlan_private * priv, struct iwreq *wrq)
330 wlan_adapter *adapter = priv->adapter;
336 data = SUBCMD_DATA(wrq);
337 if ((data == 0) || (data == 1)) {
338 ret = libertas_prepare_and_send_command(priv,
340 0, cmd_option_waitforrsp,
351 temp = CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_NOAVG],
352 adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
355 temp = CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_AVG],
356 adapter->NF[TYPE_BEACON][TYPE_AVG]);
359 temp = CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_NOAVG],
360 adapter->NF[TYPE_RXPD][TYPE_NOAVG]);
363 temp = CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
364 adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
369 val = (int *)wrq->u.name;
376 static int wlan_get_nf(wlan_private * priv, struct iwreq *wrq)
379 wlan_adapter *adapter = priv->adapter;
384 data = SUBCMD_DATA(wrq);
385 if ((data == 0) || (data == 1)) {
386 ret = libertas_prepare_and_send_command(priv,
388 0, cmd_option_waitforrsp,
399 temp = adapter->NF[TYPE_BEACON][TYPE_NOAVG];
402 temp = adapter->NF[TYPE_BEACON][TYPE_AVG];
405 temp = adapter->NF[TYPE_RXPD][TYPE_NOAVG];
408 temp = adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
416 lbs_pr_debug(1, "%s: temp = %d\n", __FUNCTION__, temp);
417 val = (int *)wrq->u.name;
422 static int wlan_get_txrate_ioctl(wlan_private * priv, struct ifreq *req)
424 wlan_adapter *adapter = priv->adapter;
426 struct iwreq *wrq = (struct iwreq *)req;
429 lbs_pr_debug(1, "wlan_get_txrate_ioctl\n");
430 ret = libertas_prepare_and_send_command(priv, cmd_802_11_tx_rate_query,
431 cmd_act_get, cmd_option_waitforrsp,
436 pdata = (int *)wrq->u.name;
437 *pdata = (int)adapter->txrate;
441 static int wlan_get_adhoc_status_ioctl(wlan_private * priv, struct iwreq *wrq)
444 wlan_adapter *adapter = priv->adapter;
446 memset(status, 0, sizeof(status));
448 switch (adapter->inframode) {
450 if (adapter->connect_status == libertas_connected) {
451 if (adapter->adhoccreate)
452 memcpy(&status, "AdhocStarted", sizeof(status));
454 memcpy(&status, "AdhocJoined", sizeof(status));
456 memcpy(&status, "AdhocIdle", sizeof(status));
459 case wlan802_11infrastructure:
460 memcpy(&status, "Inframode", sizeof(status));
463 memcpy(&status, "AutoUnknownmode", sizeof(status));
467 lbs_pr_debug(1, "status = %s\n", status);
468 wrq->u.data.length = strlen(status) + 1;
470 if (wrq->u.data.pointer) {
471 if (copy_to_user(wrq->u.data.pointer,
472 &status, wrq->u.data.length))
481 * @brief Set/Get WPA IE
482 * @param priv A pointer to wlan_private structure
483 * @param req A pointer to ifreq structure
484 * @return 0 --success, otherwise fail
486 static int wlan_setwpaie_ioctl(wlan_private * priv, struct ifreq *req)
488 struct iwreq *wrq = (struct iwreq *)req;
489 wlan_adapter *adapter = priv->adapter;
494 if (wrq->u.data.length) {
495 if (wrq->u.data.length > sizeof(adapter->wpa_ie)) {
496 lbs_pr_debug(1, "failed to copy WPA IE, too big \n");
499 if (copy_from_user(adapter->wpa_ie, wrq->u.data.pointer,
500 wrq->u.data.length)) {
501 lbs_pr_debug(1, "failed to copy WPA IE \n");
504 adapter->wpa_ie_len = wrq->u.data.length;
505 lbs_pr_debug(1, "Set wpa_ie_len=%d IE=%#x\n", adapter->wpa_ie_len,
507 lbs_dbg_hex("wpa_ie", adapter->wpa_ie, adapter->wpa_ie_len);
508 if (adapter->wpa_ie[0] == WPA_IE)
509 adapter->secinfo.WPAenabled = 1;
510 else if (adapter->wpa_ie[0] == WPA2_IE)
511 adapter->secinfo.WPA2enabled = 1;
513 adapter->secinfo.WPAenabled = 0;
514 adapter->secinfo.WPA2enabled = 0;
517 memset(adapter->wpa_ie, 0, sizeof(adapter->wpa_ie));
518 adapter->wpa_ie_len = wrq->u.data.length;
519 lbs_pr_debug(1, "Reset wpa_ie_len=%d IE=%#x\n",
520 adapter->wpa_ie_len, adapter->wpa_ie[0]);
521 adapter->secinfo.WPAenabled = 0;
522 adapter->secinfo.WPA2enabled = 0;
525 // enable/disable RSN in firmware if WPA is enabled/disabled
526 // depending on variable adapter->secinfo.WPAenabled is set or not
527 ret = libertas_prepare_and_send_command(priv, cmd_802_11_enable_rsn,
528 cmd_act_set, cmd_option_waitforrsp,
536 * @brief Set Auto prescan
537 * @param priv A pointer to wlan_private structure
538 * @param wrq A pointer to iwreq structure
539 * @return 0 --success, otherwise fail
541 static int wlan_subcmd_setprescan_ioctl(wlan_private * priv, struct iwreq *wrq)
544 wlan_adapter *adapter = priv->adapter;
547 data = SUBCMD_DATA(wrq);
548 lbs_pr_debug(1, "WLAN_SUBCMD_SET_PRESCAN %d\n", data);
549 adapter->prescan = data;
551 val = (int *)wrq->u.name;
556 static int wlan_set_multiple_dtim_ioctl(wlan_private * priv, struct ifreq *req)
558 struct iwreq *wrq = (struct iwreq *)req;
565 idata = SUBCMD_DATA(wrq);
567 if (((mdtim >= MRVDRV_MIN_MULTIPLE_DTIM)
568 && (mdtim <= MRVDRV_MAX_MULTIPLE_DTIM))
569 || (mdtim == MRVDRV_IGNORE_MULTIPLE_DTIM)) {
570 priv->adapter->multipledtim = mdtim;
574 lbs_pr_debug(1, "Invalid parameter, multipledtim not changed.\n");
581 * @brief Set authentication mode
582 * @param priv A pointer to wlan_private structure
583 * @param req A pointer to ifreq structure
584 * @return 0 --success, otherwise fail
586 static int wlan_setauthalg_ioctl(wlan_private * priv, struct ifreq *req)
589 struct iwreq *wrq = (struct iwreq *)req;
590 wlan_adapter *adapter = priv->adapter;
592 if (wrq->u.data.flags == 0) {
594 alg = SUBCMD_DATA(wrq);
596 //from wpa_supplicant subcmd
597 if (copy_from_user(&alg, wrq->u.data.pointer, sizeof(alg))) {
598 lbs_pr_debug(1, "Copy from user failed\n");
603 lbs_pr_debug(1, "auth alg is %#x\n", alg);
606 case AUTH_ALG_SHARED_KEY:
607 adapter->secinfo.authmode = wlan802_11authmodeshared;
609 case AUTH_ALG_NETWORK_EAP:
610 adapter->secinfo.authmode =
611 wlan802_11authmodenetworkEAP;
613 case AUTH_ALG_OPEN_SYSTEM:
615 adapter->secinfo.authmode = wlan802_11authmodeopen;
621 static int wlan_setencryptionmode_ioctl(wlan_private * priv, struct ifreq *req)
624 struct iwreq *wrq = (struct iwreq *)req;
628 if (wrq->u.data.flags == 0) {
630 mode = SUBCMD_DATA(wrq);
632 //from wpa_supplicant subcmd
633 if (copy_from_user(&mode, wrq->u.data.pointer, sizeof(int))) {
634 lbs_pr_debug(1, "Copy from user failed\n");
638 lbs_pr_debug(1, "encryption mode is %#x\n", mode);
639 priv->adapter->secinfo.Encryptionmode = mode;
645 static void adjust_mtu(wlan_private * priv)
647 int mtu_increment = 0;
649 if (priv->adapter->linkmode == WLAN_LINKMODE_802_11)
650 mtu_increment += sizeof(struct ieee80211_hdr_4addr);
652 if (priv->adapter->radiomode == WLAN_RADIOMODE_RADIOTAP)
653 mtu_increment += max(sizeof(struct tx_radiotap_hdr),
654 sizeof(struct rx_radiotap_hdr));
655 priv->wlan_dev.netdev->mtu = ETH_FRAME_LEN
656 - sizeof(struct ethhdr)
661 * @brief Set Link-Layer Layer mode
662 * @param priv A pointer to wlan_private structure
663 * @param req A pointer to ifreq structure
664 * @return 0 --success, otherwise fail
666 static int wlan_set_linkmode_ioctl(wlan_private * priv, struct ifreq *req)
670 mode = (int)((struct ifreq *)((u8 *) req + 4))->ifr_data;
673 case WLAN_LINKMODE_802_3:
674 priv->adapter->linkmode = mode;
676 case WLAN_LINKMODE_802_11:
677 priv->adapter->linkmode = mode;
680 lbs_pr_info("usb8388-5: invalid link-layer mode (%#x)\n",
685 lbs_pr_debug(1, "usb8388-5: link-layer mode is %#x\n", mode);
693 * @brief Set Radio header mode
694 * @param priv A pointer to wlan_private structure
695 * @param req A pointer to ifreq structure
696 * @return 0 --success, otherwise fail
698 static int wlan_set_radiomode_ioctl(wlan_private * priv, struct ifreq *req)
702 mode = (int)((struct ifreq *)((u8 *) req + 4))->ifr_data;
705 case WLAN_RADIOMODE_NONE:
706 priv->adapter->radiomode = mode;
708 case WLAN_RADIOMODE_RADIOTAP:
709 priv->adapter->radiomode = mode;
712 lbs_pr_debug(1, "usb8388-5: invalid radio header mode (%#x)\n",
716 lbs_pr_debug(1, "usb8388-5: radio-header mode is %#x\n", mode);
723 * @brief Set Debug header mode
724 * @param priv A pointer to wlan_private structure
725 * @param req A pointer to ifreq structure
726 * @return 0 --success, otherwise fail
728 static int wlan_set_debugmode_ioctl(wlan_private * priv, struct ifreq *req)
730 priv->adapter->debugmode = (int)((struct ifreq *)
731 ((u8 *) req + 4))->ifr_data;
735 static int wlan_subcmd_getrxantenna_ioctl(wlan_private * priv,
740 struct iwreq *wrq = (struct iwreq *)req;
742 lbs_pr_debug(1, "WLAN_SUBCMD_GETRXANTENNA\n");
743 len = getrxantenna(priv, buf);
745 wrq->u.data.length = len;
746 if (wrq->u.data.pointer) {
747 if (copy_to_user(wrq->u.data.pointer, &buf, len)) {
748 lbs_pr_debug(1, "CopyToUser failed\n");
756 static int wlan_subcmd_gettxantenna_ioctl(wlan_private * priv,
761 struct iwreq *wrq = (struct iwreq *)req;
763 lbs_pr_debug(1, "WLAN_SUBCMD_GETTXANTENNA\n");
764 len = gettxantenna(priv, buf);
766 wrq->u.data.length = len;
767 if (wrq->u.data.pointer) {
768 if (copy_to_user(wrq->u.data.pointer, &buf, len)) {
769 lbs_pr_debug(1, "CopyToUser failed\n");
777 * @brief Get the MAC TSF value from the firmware
779 * @param priv A pointer to wlan_private structure
780 * @param wrq A pointer to iwreq structure containing buffer
781 * space to store a TSF value retrieved from the firmware
783 * @return 0 if successful; IOCTL error code otherwise
785 static int wlan_get_tsf_ioctl(wlan_private * priv, struct iwreq *wrq)
790 ret = libertas_prepare_and_send_command(priv,
792 0, cmd_option_waitforrsp, 0, &tsfval);
794 lbs_pr_debug(1, "IOCTL: Get TSF = 0x%016llx\n", tsfval);
797 lbs_pr_debug(1, "IOCTL: Get TSF; command exec failed\n");
800 if (copy_to_user(wrq->u.data.pointer,
802 min_t(size_t, wrq->u.data.length,
803 sizeof(tsfval))) != 0) {
805 lbs_pr_debug(1, "IOCTL: Get TSF; Copy to user failed\n");
815 * @brief Get/Set adapt rate
816 * @param priv A pointer to wlan_private structure
817 * @param wrq A pointer to iwreq structure
818 * @return 0 --success, otherwise fail
820 static int wlan_adapt_rateset(wlan_private * priv, struct iwreq *wrq)
823 wlan_adapter *adapter = priv->adapter;
826 memset(data, 0, sizeof(data));
827 if (!wrq->u.data.length) {
828 lbs_pr_debug(1, "Get ADAPT RATE SET\n");
829 ret = libertas_prepare_and_send_command(priv,
830 cmd_802_11_rate_adapt_rateset,
832 cmd_option_waitforrsp, 0, NULL);
833 data[0] = adapter->enablehwauto;
834 data[1] = adapter->ratebitmap;
835 if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * 2)) {
836 lbs_pr_debug(1, "Copy to user failed\n");
839 #define GET_TWO_INT 2
840 wrq->u.data.length = GET_TWO_INT;
842 lbs_pr_debug(1, "Set ADAPT RATE SET\n");
843 if (wrq->u.data.length > 2)
846 (data, wrq->u.data.pointer,
847 sizeof(int) * wrq->u.data.length)) {
848 lbs_pr_debug(1, "Copy from user failed\n");
852 adapter->enablehwauto = data[0];
853 adapter->ratebitmap = data[1];
854 ret = libertas_prepare_and_send_command(priv,
855 cmd_802_11_rate_adapt_rateset,
857 cmd_option_waitforrsp, 0, NULL);
863 * @brief Get/Set inactivity timeout
864 * @param priv A pointer to wlan_private structure
865 * @param wrq A pointer to iwreq structure
866 * @return 0 --success, otherwise fail
868 static int wlan_inactivity_timeout(wlan_private * priv, struct iwreq *wrq)
875 if (wrq->u.data.length > 1)
878 if (wrq->u.data.length == 0) {
880 ret = libertas_prepare_and_send_command(priv,
881 cmd_802_11_inactivity_timeout,
883 cmd_option_waitforrsp, 0,
886 if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) {
887 lbs_pr_debug(1, "Copy to user failed\n");
892 if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
893 lbs_pr_debug(1, "Copy from user failed\n");
898 ret = libertas_prepare_and_send_command(priv,
899 cmd_802_11_inactivity_timeout,
901 cmd_option_waitforrsp, 0,
905 wrq->u.data.length = 1;
911 static int wlan_do_getlog_ioctl(wlan_private * priv, struct iwreq *wrq)
914 char buf[GETLOG_BUFSIZE - 1];
915 wlan_adapter *adapter = priv->adapter;
917 lbs_pr_debug(1, " GET STATS\n");
919 ret = libertas_prepare_and_send_command(priv, cmd_802_11_get_log,
920 0, cmd_option_waitforrsp, 0, NULL);
926 if (wrq->u.data.pointer) {
927 sprintf(buf, "\n mcasttxframe %u failed %u retry %u "
928 "multiretry %u framedup %u "
929 "rtssuccess %u rtsfailure %u ackfailure %u\n"
930 "rxfrag %u mcastrxframe %u fcserror %u "
931 "txframe %u wepundecryptable %u ",
932 adapter->logmsg.mcasttxframe,
933 adapter->logmsg.failed,
934 adapter->logmsg.retry,
935 adapter->logmsg.multiretry,
936 adapter->logmsg.framedup,
937 adapter->logmsg.rtssuccess,
938 adapter->logmsg.rtsfailure,
939 adapter->logmsg.ackfailure,
940 adapter->logmsg.rxfrag,
941 adapter->logmsg.mcastrxframe,
942 adapter->logmsg.fcserror,
943 adapter->logmsg.txframe,
944 adapter->logmsg.wepundecryptable);
945 wrq->u.data.length = strlen(buf) + 1;
946 if (copy_to_user(wrq->u.data.pointer, buf, wrq->u.data.length)) {
947 lbs_pr_debug(1, "Copy to user failed\n");
955 static int wlan_scan_type_ioctl(wlan_private * priv, struct iwreq *wrq)
958 u8 *option[] = { "active", "passive", "get", };
959 int i, max_options = (sizeof(option) / sizeof(option[0]));
961 wlan_adapter *adapter = priv->adapter;
963 if (priv->adapter->enable11d) {
964 lbs_pr_debug(1, "11D: Cannot set scantype when 11D enabled\n");
968 memset(buf, 0, sizeof(buf));
970 if (copy_from_user(buf, wrq->u.data.pointer, min_t(size_t, sizeof(buf),
971 wrq->u.data.length)))
974 lbs_pr_debug(1, "Scan type Option = %s\n", buf);
976 buf[sizeof(buf) - 1] = '\0';
978 for (i = 0; i < max_options; i++) {
979 if (!strcmp(buf, option[i]))
985 adapter->scantype = cmd_scan_type_active;
988 adapter->scantype = cmd_scan_type_passive;
991 wrq->u.data.length = strlen(option[adapter->scantype]) + 1;
993 if (copy_to_user(wrq->u.data.pointer,
994 option[adapter->scantype],
995 wrq->u.data.length)) {
996 lbs_pr_debug(1, "Copy to user failed\n");
1002 lbs_pr_debug(1, "Invalid Scan type Ioctl Option\n");
1010 static int wlan_scan_mode_ioctl(wlan_private * priv, struct iwreq *wrq)
1012 wlan_adapter *adapter = priv->adapter;
1014 u8 *option[] = { "bss", "ibss", "any", "get" };
1015 int i, max_options = (sizeof(option) / sizeof(option[0]));
1020 memset(buf, 0, sizeof(buf));
1022 if (copy_from_user(buf, wrq->u.data.pointer, min_t(size_t, sizeof(buf),
1023 wrq->u.data.length))) {
1024 lbs_pr_debug(1, "Copy from user failed\n");
1028 lbs_pr_debug(1, "Scan mode Option = %s\n", buf);
1030 buf[sizeof(buf) - 1] = '\0';
1032 for (i = 0; i < max_options; i++) {
1033 if (!strcmp(buf, option[i]))
1040 adapter->scanmode = cmd_bss_type_bss;
1043 adapter->scanmode = cmd_bss_type_ibss;
1046 adapter->scanmode = cmd_bss_type_any;
1050 wrq->u.data.length = strlen(option[adapter->scanmode - 1]) + 1;
1052 lbs_pr_debug(1, "Get Scan mode Option = %s\n",
1053 option[adapter->scanmode - 1]);
1055 lbs_pr_debug(1, "Scan mode length %d\n", wrq->u.data.length);
1057 if (copy_to_user(wrq->u.data.pointer,
1058 option[adapter->scanmode - 1],
1059 wrq->u.data.length)) {
1060 lbs_pr_debug(1, "Copy to user failed\n");
1063 lbs_pr_debug(1, "GET Scan type Option after copy = %s\n",
1064 (char *)wrq->u.data.pointer);
1069 lbs_pr_debug(1, "Invalid Scan mode Ioctl Option\n");
1079 * @brief Get/Set Adhoc G Rate
1081 * @param priv A pointer to wlan_private structure
1082 * @param wrq A pointer to user data
1083 * @return 0--success, otherwise fail
1085 static int wlan_do_set_grate_ioctl(wlan_private * priv, struct iwreq *wrq)
1087 wlan_adapter *adapter = priv->adapter;
1093 data1 = SUBCMD_DATA(wrq);
1096 adapter->adhoc_grate_enabled = 0;
1099 adapter->adhoc_grate_enabled = 1;
1106 data = adapter->adhoc_grate_enabled;
1107 val = (int *)wrq->u.name;
1113 static inline int hex2int(char c)
1115 if (c >= '0' && c <= '9')
1117 if (c >= 'a' && c <= 'f')
1118 return (c - 'a' + 10);
1119 if (c >= 'A' && c <= 'F')
1120 return (c - 'A' + 10);
1124 /* Convert a string representation of a MAC address ("xx:xx:xx:xx:xx:xx")
1125 into binary format (6 bytes).
1127 This function expects that each byte is represented with 2 characters
1128 (e.g., 11:2:11:11:11:11 is invalid)
1131 static char *eth_str2addr(char *ethstr, u8 * addr)
1136 /* get rid of initial blanks */
1137 while (*pos == ' ' || *pos == '\t')
1140 for (i = 0; i < 6; i++) {
1141 val = hex2int(*pos++);
1144 val2 = hex2int(*pos++);
1147 addr[i] = (val * 16 + val2) & 0xff;
1149 if (i < 5 && *pos++ != ':')
1155 /* this writes xx:xx:xx:xx:xx:xx into ethstr
1156 (ethstr must have space for 18 chars) */
1157 static int eth_addr2str(u8 * addr, char *ethstr)
1162 for (i = 0; i < 6; i++) {
1163 sprintf(pos, "%02x", addr[i] & 0xff);
1172 * @brief Add an entry to the BT table
1173 * @param priv A pointer to wlan_private structure
1174 * @param req A pointer to ifreq structure
1175 * @return 0 --success, otherwise fail
1177 static int wlan_bt_add_ioctl(wlan_private * priv, struct ifreq *req)
1179 struct iwreq *wrq = (struct iwreq *)req;
1180 char ethaddrs_str[18];
1182 u8 ethaddr[ETH_ALEN];
1185 if (copy_from_user(ethaddrs_str, wrq->u.data.pointer,
1186 sizeof(ethaddrs_str)))
1189 if ((pos = eth_str2addr(ethaddrs_str, ethaddr)) == NULL) {
1190 lbs_pr_info("BT_ADD: Invalid MAC address\n");
1194 lbs_pr_debug(1, "BT: adding %s\n", ethaddrs_str);
1196 return (libertas_prepare_and_send_command(priv, cmd_bt_access,
1197 cmd_act_bt_access_add,
1198 cmd_option_waitforrsp, 0, ethaddr));
1202 * @brief Delete an entry from the BT table
1203 * @param priv A pointer to wlan_private structure
1204 * @param req A pointer to ifreq structure
1205 * @return 0 --success, otherwise fail
1207 static int wlan_bt_del_ioctl(wlan_private * priv, struct ifreq *req)
1209 struct iwreq *wrq = (struct iwreq *)req;
1210 char ethaddrs_str[18];
1211 u8 ethaddr[ETH_ALEN];
1215 if (copy_from_user(ethaddrs_str, wrq->u.data.pointer,
1216 sizeof(ethaddrs_str)))
1219 if ((pos = eth_str2addr(ethaddrs_str, ethaddr)) == NULL) {
1220 lbs_pr_info("Invalid MAC address\n");
1224 lbs_pr_debug(1, "BT: deleting %s\n", ethaddrs_str);
1226 return (libertas_prepare_and_send_command(priv,
1228 cmd_act_bt_access_del,
1229 cmd_option_waitforrsp, 0, ethaddr));
1235 * @brief Reset all entries from the BT table
1236 * @param priv A pointer to wlan_private structure
1237 * @return 0 --success, otherwise fail
1239 static int wlan_bt_reset_ioctl(wlan_private * priv)
1243 lbs_pr_alert( "BT: resetting\n");
1245 return (libertas_prepare_and_send_command(priv,
1247 cmd_act_bt_access_reset,
1248 cmd_option_waitforrsp, 0, NULL));
1255 * @brief List an entry from the BT table
1256 * @param priv A pointer to wlan_private structure
1257 * @param req A pointer to ifreq structure
1258 * @return 0 --success, otherwise fail
1260 static int wlan_bt_list_ioctl(wlan_private * priv, struct ifreq *req)
1264 struct iwreq *wrq = (struct iwreq *)req;
1265 /* used to pass id and store the bt entry returned by the FW */
1268 char addr1addr2[2 * ETH_ALEN];
1270 static char outstr[64];
1271 char *pbuf = outstr;
1276 if (copy_from_user(outstr, wrq->u.data.pointer, sizeof(outstr))) {
1277 lbs_pr_debug(1, "Copy from user failed\n");
1280 param.id = simple_strtoul(outstr, NULL, 10);
1281 pos = sprintf(pbuf, "%d: ", param.id);
1284 ret = libertas_prepare_and_send_command(priv, cmd_bt_access,
1285 cmd_act_bt_access_list,
1286 cmd_option_waitforrsp, 0,
1290 addr1 = param.addr1addr2;
1292 pos = sprintf(pbuf, "ignoring traffic from ");
1294 pos = eth_addr2str(addr1, pbuf);
1297 sprintf(pbuf, "(null)");
1301 wrq->u.data.length = strlen(outstr);
1302 if (copy_to_user(wrq->u.data.pointer, (char *)outstr,
1303 wrq->u.data.length)) {
1304 lbs_pr_debug(1, "BT_LIST: Copy to user failed!\n");
1313 * @brief Find the next parameter in an input string
1314 * @param ptr A pointer to the input parameter string
1315 * @return A pointer to the next parameter, or 0 if no parameters left.
1317 static char * next_param(char * ptr)
1319 if (!ptr) return NULL;
1320 while (*ptr == ' ' || *ptr == '\t') ++ptr;
1321 return (*ptr == '\0') ? NULL : ptr;
1325 * @brief Add an entry to the FWT table
1326 * @param priv A pointer to wlan_private structure
1327 * @param req A pointer to ifreq structure
1328 * @return 0 --success, otherwise fail
1330 static int wlan_fwt_add_ioctl(wlan_private * priv, struct ifreq *req)
1332 struct iwreq *wrq = (struct iwreq *)req;
1334 static struct cmd_ds_fwt_access fwt_access;
1338 if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
1341 if ((ptr = eth_str2addr(in_str, fwt_access.da)) == NULL) {
1342 lbs_pr_alert( "FWT_ADD: Invalid MAC address 1\n");
1346 if ((ptr = eth_str2addr(ptr, fwt_access.ra)) == NULL) {
1347 lbs_pr_alert( "FWT_ADD: Invalid MAC address 2\n");
1351 if ((ptr = next_param(ptr)))
1353 cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
1355 fwt_access.metric = FWT_DEFAULT_METRIC;
1357 if ((ptr = next_param(ptr)))
1358 fwt_access.dir = (u8)simple_strtoul(ptr, &ptr, 10);
1360 fwt_access.dir = FWT_DEFAULT_DIR;
1362 if ((ptr = next_param(ptr)))
1364 cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
1366 fwt_access.ssn = FWT_DEFAULT_SSN;
1368 if ((ptr = next_param(ptr)))
1370 cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
1372 fwt_access.dsn = FWT_DEFAULT_DSN;
1374 if ((ptr = next_param(ptr)))
1375 fwt_access.hopcount = simple_strtoul(ptr, &ptr, 10);
1377 fwt_access.hopcount = FWT_DEFAULT_HOPCOUNT;
1379 if ((ptr = next_param(ptr)))
1380 fwt_access.ttl = simple_strtoul(ptr, &ptr, 10);
1382 fwt_access.ttl = FWT_DEFAULT_TTL;
1384 if ((ptr = next_param(ptr)))
1385 fwt_access.expiration =
1386 cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
1388 fwt_access.expiration = FWT_DEFAULT_EXPIRATION;
1390 if ((ptr = next_param(ptr)))
1391 fwt_access.sleepmode = (u8)simple_strtoul(ptr, &ptr, 10);
1393 fwt_access.sleepmode = FWT_DEFAULT_SLEEPMODE;
1395 if ((ptr = next_param(ptr)))
1397 cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
1399 fwt_access.snr = FWT_DEFAULT_SNR;
1403 char ethaddr1_str[18], ethaddr2_str[18];
1404 eth_addr2str(fwt_access.da, ethaddr1_str);
1405 eth_addr2str(fwt_access.ra, ethaddr2_str);
1406 lbs_pr_debug(1, "FWT_ADD: adding (da:%s,%i,ra:%s)\n", ethaddr1_str,
1407 fwt_access.dir, ethaddr2_str);
1408 lbs_pr_debug(1, "FWT_ADD: ssn:%u dsn:%u met:%u hop:%u ttl:%u exp:%u slp:%u snr:%u\n",
1409 fwt_access.ssn, fwt_access.dsn, fwt_access.metric,
1410 fwt_access.hopcount, fwt_access.ttl, fwt_access.expiration,
1411 fwt_access.sleepmode, fwt_access.snr);
1416 return (libertas_prepare_and_send_command(priv, cmd_fwt_access,
1417 cmd_act_fwt_access_add,
1418 cmd_option_waitforrsp, 0,
1419 (void *)&fwt_access));
1423 * @brief Delete an entry from the FWT table
1424 * @param priv A pointer to wlan_private structure
1425 * @param req A pointer to ifreq structure
1426 * @return 0 --success, otherwise fail
1428 static int wlan_fwt_del_ioctl(wlan_private * priv, struct ifreq *req)
1430 struct iwreq *wrq = (struct iwreq *)req;
1432 static struct cmd_ds_fwt_access fwt_access;
1436 if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
1439 if ((ptr = eth_str2addr(in_str, fwt_access.da)) == NULL) {
1440 lbs_pr_alert( "FWT_DEL: Invalid MAC address 1\n");
1444 if ((ptr = eth_str2addr(ptr, fwt_access.ra)) == NULL) {
1445 lbs_pr_alert( "FWT_DEL: Invalid MAC address 2\n");
1449 if ((ptr = next_param(ptr)))
1450 fwt_access.dir = (u8)simple_strtoul(ptr, &ptr, 10);
1452 fwt_access.dir = FWT_DEFAULT_DIR;
1456 char ethaddr1_str[18], ethaddr2_str[18];
1457 lbs_pr_debug(1, "FWT_DEL: line is %s\n", in_str);
1458 eth_addr2str(fwt_access.da, ethaddr1_str);
1459 eth_addr2str(fwt_access.ra, ethaddr2_str);
1460 lbs_pr_debug(1, "FWT_DEL: removing (da:%s,ra:%s,dir:%d)\n", ethaddr1_str,
1461 ethaddr2_str, fwt_access.dir);
1466 return (libertas_prepare_and_send_command(priv,
1468 cmd_act_fwt_access_del,
1469 cmd_option_waitforrsp, 0,
1470 (void *)&fwt_access));
1475 * @brief Print route parameters
1476 * @param fwt_access struct cmd_ds_fwt_access with route info
1477 * @param buf destination buffer for route info
1479 static void print_route(struct cmd_ds_fwt_access fwt_access, char *buf)
1481 buf += sprintf(buf, " ");
1482 buf += eth_addr2str(fwt_access.da, buf);
1483 buf += sprintf(buf, " ");
1484 buf += eth_addr2str(fwt_access.ra, buf);
1485 buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.metric));
1486 buf += sprintf(buf, " %u", fwt_access.dir);
1487 buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.ssn));
1488 buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.dsn));
1489 buf += sprintf(buf, " %u", fwt_access.hopcount);
1490 buf += sprintf(buf, " %u", fwt_access.ttl);
1491 buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.expiration));
1492 buf += sprintf(buf, " %u", fwt_access.sleepmode);
1493 buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.snr));
1497 * @brief Lookup an entry in the FWT table
1498 * @param priv A pointer to wlan_private structure
1499 * @param req A pointer to ifreq structure
1500 * @return 0 --success, otherwise fail
1502 static int wlan_fwt_lookup_ioctl(wlan_private * priv, struct ifreq *req)
1504 struct iwreq *wrq = (struct iwreq *)req;
1507 static struct cmd_ds_fwt_access fwt_access;
1508 static char out_str[128];
1512 if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
1515 if ((ptr = eth_str2addr(in_str, fwt_access.da)) == NULL) {
1516 lbs_pr_alert( "FWT_LOOKUP: Invalid MAC address\n");
1522 char ethaddr1_str[18];
1523 lbs_pr_debug(1, "FWT_LOOKUP: line is %s\n", in_str);
1524 eth_addr2str(fwt_access.da, ethaddr1_str);
1525 lbs_pr_debug(1, "FWT_LOOKUP: looking for (da:%s)\n", ethaddr1_str);
1529 ret = libertas_prepare_and_send_command(priv,
1531 cmd_act_fwt_access_lookup,
1532 cmd_option_waitforrsp, 0,
1533 (void *)&fwt_access);
1536 print_route(fwt_access, out_str);
1538 sprintf(out_str, "(null)");
1540 wrq->u.data.length = strlen(out_str);
1541 if (copy_to_user(wrq->u.data.pointer, (char *)out_str,
1542 wrq->u.data.length)) {
1543 lbs_pr_debug(1, "FWT_LOOKUP: Copy to user failed!\n");
1552 * @brief Reset all entries from the FWT table
1553 * @param priv A pointer to wlan_private structure
1554 * @return 0 --success, otherwise fail
1556 static int wlan_fwt_reset_ioctl(wlan_private * priv)
1558 lbs_pr_debug(1, "FWT: resetting\n");
1560 return (libertas_prepare_and_send_command(priv,
1562 cmd_act_fwt_access_reset,
1563 cmd_option_waitforrsp, 0, NULL));
1567 * @brief List an entry from the FWT table
1568 * @param priv A pointer to wlan_private structure
1569 * @param req A pointer to ifreq structure
1570 * @return 0 --success, otherwise fail
1572 static int wlan_fwt_list_ioctl(wlan_private * priv, struct ifreq *req)
1574 struct iwreq *wrq = (struct iwreq *)req;
1576 static struct cmd_ds_fwt_access fwt_access;
1578 static char out_str[128];
1579 char *pbuf = out_str;
1583 if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
1586 fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
1590 lbs_pr_debug(1, "FWT_LIST: line is %s\n", in_str);
1591 lbs_pr_debug(1, "FWT_LIST: listing id:%i\n", le32_to_cpu(fwt_access.id));
1595 ret = libertas_prepare_and_send_command(priv, cmd_fwt_access,
1596 cmd_act_fwt_access_list,
1597 cmd_option_waitforrsp, 0, (void *)&fwt_access);
1600 print_route(fwt_access, pbuf);
1602 pbuf += sprintf(pbuf, " (null)");
1604 wrq->u.data.length = strlen(out_str);
1605 if (copy_to_user(wrq->u.data.pointer, (char *)out_str,
1606 wrq->u.data.length)) {
1607 lbs_pr_debug(1, "FWT_LIST: Copy to user failed!\n");
1616 * @brief List an entry from the FRT table
1617 * @param priv A pointer to wlan_private structure
1618 * @param req A pointer to ifreq structure
1619 * @return 0 --success, otherwise fail
1621 static int wlan_fwt_list_route_ioctl(wlan_private * priv, struct ifreq *req)
1623 struct iwreq *wrq = (struct iwreq *)req;
1625 static struct cmd_ds_fwt_access fwt_access;
1627 static char out_str[128];
1628 char *pbuf = out_str;
1632 if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
1635 fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
1639 lbs_pr_debug(1, "FWT_LIST_ROUTE: line is %s\n", in_str);
1640 lbs_pr_debug(1, "FWT_LIST_ROUTE: listing id:%i\n", le32_to_cpu(fwt_access.id));
1644 ret = libertas_prepare_and_send_command(priv, cmd_fwt_access,
1645 cmd_act_fwt_access_list_route,
1646 cmd_option_waitforrsp, 0, (void *)&fwt_access);
1649 pbuf += sprintf(pbuf, " ");
1650 pbuf += eth_addr2str(fwt_access.da, pbuf);
1651 pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.metric));
1652 pbuf += sprintf(pbuf, " %u", fwt_access.dir);
1653 /* note that the firmware returns the nid in the id field */
1654 pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.id));
1655 pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.ssn));
1656 pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.dsn));
1657 pbuf += sprintf(pbuf, " hop %u", fwt_access.hopcount);
1658 pbuf += sprintf(pbuf, " ttl %u", fwt_access.ttl);
1659 pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.expiration));
1661 pbuf += sprintf(pbuf, " (null)");
1663 wrq->u.data.length = strlen(out_str);
1664 if (copy_to_user(wrq->u.data.pointer, (char *)out_str,
1665 wrq->u.data.length)) {
1666 lbs_pr_debug(1, "FWT_LIST_ROUTE: Copy to user failed!\n");
1675 * @brief List an entry from the FNT table
1676 * @param priv A pointer to wlan_private structure
1677 * @param req A pointer to ifreq structure
1678 * @return 0 --success, otherwise fail
1680 static int wlan_fwt_list_neighbor_ioctl(wlan_private * priv, struct ifreq *req)
1682 struct iwreq *wrq = (struct iwreq *)req;
1684 static struct cmd_ds_fwt_access fwt_access;
1686 static char out_str[128];
1687 char *pbuf = out_str;
1691 if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
1694 memset(&fwt_access, 0, sizeof(fwt_access));
1695 fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
1699 lbs_pr_debug(1, "FWT_LIST_NEIGHBOR: line is %s\n", in_str);
1700 lbs_pr_debug(1, "FWT_LIST_NEIGHBOR: listing id:%i\n", le32_to_cpu(fwt_access.id));
1704 ret = libertas_prepare_and_send_command(priv, cmd_fwt_access,
1705 cmd_act_fwt_access_list_neighbor,
1706 cmd_option_waitforrsp, 0,
1707 (void *)&fwt_access);
1710 pbuf += sprintf(pbuf, " ra ");
1711 pbuf += eth_addr2str(fwt_access.ra, pbuf);
1712 pbuf += sprintf(pbuf, " slp %u", fwt_access.sleepmode);
1713 pbuf += sprintf(pbuf, " snr %u", le32_to_cpu(fwt_access.snr));
1714 pbuf += sprintf(pbuf, " ref %u", le32_to_cpu(fwt_access.references));
1716 pbuf += sprintf(pbuf, " (null)");
1718 wrq->u.data.length = strlen(out_str);
1719 if (copy_to_user(wrq->u.data.pointer, (char *)out_str,
1720 wrq->u.data.length)) {
1721 lbs_pr_debug(1, "FWT_LIST_NEIGHBOR: Copy to user failed!\n");
1730 * @brief Cleans up the route (FRT) and neighbor (FNT) tables
1731 * (Garbage Collection)
1732 * @param priv A pointer to wlan_private structure
1733 * @param req A pointer to ifreq structure
1734 * @return 0 --success, otherwise fail
1736 static int wlan_fwt_cleanup_ioctl(wlan_private * priv, struct ifreq *req)
1738 static struct cmd_ds_fwt_access fwt_access;
1743 lbs_pr_debug(1, "FWT: cleaning up\n");
1745 memset(&fwt_access, 0, sizeof(fwt_access));
1747 ret = libertas_prepare_and_send_command(priv, cmd_fwt_access,
1748 cmd_act_fwt_access_cleanup,
1749 cmd_option_waitforrsp, 0,
1750 (void *)&fwt_access);
1753 req->ifr_data = (char *)(le32_to_cpu(fwt_access.references));
1762 * @brief Gets firmware internal time (debug purposes)
1763 * @param priv A pointer to wlan_private structure
1764 * @param req A pointer to ifreq structure
1765 * @return 0 --success, otherwise fail
1767 static int wlan_fwt_time_ioctl(wlan_private * priv, struct ifreq *req)
1769 static struct cmd_ds_fwt_access fwt_access;
1774 lbs_pr_debug(1, "FWT: getting time\n");
1776 memset(&fwt_access, 0, sizeof(fwt_access));
1778 ret = libertas_prepare_and_send_command(priv, cmd_fwt_access,
1779 cmd_act_fwt_access_time,
1780 cmd_option_waitforrsp, 0,
1781 (void *)&fwt_access);
1784 req->ifr_data = (char *)(le32_to_cpu(fwt_access.references));
1793 * @brief Gets mesh ttl from firmware
1794 * @param priv A pointer to wlan_private structure
1795 * @param req A pointer to ifreq structure
1796 * @return 0 --success, otherwise fail
1798 static int wlan_mesh_get_ttl_ioctl(wlan_private * priv, struct ifreq *req)
1800 struct cmd_ds_mesh_access mesh_access;
1805 memset(&mesh_access, 0, sizeof(mesh_access));
1807 ret = libertas_prepare_and_send_command(priv, cmd_mesh_access,
1808 cmd_act_mesh_get_ttl,
1809 cmd_option_waitforrsp, 0,
1810 (void *)&mesh_access);
1813 req->ifr_data = (char *)(le32_to_cpu(mesh_access.data[0]));
1823 * @brief Gets mesh ttl from firmware
1824 * @param priv A pointer to wlan_private structure
1825 * @param ttl New ttl value
1826 * @return 0 --success, otherwise fail
1828 static int wlan_mesh_set_ttl_ioctl(wlan_private * priv, int ttl)
1830 struct cmd_ds_mesh_access mesh_access;
1835 if( (ttl > 0xff) || (ttl < 0) )
1838 memset(&mesh_access, 0, sizeof(mesh_access));
1839 mesh_access.data[0] = ttl;
1841 ret = libertas_prepare_and_send_command(priv, cmd_mesh_access,
1842 cmd_act_mesh_set_ttl,
1843 cmd_option_waitforrsp, 0,
1844 (void *)&mesh_access);
1854 * @brief ioctl function - entry point
1856 * @param dev A pointer to net_device structure
1857 * @param req A pointer to ifreq structure
1858 * @param cmd command
1859 * @return 0--success, otherwise fail
1861 int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
1867 wlan_private *priv = dev->priv;
1868 wlan_adapter *adapter = priv->adapter;
1869 struct iwreq *wrq = (struct iwreq *)req;
1873 lbs_pr_debug(1, "libertas_do_ioctl: ioctl cmd = 0x%x\n", cmd);
1876 lbs_pr_debug(1, "Scan type Ioctl\n");
1877 ret = wlan_scan_type_ioctl(priv, wrq);
1880 case WLAN_SETNONE_GETNONE: /* set WPA mode on/off ioctl #20 */
1881 switch (wrq->u.data.flags) {
1883 lbs_pr_debug(1, "Deauth\n");
1884 libertas_send_deauth(priv);
1888 lbs_pr_debug(1, "Adhoc stop\n");
1889 ret = libertas_do_adhocstop_ioctl(priv);
1893 wlan_radio_ioctl(priv, 1);
1897 wlan_radio_ioctl(priv, 0);
1899 case WLANWLANIDLEON:
1900 libertas_idle_on(priv);
1902 case WLANWLANIDLEOFF:
1903 libertas_idle_off(priv);
1905 case WLAN_SUBCMD_BT_RESET: /* bt_reset */
1906 wlan_bt_reset_ioctl(priv);
1908 case WLAN_SUBCMD_FWT_RESET: /* fwt_reset */
1909 wlan_fwt_reset_ioctl(priv);
1911 } /* End of switch */
1915 ret = wlan_setwpaie_ioctl(priv, req);
1917 case WLAN_SETINT_GETINT:
1918 /* The first 4 bytes of req->ifr_data is sub-ioctl number
1919 * after 4 bytes sits the payload.
1921 subcmd = (int)req->ifr_data; //from iwpriv subcmd
1924 ret = wlan_get_nf(priv, wrq);
1927 ret = wlan_get_rssi(priv, wrq);
1930 ret = libertas_cmd_enable_11d(priv, wrq);
1932 case WLANADHOCGRATE:
1933 ret = wlan_do_set_grate_ioctl(priv, wrq);
1935 case WLAN_SUBCMD_SET_PRESCAN:
1936 ret = wlan_subcmd_setprescan_ioctl(priv, wrq);
1941 case WLAN_SETONEINT_GETONEINT:
1942 switch (wrq->u.data.flags) {
1943 case WLAN_BEACON_INTERVAL:
1944 ret = wlan_beacon_interval(priv, wrq);
1947 case WLAN_LISTENINTRVL:
1948 if (!wrq->u.data.length) {
1950 lbs_pr_debug(1, "Get locallisteninterval value\n");
1951 #define GET_ONE_INT 1
1952 data = adapter->locallisteninterval;
1953 if (copy_to_user(wrq->u.data.pointer,
1954 &data, sizeof(int))) {
1955 lbs_pr_debug(1, "Copy to user failed\n");
1959 wrq->u.data.length = GET_ONE_INT;
1963 (&data, wrq->u.data.pointer, sizeof(int))) {
1964 lbs_pr_debug(1, "Copy from user failed\n");
1968 lbs_pr_debug(1, "Set locallisteninterval = %d\n",
1970 #define MAX_U16_VAL 65535
1971 if (data > MAX_U16_VAL) {
1972 lbs_pr_debug(1, "Exceeds U16 value\n");
1975 adapter->locallisteninterval = data;
1978 case WLAN_TXCONTROL:
1979 ret = wlan_txcontrol(priv, wrq); //adds for txcontrol ioctl
1982 case WLAN_NULLPKTINTERVAL:
1983 ret = wlan_null_pkt_interval(priv, wrq);
1992 case WLAN_SETONEINT_GETNONE:
1993 /* The first 4 bytes of req->ifr_data is sub-ioctl number
1994 * after 4 bytes sits the payload.
1996 subcmd = wrq->u.data.flags; //from wpa_supplicant subcmd
1999 subcmd = (int)req->ifr_data; //from iwpriv subcmd
2002 case WLAN_SUBCMD_SETRXANTENNA: /* SETRXANTENNA */
2003 idata = SUBCMD_DATA(wrq);
2004 ret = setrxantenna(priv, idata);
2006 case WLAN_SUBCMD_SETTXANTENNA: /* SETTXANTENNA */
2007 idata = SUBCMD_DATA(wrq);
2008 ret = settxantenna(priv, idata);
2010 case WLAN_SET_ATIM_WINDOW:
2011 adapter->atimwindow = SUBCMD_DATA(wrq);
2012 adapter->atimwindow = min_t(__u16, adapter->atimwindow, 50);
2015 adapter->bcn_avg_factor = SUBCMD_DATA(wrq);
2016 if (adapter->bcn_avg_factor == 0)
2017 adapter->bcn_avg_factor =
2018 DEFAULT_BCN_AVG_FACTOR;
2019 if (adapter->bcn_avg_factor > DEFAULT_BCN_AVG_FACTOR)
2020 adapter->bcn_avg_factor =
2021 DEFAULT_BCN_AVG_FACTOR;
2023 case WLANSETDATAAVG:
2024 adapter->data_avg_factor = SUBCMD_DATA(wrq);
2025 if (adapter->data_avg_factor == 0)
2026 adapter->data_avg_factor =
2027 DEFAULT_DATA_AVG_FACTOR;
2028 if (adapter->data_avg_factor > DEFAULT_DATA_AVG_FACTOR)
2029 adapter->data_avg_factor =
2030 DEFAULT_DATA_AVG_FACTOR;
2033 idata = SUBCMD_DATA(wrq);
2034 ret = wlan_set_region(priv, (u16) idata);
2037 case WLAN_SET_LISTEN_INTERVAL:
2038 idata = SUBCMD_DATA(wrq);
2039 adapter->listeninterval = (u16) idata;
2042 case WLAN_SET_MULTIPLE_DTIM:
2043 ret = wlan_set_multiple_dtim_ioctl(priv, req);
2046 case WLANSETAUTHALG:
2047 ret = wlan_setauthalg_ioctl(priv, req);
2050 case WLANSETENCRYPTIONMODE:
2051 ret = wlan_setencryptionmode_ioctl(priv, req);
2054 case WLAN_SET_LINKMODE:
2055 ret = wlan_set_linkmode_ioctl(priv, req);
2058 case WLAN_SET_RADIOMODE:
2059 ret = wlan_set_radiomode_ioctl(priv, req);
2062 case WLAN_SET_DEBUGMODE:
2063 ret = wlan_set_debugmode_ioctl(priv, req);
2066 case WLAN_SUBCMD_MESH_SET_TTL:
2067 idata = SUBCMD_DATA(wrq);
2068 ret = wlan_mesh_set_ttl_ioctl(priv, idata);
2078 case WLAN_SETNONE_GETTWELVE_CHAR: /* Get Antenna settings */
2080 * We've not used IW_PRIV_TYPE_FIXED so sub-ioctl number is
2081 * in flags of iwreq structure, otherwise it will be in
2082 * mode member of iwreq structure.
2084 switch ((int)wrq->u.data.flags) {
2085 case WLAN_SUBCMD_GETRXANTENNA: /* Get Rx Antenna */
2086 ret = wlan_subcmd_getrxantenna_ioctl(priv, req);
2089 case WLAN_SUBCMD_GETTXANTENNA: /* Get Tx Antenna */
2090 ret = wlan_subcmd_gettxantenna_ioctl(priv, req);
2094 ret = wlan_get_tsf_ioctl(priv, wrq);
2099 case WLAN_SET128CHAR_GET128CHAR:
2100 switch ((int)wrq->u.data.flags) {
2103 lbs_pr_debug(1, "Scan mode Ioctl\n");
2104 ret = wlan_scan_mode_ioctl(priv, wrq);
2107 case WLAN_GET_ADHOC_STATUS:
2108 ret = wlan_get_adhoc_status_ioctl(priv, wrq);
2110 case WLAN_SUBCMD_BT_ADD:
2111 ret = wlan_bt_add_ioctl(priv, req);
2113 case WLAN_SUBCMD_BT_DEL:
2114 ret = wlan_bt_del_ioctl(priv, req);
2116 case WLAN_SUBCMD_BT_LIST:
2117 ret = wlan_bt_list_ioctl(priv, req);
2119 case WLAN_SUBCMD_FWT_ADD:
2120 ret = wlan_fwt_add_ioctl(priv, req);
2122 case WLAN_SUBCMD_FWT_DEL:
2123 ret = wlan_fwt_del_ioctl(priv, req);
2125 case WLAN_SUBCMD_FWT_LOOKUP:
2126 ret = wlan_fwt_lookup_ioctl(priv, req);
2128 case WLAN_SUBCMD_FWT_LIST_NEIGHBOR:
2129 ret = wlan_fwt_list_neighbor_ioctl(priv, req);
2131 case WLAN_SUBCMD_FWT_LIST:
2132 ret = wlan_fwt_list_ioctl(priv, req);
2134 case WLAN_SUBCMD_FWT_LIST_ROUTE:
2135 ret = wlan_fwt_list_route_ioctl(priv, req);
2140 case WLAN_SETNONE_GETONEINT:
2141 switch ((int)req->ifr_data) {
2143 pdata = (int *)wrq->u.name;
2144 *pdata = (int)adapter->bcn_avg_factor;
2148 pdata = (int *)wrq->u.name;
2149 *pdata = (int)adapter->regioncode;
2152 case WLAN_GET_LISTEN_INTERVAL:
2153 pdata = (int *)wrq->u.name;
2154 *pdata = (int)adapter->listeninterval;
2157 case WLAN_GET_LINKMODE:
2158 req->ifr_data = (char *)((u32) adapter->linkmode);
2161 case WLAN_GET_RADIOMODE:
2162 req->ifr_data = (char *)((u32) adapter->radiomode);
2165 case WLAN_GET_DEBUGMODE:
2166 req->ifr_data = (char *)((u32) adapter->debugmode);
2169 case WLAN_GET_MULTIPLE_DTIM:
2170 pdata = (int *)wrq->u.name;
2171 *pdata = (int)adapter->multipledtim;
2173 case WLAN_GET_TX_RATE:
2174 ret = wlan_get_txrate_ioctl(priv, req);
2176 case WLAN_SUBCMD_FWT_CLEANUP: /* fwt_cleanup */
2177 ret = wlan_fwt_cleanup_ioctl(priv, req);
2180 case WLAN_SUBCMD_FWT_TIME: /* fwt_time */
2181 ret = wlan_fwt_time_ioctl(priv, req);
2184 case WLAN_SUBCMD_MESH_GET_TTL:
2185 ret = wlan_mesh_get_ttl_ioctl(priv, req);
2196 ret = wlan_do_getlog_ioctl(priv, wrq);
2199 case WLAN_SET_GET_SIXTEEN_INT:
2200 switch ((int)wrq->u.data.flags) {
2204 struct cmd_ds_802_11_tpc_cfg cfg;
2205 memset(&cfg, 0, sizeof(cfg));
2206 if ((wrq->u.data.length > 1)
2207 && (wrq->u.data.length != 5))
2210 if (wrq->u.data.length == 0) {
2216 (data, wrq->u.data.pointer,
2219 "Copy from user failed\n");
2226 cfg.enable = data[0];
2227 cfg.usesnr = data[1];
2234 libertas_prepare_and_send_command(priv,
2237 cmd_option_waitforrsp,
2240 data[0] = cfg.enable;
2241 data[1] = cfg.usesnr;
2246 (wrq->u.data.pointer, data,
2248 lbs_pr_debug(1, "Copy to user failed\n");
2252 wrq->u.data.length = 5;
2259 struct cmd_ds_802_11_pwr_cfg cfg;
2260 memset(&cfg, 0, sizeof(cfg));
2261 if ((wrq->u.data.length > 1)
2262 && (wrq->u.data.length != 4))
2264 if (wrq->u.data.length == 0) {
2270 (data, wrq->u.data.pointer,
2273 "Copy from user failed\n");
2280 cfg.enable = data[0];
2281 cfg.PA_P0 = data[1];
2282 cfg.PA_P1 = data[2];
2283 cfg.PA_P2 = data[3];
2286 libertas_prepare_and_send_command(priv,
2289 cmd_option_waitforrsp,
2291 data[0] = cfg.enable;
2292 data[1] = cfg.PA_P0;
2293 data[2] = cfg.PA_P1;
2294 data[3] = cfg.PA_P2;
2296 (wrq->u.data.pointer, data,
2298 lbs_pr_debug(1, "Copy to user failed\n");
2302 wrq->u.data.length = 4;
2305 case WLAN_AUTO_FREQ_SET:
2308 struct cmd_ds_802_11_afc afc;
2309 memset(&afc, 0, sizeof(afc));
2310 if (wrq->u.data.length != 3)
2313 (data, wrq->u.data.pointer,
2315 lbs_pr_debug(1, "Copy from user failed\n");
2318 afc.afc_auto = data[0];
2320 if (afc.afc_auto != 0) {
2321 afc.threshold = data[1];
2322 afc.period = data[2];
2324 afc.timing_offset = data[1];
2325 afc.carrier_offset = data[2];
2328 libertas_prepare_and_send_command(priv,
2331 cmd_option_waitforrsp,
2335 case WLAN_AUTO_FREQ_GET:
2338 struct cmd_ds_802_11_afc afc;
2339 memset(&afc, 0, sizeof(afc));
2341 libertas_prepare_and_send_command(priv,
2344 cmd_option_waitforrsp,
2346 data[0] = afc.afc_auto;
2347 data[1] = afc.timing_offset;
2348 data[2] = afc.carrier_offset;
2350 (wrq->u.data.pointer, data,
2352 lbs_pr_debug(1, "Copy to user failed\n");
2356 wrq->u.data.length = 3;
2359 case WLAN_SCANPROBES:
2362 if (wrq->u.data.length > 0) {
2364 (&data, wrq->u.data.pointer,
2367 "Copy from user failed\n");
2371 adapter->scanprobes = data;
2373 data = adapter->scanprobes;
2375 (wrq->u.data.pointer, &data,
2378 "Copy to user failed\n");
2382 wrq->u.data.length = 1;
2385 case WLAN_LED_GPIO_CTRL:
2390 struct cmd_ds_802_11_led_ctrl ctrl;
2391 struct mrvlietypes_ledgpio *gpio =
2392 (struct mrvlietypes_ledgpio *) ctrl.data;
2394 memset(&ctrl, 0, sizeof(ctrl));
2395 if (wrq->u.data.length > MAX_LEDS * 2)
2397 if ((wrq->u.data.length % 2) != 0)
2399 if (wrq->u.data.length == 0) {
2405 (data, wrq->u.data.pointer,
2407 wrq->u.data.length)) {
2409 "Copy from user failed\n");
2416 ctrl.numled = cpu_to_le16(0);
2418 cpu_to_le16(TLV_TYPE_LED_GPIO);
2419 gpio->header.len = wrq->u.data.length;
2420 for (i = 0; i < wrq->u.data.length;
2422 gpio->ledpin[i / 2].led =
2424 gpio->ledpin[i / 2].pin =
2429 libertas_prepare_and_send_command(priv,
2430 cmd_802_11_led_gpio_ctrl,
2432 cmd_option_waitforrsp,
2434 for (i = 0; i < gpio->header.len; i += 2) {
2435 data[i] = gpio->ledpin[i / 2].led;
2436 data[i + 1] = gpio->ledpin[i / 2].pin;
2438 if (copy_to_user(wrq->u.data.pointer, data,
2440 gpio->header.len)) {
2441 lbs_pr_debug(1, "Copy to user failed\n");
2445 wrq->u.data.length = gpio->header.len;
2448 case WLAN_ADAPT_RATESET:
2449 ret = wlan_adapt_rateset(priv, wrq);
2451 case WLAN_INACTIVITY_TIMEOUT:
2452 ret = wlan_inactivity_timeout(priv, wrq);
2455 ret = wlan_get_snr(priv, wrq);
2457 case WLAN_GET_RXINFO:
2458 ret = wlan_get_rxinfo(priv, wrq);