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

📄 hfa384x.c

📁 uClinux2.6上兼容PRISM2.0芯片组的USB设备驱动程序.
💻 C
📖 第 1 页 / 共 5 页
字号:
* hfa384x_drvr_readpda** Performs the sequence to read the PDA space.  Note there is no* drvr_writepda() function.  Writing a PDA is* generally implemented by a calling component via calls to * cmd_download and writing to the flash download buffer via the * aux regs.** Arguments:*	hw		device structure*	buf		buffer to store PDA in*	len		buffer length** Returns: *	0		success*	>0		f/w reported error - f/w status code*	<0		driver reported error*	-ETIMEOUT	timout waiting for the cmd regs to become*			available, or waiting for the control reg*			to indicate the Aux port is enabled.*	-ENODATA	the buffer does NOT contain a valid PDA.*			Either the card PDA is bad, or the auxdata*			reads are giving us garbage.** Side effects:** Call context:*	process thread or non-card interrupt.----------------------------------------------------------------*/int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, UINT len){	int		result = 0;	UINT16		*pda = buf;	int		pdaok = 0;	int		morepdrs = 1;	int		currpdr = 0;	/* word offset of the current pdr */	int		i;	UINT16		pdrlen;		/* pdr length in bytes, host order */	UINT16		pdrcode;	/* pdr code, host order */	UINT16		crc;	UINT16		pdacrc;	struct pdaloc {		UINT32	cardaddr;		UINT16	auxctl;	} pdaloc[] =	{		{ HFA3842_PDA_BASE,		HFA384x_AUX_CTL_NV},		{ HFA3842_PDA_BASE,		HFA384x_AUX_CTL_EXTDS},		{ HFA3841_PDA_BASE,		HFA384x_AUX_CTL_NV}, 		{ HFA3841_PDA_BASE,		HFA384x_AUX_CTL_EXTDS}, 		{ HFA3841_PDA_BOGUS_BASE,	HFA384x_AUX_CTL_NV}	};	DBFENTER;	/* Check for aux available */	result = hfa384x_cmd_aux_enable(hw, 0);	if ( result ) {		WLAN_LOG_DEBUG(1,"aux_enable() failed. result=%d\n", result);		goto failed;	}	/* Read the pda from each known address.  */	for ( i = 0; i < (sizeof(pdaloc)/sizeof(pdaloc[0])); i++) {		WLAN_LOG_DEBUG( 3, "Checking PDA@(0x%08x,%s)\n",			pdaloc[i].cardaddr,			pdaloc[i].auxctl == HFA384x_AUX_CTL_NV ?			"CTL_NV" : "CTL_EXTDS");		/* Copy bufsize bytes from our current pdaloc */		hfa384x_copy_from_aux(hw, 			pdaloc[i].cardaddr, 			pdaloc[i].auxctl, 			buf, 			len);		/* Test for garbage */		/* Traverse the PDR list Looking for PDA-END */		pdaok = 1;	/* intially assume good */		morepdrs = 1;		currpdr = 0;		while ( pdaok && morepdrs ) {			pdrlen = hfa384x2host_16(pda[currpdr]) * 2;			pdrcode = hfa384x2host_16(pda[currpdr+1]);							/* Test for completion at END record */			if ( pdrcode == HFA384x_PDR_END_OF_PDA ) {				if ( pdrlen == 4 ) { 					morepdrs = 0;					/* Calculate CRC-16 and compare to PDA					 * value.  Note the addition of 2 words					 * for ENDREC.len and ENDREC.code					 * fields.					 */					crc = hfa384x_mkcrc16( (UINT8*)pda, 						(currpdr + 2) * sizeof(UINT16));					pdacrc =hfa384x2host_16(pda[currpdr+2]);					if ( crc != pdacrc ) {						WLAN_LOG_DEBUG(3,						"PDA crc failed:"						"calc_crc=0x%04x,"						"pdr_crc=0x%04x.\n",						crc, pdacrc);						pdaok = 0;					}				} else {					WLAN_LOG_DEBUG(3, 					"END record detected w/ "					"len(%d) != 2, assuming bad PDA\n",					pdrlen);					pdaok = 0;				}				break;			}				/* Test the record length */			if ( pdrlen > HFA384x_PDR_LEN_MAX || pdrlen == 0) {				WLAN_LOG_DEBUG(3,					"pdrlen for address #%d "					"at %#x:%#x:%d\n",					i, pdaloc[i].cardaddr, 					pdaloc[i].auxctl, pdrlen);				WLAN_LOG_DEBUG(3,"pdrlen invalid=%d\n", 					pdrlen);				pdaok = 0;				break;			}			/* Move to the next pdr */			if ( morepdrs ) {				/* note the access to pda[], we need words */				currpdr += hfa384x2host_16(pda[currpdr]) + 1;				if (currpdr*sizeof(UINT16) > len) {					WLAN_LOG_DEBUG(3,					"Didn't find PDA_END in buffer, "					"trying next location.\n");					pdaok = 0;					break;				}			}		}			if ( pdaok ) {			WLAN_LOG_INFO(				"PDA Read from 0x%08x in %s space.\n",				pdaloc[i].cardaddr, 				pdaloc[i].auxctl == 0 ? "EXTDS" :				pdaloc[i].auxctl == 1 ? "NV" :				pdaloc[i].auxctl == 2 ? "PHY" :				pdaloc[i].auxctl == 3 ? "ICSRAM" : 				"<bogus auxctl>");			break;		} 	}	result = pdaok ? 0 : -ENODATA;	if ( result ) {		WLAN_LOG_DEBUG(3,"Failure: pda is not okay\n");	}	hfa384x_cmd_aux_disable(hw);failed:	DBFEXIT;	return result;}/*----------------------------------------------------------------* mkpda_crc** Calculates the CRC16 for the given PDA and inserts the value* into the end record.** Arguments:*	pda	ptr to the PDA data structure.** Returns: *	0	- success *	~0	- failure (probably an errno)----------------------------------------------------------------*/static UINT16 hfa384x_mkcrc16(UINT8 *p, int len){	UINT16	crc = 0;	UINT8	*lim = p + len;	while (p < lim) {			crc = (crc >> 8 ) ^ crc16tab[(crc & 0xff) ^ *p++];	}	return crc;}/*----------------------------------------------------------------* hfa384x_drvr_ramdl_enable** Begins the ram download state.  Checks to see that we're not* already in a download state and that a port isn't enabled.* Sets the download state and calls cmd_download with the * ENABLE_VOLATILE subcommand and the exeaddr argument.** Arguments:*	hw		device structure*	exeaddr		the card execution address that will be *                       jumped to when ramdl_disable() is called*			(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_ramdl_enable(hfa384x_t *hw, UINT32 exeaddr){	int		result = 0;	UINT16		lowaddr;	UINT16		hiaddr;	int		i;	DBFENTER;	/* Check that a port isn't active */	for ( i = 0; i < HFA384x_PORTID_MAX; i++) {		if ( hw->port_enabled[i] ) {			WLAN_LOG_DEBUG(1,"Can't download with a port enabled.\n");			result = -EINVAL; 			goto done;		}	}	/* Check that we're not already in a download state */	if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) {		WLAN_LOG_DEBUG(1,"Download state not disabled.\n");		result = -EINVAL;		goto done;	}	/* Are we supposed to go into genesis mode? */	if (exeaddr == 0x3f0000) {		UINT16 initseq[2] = { 0xe100, 0xffa1 };		UINT16 readbuf[2];		UINT8 hcr = 0x0f; /* Default to x16 SRAM */		hw->isram16 = 1;		WLAN_LOG_DEBUG(1, "Dropping into Genesis mode\n");		/* Issue card reset and enable aux port */		hfa384x_corereset(hw, prism2_reset_holdtime,				  prism2_reset_settletime, 0);		hfa384x_cmd_aux_enable(hw, 1);		/* Genesis set */		hfa384x_copy_to_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS, 				    initseq, sizeof(initseq));		hfa384x_corereset(hw, prism2_reset_holdtime,				  prism2_reset_settletime, hcr);		/* Validate memory config */		hfa384x_copy_to_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS, 				    initseq, sizeof(initseq));		hfa384x_copy_from_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS, 				    readbuf, sizeof(initseq));		WLAN_HEX_DUMP(3, "readback", readbuf, sizeof(readbuf));		if (memcmp(initseq, readbuf, sizeof(readbuf))) {			hcr = 0x1f; /* x8 SRAM */			hw->isram16 = 0;			hfa384x_copy_to_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS, 					    initseq, sizeof(initseq));			hfa384x_corereset(hw, prism2_reset_holdtime,					  prism2_reset_settletime, hcr);			hfa384x_copy_to_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS, 					    initseq, sizeof(initseq));			hfa384x_copy_from_aux(hw, 0x7E0038, HFA384x_AUX_CTL_EXTDS, 					    readbuf, sizeof(initseq));			WLAN_HEX_DUMP(2, "readback", readbuf, sizeof(readbuf));			if (memcmp(initseq, readbuf, sizeof(readbuf))) {				WLAN_LOG_ERROR("Genesis mode failed\n");				result = -1;				goto done;			}		}		/* Now we're in genesis mode */		hw->dlstate = HFA384x_DLSTATE_GENESIS;		goto done;	}	/* Retrieve the buffer loc&size and timeout */	if ( (result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER, 				&(hw->bufinfo), sizeof(hw->bufinfo))) ) {		goto done;	}	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))) ) {		goto done;	}	hw->dltimeout = hfa384x2host_16(hw->dltimeout);	/* Enable the aux port */	if ( (result = hfa384x_cmd_aux_enable(hw, 0)) ) {		WLAN_LOG_DEBUG(1,"Aux enable failed, result=%d.\n", result);		goto done;	}	/* Call the download(1,addr) function */	lowaddr = HFA384x_ADDR_CMD_MKOFF(exeaddr);	hiaddr =  HFA384x_ADDR_CMD_MKPAGE(exeaddr);	result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_RAM, 			lowaddr, hiaddr, 0);	if ( result == 0) {		/* Set the download state */		hw->dlstate = HFA384x_DLSTATE_RAMENABLED;	} else {		WLAN_LOG_DEBUG(1,"cmd_download(0x%04x, 0x%04x) failed, result=%d.\n",				lowaddr,hiaddr, result);		/* Disable  the aux port */		hfa384x_cmd_aux_disable(hw);	} done:	DBFEXIT;	return result;}/*----------------------------------------------------------------* 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 thread ----------------------------------------------------------------*/int hfa384x_drvr_ramdl_disable(hfa384x_t *hw){	DBFENTER;	/* Check that we're already in the download state */	if ( ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) && 	     ( hw->dlstate != HFA384x_DLSTATE_GENESIS ) ) {		return -EINVAL;	}	if (hw->dlstate == HFA384x_DLSTATE_GENESIS) {		hfa384x_corereset(hw, prism2_reset_holdtime, 				  prism2_reset_settletime, 				  hw->isram16 ? 0x07: 0x17);		goto done;	}	/* Disable the aux port */	hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0); done:	hw->dlstate = HFA384x_DLSTATE_DISABLED;	hfa384x_cmd_aux_disable(hw);	DBFEXIT;	return 0;}/*----------------------------------------------------------------* hfa384x_drvr_ramdl_write** Performs a RAM download of a chunk of data. First checks to see* that we're in the RAM download state, then uses the aux functions* to 1) copy the data, 2) readback and compare.  The download* state is unaffected.  When all data has been written using* this function, call drvr_ramdl_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_ramdl_write(hfa384x_t *hw, UINT32 daddr, void* buf, UINT32 len){	int		result = 0;	UINT8		*verbuf;	DBFENTER;	/* Check that we're in the ram download state */	if ( ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) && 	     ( hw->dlstate != HFA384x_DLSTATE_GENESIS ) ) {		return -EINVAL;	}	WLAN_LOG_INFO("Writing %d bytes to ram @0x%06x\n", len, daddr);#if 0WLAN_HEX_DUMP(1, "dldata", buf, len);#endif	/* Copy the data via the aux port */	hfa384x_copy_to_aux(hw, daddr, HFA384x_AUX_CTL_EXTDS, buf, len);	/* Create a buffer for the verify */	verbuf = kmalloc(len, GFP_KERNEL);	if (verbuf == NULL ) return 1;	/* Read back and compare */	hfa384x_copy_from_aux(hw, daddr, HFA384x_AUX_CTL_EXTDS, verbuf, len);	if ( memcmp(buf, verbuf, len) ) {		WLAN_LOG_DEBUG(1,"ramdl verify failed!\n");		result = -EINVAL;	}	kfree_s(verbuf, len);	DBFEXIT;	return result;}/*----------------------------------------------------------------* hfa384x_drvr_flashdl_enable** Begins the flash download state.  Checks to see that we're not* already in a download state and that a port isn't enabled.* Sets the download state and retrieves the flash download* buffer location, buffer size, and timeout length.** 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_enable(hfa384x_t *hw){	int		result = 0;	int		i;	DBFENTER;	/* Check that a port isn't active */	for ( i = 0; i < HFA384x_PORTID_MAX; i++) {		if ( hw->port_enabled[i] ) {			WLAN_LOG_DEBUG(1,"called when port enabled.\n");			return -EINVAL; 		}	}	/* Check that we're not already in a download state */	if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) {		return -EINVAL;	}

⌨️ 快捷键说明

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