📄 hfa384x.c
字号:
/* 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); /* Enable the aux port */ if ( (result = hfa384x_cmd_aux_enable(hw, 0)) ) { return result; } 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 thread ----------------------------------------------------------------*/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; } /* 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; /* Disable the aux port */ hfa384x_cmd_aux_disable(hw); 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 thread ----------------------------------------------------------------*/int hfa384x_drvr_flashdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len){ int result = 0; UINT8 *verbuf; UINT32 dlbufaddr; UINT32 currlen; UINT32 currdaddr; UINT16 destlo; UINT16 desthi; int nwrites; int i; DBFENTER; /* Check that we're in the flash download state */ if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) { return -EINVAL; } WLAN_LOG_INFO("Download %d bytes to flash @0x%06x\n", len, daddr); /* Need a flat address for arithmetic */ dlbufaddr = HFA384x_ADDR_AUX_MKFLAT( hw->bufinfo.page, hw->bufinfo.offset); verbuf = kmalloc(hw->bufinfo.len, GFP_KERNEL);#if 0WLAN_LOG_WARNING("dlbuf@0x%06lx len=%d to=%d\n", dlbufaddr, hw->bufinfo.len, hw->dltimeout);#endif /* Figure out how many times to to the flash prog */ nwrites = len / hw->bufinfo.len; nwrites += (len % hw->bufinfo.len) ? 1 : 0; if ( verbuf == NULL ) { WLAN_LOG_ERROR("Failed to allocate flash verify buffer\n"); return 1; } /* For each */ for ( i = 0; i < nwrites; i++) { /* Get the dest address and len */ currlen = (len - (hw->bufinfo.len * i)) > hw->bufinfo.len ? hw->bufinfo.len : (len - (hw->bufinfo.len * i)); currdaddr = daddr + (hw->bufinfo.len * i); destlo = HFA384x_ADDR_CMD_MKOFF(currdaddr); desthi = HFA384x_ADDR_CMD_MKPAGE(currdaddr); WLAN_LOG_INFO("Writing %d bytes to flash @0x%06x\n", currlen, currdaddr);#if 0WLAN_HEX_DUMP(1, "dldata", buf+(hw->bufinfo.len*i), currlen);#endif /* Set the download mode */ result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NV, destlo, desthi, currlen); if ( result ) { WLAN_LOG_ERROR("download(NV,lo=%x,hi=%x,len=%x) " "cmd failed, result=%d. Aborting d/l\n", destlo, desthi, currlen, result); goto exit_proc; } /* copy the data to the flash buffer */ hfa384x_copy_to_aux(hw, dlbufaddr, HFA384x_AUX_CTL_EXTDS, buf+(hw->bufinfo.len*i), currlen); /* set the download 'write flash' mode */ result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NVWRITE, 0,0,0); if ( result ) { WLAN_LOG_ERROR( "download(NVWRITE,lo=%x,hi=%x,len=%x) " "cmd failed, result=%d. Aborting d/l\n", destlo, desthi, currlen, result); goto exit_proc; } /* readback and compare, if fail...bail */ hfa384x_copy_from_aux(hw, currdaddr, HFA384x_AUX_CTL_NV, verbuf, currlen); if ( memcmp(buf+(hw->bufinfo.len*i), verbuf, currlen) ) { return -EINVAL; } }exit_proc: /* DOH! This kfree's for you Mark :-) My forehead hurts... */ kfree(verbuf); /* 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_cmd_initialize** Issues the initialize command and sets the hw->state based* on the result.** 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 thread ----------------------------------------------------------------*/int hfa384x_cmd_initialize(hfa384x_t *hw){ int result = 0; int i; hfa384x_metacmd_t cmd; DBFENTER; /* we don't want to be interrupted during the reset */ hfa384x_setreg(hw, 0, HFA384x_INTEN); hfa384x_setreg(hw, 0xffff, HFA384x_EVACK); cmd.cmd = HFA384x_CMDCODE_INIT; cmd.parm0 = 0; cmd.parm1 = 0; cmd.parm2 = 0; spin_lock_bh(&hw->cmdlock); result = hfa384x_docmd_wait(hw, &cmd); spin_unlock_bh(&hw->cmdlock); if ( result == 0 ) { for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) { hw->port_enabled[i] = 0; } } hw->link_status = HFA384x_LINK_NOTCONNECTED; 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; int result; DBFENTER; cmd.cmd = HFA384x_CMDCODE_INQ; cmd.parm0 = HFA384x_IT_COMMTALLIES; cmd.parm1 = 0; cmd.parm2 = 0; spin_lock_bh(&hw->cmdlock); result = hfa384x_docmd_wait(hw, &cmd); spin_unlock_bh(&hw->cmdlock); 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 thread ----------------------------------------------------------------*/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_cmd_enable** Issues the the enable command to enable communications on one of the* MACs 'ports'.** 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 thread ----------------------------------------------------------------*/int hfa384x_cmd_enable(hfa384x_t *hw, UINT16 macport){ int result = 0; hfa384x_metacmd_t cmd; DBFENTER; cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ENABLE) | HFA384x_CMD_MACPORT_SET(macport); cmd.parm0 = 0; cmd.parm1 = 0; cmd.parm2 = 0; spin_lock_bh(&hw->cmdlock); result = hfa384x_docmd_wait(hw, &cmd); spin_unlock_bh(&hw->cmdlock); DBFEXIT; return result;}/*----------------------------------------------------------------* 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 thread ----------------------------------------------------------------*/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_cmd_disable** Issues the command to disable a port.** 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 thread ----------------------------------------------------------------*/int hfa384x_cmd_disable(hfa384x_t *hw, UINT16 macport){ int result = 0; hfa384x_metacmd_t cmd; DBFENTER; cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DISABLE) | HFA384x_CMD_MACPORT_SET(macport); cmd.parm0 = 0; cmd.parm1 = 0; cmd.parm2 = 0; spin_lock_bh(&hw->cmdlock); result = hfa384x_docmd_wait(hw, &cmd); spin_unlock_bh(&hw->cmdlock); DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_cmd_diagnose** Issues the diagnose command to test the: register interface,* MAC controller (including loopback), External RAM, Non-volatile* memory integrity, and synthesizers. Following execution of this* command, MAC/firmware are in the 'initial state'. Therefore,* the Initialize command should be issued after successful* completion of this command. This function may only be called* when the MAC is in the 'communication disabled' state.** Arguments:* hw device structure** Returns: * 0 success* >0 f/w reported failure - f/w status code* <0 driver reported error (timeout|bad arg)** Side effects:** Call context:* process thread ----------------------------------------------------------------*/#define DIAG_PATTERNA ((UINT16)0xaaaa)#define DIAG_PATTERNB ((UINT16)~0xaaaa)int hfa384x_cmd_diagnose(hfa384x_t *hw){ int result = 0; hfa384x_metacmd_t cmd; DBFENTER; cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DIAG); cmd.parm0 = DIAG_PATTERNA; cmd.parm1 = DIAG_PATTERNB; cmd.parm2 = 0; spin_lock_bh(&hw->cmdlock); result = hfa384x_docmd_wait(hw, &cmd);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -