📄 ar6000_drv.c
字号:
ret = -EIO; } break; } case AR6000_XIOCTL_SET_VOICE_PKT_SIZE: ret = ar6000_xioctl_set_voice_pkt_size(dev, userdata); break; case AR6000_XIOCTL_SET_MAX_SP: ret = ar6000_xioctl_set_max_sp_len(dev, userdata); break; case AR6000_XIOCTL_WMI_GET_ROAM_TBL: ret = ar6000_ioctl_get_roam_tbl(dev, rq); break; case AR6000_XIOCTL_WMI_SET_ROAM_CTRL: ret = ar6000_ioctl_set_roam_ctrl(dev, userdata); break; case AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS: ret = ar6000_ioctl_set_powersave_timers(dev, userdata); break; case AR6000_XIOCTRL_WMI_GET_POWER_MODE: ret = ar6000_ioctl_get_power_mode(dev, rq); break; case AR6000_XIOCTRL_WMI_SET_WLAN_STATE: get_user(ar->arWlanState, (unsigned int *)userdata); if (ar->arWmiReady == FALSE) { ret = -EIO; break; } if (ar->arWlanState == WLAN_ENABLED) { /* Enable foreground scanning */ AR6000_SPIN_LOCK(&ar->arLock, 0); if (wmi_scanparams_cmd(ar->arWmi, scParams.fg_start_period, scParams.fg_end_period, scParams.bg_period, scParams.act_chdwell_time, scParams.pas_chdwell_time, scParams.shortScanRatio) != A_OK) { ret = -EIO; } if (ar->arSsidLen) { if (wmi_connect_cmd(ar->arWmi, ar->arNetworkType, ar->arDot11AuthMode, ar->arAuthMode, ar->arPairwiseCrypto, ar->arPairwiseCryptoLen, ar->arGroupCrypto, ar->arGroupCryptoLen, ar->arSsidLen, ar->arSsid, ar->arReqBssid, ar->arChannelHint) != A_OK) { ret = -EIO; } else { ar->arConnectPending = TRUE; } } AR6000_SPIN_UNLOCK(&ar->arLock, 0); } else { /* Disconnect from the AP and disable foreground scanning */ AR6000_SPIN_LOCK(&ar->arLock, 0); if (ar->arConnected == TRUE || ar->arConnectPending == TRUE) { wmi_disconnect_cmd(ar->arWmi); } if (wmi_scanparams_cmd(ar->arWmi, 65535, 0, 0, 0, 0, 0) != A_OK) { ret = -EIO; } AR6000_SPIN_UNLOCK(&ar->arLock, 0); } break; case AR6000_XIOCTL_WMI_GET_ROAM_DATA: ret = ar6000_ioctl_get_roam_data(dev, rq); break; default: ret = -EOPNOTSUPP; } return ret;}voidar6000_bitrate_rx(void *devt, A_INT32 rateKbps){ AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; ar->arBitRate = rateKbps; wake_up(&arEvent);}voidar6000_txPwr_rx(void *devt, A_UINT8 txPwr){ AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; ar->arTxPwr = txPwr; wake_up(&arEvent);}static intar6000_ioctl_set_channelParams(struct net_device *dev, struct ifreq *rq){ AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv; WMI_CHANNEL_PARAMS_CMD cmd, *cmdp; int ret = 0; if (ar->arWmiReady == FALSE) { return -EIO; } if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { return -EFAULT; } if (cmd.numChannels > 1) { cmdp = A_MALLOC(128); if (copy_from_user(cmdp, rq->ifr_data, sizeof (*cmdp) + ((cmd.numChannels - 1) * sizeof(A_UINT16)))) { kfree(cmdp); return -EFAULT; } } else { cmdp = &cmd; } if ((ar->arPhyCapability == WMI_11G_CAPABILITY) && ((cmdp->phyMode == WMI_11A_MODE) || (cmdp->phyMode == WMI_11AG_MODE))) { ret = -EINVAL; } AR6000_SPIN_LOCK(&ar->arLock, 0); if (!ret && (wmi_set_channelParams_cmd(ar->arWmi, cmdp->phyMode, cmdp->numChannels, cmdp->channelList) != A_OK)) { ret = -EIO; } AR6000_SPIN_UNLOCK(&ar->arLock, 0); if (cmd.numChannels > 1) { kfree(cmdp); } return ret;}static intar6000_ioctl_set_link_threshold(struct net_device *dev, struct ifreq *rq){ AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv; WMI_RSSI_THRESHOLD_PARAMS_CMD cmd; int ret = 0; if (ar->arWmiReady == FALSE) { return -EIO; } if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { return -EFAULT; } AR6000_SPIN_LOCK(&ar->arLock, 0); if( wmi_set_link_threshold_params(ar->arWmi, cmd.highThreshold_upperVal, cmd.highThreshold_lowerVal, cmd.lowThreshold_upperVal, cmd.lowThreshold_lowerVal, cmd.pollTime) != A_OK ) { ret = -EIO; } AR6000_SPIN_UNLOCK(&ar->arLock, 0); return ret;}voidar6000_channelList_rx(void *devt, A_INT8 numChan, A_UINT16 *chanList){ AR_SOFTC_T *ar = (AR_SOFTC_T *)devt; A_MEMCPY(ar->arChannelList, chanList, numChan * sizeof (A_UINT16)); ar->arNumChannels = numChan; wake_up(&arEvent);}static intar6000_ioctl_set_probedSsid(struct net_device *dev, struct ifreq *rq){ AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv; WMI_PROBED_SSID_CMD cmd; int ret = 0; if (ar->arWmiReady == FALSE) { return -EIO; } if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { return -EFAULT; } AR6000_SPIN_LOCK(&ar->arLock, 0); if (wmi_probedSsid_cmd(ar->arWmi, cmd.entryIndex, cmd.flag, cmd.ssidLength, cmd.ssid) != A_OK) { ret = -EIO; } AR6000_SPIN_UNLOCK(&ar->arLock, 0); return ret;}static intar6000_ioctl_set_badAp(struct net_device *dev, struct ifreq *rq){ AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv; WMI_ADD_BAD_AP_CMD cmd; int ret = 0; if (ar->arWmiReady == FALSE) { return -EIO; } if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { return -EFAULT; } if (cmd.badApIndex > WMI_MAX_BAD_AP_INDEX) { return -EIO; } AR6000_SPIN_LOCK(&ar->arLock, 0); if (A_MEMCMP(cmd.bssid, null_mac, AR6000_ETH_ADDR_LEN) == 0) { /* * This is a delete badAP. */ if (wmi_deleteBadAp_cmd(ar->arWmi, cmd.badApIndex) != A_OK) { ret = -EIO; } } else { if (wmi_addBadAp_cmd(ar->arWmi, cmd.badApIndex, cmd.bssid) != A_OK) { ret = -EIO; } } AR6000_SPIN_UNLOCK(&ar->arLock, 0); return ret;}static intar6000_ioctl_create_qos(struct net_device *dev, struct ifreq *rq){ AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv; WMI_CREATE_PSTREAM_CMD cmd; A_STATUS ret; if (ar->arWmiReady == FALSE) { return -EIO; } if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { return -EFAULT; } AR6000_SPIN_LOCK(&ar->arLock, 0); cmd.rxQueueNum = 0xFF; ret = wmi_verify_tspec_params(&cmd, tspecCompliance); if (ret == A_OK) ret = wmi_create_pstream_cmd(ar->arWmi, &cmd); AR6000_SPIN_UNLOCK(&ar->arLock, 0); switch (ret) { case A_OK: return 0; case A_EBUSY : return -EBUSY; case A_NO_MEMORY: return -ENOMEM; case A_EINVAL: default: return -EFAULT; }}static intar6000_ioctl_delete_qos(struct net_device *dev, struct ifreq *rq){ AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv; WMI_DELETE_PSTREAM_CMD cmd; int ret = 0; if (ar->arWmiReady == FALSE) { return -EIO; } if (copy_from_user(&cmd, rq->ifr_data, sizeof(cmd))) { return -EFAULT; } AR6000_SPIN_LOCK(&ar->arLock, 0); ret = wmi_delete_pstream_cmd(ar->arWmi, cmd.txQueueNumber, cmd.rxQueueNumber, cmd.trafficDirection); AR6000_SPIN_UNLOCK(&ar->arLock, 0); switch (ret) { case A_OK: return 0; case A_EBUSY : return -EBUSY; case A_NO_MEMORY: return -ENOMEM; case A_EINVAL: default: return -EFAULT; }}static intar6000_ioctl_get_qos_queue(struct net_device *dev, struct ifreq *rq){ AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv; struct ar6000_queuereq qreq; int ret = 0; if (ar->arWmiReady == FALSE) { return -EIO; } copy_from_user(&qreq, rq->ifr_data, sizeof(struct ar6000_queuereq)); qreq.queueNumber = wmi_get_mapped_qos_queue(ar->arWmi, qreq.trafficDirection, qreq.trafficClass); if (copy_to_user(rq->ifr_data, &qreq, sizeof(struct ar6000_queuereq))) { ret = -EFAULT; } return ret;}#ifdef HTC_RAW_INTERFACE#define RAW_HTC_READ_BUFFERS_NUM 16#define RAW_HTC_WRITE_BUFFERS_NUM 16typedef struct { int currPtr; int length; unsigned char data[AR6000_BUFFER_SIZE];} raw_htc_buffer;static struct semaphore raw_htc_read_sem[HTC_MAILBOX_NUM_MAX];static struct semaphore raw_htc_write_sem[HTC_MAILBOX_NUM_MAX];static wait_queue_head_t raw_htc_read_queue[HTC_MAILBOX_NUM_MAX];static wait_queue_head_t raw_htc_write_queue[HTC_MAILBOX_NUM_MAX];static raw_htc_buffer raw_htc_read_buffer[HTC_MAILBOX_NUM_MAX][RAW_HTC_READ_BUFFERS_NUM];static raw_htc_buffer raw_htc_write_buffer[HTC_MAILBOX_NUM_MAX][RAW_HTC_WRITE_BUFFERS_NUM];static A_BOOL write_buffer_available[HTC_MAILBOX_NUM_MAX];static A_BOOL read_buffer_available[HTC_MAILBOX_NUM_MAX];static voidar6000_htc_raw_read_cb(HTC_TARGET *htcTarget, HTC_ENDPOINT_ID endPointId, HTC_EVENT_ID evId, HTC_EVENT_INFO *evInfo, void *arg){ HTC_TARGET *target; raw_htc_buffer *busy; target = (HTC_TARGET *)arg; A_ASSERT(target != NULL); busy = (raw_htc_buffer *)evInfo->cookie; A_ASSERT(busy != NULL); if (evInfo->status == A_ECANCELED) { /* * HTC provides A_ECANCELED status when it doesn't want to be refilled * (probably due to a shutdown) */ memset(busy, 0, sizeof(raw_htc_buffer)); return; }#ifdef CF if (down_trylock(&raw_htc_read_sem[endPointId])) {#else if (down_interruptible(&raw_htc_read_sem[endPointId])) {#endif /* CF */ AR_DEBUG2_PRINTF("Unable to down the semaphore\n"); } A_ASSERT(evId == HTC_BUFFER_RECEIVED); A_ASSERT((evInfo->status != A_OK) || (evInfo->buffer == (busy->data + HTC_HEADER_LEN))); busy->length = evInfo->actualLength + HTC_HEADER_LEN; busy->currPtr = HTC_HEADER_LEN
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -