hfa384x.c
来自「Linux的无线局域网方案是一个Linux设备驱动程序和子系统 一揽子方案的用」· C语言 代码 · 共 2,425 行 · 第 1/5 页
C
2,425 行
* Arguments:* hw device structure** Returns: * 0 success* >0 f/w reported failure - f/w status code* <0 driver reported error (timeout)** Side effects:** Call context:* process thread ----------------------------------------------------------------*/int hfa384x_cmd_aux_enable(hfa384x_t *hw){ int result = -ETIMEDOUT; wlan_flags_t flags; UINT32 timeout; UINT16 reg = 0; DBFENTER; /* Check for existing enable */ if ( hw->auxen ) { hw->auxen++; return 0; } /* acquire the lock */ spin_lock_irqsave( &(hw->cmdlock), flags); /* wait for cmd the busy bit to clear */ timeout = jiffies + 1*HZ; reg = hfa384x_getreg(hw, HFA384x_CMD); while ( HFA384x_CMD_ISBUSY(reg) && time_before( jiffies, timeout) ) { reg = hfa384x_getreg(hw, HFA384x_CMD); } if (!HFA384x_CMD_ISBUSY(reg)) { /* busy bit clear, it's OK to write to ParamX regs */ hfa384x_setreg(hw, HFA384x_AUXPW0, HFA384x_PARAM0); hfa384x_setreg(hw, HFA384x_AUXPW1, HFA384x_PARAM1); hfa384x_setreg(hw, HFA384x_AUXPW2, HFA384x_PARAM2); /* Set the aux enable in the Control register */ hfa384x_setreg(hw, HFA384x_CONTROL_AUX_DOENABLE, HFA384x_CONTROL); /* Now wait for completion */ timeout = jiffies + 1*HZ; reg = hfa384x_getreg(hw, HFA384x_CONTROL); while ( ((reg & (BIT14|BIT15)) != HFA384x_CONTROL_AUX_ISENABLED) && time_before(jiffies,timeout) ){ udelay(10); reg = hfa384x_getreg(hw, HFA384x_CONTROL); } if ( (reg & (BIT14|BIT15)) == HFA384x_CONTROL_AUX_ISENABLED ) { result = 0; hw->auxen++; } } spin_unlock_irqrestore( &(hw->cmdlock), flags); DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_cmd_aux_disable** Goes through the process of disabling the auxilary port * enabled with aux_enable().** Arguments:* hw device structure** Returns: * 0 success* >0 f/w reported failure - f/w status code* <0 driver reported error (timeout)** Side effects:** Call context:* process thread ----------------------------------------------------------------*/int hfa384x_cmd_aux_disable(hfa384x_t *hw){ int result = -ETIMEDOUT; UINT32 timeout; UINT16 reg = 0; DBFENTER; /* See if there's more than one enable */ if (hw->auxen) hw->auxen--; if (hw->auxen) return 0; /* Clear the aux enable in the Control register */ hfa384x_setreg(hw, 0, HFA384x_PARAM0); hfa384x_setreg(hw, 0, HFA384x_PARAM1); hfa384x_setreg(hw, 0, HFA384x_PARAM2); hfa384x_setreg(hw, HFA384x_CONTROL_AUX_DODISABLE, HFA384x_CONTROL); /* Now wait for completion */ timeout = jiffies + 1*HZ; reg = hfa384x_getreg(hw, HFA384x_CONTROL); while ( ((reg & (BIT14|BIT15)) != HFA384x_CONTROL_AUX_ISDISABLED) && time_before(jiffies,timeout) ){ udelay(10); reg = hfa384x_getreg(hw, HFA384x_CONTROL); } if ((reg & (BIT14|BIT15)) == HFA384x_CONTROL_AUX_ISDISABLED ) { result = 0; } DBFEXIT; return result;}/*----------------------------------------------------------------* 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 thread ----------------------------------------------------------------*/int hfa384x_drvr_low_level(hfa384x_t *hw, UINT32 command, UINT32 param0, UINT32 param1, UINT32 param2){ 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;}/* TODO: determine if these will ever be needed */#if 0int hfa384x_cmd_readmif(hfa384x_t *hw){ DBFENTER; DBFEXIT; return 0;}int hfa384x_cmd_writemif(hfa384x_t *hw){ DBFENTER; DBFEXIT; return 0;}#endif/*----------------------------------------------------------------* hfa384x_drvr_test_command** 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 thread----------------------------------------------------------------*/int hfa384x_drvr_test_command(hfa384x_t *hw, UINT32 test_mode, UINT32 test_param){ int result = 0; UINT16 cmd = ((UINT16) test_mode) << 8 | 0x38; UINT16 param = (UINT16)test_param; DBFENTER; result = hfa384x_docmd_wait(hw, cmd, param, 0, 0); DBFEXIT; return result;}/*----------------------------------------------------------------* 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 thread----------------------------------------------------------------*/int hfa384x_drvr_mmi_read(hfa384x_t *hw, UINT32 addr){ 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;}/*----------------------------------------------------------------* 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 thread----------------------------------------------------------------*/inthfa384x_drvr_mmi_write(hfa384x_t *hw, UINT32 addr, UINT32 data){ 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;}/* TODO: determine if these will ever be needed */#if 0int hfa384x_cmd_readmif(hfa384x_t *hw){ DBFENTER; DBFEXIT; return 0;}int hfa384x_cmd_writemif(hfa384x_t *hw){ DBFENTER; DBFEXIT; return 0;}#endif/*----------------------------------------------------------------* hfa384x_copy_from_bap** Copies a collection of bytes from the MAC controller memory via* one set of BAP registers.** Arguments:* hw device structure* bap [0|1] which BAP to use* id FID or RID, destined for the select register (host order)* offset An _even_ offset into the buffer for the given* FID/RID. We haven't the means to validate this,* so be careful. (host order)* buf ptr to array of bytes* len length of data to transfer in bytes** Returns: * 0 success* >0 f/w reported failure - value of offset reg.* <0 driver reported error (timeout|bad arg)** Side effects:** Call context:* process thread* interrupt----------------------------------------------------------------*/int hfa384x_copy_from_bap(hfa384x_t *hw, UINT16 bap, UINT16 id, UINT16 offset, void *buf, UINT len){ int result = 0; wlan_flags_t flags; UINT8 *d = (UINT8*)buf; UINT selectreg; UINT offsetreg; UINT datareg; UINT i; UINT16 reg = 0; DBFENTER; /* Validate bap, offset, buf, and len */ if ( (bap > 1) || (offset > HFA384x_BAP_OFFSET_MAX) || (offset % 2) || (buf == NULL) || (len > HFA384x_BAP_DATALEN_MAX) ){ result = -EINVAL; } else { selectreg = (bap == 1) ? HFA384x_SELECT1 : HFA384x_SELECT0 ; offsetreg = (bap == 1) ? HFA384x_OFFSET1 : HFA384x_OFFSET0 ; datareg = (bap == 1) ? HFA384x_DATA1 : HFA384x_DATA0 ; /* Obtain lock */ spin_lock_irqsave( &(hw->baplock[bap]), flags); /* Write id to select reg */ hfa384x_setreg(hw, id, selectreg); /* Write offset to offset reg */ hfa384x_setreg(hw, offset, offsetreg); /* Wait for offset[busy] to clear (see BAP_TIMEOUT) */ i = 0; do { reg = hfa384x_getreg(hw, offsetreg); if ( i > 0 ) udelay(2); i++; } while ( i < BAP_TIMEOUT && HFA384x_OFFSET_ISBUSY(reg)); if ( HFA384x_OFFSET_ISBUSY(reg) ){ /* If timeout, return -ETIMEDOUT */ result = reg; } else if ( HFA384x_OFFSET_ISERR(reg) ){ /* If offset[err] == 1, return -EINVAL */ result = reg; } else { /* Read even(len) buf contents from data reg */ for ( i = 0; i < (len & 0xfffe); i+=2 ) { *(UINT16*)(&(d[i])) = hfa384x_getreg_noswap(hw, datareg); } /* If len odd, handle last byte */ if ( len % 2 ){ reg = hfa384x_getreg_noswap(hw, datareg); d[len-1] = ((UINT8*)(®))[0]; } } /* Release lock */ spin_unlock_irqrestore( &(hw->baplock[bap]), flags); } if (result) { WLAN_LOG_DEBUG3(1, "copy_from_bap(0x%04x, 0, %d) failed, result=0x%x\n", reg, len, result); } DBFEXIT; return result;}/*----------------------------------------------------------------* hfa384x_copy_to_bap** Copies a collection of bytes to the MAC controller memory via* one set of BAP registers.** Arguments:* hw device structure* bap [0|1] which BAP to use* id FID or RID, destined for the select register (host order)* offset An _even_ offset into the buffer for the given* FID/RID. We haven't the means to validate this,* so be careful. (host order)* buf ptr to array of bytes* len length of data to transfer (in bytes)** Returns: * 0 success* >0 f/w reported failure - value of offset reg.* <0 driver reported error (timeout|bad arg)** Side effects:** Call context:* process thread* interrupt----------------------------------------------------------------*/int hfa384x_copy_to_bap(hfa384x_t *hw, UINT16 bap, UINT16 id, UINT16 offset, void *buf, UINT len){ int result = 0; wlan_flags_t flags; UINT8 *d = (UINT8*)buf; UINT selectreg; UINT offsetreg; UINT datareg; UINT i; UINT16 reg; UINT16 savereg; DBFENTER; /* Validate bap, offset, buf, and len */ if ( (bap > 1) || (offset > HFA384x_BAP_OFFSET_MAX) || (offset % 2) || (buf == NULL) || (len > HFA384x_BAP_DATALEN_MAX) ){ result = -EINVAL; } else { selectreg = (bap == 1) ? HFA384x_SELECT1 : HFA384x_SELECT0; offsetreg = (bap == 1) ? HFA384x_OFFSET1 : HFA384x_OFFSET0; datareg = (bap == 1) ? HFA384x_DATA1 : HFA384x_DATA0; /* Obtain lock */ spin_lock_irqsave( &(hw->baplock[bap]), flags); /* Write id to select reg */ hfa384x_setreg(hw, id, selectreg); udelay(10); /* Write offset to offset reg */ hfa384x_setreg(hw, offset, offsetreg); /* Wait for offset[busy] to clear (see BAP_TIMEOUT) */ i = 0; do { reg = hfa384x_getreg(hw, offsetreg); if ( i > 0 ) udelay(
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?