⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ar6000_drv.c

📁 Linux下SDIO设备的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
                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 + -