📄 hfa384x_usb.c
字号:
* Side effects:* * Call context:* interrupt (wait==0)* process (wait==0 || wait==1)----------------------------------------------------------------*/static inthfa384x_dorrid( hfa384x_t *hw, UINT wait, UINT16 rid, void *riddata, UINT riddatalen, ctlx_usercb_t usercb, void *usercb_data){ int result; hfa384x_usbctlx_t *ctlx; UINT maclen; 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.rridreq.type = host2hfa384x_16(HFA384x_USB_RRIDREQ); ctlx->outbuf.rridreq.frmlen = host2hfa384x_16(sizeof(ctlx->outbuf.rridreq.rid)); ctlx->outbuf.rridreq.rid = host2hfa384x_16(rid); /* 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.rridreq)), hfa384x_ctlxout_callback, ctlx); ctlx->outurb.transfer_flags |= USB_QUEUE_BULK; /* Submit the CTLX */ 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: /* The results are in ctlx->outbuf */ /* Validate the length, note body len calculation in bytes */ maclen = ((hfa384x2host_16(ctlx->inbuf.rridresp.frmlen)-1)*2); if ( maclen != riddatalen ) { WLAN_LOG_WARNING( "RID len mismatch, rid=0x%04x hlen=%d fwlen=%d\n", rid, riddatalen, maclen); result = -ENODATA; break; } memcpy( riddata, ctlx->inbuf.rridresp.data, riddatalen); result = 0; 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_dowrid** Constructs a write rid CTLX and issues it.** NOTE: Any changes to the 'post-submit' code in this function * need to be carried over to hfa384x_cbwrid() since the handling* is virtually identical.** Arguments:* hw device structure* wait 1=wait for completion, 0=async* rid RID code* riddata Data portion of RID formatted for MAC* riddatalen Length of the data portion in bytes* usercb user callback for async calls, NULL for wait==1 calls* usercb_data user supplied data pointer for async calls, NULL** Returns: * 0 success* -ETIMEDOUT timed out waiting for register ready or* command completion* >0 command indicated error, Status and Resp0-2 are* in hw structure.** Side effects:* * Call context:* interrupt (wait==0)* process (wait==0 || wait==1)----------------------------------------------------------------*/inthfa384x_dowrid( hfa384x_t *hw, UINT wait, UINT16 rid, void *riddata, UINT riddatalen, 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.wridreq.type = host2hfa384x_16(HFA384x_USB_WRIDREQ); ctlx->outbuf.wridreq.frmlen = host2hfa384x_16( (sizeof(ctlx->outbuf.rridreq.rid) + riddatalen + 1) / 2); ctlx->outbuf.wridreq.rid = host2hfa384x_16(rid); memcpy(ctlx->outbuf.wridreq.data, riddata, riddatalen); /* 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.wridreq.type) + sizeof(ctlx->outbuf.wridreq.frmlen) + sizeof(ctlx->outbuf.wridreq.rid) + riddatalen), hfa384x_ctlxout_callback, ctlx); ctlx->outurb.transfer_flags |= USB_QUEUE_BULK; /* Submit the CTLX */ 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.wridresp.status); result &= HFA384x_STATUS_RESULT;/* hw->status = hfa384x2host_16(ctlx->inbuf.wridresp.status); hw->resp0 = hfa384x2host_16(ctlx->inbuf.wridresp.resp0); hw->resp1 = hfa384x2host_16(ctlx->inbuf.wridresp.resp1); hw->resp2 = hfa384x2host_16(ctlx->inbuf.wridresp.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_dormem** Constructs a readmem CTLX and issues it.** NOTE: Any changes to the 'post-submit' code in this function * need to be carried over to hfa384x_cbrmem() since the handling* is virtually identical.** Arguments:* hw device structure* wait 1=wait for completion, 0=async* page MAC address space page (CMD format)* offset MAC address space offset* data Ptr to data buffer to receive read* len Length of the data to read (max == 2048)* usercb user callback for async calls, NULL for wait==1 calls* usercb_data user supplied data pointer for async calls, NULL** Returns: * 0 success* -ETIMEDOUT timed out waiting for register ready or* command completion* >0 command indicated error, Status and Resp0-2 are* in hw structure.** Side effects:* * Call context:* interrupt (wait==0)* process (wait==0 || wait==1)----------------------------------------------------------------*/inthfa384x_dormem( hfa384x_t *hw, UINT wait, UINT16 page, UINT16 offset, void *data, UINT len, 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.rmemreq.type = host2hfa384x_16(HFA384x_USB_RMEMREQ); ctlx->outbuf.rmemreq.frmlen = host2hfa384x_16( sizeof(ctlx->outbuf.rmemreq.offset) + sizeof(ctlx->outbuf.rmemreq.page) + len); ctlx->outbuf.rmemreq.offset = host2hfa384x_16(offset); ctlx->outbuf.rmemreq.page = host2hfa384x_16(page); WLAN_LOG_DEBUG(4, "type=0x%04x frmlen=%d offset=0x%04x page=0x%04x\n", ctlx->outbuf.rmemreq.type, ctlx->outbuf.rmemreq.frmlen, ctlx->outbuf.rmemreq.offset, ctlx->outbuf.rmemreq.page); WLAN_LOG_DEBUG(4,"pktsize=%d\n", ROUNDUP64(sizeof(ctlx->outbuf.rmemreq))); /* 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.rmemreq)), 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: WLAN_LOG_DEBUG(4,"rmemresp:len=%d\n", ctlx->inbuf.rmemresp.frmlen); memcpy(data, ctlx->inbuf.rmemresp.data, len); result = 0; 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_dowmem** Constructs a writemem CTLX and issues it.** NOTE: Any changes to the 'post-submit' code in this function * need to be carried over to hfa384x_cbwmem() since the handling* is virtually identical.** Arguments:* hw device structure* wait 1=wait for completion, 0=async* page MAC address space page (CMD format)* offset MAC address space offset* data Ptr to data buffer containing write data* len Length of the data to read (max == 2048)* usercb user callback for async calls, NULL for wait==1 calls* usercb_data user supplied data pointer for async calls, NULL** Returns: * 0 success* -ETIMEDOUT timed out waiting for register ready or* command completion* >0 command indicated error, Status and Resp0-2 are* in hw structure.** Side effects:* * Call context:* interrupt (wait==0)* process (wait==0 || wait==1)----------------------------------------------------------------*/inthfa384x_dowmem( hfa384x_t *hw, UINT wait, UINT16 page, UINT16 offset, void *data, UINT len, ctlx_usercb_t usercb, void *usercb_data){ int result; hfa384x_usbctlx_t *ctlx; DBFENTER; WLAN_LOG_DEBUG(5, "page=0x%04x offset=0x%04x len=%d\n", page,offset,len); 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.wmemreq.type = host2hfa384x_16(HFA384x_USB_WMEMREQ); ctlx->outbuf.wmemreq.frmlen = host2hfa384x_16( sizeof(ctlx->outbuf.wmemreq.offset) + sizeof(ctlx->outbuf.wmemreq.page) + len); ctlx->outbuf.wmemreq.offset = host2hfa384x_16(offset); ctlx->outbuf.wmemreq.page = host2hfa384x_16(page); memcpy(ctlx->outbuf.wmemreq.data, data, len); /* 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.wmemreq.type) + sizeof(ctlx->outbuf.wmemreq.frmlen) + sizeof(ctlx->outbuf.wmemreq.offset) + sizeof(ctlx->outbuf.wmemreq.page) + len), 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.wmemresp.status);/* hw->status = hfa384x2host_16(ctlx->inbuf.wmemresp.status); hw->resp0 = hfa384x2host_16(ctlx->inbuf.wmemresp.resp0); hw->resp1 = hfa384x2host_16(ctlx->inbuf.wmemresp.resp1); hw->resp2 = hfa384x2host_16(ctlx->inbuf.wmemresp.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_drvr_commtallies** Send a commtallies inquiry to the MAC. Note that this is an async* call that will result in an info frame arriving sometime later.** Arguments:* hw device structure** Returns: * zero success.** Side effects:** Call context:* process----------------------------------------------------------------*/int hfa384x_drvr_commtallies( hfa384x_t *hw ){ hfa384x_metacmd_t cmd; DBFENTER; cmd.cmd = HFA384x_CMDCODE_INQ; cmd.parm0 = HFA384x_IT_COMMTALLIES; cmd.parm1 = 0; cmd.parm2 = 0; hfa384x_docmd(hw, DOASYNC, &cmd, NULL, NULL); DBFEXIT; return 0;}/*----------------------------------------------------------------* hfa384x_drvr_disable** Issues the disable command to stop communications on one of * the MACs 'ports'. Only macport 0 is valid for stations.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -