Index: chromeos/drivers/ath6kl/os/linux/ioctl.c |
diff --git a/chromeos/drivers/ath6kl/os/linux/ioctl.c b/chromeos/drivers/ath6kl/os/linux/ioctl.c |
index 3d6543f0c9bcd643062f80eccf60e38a780a9b93..d5f7ac08ab967181e5c2a9883d95f8dc7e1d3493 100644 |
--- a/chromeos/drivers/ath6kl/os/linux/ioctl.c |
+++ b/chromeos/drivers/ath6kl/os/linux/ioctl.c |
@@ -1,21 +1,25 @@ |
-/* |
- * |
- * Copyright (c) 2004-2010 Atheros Communications Inc. |
- * All rights reserved. |
- * |
- * |
-// This program is free software; you can redistribute it and/or modify |
-// it under the terms of the GNU General Public License version 2 as |
-// published by the Free Software Foundation; |
+//------------------------------------------------------------------------------ |
+// Copyright (c) 2004-2010 Atheros Communications Inc. |
+// All rights reserved. |
// |
-// Software distributed under the License is distributed on an "AS |
-// IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or |
-// implied. See the License for the specific language governing |
-// rights and limitations under the License. |
+// |
// |
+// Permission to use, copy, modify, and/or distribute this software for any |
+// purpose with or without fee is hereby granted, provided that the above |
+// copyright notice and this permission notice appear in all copies. |
// |
- * |
- */ |
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
+// |
+// |
+// |
+// Author(s): ="Atheros" |
+//------------------------------------------------------------------------------ |
#include "ar6000_drv.h" |
#include "ieee80211_ioctl.h" |
@@ -827,19 +831,19 @@ static int |
ar6000_ioctl_get_ap_stats(struct net_device *dev, struct ifreq *rq) |
{ |
AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev); |
- WMI_AP_MODE_STAT cmd; |
+ A_UINT32 action; /* Allocating only the desired space on the frame. Declaring is as a WMI_AP_MODE_STAT variable results in exceeding the compiler imposed limit on the maximum frame size */ |
WMI_AP_MODE_STAT *pStats = &ar->arAPStats; |
int ret = 0; |
if (ar->arWmiReady == FALSE) { |
return -EIO; |
} |
- if (copy_from_user(&cmd, (char *)((unsigned int*)rq->ifr_data + 1), |
- sizeof(cmd))) |
+ if (copy_from_user(&action, (char *)((unsigned int*)rq->ifr_data + 1), |
+ sizeof(A_UINT32))) |
{ |
return -EFAULT; |
} |
- if (cmd.action == AP_CLEAR_STATS) { |
+ if (action == AP_CLEAR_STATS) { |
A_UINT8 i; |
AR6000_SPIN_LOCK(&ar->arLock, 0); |
for(i = 0; i < AP_MAX_NUM_STA; i++) { |
@@ -1793,7 +1797,7 @@ ar6000_ioctl_setkey(AR_SOFTC_T *ar, struct ieee80211req_key *ik) |
return -EIO; |
} |
- if (WEP_CRYPT == keyType) { |
+ if ((WEP_CRYPT == keyType)&&(!ar->arConnected)) { |
int index = ik->ik_keyix; |
if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(ik->ik_keylen)) { |
@@ -1870,7 +1874,10 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
* the first word of the parameter block, and use the command |
* AR6000_IOCTL_EXTENDED_CMD on the ioctl call. |
*/ |
- get_user(cmd, (int *)rq->ifr_data); |
+ if (get_user(cmd, (int *)rq->ifr_data)) { |
+ ret = -EFAULT; |
+ goto ioctl_done; |
+ } |
userdata = (char *)(((unsigned int *)rq->ifr_data)+1); |
if(is_xioctl_allowed(ar->arNextMode, cmd) != A_OK) { |
A_PRINTF("xioctl: cmd=%d not allowed in this mode\n",cmd); |
@@ -1896,6 +1903,10 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
(cmd != AR6000_XIOCTL_GET_WLAN_SLEEP_STATE) && |
(cmd != AR6000_XIOCTL_DIAG_READ) && |
(cmd != AR6000_XIOCTL_DIAG_WRITE) && |
+ (cmd != AR6000_XIOCTL_SET_BT_HW_POWER_STATE) && |
+ (cmd != AR6000_XIOCTL_GET_BT_HW_POWER_STATE) && |
+ (cmd != AR6000_XIOCTL_ADD_AP_INTERFACE) && |
+ (cmd != AR6000_XIOCTL_REMOVE_AP_INTERFACE) && |
(cmd != AR6000_IOCTL_WMI_GETREV))) |
{ |
ret = -EIO; |
@@ -2005,7 +2016,9 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
{ |
TCMD_CONT_TX txCmd; |
- if (ar->tcmdPm == TCMD_PM_SLEEP) { |
+ if ((ar->tcmdPm == TCMD_PM_SLEEP) || |
+ (ar->tcmdPm == TCMD_PM_DEEPSLEEP)) |
+ { |
A_PRINTF("Can NOT send tx tcmd when target is asleep! \n"); |
ret = -EFAULT; |
goto ioctl_done; |
@@ -2023,7 +2036,9 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
{ |
TCMD_CONT_RX rxCmd; |
- if (ar->tcmdPm == TCMD_PM_SLEEP) { |
+ if ((ar->tcmdPm == TCMD_PM_SLEEP) || |
+ (ar->tcmdPm == TCMD_PM_DEEPSLEEP)) |
+ { |
A_PRINTF("Can NOT send rx tcmd when target is asleep! \n"); |
ret = -EFAULT; |
goto ioctl_done; |
@@ -2082,8 +2097,12 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
break; |
case AR6000_XIOCTL_BMI_READ_MEMORY: |
- get_user(address, (unsigned int *)userdata); |
- get_user(length, (unsigned int *)userdata + 1); |
+ if (get_user(address, (unsigned int *)userdata) || |
+ get_user(length, (unsigned int *)userdata + 1)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
+ |
AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Read Memory (address: 0x%x, length: %d)\n", |
address, length)); |
if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) { |
@@ -2099,8 +2118,11 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
break; |
case AR6000_XIOCTL_BMI_WRITE_MEMORY: |
- get_user(address, (unsigned int *)userdata); |
- get_user(length, (unsigned int *)userdata + 1); |
+ if (get_user(address, (unsigned int *)userdata) || |
+ get_user(length, (unsigned int *)userdata + 1)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Write Memory (address: 0x%x, length: %d)\n", |
address, length)); |
if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) { |
@@ -2124,29 +2146,49 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
break; |
case AR6000_XIOCTL_BMI_EXECUTE: |
- get_user(address, (unsigned int *)userdata); |
- get_user(param, (unsigned int *)userdata + 1); |
+ if (get_user(address, (unsigned int *)userdata) || |
+ get_user(param, (unsigned int *)userdata + 1)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Execute (address: 0x%x, param: %d)\n", |
address, param)); |
ret = BMIExecute(hifDevice, address, (A_UINT32*)¶m); |
- put_user(param, (unsigned int *)rq->ifr_data); /* return value */ |
+ /* return value */ |
+ if (put_user(param, (unsigned int *)rq->ifr_data)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
break; |
case AR6000_XIOCTL_BMI_SET_APP_START: |
- get_user(address, (unsigned int *)userdata); |
+ if (get_user(address, (unsigned int *)userdata)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Set App Start (address: 0x%x)\n", address)); |
ret = BMISetAppStart(hifDevice, address); |
break; |
case AR6000_XIOCTL_BMI_READ_SOC_REGISTER: |
- get_user(address, (unsigned int *)userdata); |
+ if (get_user(address, (unsigned int *)userdata)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
ret = BMIReadSOCRegister(hifDevice, address, (A_UINT32*)¶m); |
- put_user(param, (unsigned int *)rq->ifr_data); /* return value */ |
+ /* return value */ |
+ if (put_user(param, (unsigned int *)rq->ifr_data)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
break; |
case AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER: |
- get_user(address, (unsigned int *)userdata); |
- get_user(param, (unsigned int *)userdata + 1); |
+ if (get_user(address, (unsigned int *)userdata) || |
+ get_user(param, (unsigned int *)userdata + 1)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
ret = BMIWriteSOCRegister(hifDevice, address, param); |
break; |
@@ -2184,12 +2226,18 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
case AR6000_XIOCTL_HTC_RAW_READ: |
if (arRawIfEnabled(ar)) { |
unsigned int streamID; |
- get_user(streamID, (unsigned int *)userdata); |
- get_user(length, (unsigned int *)userdata + 1); |
+ if (get_user(streamID, (unsigned int *)userdata) || |
+ get_user(length, (unsigned int *)userdata + 1)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
buffer = (unsigned char*)rq->ifr_data + sizeof(length); |
ret = ar6000_htc_raw_read(ar, (HTC_RAW_STREAM_ID)streamID, |
(char*)buffer, length); |
- put_user(ret, (unsigned int *)rq->ifr_data); |
+ if (put_user(ret, (unsigned int *)rq->ifr_data)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
} else { |
ret = A_ERROR; |
} |
@@ -2198,12 +2246,18 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
case AR6000_XIOCTL_HTC_RAW_WRITE: |
if (arRawIfEnabled(ar)) { |
unsigned int streamID; |
- get_user(streamID, (unsigned int *)userdata); |
- get_user(length, (unsigned int *)userdata + 1); |
+ if (get_user(streamID, (unsigned int *)userdata) || |
+ get_user(length, (unsigned int *)userdata + 1)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
buffer = (unsigned char*)userdata + sizeof(streamID) + sizeof(length); |
ret = ar6000_htc_raw_write(ar, (HTC_RAW_STREAM_ID)streamID, |
(char*)buffer, length); |
- put_user(ret, (unsigned int *)rq->ifr_data); |
+ if (put_user(ret, (unsigned int *)rq->ifr_data)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
} else { |
ret = A_ERROR; |
} |
@@ -2211,13 +2265,19 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
#endif /* HTC_RAW_INTERFACE */ |
case AR6000_XIOCTL_BMI_LZ_STREAM_START: |
- get_user(address, (unsigned int *)userdata); |
+ if (get_user(address, (unsigned int *)userdata)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Start Compressed Stream (address: 0x%x)\n", address)); |
ret = BMILZStreamStart(hifDevice, address); |
break; |
case AR6000_XIOCTL_BMI_LZ_DATA: |
- get_user(length, (unsigned int *)userdata); |
+ if (get_user(length, (unsigned int *)userdata)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Send Compressed Data (length: %d)\n", length)); |
if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) { |
A_MEMZERO(buffer, length); |
@@ -2244,8 +2304,11 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
{ |
A_UINT32 period; |
A_UINT32 nbins; |
- get_user(period, (unsigned int *)userdata); |
- get_user(nbins, (unsigned int *)userdata + 1); |
+ if (get_user(period, (unsigned int *)userdata) || |
+ get_user(nbins, (unsigned int *)userdata + 1)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
if (wmi_prof_cfg_cmd(ar->arWmi, period, nbins) != A_OK) { |
ret = -EIO; |
@@ -2258,7 +2321,10 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
case AR6000_XIOCTL_PROF_ADDR_SET: |
{ |
A_UINT32 addr; |
- get_user(addr, (unsigned int *)userdata); |
+ if (get_user(addr, (unsigned int *)userdata)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
if (wmi_prof_addr_set_cmd(ar->arWmi, addr) != A_OK) { |
ret = -EIO; |
@@ -2508,6 +2574,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
} |
break; |
} |
+ |
case AR6000_IOCTL_WMI_SET_SNRTHRESHOLD: |
{ |
ret = ar6000_ioctl_set_snr_threshold(dev, rq); |
@@ -2559,7 +2626,6 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
case AR6000_XIOCTL_WMI_SET_RTS: |
{ |
WMI_SET_RTS_CMD rtsCmd; |
- |
if (ar->arWmiReady == FALSE) { |
ret = -EIO; |
} else if (copy_from_user(&rtsCmd, userdata, |
@@ -2644,30 +2710,29 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
if (ar->arWmiReady == FALSE) { |
ret = -EIO; |
- } else { |
- get_user(cmd.ieType, userdata); |
- if (cmd.ieType >= WMI_MAX_ASSOC_INFO_TYPE) { |
- ret = -EIO; |
- } else { |
- get_user(cmd.bufferSize, userdata + 1); |
- if (cmd.bufferSize > WMI_MAX_ASSOC_INFO_LEN) { |
- ret = -EFAULT; |
- break; |
- } |
- if (copy_from_user(assocInfo, userdata + 2, |
- cmd.bufferSize)) |
- { |
- ret = -EFAULT; |
- } else { |
- if (wmi_associnfo_cmd(ar->arWmi, cmd.ieType, |
- cmd.bufferSize, |
- assocInfo) != A_OK) |
- { |
- ret = -EIO; |
- } |
- } |
- } |
- } |
+ break; |
+ } |
+ |
+ if (get_user(cmd.ieType, userdata)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
+ if (cmd.ieType >= WMI_MAX_ASSOC_INFO_TYPE) { |
+ ret = -EIO; |
+ break; |
+ } |
+ |
+ if (get_user(cmd.bufferSize, userdata + 1) || |
+ (cmd.bufferSize > WMI_MAX_ASSOC_INFO_LEN) || |
+ copy_from_user(assocInfo, userdata + 2, cmd.bufferSize)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
+ if (wmi_associnfo_cmd(ar->arWmi, cmd.ieType, |
+ cmd.bufferSize, assocInfo) != A_OK) { |
+ ret = -EIO; |
+ break; |
+ } |
break; |
} |
case AR6000_IOCTL_WMI_SET_ACCESS_PARAMS: |
@@ -3200,10 +3265,10 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
case AR6000_XIOCTRL_WMI_SET_WLAN_STATE: |
{ |
AR6000_WLAN_STATE state; |
- get_user(state, (unsigned int *)userdata); |
- if (ar6000_set_wlan_state(ar, state)!=A_OK) { |
+ if (get_user(state, (unsigned int *)userdata)) |
+ ret = -EFAULT; |
+ else if (ar6000_set_wlan_state(ar, state) != A_OK) |
ret = -EIO; |
- } |
break; |
} |
case AR6000_XIOCTL_WMI_GET_ROAM_DATA: |
@@ -3414,19 +3479,28 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
case AR6000_XIOCTL_DIAG_READ: |
{ |
A_UINT32 addr, data; |
- get_user(addr, (unsigned int *)userdata); |
+ if (get_user(addr, (unsigned int *)userdata)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
addr = TARG_VTOP(ar->arTargetType, addr); |
if (ar6000_ReadRegDiag(ar->arHifDevice, &addr, &data) != A_OK) { |
ret = -EIO; |
} |
- put_user(data, (unsigned int *)userdata + 1); |
+ if (put_user(data, (unsigned int *)userdata + 1)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
break; |
} |
case AR6000_XIOCTL_DIAG_WRITE: |
{ |
A_UINT32 addr, data; |
- get_user(addr, (unsigned int *)userdata); |
- get_user(data, (unsigned int *)userdata + 1); |
+ if (get_user(addr, (unsigned int *)userdata) || |
+ get_user(data, (unsigned int *)userdata + 1)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
addr = TARG_VTOP(ar->arTargetType, addr); |
if (ar6000_WriteRegDiag(ar->arHifDevice, &addr, &data) != A_OK) { |
ret = -EIO; |
@@ -3580,12 +3654,18 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
ret = -EIO; |
goto ioctl_done; |
} |
- get_user(fType, (A_UINT32 *)userdata); |
+ if (get_user(fType, (A_UINT32 *)userdata)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
appIEcmd.mgmtFrmType = fType; |
if (appIEcmd.mgmtFrmType >= IEEE80211_APPIE_NUM_OF_FRAME) { |
ret = -EIO; |
} else { |
- get_user(ieLen, (A_UINT32 *)(userdata + 4)); |
+ if (get_user(ieLen, (A_UINT32 *)(userdata + 4))) { |
+ ret = -EFAULT; |
+ break; |
+ } |
appIEcmd.ieLen = ieLen; |
A_PRINTF("WPSIE: Type-%d, Len-%d\n",appIEcmd.mgmtFrmType, appIEcmd.ieLen); |
if (appIEcmd.ieLen > IEEE80211_APPIE_FRAME_MAX_LEN) { |
@@ -3657,16 +3737,23 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
A_UINT32 do_activate; |
A_UINT32 rompatch_id; |
- get_user(ROM_addr, (A_UINT32 *)userdata); |
- get_user(RAM_addr, (A_UINT32 *)userdata + 1); |
- get_user(nbytes, (A_UINT32 *)userdata + 2); |
- get_user(do_activate, (A_UINT32 *)userdata + 3); |
+ if (get_user(ROM_addr, (A_UINT32 *)userdata) || |
+ get_user(RAM_addr, (A_UINT32 *)userdata + 1) || |
+ get_user(nbytes, (A_UINT32 *)userdata + 2) || |
+ get_user(do_activate, (A_UINT32 *)userdata + 3)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Install rompatch from ROM: 0x%x to RAM: 0x%x length: %d\n", |
ROM_addr, RAM_addr, nbytes)); |
ret = BMIrompatchInstall(hifDevice, ROM_addr, RAM_addr, |
nbytes, do_activate, &rompatch_id); |
if (ret == A_OK) { |
- put_user(rompatch_id, (unsigned int *)rq->ifr_data); /* return value */ |
+ /* return value */ |
+ if (put_user(rompatch_id, (unsigned int *)rq->ifr_data)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
} |
break; |
} |
@@ -3675,7 +3762,10 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
{ |
A_UINT32 rompatch_id; |
- get_user(rompatch_id, (A_UINT32 *)userdata); |
+ if (get_user(rompatch_id, (A_UINT32 *)userdata)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("UNinstall rompatch_id %d\n", rompatch_id)); |
ret = BMIrompatchUninstall(hifDevice, rompatch_id); |
break; |
@@ -3686,7 +3776,10 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
{ |
A_UINT32 rompatch_count; |
- get_user(rompatch_count, (A_UINT32 *)userdata); |
+ if (get_user(rompatch_count, (A_UINT32 *)userdata)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Change rompatch activation count=%d\n", rompatch_count)); |
length = sizeof(A_UINT32) * rompatch_count; |
if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) { |
@@ -3850,7 +3943,9 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
} |
case AR6000_XIOCTL_DUMP_HTC_CREDIT_STATE: |
if (ar->arHtcTarget != NULL) { |
+#ifdef ATH_DEBUG_MODULE |
HTCDumpCreditStates(ar->arHtcTarget); |
+#endif /* ATH_DEBUG_MODULE */ |
#ifdef HTC_EP_STAT_PROFILING |
{ |
HTC_ENDPOINT_STATS stats; |
@@ -4453,7 +4548,7 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
{ |
WMI_SET_RTS_CMD rts; |
rts.threshold = ar->arRTS; |
- |
+ |
if (ar->arWmiReady == FALSE) { |
ret = -EIO; |
} else if(copy_to_user((WMI_SET_RTS_CMD *)rq->ifr_data, |
@@ -4504,6 +4599,68 @@ int ar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
sizeof(WMI_REPORT_SLEEP_STATE_EVENTID)); |
break; |
} |
+#ifdef CONFIG_PM |
+ case AR6000_XIOCTL_SET_BT_HW_POWER_STATE: |
+ { |
+ unsigned int state; |
+ if (get_user(state, (unsigned int *)userdata)) { |
+ ret = -EFAULT; |
+ break; |
+ } |
+ if (ar6000_set_bt_hw_state(ar, state)!=A_OK) { |
+ ret = -EIO; |
+ } |
+ } |
+ break; |
+ case AR6000_XIOCTL_GET_BT_HW_POWER_STATE: |
+ rq->ifr_ifru.ifru_ivalue = !ar->arBTOff; /* return value */ |
+ break; |
+#endif |
+ |
+ case AR6000_XIOCTL_WMI_SET_TX_SGI_PARAM: |
+ { |
+ WMI_SET_TX_SGI_PARAM_CMD SGICmd; |
+ |
+ if (ar->arWmiReady == FALSE) { |
+ ret = -EIO; |
+ } else if (copy_from_user(&SGICmd, userdata, |
+ sizeof(SGICmd))){ |
+ ret = -EFAULT; |
+ } else{ |
+ if (wmi_SGI_cmd(ar->arWmi, SGICmd.sgiMask, SGICmd.sgiPERThreshold) != A_OK) { |
+ ret = -EIO; |
+ } |
+ |
+ } |
+ break; |
+ } |
+ |
+ case AR6000_XIOCTL_ADD_AP_INTERFACE: |
+#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT |
+ { |
+ char ap_ifname[IFNAMSIZ] = {0,}; |
+ if (copy_from_user(ap_ifname, userdata, IFNAMSIZ)) { |
+ ret = -EFAULT; |
+ } else { |
+ if (ar6000_add_ap_interface(ar, ap_ifname) != A_OK) { |
+ ret = -EIO; |
+ } |
+ } |
+ } |
+#else |
+ ret = -EOPNOTSUPP; |
+#endif |
+ break; |
+ case AR6000_XIOCTL_REMOVE_AP_INTERFACE: |
+#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT |
+ if (ar6000_remove_ap_interface(ar) != A_OK) { |
+ ret = -EIO; |
+ } |
+#else |
+ ret = -EOPNOTSUPP; |
+#endif |
+ break; |
+ |
default: |
ret = -EOPNOTSUPP; |
} |