📄 hfa384x_usb.c
字号:
* is in the enabled state.** Arguments:* hw device structure* reclaim [0|1] indicates whether the given FID will* be handed back (via Alloc event) for reuse.* (host order)* fid FID of buffer containing the frame that was* previously copied to MAC memory via the bap.* (host order)** Returns: * 0 success* >0 f/w reported failure - f/w status code* <0 driver reported error (timeout|bad arg)** Side effects:* hw->resp0 will contain the FID being used by async notify* process. If reclaim==0, resp0 will be the same as the fid* argument. If reclaim==1, resp0 will be the different.** Call context:* process ----------------------------------------------------------------*/int hfa384x_cmd_notify(hfa384x_t *hw, UINT16 reclaim, UINT16 fid, void *buf, UINT16 len){#if 0 int result = 0; UINT16 cmd; DBFENTER; cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_NOTIFY) | HFA384x_CMD_RECL_SET(reclaim); result = hfa384x_docmd_wait(hw, cmd, fid, 0, 0); DBFEXIT; return result;#endifreturn 0;}/*----------------------------------------------------------------* hfa384x_cmd_inquiry** Requests an info frame from the firmware. The info frame will* be delivered asynchronously via the Info event.** Arguments:* hw device structure* fid FID of the info frame requested. (host order)** Returns: * 0 success* >0 f/w reported failure - f/w status code* <0 driver reported error (timeout|bad arg)** Side effects:** Call context:* process ----------------------------------------------------------------*/int hfa384x_cmd_inquiry(hfa384x_t *hw, UINT16 fid){ int result = 0; hfa384x_metacmd_t cmd; DBFENTER; cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_INQ); cmd.parm0 = 0; cmd.parm1 = 0; cmd.parm2 = 0; result = hfa384x_docmd(hw, DOWAIT, &cmd, NULL, NULL); DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_cmd_monitor** Enables the 'monitor mode' of the MAC. Here's the description of* monitor mode that I've received thus far:** "The "monitor mode" of operation is that the MAC passes all * frames for which the PLCP checks are correct. All received * MPDUs are passed to the host with MAC Port = 7, with a * receive status of good, FCS error, or undecryptable. Passing * certain MPDUs is a violation of the 802.11 standard, but useful * for a debugging tool." Normal communication is not possible* while monitor mode is enabled.** Arguments:* hw device structure* enable a code (0x0b|0x0f) that enables/disables* monitor mode. (host order)** Returns: * 0 success* >0 f/w reported failure - f/w status code* <0 driver reported error (timeout|bad arg)** Side effects:** Call context:* process ----------------------------------------------------------------*/int hfa384x_cmd_monitor(hfa384x_t *hw, UINT16 enable){ int result = 0; hfa384x_metacmd_t cmd; DBFENTER; cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR) | HFA384x_CMD_AINFO_SET(enable); cmd.parm0 = 0; cmd.parm1 = 0; cmd.parm2 = 0; result = hfa384x_docmd(hw, DOWAIT, &cmd, NULL, NULL); DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_cmd_download** Sets the controls for the MAC controller code/data download* process. The arguments set the mode and address associated * with a download. Note that the aux registers should be enabled* prior to setting one of the download enable modes.** Arguments:* hw device structure* mode 0 - Disable programming and begin code exec* 1 - Enable volatile mem programming* 2 - Enable non-volatile mem programming* 3 - Program non-volatile section from NV download* buffer. * (host order)* lowaddr * highaddr For mode 1, sets the high & low order bits of * the "destination address". This address will be* the execution start address when download is* subsequently disabled.* For mode 2, sets the high & low order bits of * the destination in NV ram.* For modes 0 & 3, should be zero. (host order)* NOTE: these are CMD format.* codelen Length of the data to write in mode 2, * zero otherwise. (host order)** Returns: * 0 success* >0 f/w reported failure - f/w status code* <0 driver reported error (timeout|bad arg)** Side effects:** Call context:* process ----------------------------------------------------------------*/int hfa384x_cmd_download(hfa384x_t *hw, UINT16 mode, UINT16 lowaddr, UINT16 highaddr, UINT16 codelen){ int result = 0; hfa384x_metacmd_t cmd; DBFENTER; WLAN_LOG_DEBUG(5, "mode=%d, lowaddr=0x%04x, highaddr=0x%04x, codelen=%d\n", mode, lowaddr, highaddr, codelen); cmd.cmd = (HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DOWNLD) | HFA384x_CMD_PROGMODE_SET(mode)); cmd.parm0 = lowaddr; cmd.parm1 = highaddr; cmd.parm2 = codelen; result = hfa384x_docmd(hw, DOWAIT, &cmd, NULL, NULL); DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_copy_from_aux** Copies a collection of bytes from the controller memory. The* Auxiliary port MUST be enabled prior to calling this function.* We _might_ be in a download state.** Arguments:* hw device structure* cardaddr address in hfa384x data space to read* auxctl address space select* buf ptr to destination host buffer* len length of data to transfer (in bytes)** Returns: * nothing** Side effects:* buf contains the data copied** Call context:* process* interrupt----------------------------------------------------------------*/void hfa384x_copy_from_aux( hfa384x_t *hw, UINT32 cardaddr, UINT32 auxctl, void *buf, UINT len){ DBFENTER; WLAN_LOG_ERROR("not used in USB.\n"); DBFEXIT;}/*----------------------------------------------------------------* hfa384x_copy_to_aux** Copies a collection of bytes to the controller memory. The* Auxiliary port MUST be enabled prior to calling this function.* We _might_ be in a download state.** Arguments:* hw device structure* cardaddr address in hfa384x data space to read* auxctl address space select* buf ptr to destination host buffer* len length of data to transfer (in bytes)** Returns: * nothing** Side effects:* Controller memory now contains a copy of buf** Call context:* process* interrupt----------------------------------------------------------------*/void hfa384x_copy_to_aux( hfa384x_t *hw, UINT32 cardaddr, UINT32 auxctl, void *buf, UINT len){ DBFENTER; WLAN_LOG_ERROR("not used in USB.\n"); DBFEXIT;}/*----------------------------------------------------------------* hfa384x_corereset** Perform a reset of the hfa38xx MAC core. We assume that the hw * structure is in its "created" state. That is, it is initialized* with proper values. Note that if a reset is done after the * device has been active for awhile, the caller might have to clean * up some leftover cruft in the hw structure.** Arguments:* hw device structure* holdtime how long (in ms) to hold the reset* settletime how long (in ms) to wait after releasing* the reset** Returns: * nothing** Side effects:** Call context:* process ----------------------------------------------------------------*/int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis){#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) struct usb_device *parent = hw->usb->parent; int i; int port = -1;#endif int result = 0;#define P2_USB_RT_PORT (USB_TYPE_CLASS | USB_RECIP_OTHER)#define P2_USB_FEAT_RESET 4#define P2_USB_FEAT_C_RESET 20 DBFENTER;#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) /* Find the hub port */ for ( i = 0; i < parent->maxchild; i++) { if (parent->children[i] == hw->usb) { port = i; break; } } if (port < 0) return -ENOENT; /* Set and clear the reset */ usb_control_msg(parent, usb_sndctrlpipe(parent, 0), USB_REQ_SET_FEATURE, P2_USB_RT_PORT, P2_USB_FEAT_RESET, port+1, NULL, 0, 1*HZ); wait_ms(holdtime); usb_control_msg(parent, usb_sndctrlpipe(parent, 0), USB_REQ_CLEAR_FEATURE, P2_USB_RT_PORT, P2_USB_FEAT_C_RESET, port+1, NULL, 0, 1*HZ); wait_ms(settletime); /* Set the device address */ result=usb_set_address(hw->usb); if (result < 0) { WLAN_LOG_ERROR("reset_usbdev: Dev not accepting address, " "result=%d\n", result); clear_bit(hw->usb->devnum, &hw->usb->bus->devmap.devicemap); hw->usb->devnum = -1; goto done; } /* Let the address settle */ wait_ms(20); /* Assume we're reusing the original descriptor data */ /* Set the configuration. */ WLAN_LOG_DEBUG(3, "Setting Configuration %d\n", hw->usb->config[0].bConfigurationValue); result=usb_set_configuration(hw->usb, hw->usb->config[0].bConfigurationValue); if ( result ) { WLAN_LOG_ERROR("usb_set_configuration() failed, result=%d.\n", result); goto done; } /* Let the configuration settle */ wait_ms(20); done: #else WLAN_LOG_WARNING("hfa384x_corereset not supported on USB on 2.5/2.6 kernels.\n");#endif DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_docmd** Constructs a command CTLX and submits it.** NOTE: Any changes to the 'post-submit' code in this function * need to be carried over to hfa384x_cbcmd() since the handling* is virtually identical.** Arguments:* hw device structure* wait 1=wait for completion, 0=async* cmd cmd structure. Includes all arguments and result* data points. All in host order. in host order* usercb user callback for async calls, NULL for wait==1 calls* usercb_data user supplied data pointer for async calls, NULL* for wait==1 calls** Returns: * 0 success* -EIO CTLX failure* -ERESTARTSYS Awakened on signal* >0 command indicated error, Status and Resp0-2 are* in hw structure.** Side effects:* ** Call context:* process ----------------------------------------------------------------*/static int hfa384x_docmd( hfa384x_t *hw, UINT wait, hfa384x_metacmd_t *cmd, ctlx_usercb_t usercb, void *usercb_data){ int result; hfa384x_usbctlx_t *ctlx; DBFENTER; ctlx = kmalloc(sizeof(*ctlx), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); if ( ctlx == NULL ) { result = -ENOMEM; goto done; } hfa384x_usbctlx_init(ctlx, hw); /* Initialize the command */ ctlx->outbuf.cmdreq.type = host2hfa384x_16(HFA384x_USB_CMDREQ); ctlx->outbuf.cmdreq.cmd = host2hfa384x_16(cmd->cmd); ctlx->outbuf.cmdreq.parm0 = host2hfa384x_16(cmd->parm0); ctlx->outbuf.cmdreq.parm1 = host2hfa384x_16(cmd->parm1); ctlx->outbuf.cmdreq.parm2 = host2hfa384x_16(cmd->parm2); WLAN_LOG_DEBUG(4, "cmdreq: cmd=0x%04x " "parm0=0x%04x parm1=0x%04x parm2=0x%04x\n", cmd->cmd, cmd->parm0, cmd->parm1, cmd->parm2); /* Fill the out packet */ usb_fill_bulk_urb( &(ctlx->outurb), hw->usb, usb_sndbulkpipe(hw->usb, hw->endp_out), &(ctlx->outbuf), ROUNDUP64(sizeof(ctlx->outbuf.cmdreq)), hfa384x_ctlxout_callback, ctlx); ctlx->outurb.transfer_flags |= USB_QUEUE_BULK; if ( wait ) { hfa384x_usbctlx_submit_wait(hw, ctlx); } else if ( hfa384x_usbctlx_submit_async( hw, ctlx, usercb, usercb_data) == 0 ) { result = 0; goto done; } /* All of the following is skipped for async calls */ /* On reawakening, check the ctlx status */ switch(ctlx->state) { case CTLX_COMPLETE: result = hfa384x2host_16(ctlx->inbuf.cmdresp.status); result &= HFA384x_STATUS_RESULT; cmd->status = hfa384x2host_16(ctlx->inbuf.cmdresp.status); cmd->resp0 = hfa384x2host_16(ctlx->inbuf.cmdresp.resp0); cmd->resp1 = hfa384x2host_16(ctlx->inbuf.cmdresp.resp1); cmd->resp2 = hfa384x2host_16(ctlx->inbuf.cmdresp.resp2); WLAN_LOG_DEBUG(4, "cmdresp:status=0x%04x " "resp0=0x%04x resp1=0x%04x resp2=0x%04x\n", cmd->status, cmd->resp0, cmd->resp1, cmd->resp2); break; case CTLX_REQSUBMIT_FAIL: WLAN_LOG_WARNING("ctlx failure=REQSUBMIT_FAIL\n"); result = -EIO; break; case CTLX_REQ_TIMEOUT: WLAN_LOG_WARNING("ctlx failure=REQ_TIMEOUT\n"); result = -EIO; break; case CTLX_REQ_FAILED: WLAN_LOG_WARNING("ctlx failure=REQ_FAILED\n"); result = -EIO; break; case CTLX_START: result = -EIO; break; default: result = -ERESTARTSYS; break; } /* switch */ complete(&ctlx->done); kfree(ctlx);done: DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_dorrid** Constructs a read rid CTLX and issues it.** NOTE: Any changes to the 'post-submit' code in this function * need to be carried over to hfa384x_cbrrid() since the handling* is virtually identical.** Arguments:* hw device structure* wait 1=wait for completion, 0=async* rid Read RID number (host order)* riddata Caller supplied buffer that MAC formatted RID.data * record will be written to for wait==1 calls. Should* be NULL for wait==0 calls.* riddatalen Buffer length for wait==1 calls. Zero for wait==0 calls.* usercb user callback for async calls, NULL for wait==1 calls* usercb_data user supplied data pointer for async calls, NULL* for wait==1 calls** Returns: * 0 success* -EIO CTLX failure* -ERESTARTSYS Awakened on signal* -ENODATA riddatalen != macdatalen* >0 command indicated error, Status and Resp0-2 are* in hw structure.*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -