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*)(&reg))[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 + -
显示快捷键?