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;
622 * @brief Set 802.1x authentication mode
623 * @param priv A pointer to wlan_private structure
624 * @param req A pointer to ifreq structure
625 * @return 0 --success, otherwise fail
627 static int wlan_set8021xauthalg_ioctl(wlan_private * priv, struct ifreq *req)
630 struct iwreq *wrq = (struct iwreq *)req;
632 if (wrq->u.data.flags == 0) {
634 alg = SUBCMD_DATA(wrq);
636 //from wpa_supplicant subcmd
637 if (copy_from_user(&alg, wrq->u.data.pointer, sizeof(int))) {
638 lbs_pr_debug(1, "Copy from user failed\n");
642 lbs_pr_debug(1, "802.1x auth alg is %#x\n", alg);
643 priv->adapter->secinfo.auth1xalg = alg;
647 static int wlan_setencryptionmode_ioctl(wlan_private * priv, struct ifreq *req)
650 struct iwreq *wrq = (struct iwreq *)req;
654 if (wrq->u.data.flags == 0) {
656 mode = SUBCMD_DATA(wrq);
658 //from wpa_supplicant subcmd
659 if (copy_from_user(&mode, wrq->u.data.pointer, sizeof(int))) {
660 lbs_pr_debug(1, "Copy from user failed\n");
664 lbs_pr_debug(1, "encryption mode is %#x\n", mode);
665 priv->adapter->secinfo.Encryptionmode = mode;
671 static void adjust_mtu(wlan_private * priv)
673 int mtu_increment = 0;
675 if (priv->adapter->linkmode == WLAN_LINKMODE_802_11)
676 mtu_increment += sizeof(struct ieee80211_hdr_4addr);
678 if (priv->adapter->radiomode == WLAN_RADIOMODE_RADIOTAP)
679 mtu_increment += max(sizeof(struct tx_radiotap_hdr),
680 sizeof(struct rx_radiotap_hdr));
681 priv->wlan_dev.netdev->mtu = ETH_FRAME_LEN
682 - sizeof(struct ethhdr)
687 * @brief Set Link-Layer Layer mode
688 * @param priv A pointer to wlan_private structure
689 * @param req A pointer to ifreq structure
690 * @return 0 --success, otherwise fail
692 static int wlan_set_linkmode_ioctl(wlan_private * priv, struct ifreq *req)
696 mode = (int)((struct ifreq *)((u8 *) req + 4))->ifr_data;
699 case WLAN_LINKMODE_802_3:
700 priv->adapter->linkmode = mode;
702 case WLAN_LINKMODE_802_11:
703 priv->adapter->linkmode = mode;
706 lbs_pr_info("usb8388-5: invalid link-layer mode (%#x)\n",
711 lbs_pr_debug(1, "usb8388-5: link-layer mode is %#x\n", mode);
719 * @brief Set Radio header mode
720 * @param priv A pointer to wlan_private structure
721 * @param req A pointer to ifreq structure
722 * @return 0 --success, otherwise fail
724 static int wlan_set_radiomode_ioctl(wlan_private * priv, struct ifreq *req)
728 mode = (int)((struct ifreq *)((u8 *) req + 4))->ifr_data;
731 case WLAN_RADIOMODE_NONE:
732 priv->adapter->radiomode = mode;
734 case WLAN_RADIOMODE_RADIOTAP:
735 priv->adapter->radiomode = mode;
738 lbs_pr_debug(1, "usb8388-5: invalid radio header mode (%#x)\n",
742 lbs_pr_debug(1, "usb8388-5: radio-header mode is %#x\n", mode);
749 * @brief Set Debug header mode
750 * @param priv A pointer to wlan_private structure
751 * @param req A pointer to ifreq structure
752 * @return 0 --success, otherwise fail
754 static int wlan_set_debugmode_ioctl(wlan_private * priv, struct ifreq *req)
756 priv->adapter->debugmode = (int)((struct ifreq *)
757 ((u8 *) req + 4))->ifr_data;
761 static int wlan_subcmd_getrxantenna_ioctl(wlan_private * priv,
766 struct iwreq *wrq = (struct iwreq *)req;
768 lbs_pr_debug(1, "WLAN_SUBCMD_GETRXANTENNA\n");
769 len = getrxantenna(priv, buf);
771 wrq->u.data.length = len;
772 if (wrq->u.data.pointer) {
773 if (copy_to_user(wrq->u.data.pointer, &buf, len)) {
774 lbs_pr_debug(1, "CopyToUser failed\n");
782 static int wlan_subcmd_gettxantenna_ioctl(wlan_private * priv,
787 struct iwreq *wrq = (struct iwreq *)req;
789 lbs_pr_debug(1, "WLAN_SUBCMD_GETTXANTENNA\n");
790 len = gettxantenna(priv, buf);
792 wrq->u.data.length = len;
793 if (wrq->u.data.pointer) {
794 if (copy_to_user(wrq->u.data.pointer, &buf, len)) {
795 lbs_pr_debug(1, "CopyToUser failed\n");
803 * @brief Get the MAC TSF value from the firmware
805 * @param priv A pointer to wlan_private structure
806 * @param wrq A pointer to iwreq structure containing buffer
807 * space to store a TSF value retrieved from the firmware
809 * @return 0 if successful; IOCTL error code otherwise
811 static int wlan_get_tsf_ioctl(wlan_private * priv, struct iwreq *wrq)
816 ret = libertas_prepare_and_send_command(priv,
818 0, cmd_option_waitforrsp, 0, &tsfval);
820 lbs_pr_debug(1, "IOCTL: Get TSF = 0x%016llx\n", tsfval);
823 lbs_pr_debug(1, "IOCTL: Get TSF; command exec failed\n");
826 if (copy_to_user(wrq->u.data.pointer,
828 min_t(size_t, wrq->u.data.length,
829 sizeof(tsfval))) != 0) {
831 lbs_pr_debug(1, "IOCTL: Get TSF; Copy to user failed\n");
841 * @brief Get/Set adapt rate
842 * @param priv A pointer to wlan_private structure
843 * @param wrq A pointer to iwreq structure
844 * @return 0 --success, otherwise fail
846 static int wlan_adapt_rateset(wlan_private * priv, struct iwreq *wrq)
849 wlan_adapter *adapter = priv->adapter;
852 memset(data, 0, sizeof(data));
853 if (!wrq->u.data.length) {
854 lbs_pr_debug(1, "Get ADAPT RATE SET\n");
855 ret = libertas_prepare_and_send_command(priv,
856 cmd_802_11_rate_adapt_rateset,
858 cmd_option_waitforrsp, 0, NULL);
859 data[0] = adapter->enablehwauto;
860 data[1] = adapter->ratebitmap;
861 if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * 2)) {
862 lbs_pr_debug(1, "Copy to user failed\n");
865 #define GET_TWO_INT 2
866 wrq->u.data.length = GET_TWO_INT;
868 lbs_pr_debug(1, "Set ADAPT RATE SET\n");
869 if (wrq->u.data.length > 2)
872 (data, wrq->u.data.pointer,
873 sizeof(int) * wrq->u.data.length)) {
874 lbs_pr_debug(1, "Copy from user failed\n");
878 adapter->enablehwauto = data[0];
879 adapter->ratebitmap = data[1];
880 ret = libertas_prepare_and_send_command(priv,
881 cmd_802_11_rate_adapt_rateset,
883 cmd_option_waitforrsp, 0, NULL);
889 * @brief Get/Set inactivity timeout
890 * @param priv A pointer to wlan_private structure
891 * @param wrq A pointer to iwreq structure
892 * @return 0 --success, otherwise fail
894 static int wlan_inactivity_timeout(wlan_private * priv, struct iwreq *wrq)
901 if (wrq->u.data.length > 1)
904 if (wrq->u.data.length == 0) {
906 ret = libertas_prepare_and_send_command(priv,
907 cmd_802_11_inactivity_timeout,
909 cmd_option_waitforrsp, 0,
912 if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) {
913 lbs_pr_debug(1, "Copy to user failed\n");
918 if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
919 lbs_pr_debug(1, "Copy from user failed\n");
924 ret = libertas_prepare_and_send_command(priv,
925 cmd_802_11_inactivity_timeout,
927 cmd_option_waitforrsp, 0,
931 wrq->u.data.length = 1;
937 static int wlan_do_getlog_ioctl(wlan_private * priv, struct iwreq *wrq)
940 char buf[GETLOG_BUFSIZE - 1];
941 wlan_adapter *adapter = priv->adapter;
943 lbs_pr_debug(1, " GET STATS\n");
945 ret = libertas_prepare_and_send_command(priv, cmd_802_11_get_log,
946 0, cmd_option_waitforrsp, 0, NULL);
952 if (wrq->u.data.pointer) {
953 sprintf(buf, "\n mcasttxframe %u failed %u retry %u "
954 "multiretry %u framedup %u "
955 "rtssuccess %u rtsfailure %u ackfailure %u\n"
956 "rxfrag %u mcastrxframe %u fcserror %u "
957 "txframe %u wepundecryptable %u ",
958 adapter->logmsg.mcasttxframe,
959 adapter->logmsg.failed,
960 adapter->logmsg.retry,
961 adapter->logmsg.multiretry,
962 adapter->logmsg.framedup,
963 adapter->logmsg.rtssuccess,
964 adapter->logmsg.rtsfailure,
965 adapter->logmsg.ackfailure,
966 adapter->logmsg.rxfrag,
967 adapter->logmsg.mcastrxframe,
968 adapter->logmsg.fcserror,
969 adapter->logmsg.txframe,
970 adapter->logmsg.wepundecryptable);
971 wrq->u.data.length = strlen(buf) + 1;
972 if (copy_to_user(wrq->u.data.pointer, buf, wrq->u.data.length)) {
973 lbs_pr_debug(1, "Copy to user failed\n");
981 static int wlan_scan_type_ioctl(wlan_private * priv, struct iwreq *wrq)
984 u8 *option[] = { "active", "passive", "get", };
985 int i, max_options = (sizeof(option) / sizeof(option[0]));
987 wlan_adapter *adapter = priv->adapter;
989 if (priv->adapter->enable11d) {
990 lbs_pr_debug(1, "11D: Cannot set scantype when 11D enabled\n");
994 memset(buf, 0, sizeof(buf));
996 if (copy_from_user(buf, wrq->u.data.pointer, min_t(size_t, sizeof(buf),
997 wrq->u.data.length)))
1000 lbs_pr_debug(1, "Scan type Option = %s\n", buf);
1002 buf[sizeof(buf) - 1] = '\0';
1004 for (i = 0; i < max_options; i++) {
1005 if (!strcmp(buf, option[i]))
1011 adapter->scantype = cmd_scan_type_active;
1014 adapter->scantype = cmd_scan_type_passive;
1017 wrq->u.data.length = strlen(option[adapter->scantype]) + 1;
1019 if (copy_to_user(wrq->u.data.pointer,
1020 option[adapter->scantype],
1021 wrq->u.data.length)) {
1022 lbs_pr_debug(1, "Copy to user failed\n");
1028 lbs_pr_debug(1, "Invalid Scan type Ioctl Option\n");
1036 static int wlan_scan_mode_ioctl(wlan_private * priv, struct iwreq *wrq)
1038 wlan_adapter *adapter = priv->adapter;
1040 u8 *option[] = { "bss", "ibss", "any", "get" };
1041 int i, max_options = (sizeof(option) / sizeof(option[0]));
1046 memset(buf, 0, sizeof(buf));
1048 if (copy_from_user(buf, wrq->u.data.pointer, min_t(size_t, sizeof(buf),
1049 wrq->u.data.length))) {
1050 lbs_pr_debug(1, "Copy from user failed\n");
1054 lbs_pr_debug(1, "Scan mode Option = %s\n", buf);
1056 buf[sizeof(buf) - 1] = '\0';
1058 for (i = 0; i < max_options; i++) {
1059 if (!strcmp(buf, option[i]))
1066 adapter->scanmode = cmd_bss_type_bss;
1069 adapter->scanmode = cmd_bss_type_ibss;
1072 adapter->scanmode = cmd_bss_type_any;
1076 wrq->u.data.length = strlen(option[adapter->scanmode - 1]) + 1;
1078 lbs_pr_debug(1, "Get Scan mode Option = %s\n",
1079 option[adapter->scanmode - 1]);
1081 lbs_pr_debug(1, "Scan mode length %d\n", wrq->u.data.length);
1083 if (copy_to_user(wrq->u.data.pointer,
1084 option[adapter->scanmode - 1],
1085 wrq->u.data.length)) {
1086 lbs_pr_debug(1, "Copy to user failed\n");
1089 lbs_pr_debug(1, "GET Scan type Option after copy = %s\n",
1090 (char *)wrq->u.data.pointer);
1095 lbs_pr_debug(1, "Invalid Scan mode Ioctl Option\n");
1105 * @brief Get/Set Adhoc G Rate
1107 * @param priv A pointer to wlan_private structure
1108 * @param wrq A pointer to user data
1109 * @return 0--success, otherwise fail
1111 static int wlan_do_set_grate_ioctl(wlan_private * priv, struct iwreq *wrq)
1113 wlan_adapter *adapter = priv->adapter;
1119 data1 = SUBCMD_DATA(wrq);
1122 adapter->adhoc_grate_enabled = 0;
1125 adapter->adhoc_grate_enabled = 1;
1132 data = adapter->adhoc_grate_enabled;
1133 val = (int *)wrq->u.name;
1139 static inline int hex2int(char c)
1141 if (c >= '0' && c <= '9')
1143 if (c >= 'a' && c <= 'f')
1144 return (c - 'a' + 10);
1145 if (c >= 'A' && c <= 'F')
1146 return (c - 'A' + 10);
1150 /* Convert a string representation of a MAC address ("xx:xx:xx:xx:xx:xx")
1151 into binary format (6 bytes).
1153 This function expects that each byte is represented with 2 characters
1154 (e.g., 11:2:11:11:11:11 is invalid)
1157 static char *eth_str2addr(char *ethstr, u8 * addr)
1162 /* get rid of initial blanks */
1163 while (*pos == ' ' || *pos == '\t')
1166 for (i = 0; i < 6; i++) {
1167 val = hex2int(*pos++);
1170 val2 = hex2int(*pos++);
1173 addr[i] = (val * 16 + val2) & 0xff;
1175 if (i < 5 && *pos++ != ':')
1181 /* this writes xx:xx:xx:xx:xx:xx into ethstr
1182 (ethstr must have space for 18 chars) */
1183 static int eth_addr2str(u8 * addr, char *ethstr)
1188 for (i = 0; i < 6; i++) {
1189 sprintf(pos, "%02x", addr[i] & 0xff);
1198 * @brief Add an entry to the BT table
1199 * @param priv A pointer to wlan_private structure
1200 * @param req A pointer to ifreq structure
1201 * @return 0 --success, otherwise fail
1203 static int wlan_bt_add_ioctl(wlan_private * priv, struct ifreq *req)
1205 struct iwreq *wrq = (struct iwreq *)req;
1206 char ethaddrs_str[18];
1208 u8 ethaddr[ETH_ALEN];
1211 if (copy_from_user(ethaddrs_str, wrq->u.data.pointer,
1212 sizeof(ethaddrs_str)))
1215 if ((pos = eth_str2addr(ethaddrs_str, ethaddr)) == NULL) {
1216 lbs_pr_info("BT_ADD: Invalid MAC address\n");
1220 lbs_pr_debug(1, "BT: adding %s\n", ethaddrs_str);
1222 return (libertas_prepare_and_send_command(priv, cmd_bt_access,
1223 cmd_act_bt_access_add,
1224 cmd_option_waitforrsp, 0, ethaddr));
1228 * @brief Delete an entry from the BT table
1229 * @param priv A pointer to wlan_private structure
1230 * @param req A pointer to ifreq structure
1231 * @return 0 --success, otherwise fail
1233 static int wlan_bt_del_ioctl(wlan_private * priv, struct ifreq *req)
1235 struct iwreq *wrq = (struct iwreq *)req;
1236 char ethaddrs_str[18];
1237 u8 ethaddr[ETH_ALEN];
1241 if (copy_from_user(ethaddrs_str, wrq->u.data.pointer,
1242 sizeof(ethaddrs_str)))
1245 if ((pos = eth_str2addr(ethaddrs_str, ethaddr)) == NULL) {
1246 lbs_pr_info("Invalid MAC address\n");
1250 lbs_pr_debug(1, "BT: deleting %s\n", ethaddrs_str);
1252 return (libertas_prepare_and_send_command(priv,
1254 cmd_act_bt_access_del,
1255 cmd_option_waitforrsp, 0, ethaddr));
1261 * @brief Reset all entries from the BT table
1262 * @param priv A pointer to wlan_private structure
1263 * @return 0 --success, otherwise fail
1265 static int wlan_bt_reset_ioctl(wlan_private * priv)
1269 lbs_pr_alert( "BT: resetting\n");
1271 return (libertas_prepare_and_send_command(priv,
1273 cmd_act_bt_access_reset,
1274 cmd_option_waitforrsp, 0, NULL));
1281 * @brief List an entry from the BT table
1282 * @param priv A pointer to wlan_private structure
1283 * @param req A pointer to ifreq structure
1284 * @return 0 --success, otherwise fail
1286 static int wlan_bt_list_ioctl(wlan_private * priv, struct ifreq *req)
1290 struct iwreq *wrq = (struct iwreq *)req;
1291 /* used to pass id and store the bt entry returned by the FW */
1294 char addr1addr2[2 * ETH_ALEN];
1296 static char outstr[64];
1297 char *pbuf = outstr;
1302 if (copy_from_user(outstr, wrq->u.data.pointer, sizeof(outstr))) {
1303 lbs_pr_debug(1, "Copy from user failed\n");
1306 param.id = simple_strtoul(outstr, NULL, 10);
1307 pos = sprintf(pbuf, "%d: ", param.id);
1310 ret = libertas_prepare_and_send_command(priv, cmd_bt_access,
1311 cmd_act_bt_access_list,
1312 cmd_option_waitforrsp, 0,
1316 addr1 = param.addr1addr2;
1318 pos = sprintf(pbuf, "ignoring traffic from ");
1320 pos = eth_addr2str(addr1, pbuf);
1323 sprintf(pbuf, "(null)");
1327 wrq->u.data.length = strlen(outstr);
1328 if (copy_to_user(wrq->u.data.pointer, (char *)outstr,
1329 wrq->u.data.length)) {
1330 lbs_pr_debug(1, "BT_LIST: Copy to user failed!\n");
1339 * @brief Find the next parameter in an input string
1340 * @param ptr A pointer to the input parameter string
1341 * @return A pointer to the next parameter, or 0 if no parameters left.
1343 static char * next_param(char * ptr)
1345 if (!ptr) return NULL;
1346 while (*ptr == ' ' || *ptr == '\t') ++ptr;
1347 return (*ptr == '\0') ? NULL : ptr;
1351 * @brief Add an entry to the FWT table
1352 * @param priv A pointer to wlan_private structure
1353 * @param req A pointer to ifreq structure
1354 * @return 0 --success, otherwise fail
1356 static int wlan_fwt_add_ioctl(wlan_private * priv, struct ifreq *req)
1358 struct iwreq *wrq = (struct iwreq *)req;
1360 static struct cmd_ds_fwt_access fwt_access;
1364 if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
1367 if ((ptr = eth_str2addr(in_str, fwt_access.da)) == NULL) {
1368 lbs_pr_alert( "FWT_ADD: Invalid MAC address 1\n");
1372 if ((ptr = eth_str2addr(ptr, fwt_access.ra)) == NULL) {
1373 lbs_pr_alert( "FWT_ADD: Invalid MAC address 2\n");
1377 if ((ptr = next_param(ptr)))
1379 cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
1381 fwt_access.metric = FWT_DEFAULT_METRIC;
1383 if ((ptr = next_param(ptr)))
1384 fwt_access.dir = (u8)simple_strtoul(ptr, &ptr, 10);
1386 fwt_access.dir = FWT_DEFAULT_DIR;
1388 if ((ptr = next_param(ptr)))
1390 cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
1392 fwt_access.ssn = FWT_DEFAULT_SSN;
1394 if ((ptr = next_param(ptr)))
1396 cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
1398 fwt_access.dsn = FWT_DEFAULT_DSN;
1400 if ((ptr = next_param(ptr)))
1401 fwt_access.hopcount = simple_strtoul(ptr, &ptr, 10);
1403 fwt_access.hopcount = FWT_DEFAULT_HOPCOUNT;
1405 if ((ptr = next_param(ptr)))
1406 fwt_access.ttl = simple_strtoul(ptr, &ptr, 10);
1408 fwt_access.ttl = FWT_DEFAULT_TTL;
1410 if ((ptr = next_param(ptr)))
1411 fwt_access.expiration =
1412 cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
1414 fwt_access.expiration = FWT_DEFAULT_EXPIRATION;
1416 if ((ptr = next_param(ptr)))
1417 fwt_access.sleepmode = (u8)simple_strtoul(ptr, &ptr, 10);
1419 fwt_access.sleepmode = FWT_DEFAULT_SLEEPMODE;
1421 if ((ptr = next_param(ptr)))
1423 cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
1425 fwt_access.snr = FWT_DEFAULT_SNR;
1429 char ethaddr1_str[18], ethaddr2_str[18];
1430 eth_addr2str(fwt_access.da, ethaddr1_str);
1431 eth_addr2str(fwt_access.ra, ethaddr2_str);
1432 lbs_pr_debug(1, "FWT_ADD: adding (da:%s,%i,ra:%s)\n", ethaddr1_str,
1433 fwt_access.dir, ethaddr2_str);
1434 lbs_pr_debug(1, "FWT_ADD: ssn:%u dsn:%u met:%u hop:%u ttl:%u exp:%u slp:%u snr:%u\n",
1435 fwt_access.ssn, fwt_access.dsn, fwt_access.metric,
1436 fwt_access.hopcount, fwt_access.ttl, fwt_access.expiration,
1437 fwt_access.sleepmode, fwt_access.snr);
1442 return (libertas_prepare_and_send_command(priv, cmd_fwt_access,
1443 cmd_act_fwt_access_add,
1444 cmd_option_waitforrsp, 0,
1445 (void *)&fwt_access));
1449 * @brief Delete an entry from the FWT table
1450 * @param priv A pointer to wlan_private structure
1451 * @param req A pointer to ifreq structure
1452 * @return 0 --success, otherwise fail
1454 static int wlan_fwt_del_ioctl(wlan_private * priv, struct ifreq *req)
1456 struct iwreq *wrq = (struct iwreq *)req;
1458 static struct cmd_ds_fwt_access fwt_access;
1462 if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
1465 if ((ptr = eth_str2addr(in_str, fwt_access.da)) == NULL) {
1466 lbs_pr_alert( "FWT_DEL: Invalid MAC address 1\n");
1470 if ((ptr = eth_str2addr(ptr, fwt_access.ra)) == NULL) {
1471 lbs_pr_alert( "FWT_DEL: Invalid MAC address 2\n");
1475 if ((ptr = next_param(ptr)))
1476 fwt_access.dir = (u8)simple_strtoul(ptr, &ptr, 10);
1478 fwt_access.dir = FWT_DEFAULT_DIR;
1482 char ethaddr1_str[18], ethaddr2_str[18];
1483 lbs_pr_debug(1, "FWT_DEL: line is %s\n", in_str);
1484 eth_addr2str(fwt_access.da, ethaddr1_str);
1485 eth_addr2str(fwt_access.ra, ethaddr2_str);
1486 lbs_pr_debug(1, "FWT_DEL: removing (da:%s,ra:%s,dir:%d)\n", ethaddr1_str,
1487 ethaddr2_str, fwt_access.dir);
1492 return (libertas_prepare_and_send_command(priv,
1494 cmd_act_fwt_access_del,
1495 cmd_option_waitforrsp, 0,
1496 (void *)&fwt_access));
1501 * @brief Print route parameters
1502 * @param fwt_access struct cmd_ds_fwt_access with route info
1503 * @param buf destination buffer for route info
1505 static void print_route(struct cmd_ds_fwt_access fwt_access, char *buf)
1507 buf += sprintf(buf, " ");
1508 buf += eth_addr2str(fwt_access.da, buf);
1509 buf += sprintf(buf, " ");
1510 buf += eth_addr2str(fwt_access.ra, buf);
1511 buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.metric));
1512 buf += sprintf(buf, " %u", fwt_access.dir);
1513 buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.ssn));
1514 buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.dsn));
1515 buf += sprintf(buf, " %u", fwt_access.hopcount);
1516 buf += sprintf(buf, " %u", fwt_access.ttl);
1517 buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.expiration));
1518 buf += sprintf(buf, " %u", fwt_access.sleepmode);
1519 buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.snr));
1523 * @brief Lookup an entry in the FWT table
1524 * @param priv A pointer to wlan_private structure
1525 * @param req A pointer to ifreq structure
1526 * @return 0 --success, otherwise fail
1528 static int wlan_fwt_lookup_ioctl(wlan_private * priv, struct ifreq *req)
1530 struct iwreq *wrq = (struct iwreq *)req;
1533 static struct cmd_ds_fwt_access fwt_access;
1534 static char out_str[128];
1538 if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
1541 if ((ptr = eth_str2addr(in_str, fwt_access.da)) == NULL) {
1542 lbs_pr_alert( "FWT_LOOKUP: Invalid MAC address\n");
1548 char ethaddr1_str[18];
1549 lbs_pr_debug(1, "FWT_LOOKUP: line is %s\n", in_str);
1550 eth_addr2str(fwt_access.da, ethaddr1_str);
1551 lbs_pr_debug(1, "FWT_LOOKUP: looking for (da:%s)\n", ethaddr1_str);
1555 ret = libertas_prepare_and_send_command(priv,
1557 cmd_act_fwt_access_lookup,
1558 cmd_option_waitforrsp, 0,
1559 (void *)&fwt_access);
1562 print_route(fwt_access, out_str);
1564 sprintf(out_str, "(null)");
1566 wrq->u.data.length = strlen(out_str);
1567 if (copy_to_user(wrq->u.data.pointer, (char *)out_str,
1568 wrq->u.data.length)) {
1569 lbs_pr_debug(1, "FWT_LOOKUP: Copy to user failed!\n");
1578 * @brief Reset all entries from the FWT table
1579 * @param priv A pointer to wlan_private structure
1580 * @return 0 --success, otherwise fail
1582 static int wlan_fwt_reset_ioctl(wlan_private * priv)
1584 lbs_pr_debug(1, "FWT: resetting\n");
1586 return (libertas_prepare_and_send_command(priv,
1588 cmd_act_fwt_access_reset,
1589 cmd_option_waitforrsp, 0, NULL));
1593 * @brief List an entry from the FWT table
1594 * @param priv A pointer to wlan_private structure
1595 * @param req A pointer to ifreq structure
1596 * @return 0 --success, otherwise fail
1598 static int wlan_fwt_list_ioctl(wlan_private * priv, struct ifreq *req)
1600 struct iwreq *wrq = (struct iwreq *)req;
1602 static struct cmd_ds_fwt_access fwt_access;
1604 static char out_str[128];
1605 char *pbuf = out_str;
1609 if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
1612 fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
1616 lbs_pr_debug(1, "FWT_LIST: line is %s\n", in_str);
1617 lbs_pr_debug(1, "FWT_LIST: listing id:%i\n", le32_to_cpu(fwt_access.id));
1621 ret = libertas_prepare_and_send_command(priv, cmd_fwt_access,
1622 cmd_act_fwt_access_list,
1623 cmd_option_waitforrsp, 0, (void *)&fwt_access);
1626 print_route(fwt_access, pbuf);
1628 pbuf += sprintf(pbuf, " (null)");
1630 wrq->u.data.length = strlen(out_str);
1631 if (copy_to_user(wrq->u.data.pointer, (char *)out_str,
1632 wrq->u.data.length)) {
1633 lbs_pr_debug(1, "FWT_LIST: Copy to user failed!\n");
1642 * @brief List an entry from the FRT table
1643 * @param priv A pointer to wlan_private structure
1644 * @param req A pointer to ifreq structure
1645 * @return 0 --success, otherwise fail
1647 static int wlan_fwt_list_route_ioctl(wlan_private * priv, struct ifreq *req)
1649 struct iwreq *wrq = (struct iwreq *)req;
1651 static struct cmd_ds_fwt_access fwt_access;
1653 static char out_str[128];
1654 char *pbuf = out_str;
1658 if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
1661 fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
1665 lbs_pr_debug(1, "FWT_LIST_ROUTE: line is %s\n", in_str);
1666 lbs_pr_debug(1, "FWT_LIST_ROUTE: listing id:%i\n", le32_to_cpu(fwt_access.id));
1670 ret = libertas_prepare_and_send_command(priv, cmd_fwt_access,
1671 cmd_act_fwt_access_list_route,
1672 cmd_option_waitforrsp, 0, (void *)&fwt_access);
1675 pbuf += sprintf(pbuf, " ");
1676 pbuf += eth_addr2str(fwt_access.da, pbuf);
1677 pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.metric));
1678 pbuf += sprintf(pbuf, " %u", fwt_access.dir);
1679 /* note that the firmware returns the nid in the id field */
1680 pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.id));
1681 pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.ssn));
1682 pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.dsn));
1683 pbuf += sprintf(pbuf, " hop %u", fwt_access.hopcount);
1684 pbuf += sprintf(pbuf, " ttl %u", fwt_access.ttl);
1685 pbuf += sprintf(pbuf, " %u", le32_to_cpu(fwt_access.expiration));
1687 pbuf += sprintf(pbuf, " (null)");
1689 wrq->u.data.length = strlen(out_str);
1690 if (copy_to_user(wrq->u.data.pointer, (char *)out_str,
1691 wrq->u.data.length)) {
1692 lbs_pr_debug(1, "FWT_LIST_ROUTE: Copy to user failed!\n");
1701 * @brief List an entry from the FNT table
1702 * @param priv A pointer to wlan_private structure
1703 * @param req A pointer to ifreq structure
1704 * @return 0 --success, otherwise fail
1706 static int wlan_fwt_list_neighbor_ioctl(wlan_private * priv, struct ifreq *req)
1708 struct iwreq *wrq = (struct iwreq *)req;
1710 static struct cmd_ds_fwt_access fwt_access;
1712 static char out_str[128];
1713 char *pbuf = out_str;
1717 if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str)))
1720 memset(&fwt_access, 0, sizeof(fwt_access));
1721 fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10));
1725 lbs_pr_debug(1, "FWT_LIST_NEIGHBOR: line is %s\n", in_str);
1726 lbs_pr_debug(1, "FWT_LIST_NEIGHBOR: listing id:%i\n", le32_to_cpu(fwt_access.id));
1730 ret = libertas_prepare_and_send_command(priv, cmd_fwt_access,
1731 cmd_act_fwt_access_list_neighbor,
1732 cmd_option_waitforrsp, 0,
1733 (void *)&fwt_access);
1736 pbuf += sprintf(pbuf, " ra ");
1737 pbuf += eth_addr2str(fwt_access.ra, pbuf);
1738 pbuf += sprintf(pbuf, " slp %u", fwt_access.sleepmode);
1739 pbuf += sprintf(pbuf, " snr %u", le32_to_cpu(fwt_access.snr));
1740 pbuf += sprintf(pbuf, " ref %u", le32_to_cpu(fwt_access.references));
1742 pbuf += sprintf(pbuf, " (null)");
1744 wrq->u.data.length = strlen(out_str);
1745 if (copy_to_user(wrq->u.data.pointer, (char *)out_str,
1746 wrq->u.data.length)) {
1747 lbs_pr_debug(1, "FWT_LIST_NEIGHBOR: Copy to user failed!\n");
1756 * @brief Cleans up the route (FRT) and neighbor (FNT) tables
1757 * (Garbage Collection)
1758 * @param priv A pointer to wlan_private structure
1759 * @param req A pointer to ifreq structure
1760 * @return 0 --success, otherwise fail
1762 static int wlan_fwt_cleanup_ioctl(wlan_private * priv, struct ifreq *req)
1764 static struct cmd_ds_fwt_access fwt_access;
1769 lbs_pr_debug(1, "FWT: cleaning up\n");
1771 memset(&fwt_access, 0, sizeof(fwt_access));
1773 ret = libertas_prepare_and_send_command(priv, cmd_fwt_access,
1774 cmd_act_fwt_access_cleanup,
1775 cmd_option_waitforrsp, 0,
1776 (void *)&fwt_access);
1779 req->ifr_data = (char *)(le32_to_cpu(fwt_access.references));
1788 * @brief Gets firmware internal time (debug purposes)
1789 * @param priv A pointer to wlan_private structure
1790 * @param req A pointer to ifreq structure
1791 * @return 0 --success, otherwise fail
1793 static int wlan_fwt_time_ioctl(wlan_private * priv, struct ifreq *req)
1795 static struct cmd_ds_fwt_access fwt_access;
1800 lbs_pr_debug(1, "FWT: getting time\n");
1802 memset(&fwt_access, 0, sizeof(fwt_access));
1804 ret = libertas_prepare_and_send_command(priv, cmd_fwt_access,
1805 cmd_act_fwt_access_time,
1806 cmd_option_waitforrsp, 0,
1807 (void *)&fwt_access);
1810 req->ifr_data = (char *)(le32_to_cpu(fwt_access.references));
1819 * @brief Gets mesh ttl from firmware
1820 * @param priv A pointer to wlan_private structure
1821 * @param req A pointer to ifreq structure
1822 * @return 0 --success, otherwise fail
1824 static int wlan_mesh_get_ttl_ioctl(wlan_private * priv, struct ifreq *req)
1826 struct cmd_ds_mesh_access mesh_access;
1831 memset(&mesh_access, 0, sizeof(mesh_access));
1833 ret = libertas_prepare_and_send_command(priv, cmd_mesh_access,
1834 cmd_act_mesh_get_ttl,
1835 cmd_option_waitforrsp, 0,
1836 (void *)&mesh_access);
1839 req->ifr_data = (char *)(le32_to_cpu(mesh_access.data[0]));
1849 * @brief Gets mesh ttl from firmware
1850 * @param priv A pointer to wlan_private structure
1851 * @param ttl New ttl value
1852 * @return 0 --success, otherwise fail
1854 static int wlan_mesh_set_ttl_ioctl(wlan_private * priv, int ttl)
1856 struct cmd_ds_mesh_access mesh_access;
1861 if( (ttl > 0xff) || (ttl < 0) )
1864 memset(&mesh_access, 0, sizeof(mesh_access));
1865 mesh_access.data[0] = ttl;
1867 ret = libertas_prepare_and_send_command(priv, cmd_mesh_access,
1868 cmd_act_mesh_set_ttl,
1869 cmd_option_waitforrsp, 0,
1870 (void *)&mesh_access);
1880 * @brief ioctl function - entry point
1882 * @param dev A pointer to net_device structure
1883 * @param req A pointer to ifreq structure
1884 * @param cmd command
1885 * @return 0--success, otherwise fail
1887 int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
1893 wlan_private *priv = dev->priv;
1894 wlan_adapter *adapter = priv->adapter;
1895 struct iwreq *wrq = (struct iwreq *)req;
1899 lbs_pr_debug(1, "libertas_do_ioctl: ioctl cmd = 0x%x\n", cmd);
1902 lbs_pr_debug(1, "Scan type Ioctl\n");
1903 ret = wlan_scan_type_ioctl(priv, wrq);
1906 case WLAN_SETNONE_GETNONE: /* set WPA mode on/off ioctl #20 */
1907 switch (wrq->u.data.flags) {
1909 lbs_pr_debug(1, "Deauth\n");
1910 libertas_send_deauth(priv);
1914 lbs_pr_debug(1, "Adhoc stop\n");
1915 ret = libertas_do_adhocstop_ioctl(priv);
1919 wlan_radio_ioctl(priv, 1);
1923 wlan_radio_ioctl(priv, 0);
1925 case WLANWLANIDLEON:
1926 libertas_idle_on(priv);
1928 case WLANWLANIDLEOFF:
1929 libertas_idle_off(priv);
1931 case WLAN_SUBCMD_BT_RESET: /* bt_reset */
1932 wlan_bt_reset_ioctl(priv);
1934 case WLAN_SUBCMD_FWT_RESET: /* fwt_reset */
1935 wlan_fwt_reset_ioctl(priv);
1937 } /* End of switch */
1941 ret = wlan_setwpaie_ioctl(priv, req);
1943 case WLAN_SETINT_GETINT:
1944 /* The first 4 bytes of req->ifr_data is sub-ioctl number
1945 * after 4 bytes sits the payload.
1947 subcmd = (int)req->ifr_data; //from iwpriv subcmd
1950 ret = wlan_get_nf(priv, wrq);
1953 ret = wlan_get_rssi(priv, wrq);
1956 ret = libertas_cmd_enable_11d(priv, wrq);
1958 case WLANADHOCGRATE:
1959 ret = wlan_do_set_grate_ioctl(priv, wrq);
1961 case WLAN_SUBCMD_SET_PRESCAN:
1962 ret = wlan_subcmd_setprescan_ioctl(priv, wrq);
1967 case WLAN_SETONEINT_GETONEINT:
1968 switch (wrq->u.data.flags) {
1969 case WLAN_BEACON_INTERVAL:
1970 ret = wlan_beacon_interval(priv, wrq);
1973 case WLAN_LISTENINTRVL:
1974 if (!wrq->u.data.length) {
1976 lbs_pr_debug(1, "Get locallisteninterval value\n");
1977 #define GET_ONE_INT 1
1978 data = adapter->locallisteninterval;
1979 if (copy_to_user(wrq->u.data.pointer,
1980 &data, sizeof(int))) {
1981 lbs_pr_debug(1, "Copy to user failed\n");
1985 wrq->u.data.length = GET_ONE_INT;
1989 (&data, wrq->u.data.pointer, sizeof(int))) {
1990 lbs_pr_debug(1, "Copy from user failed\n");
1994 lbs_pr_debug(1, "Set locallisteninterval = %d\n",
1996 #define MAX_U16_VAL 65535
1997 if (data > MAX_U16_VAL) {
1998 lbs_pr_debug(1, "Exceeds U16 value\n");
2001 adapter->locallisteninterval = data;
2004 case WLAN_TXCONTROL:
2005 ret = wlan_txcontrol(priv, wrq); //adds for txcontrol ioctl
2008 case WLAN_NULLPKTINTERVAL:
2009 ret = wlan_null_pkt_interval(priv, wrq);
2018 case WLAN_SETONEINT_GETNONE:
2019 /* The first 4 bytes of req->ifr_data is sub-ioctl number
2020 * after 4 bytes sits the payload.
2022 subcmd = wrq->u.data.flags; //from wpa_supplicant subcmd
2025 subcmd = (int)req->ifr_data; //from iwpriv subcmd
2028 case WLAN_SUBCMD_SETRXANTENNA: /* SETRXANTENNA */
2029 idata = SUBCMD_DATA(wrq);
2030 ret = setrxantenna(priv, idata);
2032 case WLAN_SUBCMD_SETTXANTENNA: /* SETTXANTENNA */
2033 idata = SUBCMD_DATA(wrq);
2034 ret = settxantenna(priv, idata);
2036 case WLAN_SET_ATIM_WINDOW:
2037 adapter->atimwindow = SUBCMD_DATA(wrq);
2038 adapter->atimwindow = min_t(__u16, adapter->atimwindow, 50);
2041 adapter->bcn_avg_factor = SUBCMD_DATA(wrq);
2042 if (adapter->bcn_avg_factor == 0)
2043 adapter->bcn_avg_factor =
2044 DEFAULT_BCN_AVG_FACTOR;
2045 if (adapter->bcn_avg_factor > DEFAULT_BCN_AVG_FACTOR)
2046 adapter->bcn_avg_factor =
2047 DEFAULT_BCN_AVG_FACTOR;
2049 case WLANSETDATAAVG:
2050 adapter->data_avg_factor = SUBCMD_DATA(wrq);
2051 if (adapter->data_avg_factor == 0)
2052 adapter->data_avg_factor =
2053 DEFAULT_DATA_AVG_FACTOR;
2054 if (adapter->data_avg_factor > DEFAULT_DATA_AVG_FACTOR)
2055 adapter->data_avg_factor =
2056 DEFAULT_DATA_AVG_FACTOR;
2059 idata = SUBCMD_DATA(wrq);
2060 ret = wlan_set_region(priv, (u16) idata);
2063 case WLAN_SET_LISTEN_INTERVAL:
2064 idata = SUBCMD_DATA(wrq);
2065 adapter->listeninterval = (u16) idata;
2068 case WLAN_SET_MULTIPLE_DTIM:
2069 ret = wlan_set_multiple_dtim_ioctl(priv, req);
2072 case WLANSETAUTHALG:
2073 ret = wlan_setauthalg_ioctl(priv, req);
2076 case WLANSET8021XAUTHALG:
2077 ret = wlan_set8021xauthalg_ioctl(priv, req);
2080 case WLANSETENCRYPTIONMODE:
2081 ret = wlan_setencryptionmode_ioctl(priv, req);
2084 case WLAN_SET_LINKMODE:
2085 ret = wlan_set_linkmode_ioctl(priv, req);
2088 case WLAN_SET_RADIOMODE:
2089 ret = wlan_set_radiomode_ioctl(priv, req);
2092 case WLAN_SET_DEBUGMODE:
2093 ret = wlan_set_debugmode_ioctl(priv, req);
2096 case WLAN_SUBCMD_MESH_SET_TTL:
2097 idata = SUBCMD_DATA(wrq);
2098 ret = wlan_mesh_set_ttl_ioctl(priv, idata);
2108 case WLAN_SETNONE_GETTWELVE_CHAR: /* Get Antenna settings */
2110 * We've not used IW_PRIV_TYPE_FIXED so sub-ioctl number is
2111 * in flags of iwreq structure, otherwise it will be in
2112 * mode member of iwreq structure.
2114 switch ((int)wrq->u.data.flags) {
2115 case WLAN_SUBCMD_GETRXANTENNA: /* Get Rx Antenna */
2116 ret = wlan_subcmd_getrxantenna_ioctl(priv, req);
2119 case WLAN_SUBCMD_GETTXANTENNA: /* Get Tx Antenna */
2120 ret = wlan_subcmd_gettxantenna_ioctl(priv, req);
2124 ret = wlan_get_tsf_ioctl(priv, wrq);
2129 case WLAN_SET128CHAR_GET128CHAR:
2130 switch ((int)wrq->u.data.flags) {
2133 lbs_pr_debug(1, "Scan mode Ioctl\n");
2134 ret = wlan_scan_mode_ioctl(priv, wrq);
2137 case WLAN_GET_ADHOC_STATUS:
2138 ret = wlan_get_adhoc_status_ioctl(priv, wrq);
2140 case WLAN_SUBCMD_BT_ADD:
2141 ret = wlan_bt_add_ioctl(priv, req);
2143 case WLAN_SUBCMD_BT_DEL:
2144 ret = wlan_bt_del_ioctl(priv, req);
2146 case WLAN_SUBCMD_BT_LIST:
2147 ret = wlan_bt_list_ioctl(priv, req);
2149 case WLAN_SUBCMD_FWT_ADD:
2150 ret = wlan_fwt_add_ioctl(priv, req);
2152 case WLAN_SUBCMD_FWT_DEL:
2153 ret = wlan_fwt_del_ioctl(priv, req);
2155 case WLAN_SUBCMD_FWT_LOOKUP:
2156 ret = wlan_fwt_lookup_ioctl(priv, req);
2158 case WLAN_SUBCMD_FWT_LIST_NEIGHBOR:
2159 ret = wlan_fwt_list_neighbor_ioctl(priv, req);
2161 case WLAN_SUBCMD_FWT_LIST:
2162 ret = wlan_fwt_list_ioctl(priv, req);
2164 case WLAN_SUBCMD_FWT_LIST_ROUTE:
2165 ret = wlan_fwt_list_route_ioctl(priv, req);
2170 case WLAN_SETNONE_GETONEINT:
2171 switch ((int)req->ifr_data) {
2173 pdata = (int *)wrq->u.name;
2174 *pdata = (int)adapter->bcn_avg_factor;
2178 pdata = (int *)wrq->u.name;
2179 *pdata = (int)adapter->regioncode;
2182 case WLAN_GET_LISTEN_INTERVAL:
2183 pdata = (int *)wrq->u.name;
2184 *pdata = (int)adapter->listeninterval;
2187 case WLAN_GET_LINKMODE:
2188 req->ifr_data = (char *)((u32) adapter->linkmode);
2191 case WLAN_GET_RADIOMODE:
2192 req->ifr_data = (char *)((u32) adapter->radiomode);
2195 case WLAN_GET_DEBUGMODE:
2196 req->ifr_data = (char *)((u32) adapter->debugmode);
2199 case WLAN_GET_MULTIPLE_DTIM:
2200 pdata = (int *)wrq->u.name;
2201 *pdata = (int)adapter->multipledtim;
2203 case WLAN_GET_TX_RATE:
2204 ret = wlan_get_txrate_ioctl(priv, req);
2206 case WLAN_SUBCMD_FWT_CLEANUP: /* fwt_cleanup */
2207 ret = wlan_fwt_cleanup_ioctl(priv, req);
2210 case WLAN_SUBCMD_FWT_TIME: /* fwt_time */
2211 ret = wlan_fwt_time_ioctl(priv, req);
2214 case WLAN_SUBCMD_MESH_GET_TTL:
2215 ret = wlan_mesh_get_ttl_ioctl(priv, req);
2226 ret = wlan_do_getlog_ioctl(priv, wrq);
2229 case WLAN_SET_GET_SIXTEEN_INT:
2230 switch ((int)wrq->u.data.flags) {
2234 struct cmd_ds_802_11_tpc_cfg cfg;
2235 memset(&cfg, 0, sizeof(cfg));
2236 if ((wrq->u.data.length > 1)
2237 && (wrq->u.data.length != 5))
2240 if (wrq->u.data.length == 0) {
2246 (data, wrq->u.data.pointer,
2249 "Copy from user failed\n");
2256 cfg.enable = data[0];
2257 cfg.usesnr = data[1];
2264 libertas_prepare_and_send_command(priv,
2267 cmd_option_waitforrsp,
2270 data[0] = cfg.enable;
2271 data[1] = cfg.usesnr;
2276 (wrq->u.data.pointer, data,
2278 lbs_pr_debug(1, "Copy to user failed\n");
2282 wrq->u.data.length = 5;
2289 struct cmd_ds_802_11_pwr_cfg cfg;
2290 memset(&cfg, 0, sizeof(cfg));
2291 if ((wrq->u.data.length > 1)
2292 && (wrq->u.data.length != 4))
2294 if (wrq->u.data.length == 0) {
2300 (data, wrq->u.data.pointer,
2303 "Copy from user failed\n");
2310 cfg.enable = data[0];
2311 cfg.PA_P0 = data[1];
2312 cfg.PA_P1 = data[2];
2313 cfg.PA_P2 = data[3];
2316 libertas_prepare_and_send_command(priv,
2319 cmd_option_waitforrsp,
2321 data[0] = cfg.enable;
2322 data[1] = cfg.PA_P0;
2323 data[2] = cfg.PA_P1;
2324 data[3] = cfg.PA_P2;
2326 (wrq->u.data.pointer, data,
2328 lbs_pr_debug(1, "Copy to user failed\n");
2332 wrq->u.data.length = 4;
2335 case WLAN_AUTO_FREQ_SET:
2338 struct cmd_ds_802_11_afc afc;
2339 memset(&afc, 0, sizeof(afc));
2340 if (wrq->u.data.length != 3)
2343 (data, wrq->u.data.pointer,
2345 lbs_pr_debug(1, "Copy from user failed\n");
2348 afc.afc_auto = data[0];
2350 if (afc.afc_auto != 0) {
2351 afc.threshold = data[1];
2352 afc.period = data[2];
2354 afc.timing_offset = data[1];
2355 afc.carrier_offset = data[2];
2358 libertas_prepare_and_send_command(priv,
2361 cmd_option_waitforrsp,
2365 case WLAN_AUTO_FREQ_GET:
2368 struct cmd_ds_802_11_afc afc;
2369 memset(&afc, 0, sizeof(afc));
2371 libertas_prepare_and_send_command(priv,
2374 cmd_option_waitforrsp,
2376 data[0] = afc.afc_auto;
2377 data[1] = afc.timing_offset;
2378 data[2] = afc.carrier_offset;
2380 (wrq->u.data.pointer, data,
2382 lbs_pr_debug(1, "Copy to user failed\n");
2386 wrq->u.data.length = 3;
2389 case WLAN_SCANPROBES:
2392 if (wrq->u.data.length > 0) {
2394 (&data, wrq->u.data.pointer,
2397 "Copy from user failed\n");
2401 adapter->scanprobes = data;
2403 data = adapter->scanprobes;
2405 (wrq->u.data.pointer, &data,
2408 "Copy to user failed\n");
2412 wrq->u.data.length = 1;
2415 case WLAN_LED_GPIO_CTRL:
2420 struct cmd_ds_802_11_led_ctrl ctrl;
2421 struct mrvlietypes_ledgpio *gpio =
2422 (struct mrvlietypes_ledgpio *) ctrl.data;
2424 memset(&ctrl, 0, sizeof(ctrl));
2425 if (wrq->u.data.length > MAX_LEDS * 2)
2427 if ((wrq->u.data.length % 2) != 0)
2429 if (wrq->u.data.length == 0) {
2435 (data, wrq->u.data.pointer,
2437 wrq->u.data.length)) {
2439 "Copy from user failed\n");
2446 ctrl.numled = cpu_to_le16(0);
2448 cpu_to_le16(TLV_TYPE_LED_GPIO);
2449 gpio->header.len = wrq->u.data.length;
2450 for (i = 0; i < wrq->u.data.length;
2452 gpio->ledpin[i / 2].led =
2454 gpio->ledpin[i / 2].pin =
2459 libertas_prepare_and_send_command(priv,
2460 cmd_802_11_led_gpio_ctrl,
2462 cmd_option_waitforrsp,
2464 for (i = 0; i < gpio->header.len; i += 2) {
2465 data[i] = gpio->ledpin[i / 2].led;
2466 data[i + 1] = gpio->ledpin[i / 2].pin;
2468 if (copy_to_user(wrq->u.data.pointer, data,
2470 gpio->header.len)) {
2471 lbs_pr_debug(1, "Copy to user failed\n");
2475 wrq->u.data.length = gpio->header.len;
2478 case WLAN_ADAPT_RATESET:
2479 ret = wlan_adapt_rateset(priv, wrq);
2481 case WLAN_INACTIVITY_TIMEOUT:
2482 ret = wlan_inactivity_timeout(priv, wrq);
2485 ret = wlan_get_snr(priv, wrq);
2487 case WLAN_GET_RXINFO:
2488 ret = wlan_get_rxinfo(priv, wrq);