| 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;
|
| }
|
|
|