hfa384x_usb.c
来自「Linux的无线局域网方案是一个Linux设备驱动程序和子系统 一揽子方案的用」· C语言 代码 · 共 2,513 行 · 第 1/5 页
C
2,513 行
{ int result = 0; UINT8 *verbuf; UINT32 dlbufaddr; int nburns; UINT32 burnlen; UINT32 burndaddr; UINT16 burnlo; UINT16 burnhi; int nwrites; UINT8 *writebuf; UINT16 writepage; UINT16 writeoffset; UINT32 writelen; int i; int j; DBFENTER; WLAN_LOG_DEBUG2(5,"daddr=0x%08lx len=%ld\n", daddr, len); /* Check that we're in the flash download state */ if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) { return -EINVAL; } WLAN_LOG_INFO2("Download %ld bytes to flash @0x%06lx\n", len, daddr); /* Convert to flat address for arithmetic */ /* NOTE: dlbuffer RID stores the address in AUX format */ dlbufaddr = HFA384x_ADDR_AUX_MKFLAT( hw->bufinfo.page, hw->bufinfo.offset); WLAN_LOG_DEBUG3(5, "dlbuf.page=0x%04x dlbuf.offset=0x%04x dlbufaddr=0x%08lx\n", hw->bufinfo.page, hw->bufinfo.offset, dlbufaddr); verbuf = kmalloc(hw->bufinfo.len, GFP_ATOMIC); if ( verbuf == NULL ) { WLAN_LOG_ERROR0("Failed to allocate flash verify buffer\n"); return 1; }#if 0WLAN_LOG_WARNING3("dlbuf@0x%06lx len=%d to=%d\n", dlbufaddr, hw->bufinfo.len, hw->dltimeout);#endif /* Calculations to determine how many fills of the dlbuffer to do * and how many USB wmemreq's to do for each fill. At this point * in time, the dlbuffer size and the wmemreq size are the same. * Therefore, nwrites should always be 1. The extra complexity * here is a hedge against future changes. */ /* Figure out how many times to do the flash programming */ nburns = len / hw->bufinfo.len; nburns += (len % hw->bufinfo.len) ? 1 : 0; /* For each flash program cycle, how many USB wmemreq's are needed? */ nwrites = hw->bufinfo.len / HFA384x_USB_RWMEM_MAXLEN; nwrites += (hw->bufinfo.len % HFA384x_USB_RWMEM_MAXLEN) ? 1 : 0; /* For each burn */ for ( i = 0; i < nburns; i++) { /* Get the dest address and len */ burnlen = (len - (hw->bufinfo.len * i)) > hw->bufinfo.len ? hw->bufinfo.len : (len - (hw->bufinfo.len * i)); burndaddr = daddr + (hw->bufinfo.len * i); burnlo = HFA384x_ADDR_CMD_MKOFF(burndaddr); burnhi = HFA384x_ADDR_CMD_MKPAGE(burndaddr); WLAN_LOG_INFO2("Writing %ld bytes to flash @0x%06lx\n", burnlen, burndaddr); /* Set the download mode */ result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NV, burnlo, burnhi, burnlen); if ( result ) { WLAN_LOG_ERROR4("download(NV,lo=%x,hi=%x,len=%lx) " "cmd failed, result=%d. Aborting d/l\n", burnlo, burnhi, burnlen, result); goto exit_proc; } /* copy the data to the flash download buffer */ for ( j=0; j < nwrites; j++) { writebuf = buf + (i*hw->bufinfo.len) + (j*HFA384x_USB_RWMEM_MAXLEN); writepage = HFA384x_ADDR_CMD_MKPAGE( dlbufaddr + (j*HFA384x_USB_RWMEM_MAXLEN)); writeoffset = HFA384x_ADDR_CMD_MKOFF( dlbufaddr + (j*HFA384x_USB_RWMEM_MAXLEN)); writelen = burnlen-(j*HFA384x_USB_RWMEM_MAXLEN); writelen = writelen > HFA384x_USB_RWMEM_MAXLEN ? HFA384x_USB_RWMEM_MAXLEN : writelen; result = hfa384x_dowmem( hw, DOWAIT, writepage, writeoffset, writebuf, writelen, NULL, NULL);#if 0Comment out for debugging, assume the write was successful. if (result) { WLAN_LOG_ERROR1(__FUNCTION__ ": Write to dl buffer failed, " "result=0x%04x. Aborting.\n", result); goto exit_proc; }#endif } /* set the download 'write flash' mode */ result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NVWRITE, 0,0,0); if ( result ) { WLAN_LOG_ERROR4( "download(NVWRITE,lo=%x,hi=%x,len=%lx) " "cmd failed, result=%d. Aborting d/l\n", burnlo, burnhi, burnlen, result); goto exit_proc; } /* TODO: We really should do a readback and compare. */ }exit_proc: /* Leave the firmware in the 'post-prog' mode. flashdl_disable will */ /* actually disable programming mode. Remember, that will cause the */ /* the firmware to effectively reset itself. */ DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_drvr_getconfig** Performs the sequence necessary to read a config/info item.** Arguments:* hw device structure* rid config/info record id (host order)* buf host side record buffer. Upon return it will* contain the body portion of the record (minus the * RID and len).* len buffer length (in bytes, should match record length)** Returns: * 0 success* >0 f/w reported error - f/w status code* <0 driver reported error* -ENODATA length mismatch between argument and retrieved* record.** Side effects:** Call context:* process ----------------------------------------------------------------*/int hfa384x_drvr_getconfig(hfa384x_t *hw, UINT16 rid, void *buf, UINT16 len){ int result = 0; DBFENTER; result = hfa384x_dorrid(hw, DOWAIT, rid, buf, len, NULL, NULL); DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_drvr_getconfig16** Performs the sequence necessary to read a 16 bit config/info item* and convert it to host order.** Arguments:* hw device structure* rid config/info record id (in host order)* val ptr to 16 bit buffer to receive value (in host order)** Returns: * 0 success* >0 f/w reported error - f/w status code* <0 driver reported error** Side effects:** Call context:* process ----------------------------------------------------------------*/int hfa384x_drvr_getconfig16(hfa384x_t *hw, UINT16 rid, void *val){ int result = 0; DBFENTER; result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(UINT16)); if ( result == 0 ) { *((UINT16*)val) = hfa384x2host_16(*((UINT16*)val)); } DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_drvr_getconfig32** Performs the sequence necessary to read a 32 bit config/info item* and convert it to host order.** Arguments:* hw device structure* rid config/info record id (in host order)* val ptr to 32 bit buffer to receive value (in host order)** Returns: * 0 success* >0 f/w reported error - f/w status code* <0 driver reported error** Side effects:** Call context:* process ----------------------------------------------------------------*/int hfa384x_drvr_getconfig32(hfa384x_t *hw, UINT16 rid, void *val){ int result = 0; DBFENTER; result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(UINT32)); if ( result == 0 ) { *((UINT32*)val) = hfa384x2host_32(*((UINT32*)val)); } DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_drvr_getconfig_async** Performs the sequence necessary to perform an async read of* of a config/info item.** Arguments:* hw device structure* rid config/info record id (host order)* buf host side record buffer. Upon return it will* contain the body portion of the record (minus the * RID and len).* len buffer length (in bytes, should match record length)* cbfn caller supplied callback, called when the command * is done (successful or not).* cbfndata pointer to some caller supplied data that will be* passed in as an argument to the cbfn.** Returns: * nothing the cbfn gets a status argument identifying if* any errors occur.* Side effects:* Queues an hfa384x_usbcmd_t for subsequent execution.** Call context:* Any----------------------------------------------------------------*/voidhfa384x_drvr_getconfig_async( hfa384x_t *hw, UINT16 rid, ctlx_usercb_t usercb, void *usercb_data){ DBFENTER; hfa384x_dorrid(hw, DOASYNC, rid, NULL, 0, usercb, usercb_data); DBFEXIT; return;}/*----------------------------------------------------------------* hfa384x_drvr_handover** Sends a handover notification to the MAC.** Arguments:* hw device structure* addr address of station that's left** Returns: * zero success.* -ERESTARTSYS received signal while waiting for semaphore.* -EIO failed to write to bap, or failed in cmd.** Side effects:** Call context:* process----------------------------------------------------------------*/int hfa384x_drvr_handover( hfa384x_t *hw, UINT8 *addr){ DBFENTER; WLAN_LOG_WARNING0(__FUNCTION__": Not currently supported in USB!\n"); DBFEXIT; return -EIO;}/*----------------------------------------------------------------* hfa384x_drvr_low_level** Write test commands to the card. Some test commands don't make* sense without prior set-up. For example, continous TX isn't very* useful until you set the channel. That functionality should be* enforced at a higher level.** Arguments:* hw device structure* test_mode The test command code to use.* test_param A parameter needed for the test mode being used.** Returns: * 0 success* >0 f/w reported error - f/w status code* <0 driver reported error** Side effects:** Call context:* process ----------------------------------------------------------------*/int hfa384x_drvr_low_level(hfa384x_t *hw, UINT32 command, UINT32 param0, UINT32 param1, UINT32 param2){#if 0 int result = 0; UINT16 cmd = (UINT16) command; UINT16 p0 = (UINT16) param0; UINT16 p1 = (UINT16) param1; UINT16 p2 = (UINT16) param2; DBFENTER; /* Do i need a host2hfa... conversion ? */#if 0 printk(KERN_INFO "%#x %#x %#x %#x\n", cmd, p0, p1, p2);#endif result = hfa384x_docmd_wait(hw, cmd, p0, p1, p2); DBFEXIT; return result;#endifreturn 0;}/*----------------------------------------------------------------* hfa384x_drvr_mmi_read** Read mmi registers. mmi is intersil-speak for the baseband* processor registers.** Arguments:* hw device structure* register The test register to be accessed (must be even #).** Returns:* 0 success* >0 f/w reported error - f/w status code* <0 driver reported error** Side effects:** Call context:* process----------------------------------------------------------------*/int hfa384x_drvr_mmi_read(hfa384x_t *hw, UINT32 addr){#if 0 int result = 0; UINT16 cmd_code = (UINT16) 0x30; UINT16 param = (UINT16) addr; DBFENTER; /* Do i need a host2hfa... conversion ? */ result = hfa384x_docmd_wait(hw, cmd_code, param, 0, 0); DBFEXIT; return result;#endifreturn 0;}/*----------------------------------------------------------------* hfa384x_drvr_mmi_write** Read mmi registers. mmi is intersil-speak for the baseband* processor registers.** Arguments:* hw device structure* addr The test register to be accessed (must be even #).* data The data value to write to the register.** Returns:* 0 success* >0 f/w reported error - f/w status code* <0 driver reported error** Side effects:** Call context:* process----------------------------------------------------------------*/inthfa384x_drvr_mmi_write(hfa384x_t *hw, UINT32 addr, UINT32 data){#if 0 int result = 0; UINT16 cmd_code = (UINT16) 0x31; UINT16 param0 = (UINT16) addr; UINT16 param1 = (UINT16) data; DBFENTER; WLAN_LOG_DEBUG1(1,"mmi write : addr = 0x%08lx\n", addr); WLAN_LOG_DEBUG1(1,"mmi write : data = 0x%08lx\n", data); /* Do i need a host2hfa... conversion ? */ result = hfa384x_docmd_wait(hw, cmd_code, param0, param1, 0); DBFEXIT; return result;#endifreturn 0;}/*----------------------------------------------------------------* hfa384x_drvr_ramdl_disable** Ends the ram download state.** 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_ramdl_disable(hfa384x_t *hw){ DBFENTER; /* Check that we're already in the download state */ if ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) { return -EINVAL; } WLAN_LOG_DEBUG0(3,"ramdl_disable()\n"); /* 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_ramdl_enable** Begins the ram download state. Checks to see that we're not* already in a d
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?