⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 am930hw.c

📁 Linux Wireless LAN Project 的目标是开发一个完整的
💻 C
📖 第 1 页 / 共 5 页
字号:
	DBFEXIT;	return result;}/*----------------------------------------------------------------*	am930hw_sync**	Helper function to send the sutro SYNC command. **	returns: AM930HW_CMD_SUCCESS or*			 AM930HW_CMD_SYNCFAILED----------------------------------------------------------------*/UINT32 am930hw_sync( am930hw_t *hw, UINT32 ch, UINT32 startBSS, 					wlan_bss_ts_t ts, UINT32 ref_time ){	UINT32 					result = AM930HW_CMD_SUCCESS;	sucmd_sync_t			cmd;	am930hw_cmd_result_t	cmd_result;	DBFENTER;	memset( &cmd, 0, sizeof(cmd));	/* values from arguments */	cmd.set_or_ch = ch;	cmd.start_BSS = startBSS;	cmd.ref_time = host2amd32(ref_time);	if ( ts != NULL )	{		memcpy( &cmd.bss_timestamp, ts, WLAN_BSS_TS_LEN);	}	else	{		memset( &cmd.bss_timestamp, 0, WLAN_BSS_TS_LEN);	}/*	cmd.pattern = 5;	cmd.index = 1;	cmd.dwell_interval = 0x3c;*/	cmd_result = am930hw_fw_cmd( hw, SUCMD_CMD_SYNC, &cmd, sizeof(cmd));		if ( cmd_result.fw_status != SUCMD_STAT_CMPLT || 		cmd_result.drvr_status != 0 )	{		WLAN_LOG_ERROR0("sync command failed!\n");		result = AM930HW_CMD_SYNCFAILED;	}	DBFEXIT;	return result;}/*----------------------------------------------------------------*	am930hw_tx_enable**	Helper function to send the sutro INIT_TX command. *	ASSUMPTION: The queue heads have already been set in the*				members of the object.**	returns: AM930HW_CMD_SUCCESS or*			 AM930HW_CMD_INITTXFAILED----------------------------------------------------------------*/UINT32 am930hw_tx_enable(am930hw_t *hw){	UINT32 					result = AM930HW_CMD_SUCCESS;	sucmd_init_tx_t			cmd;	am930hw_cmd_result_t	cmd_result;	int						i;	DBFENTER;	/* Lets zero the last complete block */	for ( i = 0; i < 5; i++)	{		write32(hw, hw->txcmplt + (i * sizeof(UINT32)), 0);	}	/* Now send the init_tx command */	memset( &cmd, 0, sizeof(cmd));	cmd.data_desc = host2amd32(hw->tx_tail);	cmd_result = am930hw_fw_cmd( hw, SUCMD_CMD_INIT_TX, &cmd, sizeof(cmd));		if ( cmd_result.fw_status != SUCMD_STAT_CMPLT || 		cmd_result.drvr_status != 0 )	{		WLAN_LOG_ERROR0("init_tx failed!\n");		result = AM930HW_CMD_INITTXFAILED;	}	DBFEXIT;	return result;}/*----------------------------------------------------------------*	am930hw_txdata**	I/F function to send a packet via the sutro data queue.*	rate is in 100Kbps.**	returns: 0 - pkt was handed to f/w and more tx buffers avail*			>0 - pkt was handed to f/w and no more tx buffers avail*			<0 - pkt was not sent due to no tx buffers avail----------------------------------------------------------------*/UINT32 am930hw_txdata( am930hw_t* hw, wlan_pb_t *pb, UINT32 rate){	UINT32				result = 0;	UINT32				slot;	UINT8				state;	wlan_flags_t		flags;	UINT				writeaddr;	UINT				totallen = 0;	DBFENTER;		if ( pb == NULL )	{		result = 0; /* bogus success */	}	else	{		WLAN_INT_DISABLE(flags);		/* Test if there is room in the queue */		state = read8(hw, hw->tx_tail + TXD_OFF_STATE);		WLAN_INT_ENABLE(flags);		if ( !SUTXD_ST_IS_HOSTOWN(state) ) 		{			WLAN_LOG_DEBUG0(1, "f/w tx queue full, frame not tx'd.\n");			result = -1;	/* no tx, no buffers */		} 		else		{			/* if so, update the tail pointer */			slot = hw->tx_tail;			hw->tx_tail = read32(hw, hw->tx_tail + TXD_OFF_NEXT);			writeaddr = slot + sizeof(am930tx_desc_t);			if ( pb->ethhostbuf != NULL )			{				/* It's a converted frame with pieces in multiple bufs */								/* write the 802.11 header */				writecard( hw, writeaddr, pb->p80211buf, WLAN_HDR_A3_LEN);				totallen = WLAN_HDR_A3_LEN;				writeaddr += WLAN_HDR_A3_LEN;				WLAN_HEX_DUMP(3, "txf1.1", pb->p80211buf, WLAN_HDR_A3_LEN);				/* is it encrypted ? */				if ( pb->wep_iscrypt )				{					/* write the IV */					writecard( hw, writeaddr, (UINT8*)&(pb->wep_iv), sizeof(pb->wep_iv));					totallen += sizeof(pb->wep_iv);					writeaddr += sizeof(pb->wep_iv);					WLAN_HEX_DUMP(3, "txf1.2", &(pb->wep_iv), sizeof(pb->wep_iv));				}								/* Now write any remaining in p80211buf */				if ( pb->p80211buflen > WLAN_HDR_A3_LEN)				{					writecard( hw, 						writeaddr, 						pb->p80211buf + WLAN_HDR_A3_LEN,						pb->p80211buflen - WLAN_HDR_A3_LEN);					totallen += (pb->p80211buflen - WLAN_HDR_A3_LEN);					writeaddr += (pb->p80211buflen - WLAN_HDR_A3_LEN);					WLAN_HEX_DUMP(3, "txf1.3",						pb->p80211buf + WLAN_HDR_A3_LEN,						pb->p80211buflen - WLAN_HDR_A3_LEN);				}				/* It's a converted frame, write the payload from p80211 */				writecard( hw, 					writeaddr, 					pb->p80211_payload, 					pb->p80211_payloadlen);				totallen += pb->p80211_payloadlen;				writeaddr += pb->p80211_payloadlen;				WLAN_HEX_DUMP(3, "txf1.4", 					pb->p80211_payload, 					pb->p80211_payloadlen);				/* is it encrypted ? */				if ( pb->wep_iscrypt )				{					/* write the ICV */					writecard( hw, writeaddr, (UINT8*)&(pb->wep_icv), sizeof(pb->wep_icv));					totallen += sizeof(pb->wep_icv);					writeaddr += sizeof(pb->wep_icv);					WLAN_HEX_DUMP(3, "txf1.5", 						(UINT8*)&(pb->wep_icv), 						sizeof(pb->wep_icv)); 				}			}			else			{				/* write the 802.11 header */				writecard( hw, writeaddr, pb->p80211buf, WLAN_HDR_A3_LEN);				totallen = WLAN_HDR_A3_LEN;				writeaddr += WLAN_HDR_A3_LEN;				WLAN_HEX_DUMP(3, "txf2.1", pb->p80211buf, WLAN_HDR_A3_LEN);				/* is it encrypted ? */				if ( pb->wep_iscrypt )				{					/* write the IV */					writecard( hw, writeaddr, (UINT8*)&(pb->wep_iv), sizeof(pb->wep_iv));					totallen += sizeof(pb->wep_iv);					writeaddr += sizeof(pb->wep_iv);					WLAN_HEX_DUMP(3, "txf2.2", 						&(pb->wep_iv), 						sizeof(pb->wep_iv));				}				/* write the body */				writecard( hw, 					writeaddr, 					pb->p80211_payload, 					pb->p80211_payloadlen);				totallen += pb->p80211_payloadlen;				writeaddr += pb->p80211_payloadlen;				WLAN_HEX_DUMP(3, "txf2.3", 					pb->p80211_payload, 					pb->p80211_payloadlen);				/* is it encrypted ? */				if ( pb->wep_iscrypt )				{					/* write the ICV */					writecard( hw, writeaddr, (UINT8*)&(pb->wep_icv), sizeof(pb->wep_icv));					totallen += sizeof(pb->wep_icv);					writeaddr += sizeof(pb->wep_icv);					WLAN_HEX_DUMP(3, "txf2.4", 						(UINT8*)&(pb->wep_icv), 						sizeof(pb->wep_icv)); 				}			}			/* set the offset and len */			WLAN_LOG_DEBUG1(3, "totallen=%d.\n", totallen);			write32(hw, slot + TXD_OFF_START_FRAME, slot + sizeof(am930tx_desc_t));			#ifdef DB_TX_READBACK			{				UINT8 buf[2000];				readcard(hw, slot+sizeof(am930tx_desc_t), buf, totallen);				WLAN_HEX_DUMP(2,"tx rdback:", buf, totallen);			}			#endif			write16(hw, slot + TXD_OFF_LEN, totallen);			write8(hw, slot + TXD_OFF_SIFS_ATTEMPTS, 0);			write8(hw, slot + TXD_OFF_SIFS_FAILURES, 0);			write8(hw, slot + TXD_OFF_DIFS_ATTEMPTS, 0);			write8(hw, slot + TXD_OFF_DIFS_FAILURES, 0);			write8(hw, slot + TXD_OFF_RTS_ATTEMPTS, 0);			write8(hw, slot + TXD_OFF_DATA_ATTEMPTS, 0);			write8(hw, slot + TXD_OFF_TX_CNTL, 0);			write8(hw, slot + TXD_OFF_RATE, rate);			write32(hw, slot + TXD_OFF_HOST, 1);			/* give sutro ownership of the descriptor */			write8(hw, slot + TXD_OFF_STATE, SUTXD_ST_FWOWN);			hw->used_txbuf++;			result = (hw->used_txbuf >= hw->ntxbuf) ? 1 : 0;			#ifdef WLAN_INCLUDE_SNIF			if ( hw->mac->snifflags & SNIFFLAG_SNIFTX )			{				am930mac_snifframe(hw->mac, pb, NULL);			}			#endif		}		/* WLAN_INT_ENABLE(flags); */	}	DBFEXIT;	return result;}/*----------------------------------------------------------------*	am930hw_txkick**	If there is space in the f/w queue, generate a 'kicker' *	ontxcomplete for the mac.**	returns: nothing----------------------------------------------------------------*/void am930hw_txkick( am930hw_t* hw ){	wlan_flags_t	flags;	WLAN_INT_DISABLE(flags);	if ( hw->used_txbuf < hw->ntxbuf )	{		am930mac_ontxcomplete(hw->mac, 0xffffffffUL);	}	WLAN_INT_ENABLE(flags);	return;}/*----------------------------------------------------------------*	am930mem_init**	Initializes a structure to handle _very_ simple memory *	management.  The structure contains a bitarray that's used*	to indicate the alloc/free state of each fragment of a block*	of memory.  The region of memory is identified by the start and*	len members.  This implementation is used to manage the*	tx buffer memory on the PRISM card.**	Note: If len is not evenly divisible by sizeof(mem->bits)*8, then*			there will be a small chunk of memory at the end of the*			managed region that will never be allocated.**	returns: nothing----------------------------------------------------------------*/void am930mem_init( am930mem_t *mem, UINT32 start, UINT32 len){	memset( mem, 0, sizeof(*mem));	mem->start = start;	mem->len = len;	mem->fragsize = len / (sizeof(mem->bits) * 8);}/*----------------------------------------------------------------*	am930mem_alloc**	Tests the structure lock.  If set, returns NULL*	Searches the bitarray for the appropriate sized chunk,*	If found*		sets the bits*		unlocks the structure*		returns the offset*	else*		unlocks the structure*		returns NULL**	Note: LSb in mem->bits corresponds to fragment at address mem->start*	Note: mem->start can't be zero*	Note: len of alloc'd region isn't saved, caller _must_ save it!**	returns: 0 on failure, non-zero on success----------------------------------------------------------------*/UINT32 am930mem_alloc( am930mem_t *mem, UINT32 size ){	UINT32			amask;	UINT32			nbits;	INT				i;	UINT32			allocaddr = 0;	wlan_flags_t	flags;	WLAN_INT_DISABLE(flags);	if ( mem->lock == 0)	{		mem->lock = 1;		nbits = size / mem->fragsize;		nbits += ((size % mem->fragsize) ? 1 : 0);		amask = ((UINT32)0xffffffff) >> ((sizeof(mem->bits) * 8) - nbits);		allocaddr = 0;		i = 0;		while (allocaddr == 0 && i < ((sizeof(mem->bits) * 8) - nbits) )		{			if ( (amask & mem->bits) == 0 )			{				mem->bits |= amask;				allocaddr = mem->start + (mem->fragsize * i);			}			amask = amask << 1;			i++;		}		WLAN_INT_ENABLE(flags);		mem->lock = 0;	}	else	{		WLAN_LOG_DEBUG0(1, "failed! mem mgr locked.\n");	}	WLAN_INT_ENABLE(flags);	return allocaddr;}/*----------------------------------------------------------------*	am930mem_free**	Tests the structure lock.  If set, returns the value of p*	clears the bits associated with the fragments in p,*	returns NULL**	returns: 0 on failure, non-zero on success----------------------------------------------------------------*/UINT32 am930mem_free( am930mem_t *mem, UINT32 p, UINT32 size){	UINT32			amask;	UINT32			nbits;	UINT32			lshift;	wlan_flags_t	flags;	WLAN_INT_DISABLE(flags);	if ( mem->lock == 0)	{		mem->lock = 1;		nbits = size / mem->fragsize;		nbits += ((size % mem->fragsize) ? 1 : 0);		amask = ((UINT32)0xffffffff) >> ((sizeof(mem->bits)*8) - nbits);		lshift = p / mem->fragsize;		amask = amask << lshift;		mem->bits &= ~amask;		WLAN_INT_ENABLE(flags);	}	else	{		WLAN_LOG_DEBUG0(1, "failed! mem mgr locked.\n");		p = 0UL;	}	WLAN_INT_ENABLE(flags);	return p;}/*----------------------------------------------------------------*	readcard, writecard, *   read8, read16, read32, *   write8, write16, write32**	Functions to read/write to the 'shared' memory on the card.*	These functions are abstracted here so we can choose between*	either the io register or memory mapped access to the card *   memory.**	The 8, 16, and 32 functions are for reading/writing bytes, *	halfwords and words respectively.*----------------------------------------------------------------*/void readcard( am930hw_t *hw, UINT32 cardaddr, void *buf, UINT32 len){	if ( hw->usemem ) {		#if (WLAN_OS == WLAN_LINUX_KERNEL)			UINT8 * dp = (UINT8 *) buf;			volatile UINT8 *sp = ((volatile UINT8*) hw->membase) + cardaddr;			while( len-- != 0 ) {				*dp++ = readb(sp++);				udelay(am930_iodelay);			} 		#else			memcpy(buf, ((volatile UINT8 *) hw->membase) + cardaddr, len);		#endif	}	else {		UINT8			byte;		INT				i;		wlan_flags_t	flags;		UINT8			lmal;		UINT8			lmau;		UINT16			scardaddr;		/* set bank select and flash deselect */		byte = inb_p(BSS(hw));		byte &= ~0x38;  		outb_p(byte, BSS(hw));		/* save the address regs and set the new address */		WLAN_INT_DISABLE(flags);		lmal = inb( LMAL(hw));		lmau = inb( LMAU(hw));		/* if necessary, mess with the byte order */		scardaddr = cardaddr;		scardaddr =

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -