📄 ar6000_drv.c
字号:
return(-EIO); } if(HTCEventReg(ar->arHtcTarget, endpoint[i], HTC_DATA_AVAILABLE, ar6000_rx_refill, ar) != A_OK) { return(-EIO); } if(HTCEventReg(ar->arHtcTarget, endpoint[i], HTC_BUFFER_SENT, ar6000_tx_complete, ar) != A_OK) { return(-EIO); } } /* * Provide HTC with receive buffers */ ar6000_rx_refill(ar->arHtcTarget, ENDPOINT1, HTC_DATA_AVAILABLE, NULL, ar); ar6000_rx_refill(ar->arHtcTarget, ENDPOINT2, HTC_DATA_AVAILABLE, NULL, ar); /* * We will post the receive buffers only for SPE testing and so we are * making it conditional on the 'bypasswmi' flag. */ if (bypasswmi) { ar6000_rx_refill(ar->arHtcTarget, ENDPOINT3, HTC_DATA_AVAILABLE, NULL, ar); ar6000_rx_refill(ar->arHtcTarget, ENDPOINT4, HTC_DATA_AVAILABLE, NULL, ar); } /* Since cookies are used for HTC transports, they should be */ /* initialized prior to enabling HTC. */ ar6000_cookie_init(ar); /* Enable the target and the interrupts associated with it */ status = HTCStart(ar->arHtcTarget); if (status != A_OK) { if (ar->arWmiEnabled == TRUE) { wmi_shutdown(ar->arWmi); ar->arWmiEnabled = FALSE; ar->arWmi = NULL; } ar6000_cookie_cleanup(ar); return -EIO; } if (!bypasswmi) { /*Wait for Wmi event to be ready */ timeleft = wait_event_interruptible_timeout(arEvent, (ar->arWmiReady == TRUE), 1 * HZ); if(!timeleft || signal_pending(current)) { AR_DEBUG_PRINTF("WMI is not ready or wait was interrupted\n"); return -EIO; } AR_DEBUG_PRINTF("%s() WMI is ready\n", __func__); } ar->arNumDataEndPts = 1; return(0);}/* This would basically hold all the private ioctls that are not related to WLAN operation */static intar6000_ioctl(struct net_device *dev, struct ifreq *rq, int cmd){ AR_SOFTC_T *ar = (AR_SOFTC_T *)dev->priv; HIF_DEVICE *hifDevice = ar->arHifDevice; HTC_TARGET *htcTarget = ar->arHtcTarget; int ret, param; unsigned int address = 0; unsigned int length = 0; unsigned char *buffer; char *userdata;#ifdef HTC_RAW_INTERFACE HTC_ENDPOINT_ID endPointId = 0; static A_BOOL rawIfInit = FALSE;#endif /* HTC_RAW_INTERFACE */ static WMI_SCAN_PARAMS_CMD scParams = {0, 0, 0, 0, 0, WMI_SHORTSCANRATIO_DEFAULT }; if (cmd == AR6000_IOCTL_EXTENDED) { /* * This allows for many more wireless ioctls than would otherwise * be available. Applications embed the actual ioctl command in * 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); userdata = (char *)(((unsigned int *)rq->ifr_data)+1); } else { userdata = (char *)rq->ifr_data; } if ((ar->arWlanState == WLAN_DISABLED) && (cmd != AR6000_XIOCTRL_WMI_SET_WLAN_STATE)) { return -EIO; } ret = 0; switch(cmd) { case AR6000_XIOCTL_BMI_DONE: if(bmienable) { ret = ar6000_init(dev); } else { ret = BMIDone(hifDevice); } break; case AR6000_XIOCTL_BMI_READ_MEMORY: get_user(address, (unsigned int *)userdata); get_user(length, (unsigned int *)userdata + 1); AR_DEBUG_PRINTF("Read Memory (address: 0x%x, length: %d)\n", address, length); if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) { A_MEMZERO(buffer, length); ret = BMIReadMemory(hifDevice, address, buffer, length); if (copy_to_user(rq->ifr_data, buffer, length)) { ret = -EFAULT; } A_FREE(buffer); } else { ret = -ENOMEM; } break; case AR6000_XIOCTL_BMI_WRITE_MEMORY: get_user(address, (unsigned int *)userdata); get_user(length, (unsigned int *)userdata + 1); AR_DEBUG_PRINTF("Write Memory (address: 0x%x, length: %d)\n", address, length); if ((buffer = (unsigned char *)A_MALLOC(length)) != NULL) { A_MEMZERO(buffer, length); if (copy_from_user(buffer, &userdata[sizeof(address) + sizeof(length)], length)) { ret = -EFAULT; } else { ret = BMIWriteMemory(hifDevice, address, buffer, length); } A_FREE(buffer); } else { ret = -ENOMEM; } break; case AR6000_XIOCTL_BMI_TEST: AR_DEBUG_PRINTF("No longer supported\n"); ret = -EOPNOTSUPP; break; case AR6000_XIOCTL_BMI_EXECUTE: get_user(address, (unsigned int *)userdata); get_user(param, (unsigned int *)userdata + 1); AR_DEBUG_PRINTF("Execute (address: 0x%x, param: %d)\n", address, param); ret = BMIExecute(hifDevice, address, ¶m); put_user(param, (unsigned int *)rq->ifr_data); /* return value */ break; case AR6000_XIOCTL_BMI_SET_APP_START: get_user(address, (unsigned int *)userdata); AR_DEBUG_PRINTF("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); ret = BMIReadSOCRegister(hifDevice, address, ¶m); put_user(param, (unsigned int *)rq->ifr_data); /* return value */ break; case AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER: get_user(address, (unsigned int *)userdata); get_user(param, (unsigned int *)userdata + 1); ret = BMIWriteSOCRegister(hifDevice, address, param); break;#ifdef HTC_RAW_INTERFACE case AR6000_XIOCTL_HTC_RAW_OPEN: ret = A_OK; if (!rawIfInit) { /* Terminate the BMI phase */ ret = BMIDone(hifDevice); if (ret == A_OK) { ret = ar6000_htc_raw_open(htcTarget); } if (ret == A_OK) { rawIfInit = TRUE; } } break; case AR6000_XIOCTL_HTC_RAW_CLOSE: if (rawIfInit) { ret = ar6000_htc_raw_close(htcTarget); rawIfInit = FALSE; } else { ret = A_ERROR; } break; case AR6000_XIOCTL_HTC_RAW_READ: if (rawIfInit) { get_user(endPointId, (unsigned int *)userdata); get_user(length, (unsigned int *)userdata + 1); buffer = rq->ifr_data + sizeof(length); ret = ar6000_htc_raw_read(htcTarget, endPointId, buffer, length); put_user(ret, (unsigned int *)rq->ifr_data); } else { ret = A_ERROR; } break; case AR6000_XIOCTL_HTC_RAW_WRITE: if (rawIfInit) { get_user(endPointId, (unsigned int *)userdata); get_user(length, (unsigned int *)userdata + 1); buffer = userdata + sizeof(endPointId) + sizeof(length); ret = ar6000_htc_raw_write(htcTarget, endPointId, buffer, length); put_user(ret, (unsigned int *)rq->ifr_data); } else { ret = A_ERROR; } break;#endif /* HTC_RAW_INTERFACE */ case AR6000_IOCTL_WMI_GETREV: { if (copy_to_user(rq->ifr_data, &ar->arVersion, sizeof(ar->arVersion))) { ret = -EFAULT; } break; } case AR6000_IOCTL_WMI_SETPWR: { WMI_POWER_MODE_CMD pwrModeCmd; if (ar->arWmiReady == FALSE) { ret = -EIO; } else if (copy_from_user(&pwrModeCmd, userdata, sizeof(pwrModeCmd))) { ret = -EFAULT; } else { AR6000_SPIN_LOCK(&ar->arLock, 0); if (wmi_powermode_cmd(ar->arWmi, pwrModeCmd.powerMode) != A_OK) { ret = -EIO; } AR6000_SPIN_UNLOCK(&ar->arLock, 0); } break; } case AR6000_IOCTL_WMI_SET_IBSS_PM_CAPS: { WMI_IBSS_PM_CAPS_CMD ibssPmCaps; if (ar->arWmiReady == FALSE) { ret = -EIO; } else if (copy_from_user(&ibssPmCaps, userdata, sizeof(ibssPmCaps))) { ret = -EFAULT; } else { AR6000_SPIN_LOCK(&ar->arLock, 0); if (wmi_ibsspmcaps_cmd(ar->arWmi, ibssPmCaps.power_saving, ibssPmCaps.ttl, ibssPmCaps.atim_windows, ibssPmCaps.timeout_value) != A_OK) { ret = -EIO; } ar->arIbssPsEnable = ibssPmCaps.power_saving; AR6000_SPIN_UNLOCK(&ar->arLock, 0); } break; } case AR6000_IOCTL_WMI_SET_PMPARAMS: { WMI_POWER_PARAMS_CMD pmParams; if (ar->arWmiReady == FALSE) { ret = -EIO; } else if (copy_from_user(&pmParams, userdata, sizeof(pmParams))) { ret = -EFAULT; } else { AR6000_SPIN_LOCK(&ar->arLock, 0); if (wmi_pmparams_cmd(ar->arWmi, pmParams.idle_period, pmParams.pspoll_number, pmParams.dtim_policy) != A_OK) { ret = -EIO; } AR6000_SPIN_UNLOCK(&ar->arLock, 0); } break; } case AR6000_IOCTL_WMI_SETSCAN: { if (ar->arWmiReady == FALSE) { ret = -EIO; } else if (copy_from_user(&scParams, userdata, sizeof(scParams))) { ret = -EFAULT; } else { 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; } AR6000_SPIN_UNLOCK(&ar->arLock, 0); } break; } case AR6000_IOCTL_WMI_SETLISTENINT: { WMI_LISTEN_INT_CMD listenCmd; if (ar->arWmiReady == FALSE) { ret = -EIO; } else if (copy_from_user(&listenCmd, userdata, sizeof(listenCmd))) { ret = -EFAULT; } else { AR6000_SPIN_LOCK(&ar->arLock, 0); if (wmi_listeninterval_cmd(ar->arWmi, listenCmd.listenInterval, listenCmd.numBeacons) != A_OK) { ret = -EIO; } else { ar->arListenInterval = param; } AR6000_SPIN_UNLOCK(&ar->arLock, 0); } break; } case AR6000_IOCTL_WMI_SET_BMISS_TIME: { WMI_BMISS_TIME_CMD bmissCmd; if (ar->arWmiReady == FALSE) { ret = -EIO; } else if (copy_from_user(&bmissCmd, userdata, sizeof(bmissCmd))) { ret = -EFAULT; } else { AR6000_SPIN_LOCK(&ar->arLock, 0); if (wmi_bmisstime_cmd(ar->arWmi, bmissCmd.bmissTime, bmissCmd.numBeacons) != A_OK) { ret = -EIO; } AR6000_SPIN_UNLOCK(&ar->arLock, 0); } break; } case AR6000_IOCTL_WMI_SETBSSFILTER: { if (ar->arWmiReady == FALSE) { ret = -EIO; } else { get_user(param, (unsigned int *)userdata); AR6000_SPIN_LOCK(&ar->arLock, 0); if (wmi_bssfilter_cmd(ar->arWmi, param) != A_OK) { ret = -EIO; } AR6000_SPIN_UNLOCK(&ar->arLock, 0); } break; } case AR6000_IOCTL_WMI_SET_LINKTHRESHOLD: { ret = ar6000_ioctl_set_link_threshold(dev, rq); break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -