hfa384x_usb.c
来自「Linux的无线局域网方案是一个Linux设备驱动程序和子系统 一揽子方案的用」· C语言 代码 · 共 2,513 行 · 第 1/5 页
C
2,513 行
* 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 = 0; hfa384x_usbctlx_t *ctlx; DBFENTER; ctlx = kmalloc(sizeof(*ctlx), GFP_ATOMIC); if ( ctlx == NULL ) { result = -ENOMEM; goto done; } memset(ctlx, 0, sizeof(*ctlx)); ctlx->state = HFA384x_USBCTLX_START; /* 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_DEBUG4(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_DEBUG1(4,"pktsize=%d\n", ROUNDUP64(sizeof(ctlx->outbuf.rmemreq))); /* Fill the out packet */ FILL_BULK_URB( &(ctlx->outurb), hw->usb, usb_sndbulkpipe(hw->usb, 2), &(ctlx->outbuf), ROUNDUP64(sizeof(ctlx->outbuf.rmemreq)), hfa384x_usbout_callback, hw->usbcontext); ctlx->outurb.transfer_flags |= USB_ASYNC_UNLINK; if ( wait ) { hfa384x_usbctlx_submit_wait(hw, ctlx); } else { hfa384x_usbctlx_submit_async(hw, ctlx, usercb, usercb_data); goto done; } /* All of the following is skipped for async calls */ /* On reawakening, check the ctlx status */ switch(ctlx->state) { case HFA384x_USBCTLX_COMPLETE: WLAN_LOG_DEBUG1(4,"rmemresp:len=%d\n", ctlx->inbuf.rmemresp.frmlen); memcpy(data, ctlx->inbuf.rmemresp.data, len); result = 0; break; case HFA384x_USBCTLX_REQSUBMIT_FAIL: WLAN_LOG_WARNING0(__FUNCTION__":ctlx failure=REQSUBMIT_FAIL\n"); result = -EIO; break; case HFA384x_USBCTLX_REQ_TIMEOUT: WLAN_LOG_WARNING0(__FUNCTION__":ctlx failure=REQ_TIMEOUT\n"); result = -EIO; break; case HFA384x_USBCTLX_REQ_FAILED: WLAN_LOG_WARNING0(__FUNCTION__":ctlx failure=REQ_FAILED\n"); result = -EIO; break; case HFA384x_USBCTLX_RESP_TIMEOUT: WLAN_LOG_WARNING0(__FUNCTION__":ctlx failure=RESP_TIMEOUT\n"); result = -EIO; break; default: /* The ctlx is still running and probably still in the queue * We were probably awakened by a signal. Return an error * and DO NOT free the ctlx. Let the ctlx finish and it will * just be leaked. At least we won't crash that way. * TODO: we need a ctlx_cancel function */ result = -ERESTARTSYS; goto done; break; } 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 = 0; hfa384x_usbctlx_t *ctlx; DBFENTER; WLAN_LOG_DEBUG3(5, "page=0x%04x offset=0x%04x len=%d\n", page,offset,len); ctlx = kmalloc(sizeof(*ctlx), GFP_ATOMIC); if ( ctlx == NULL ) { result = -ENOMEM; goto done; } memset(ctlx, 0, sizeof(*ctlx)); ctlx->state = HFA384x_USBCTLX_START; /* 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 */ FILL_BULK_URB( &(ctlx->outurb), hw->usb, usb_sndbulkpipe(hw->usb, 2), &(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_usbout_callback, hw->usbcontext); ctlx->outurb.transfer_flags |= USB_ASYNC_UNLINK; if ( wait ) { hfa384x_usbctlx_submit_wait(hw, ctlx); } else { hfa384x_usbctlx_submit_async(hw, ctlx, usercb, usercb_data); goto done; } /* All of the following is skipped for async calls */ /* On reawakening, check the ctlx status */ switch(ctlx->state) { case HFA384x_USBCTLX_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 HFA384x_USBCTLX_REQSUBMIT_FAIL: WLAN_LOG_WARNING0(__FUNCTION__":ctlx failure=REQSUBMIT_FAIL\n"); result = -EIO; break; case HFA384x_USBCTLX_REQ_TIMEOUT: WLAN_LOG_WARNING0(__FUNCTION__":ctlx failure=REQ_TIMEOUT\n"); result = -EIO; break; case HFA384x_USBCTLX_REQ_FAILED: WLAN_LOG_WARNING0(__FUNCTION__":ctlx failure=REQ_FAILED\n"); result = -EIO; break; case HFA384x_USBCTLX_RESP_TIMEOUT: WLAN_LOG_WARNING0(__FUNCTION__":ctlx failure=RESP_TIMEOUT\n"); result = -EIO; break; default: /* The ctlx is still running and probably still in the queue * We were probably awakened by a signal. Return an error * and DO NOT free the ctlx. Let the ctlx finish and it will * just be leaked. At least we won't crash that way. * TODO: we need a ctlx_cancel function */ result = -ERESTARTSYS; goto done; break; } 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 ){ DBFENTER; hfa384x_docmd(hw, DOASYNC, HFA384x_CMDCODE_INQ, HFA384x_IT_COMMTALLIES, 0,0, 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.* APs may also disable macports 1-6. Only ports that have been* previously enabled may be disabled.** Arguments:* hw device structure* macport MAC port number (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_drvr_disable(hfa384x_t *hw, UINT16 macport){ int result = 0; DBFENTER; if ((!hw->isap && macport != 0) || (hw->isap && !(macport <= HFA384x_PORTID_MAX)) || !(hw->port_enabled[macport]) ){ result = -EINVAL; } else { result = hfa384x_cmd_disable(hw, macport); if ( result == 0 ) { hw->port_enabled[macport] = 0; } } DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_drvr_enable** Issues the enable command to enable communications on one of * the MACs 'ports'. Only macport 0 is valid for stations.* APs may also enable macports 1-6. Only ports that are currently* disabled may be enabled.** Arguments:* hw device structure* macport MAC port number** 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_drvr_enable(hfa384x_t *hw, UINT16 macport){ int result = 0; DBFENTER; if ((!hw->isap && macport != 0) || (hw->isap && !(macport <= HFA384x_PORTID_MAX)) || (hw->port_enabled[macport]) ){ result = -EINVAL; } else { result = hfa384x_cmd_enable(hw, macport); if ( result == 0 ) { hw->port_enabled[macport] = 1; } } DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_drvr_flashdl_enable** Begins the flash download state. Checks to see that we're not* already in a download state and that a port isn't enabled.* Sets the download state and retrieves the flash download* buffer location, buffer size, and timeout length.** Arguments:* hw device structure** Returns: * 0 success* >0 f/w reported error - f/w status code* <0 driver reported error** Side effects:** Call context:* process ----------------------------------------------------------------*/int hfa384x_drvr_flashdl_enable(hfa384x_t *hw){ int result = 0; int i; DBFENTER; /* Check that a port isn't active */ for ( i = 0; i < HFA384x_PORTID_MAX; i++) { if ( hw->port_enabled[i] ) { WLAN_LOG_DEBUG0(1,"called when port enabled.\n"); return -EINVAL; } } /* Check that we're not already in a download state */ if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) { return -EINVAL; } /* Retrieve the buffer loc&size and timeout */ if ( (result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER, &(hw->bufinfo), sizeof(hw->bufinfo))) ) { return result; } hw->bufinfo.page = hfa384x2host_16(hw->bufinfo.page); hw->bufinfo.offset = hfa384x2host_16(hw->bufinfo.offset); hw->bufinfo.len = hfa384x2host_16(hw->bufinfo.len); if ( (result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME, &(hw->dltimeout))) ) { return result; } hw->dltimeout = hfa384x2host_16(hw->dltimeout);#if 0WLAN_LOG_DEBUG0(1,"flashdl_enable\n");hw->dlstate = HFA384x_DLSTATE_FLASHENABLED;#endif hw->dlstate = HFA384x_DLSTATE_FLASHENABLED; DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_drvr_flashdl_disable** Ends the flash download state. Note that this will cause the MAC* firmware to restart.** Arguments:* hw device structure** Returns: * 0 success* >0 f/w reported error - f/w status code* <0 driver reported error** Side effects:** Call context:* process ----------------------------------------------------------------*/int hfa384x_drvr_flashdl_disable(hfa384x_t *hw){ DBFENTER; /* Check that we're already in the download state */ if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) { return -EINVAL; }#if 0WLAN_LOG_DEBUG0(1,"flashdl_enable\n");hw->dlstate = HFA384x_DLSTATE_DISABLED;#endif return 0; /* There isn't much we can do at this point, so I don't */ /* bother w/ the return value */ hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0); hw->dlstate = HFA384x_DLSTATE_DISABLED; DBFEXIT; return 0;}/*----------------------------------------------------------------* hfa384x_drvr_flashdl_write** Performs a FLASH download of a chunk of data. First checks to see* that we're in the FLASH download state, then sets the download* mode, uses the aux functions to 1) copy the data to the flash* buffer, 2) sets the download 'write flash' mode, 3) readback and * compare. Lather rinse, repeat as many times an necessary to get* all the given data into flash. * When all data has been written using this function (possibly * repeatedly), call drvr_flashdl_disable() to end the download state* and restart the MAC.** Arguments:* hw device structure* daddr Card address to write to. (host order)* buf Ptr to data to write.* len Length of data (host order).** Returns: * 0 success* >0 f/w reported error - f/w status code* <0 driver reported error** Side effects:** Call context:* process ----------------------------------------------------------------*/inthfa384x_drvr_flashdl_write( hfa384x_t *hw, UINT32 daddr, void *buf, UINT32 len)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?