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

📄 wvlan_hcf.c

📁 pcmcia source code
💻 C
📖 第 1 页 / 共 5 页
字号:
	disabled. If all ports or the only enabled port is to be disabled, the disabling is skipped and the	Hermes Initiate command is supposed to take care of it all.16: perform a superficial Hermes health test. Note that in hcf_initialize all (or at least most) activities are	checked for conditions like "Busy bit should drop". If such a condition is not met in time, hcf_initialize	returns an error code. Hcf_functions which are only called during "normal" operations may ignore such	events. Their only obligation is to prevent that the code hangs.	Note that early models of the Hermes needed some arbitrary read before the first write activity to operate	stable (ref tracker 27). This code achieves that function as a side effect.18:	Initialize the Hermes. The results of this way of initialization depends on the capabilities of the Hermes  	firmware. Therefore, the Hermes H/W controlled bits, like those in the evitable register are not guaranteed  	to be cleared as result of the initialize command. However it is guaranteed that no more events are in the    pipeline. Ack-ing indiscriminately all events resolves this problem. An alternative would be to use the    resulting value of "IN_PORT_WORD( ifbp->IFB_IOBase + HREG_EV_STAT )" rather than 0xFFFF to specifically    only reset those events which are set. This strategy is considered to be only more aesthetically pleasing    (if that).20:	Perform some housekeeping tasks  - Write HCF_MAGIC as signature to S/W support register 0.  This signature is used to detect card removal	wherever the presence of the card is critical while HCF may not yet have been informed by the MSF of the	removal of the card.  Note that this task can not be postponed because that would cause the hcfio_in_string	called by hcf_get_info to fail22:	  -	IFB_TickIni	must be initialized (at INI_TICK_INI) to prevent that actions like hcf_put_info immediately	    after hcf_connect (that is without intervening hcf_disable) at an absent (or failing) NIC take too	    long.  Note that this is a legal hcf-sequence according to the WCI-specification.	IFB_TickIni is the value used to initialize the S/W protection counter in a way which makes the	expiration period more or less independent of the processor speed. If IFB_TickIni is not yet calibrated,	it is done now.	First off all the Hermes Tick period is programmed for a "reasonable" interval, currently 8092 or 8k	microseconds, by means of hcf_put_info. Note that IFB_DLTarget, which is guaranteed to get the correct	value later on in hcf_enable, is misused as re-entrant storage for the RID used to program the Tick period.	The HCF synchronizes itself with the Hermes timer by waiting for the first timer tick. This synchronizing is done by	ack-ing the Tick regardless of its current value. This guarantees Tick becomes low. Then Tick is sampled	till it is high, which guarantees a new complete interval starts in the Hermes. Tick is acked again and	another Tick is awaited. This period is as accurate as we can get.	To diminish the chance that in a pre-emptive environment IFB_TickIni is calibrated too low because the HCF	just happens to loose control during this calibration, the calibration is performed 10 times and the	largest value is used.	IFB_TickIni is then set at approximately 1 second by multiplying that largest value by 128. The 8k	microseconds interval and the multiplication by 128 are chosen as a compromise between accuracy of	the calibration. time consumed by the calibration and possibilities for the compiler to optimize	the arithmetic.26:	Finally the Hermes Tick period is programmed for a "reasonable" runtime interval, currently 1 second	(1,000,000/1,024 kilo-microseconds), by means of hcf_put_info (again the available CONCATENATED storage	is misused)	Note that in case of failure, IFB_TickIni ends up as INI_TICK_INI, which is a supposedly acceptable	value to handle the rare case of a broken card.30: The Supplier Range of the Primary Firmware function is retrieved from the Hermes and checked against	the Top and Bottom level supported by this HCF.	If the primary firmware does not supply this RID or supplies the "old" HardwareStructure Info, the	Primary Compatibility check is skipped. These conditions are recognized based on the length field supplied	by the Hermes. ;?is this wise in the post-GCA area32: In case of a HCF compiled for station functionality, the Supplier Range of the Station Firmware function	is retrieved from the Hermes and checked against the Top and Bottom level supported by this HCF.	Note that the Firmware can have multiple Variants, but that the HCF currently only supports a single	variant.40:	Perform some more housekeeping tasks  -	Decrement ifbp->IFB_IntOffCnt to compensate side effect of ACT_INT_OFF action at begin of hcf_initialize (see	#2). This can not be handled by calling hcf_action with HCF_ACT_ON, because this could as undesirable	side effect actually enable interrupts	.NOTICE o  For all practical WCI purposes there is no practical difference between a Hermes disable command at all	individual ports and an hermes initialize command o  hcf_initialize disables the card interrupts, however it does NOT influence IFB_IntOffCnt.	This way it is symmetrical with hcf_enable, which does NOT enable the card interrupts.	   	IFB_CardStat  -	CARD_STAT_INCOMP_PRI				  -	CARD_STAT_INCOMP_STA   	 5:	The house keeping is done, consisting of the steps:	- allocate a Tx Frame Structure for the protocol stack	- allocate a Tx Frame Structure for the utility	- allocate a Information Frame Structure for the Notify command	Note that a subsequent allocate is only performed if the preceding one	succeeded	- if all allocates succeeded, the Resource Indicators corresponding	  with the Tx Frames are set**************************************************************************************************************/int hcf_initialize( IFBP ifbp ) {int		rc;//hcf_16	*p;hcf_8	*q;	for ( q = (hcf_8*)&ifbp->IFB_PIFRscInd; q < (hcf_8*)&ifbp[1]; *q++ = 0) /*NOP*/;					/* 2 *///	if ( (ifbp->IFB_CardStat & CARD_STAT_INI) == 0 ) {				//present but not initialized	/* 7 */	do { //;?CARD_STAT_PRESENT check superfluous as long as hcf_initialize is not defined on the WCI		rc = ini_hermes( ifbp );		if ( rc != HCF_SUCCESS ) break;																/* 32*/		OUT_PORT_WORD( ifbp->IFB_IOBase + HREG_SW_0, HCF_MAGIC );									/* 20*/		rc = calibrate( ifbp );   																	/* 22*/		if ( rc != HCF_SUCCESS ) break;#if defined MSF_COMPONENT_ID  //;?interesting question at which level HCFL interacts		#endif // MSF_COMPONENT_ID        ifbp->IFB_CardStat |= CARD_STAT_INI;	//consider this as sufficient to reach CARD_STAT_INI?	/* 24*/		if ( rc != HCF_SUCCESS ) break;   //;? apparently this still should follow the moved IFB_DLTarget logic but											//;? think this over for the different scenarios		if ( ( ifbp->IFB_PIF_FID    = alloc( ifbp, HFS_TX_ALLOC_SIZE )  ) == 0		||				/* 5 */			 ( ifbp->IFB_DUIF_FID   = alloc( ifbp, HFS_TX_ALLOC_SIZE )  ) == 0  ) {			rc = HCF_FAILURE;		} else {			ifbp->IFB_PIFRscInd = ifbp->IFB_DUIFRscInd = 1;		}	} while ( 0 ); //pseudo goto-less, accept "warning: conditional expression is constant"	return rc;}/* hcf_initialize *//*******************************************************************************************************************.MODULE			hcf_put_data.LIBRARY 		HCF.TYPE 			function.SYSTEM			msdos.SYSTEM			unix.SYSTEM			NW4.APPLICATION	Data Transfer Function for WaveLAN based drivers and utilities.ARGUMENTS	void hcf_put_data( IFBP ifbp, wci_bufp bufp, int len, hcf_16 port )	Card Interrupts disabled.RETURNS	void  MSF-accessible fields of Result Block: -.DESCRIPTION	Transfers (part of) transmit message to the NIC and handles	the Ethernet-II encapsulation if applicable.NARRATIVE	parameters:		ifbp		address of the Interface Block		bufp		char pointer, address of buffer in PC RAM		len			length (in bytes) of data to be copied		port		HCF_PORT_0 - HCF_PORT_6 .........;?					HCF_PUT_DATA_RESET	Refer to hcf_service;?non-existing reference, for a concise description about possible	relation/sequencing of hcf_put_data in the Interrupt Service Routine		In essence, hcf_put_data copies the number of bytes specified by parameter len from the location in PC	RAM specified by bufp to the NIC RAM buffer associated with the Protocol Stack dedicated FID.	The first call succeeding hcf_send (or hcf_enable), writes the first byte at offset HFS_ADDR_DEST in	the transmit data buffer, successive hcf_put_data calls continue where the preceeding hcf_put_data stopped.		IFB_FrameType determines whether the message in the PC RAM buffer is interpreted as an 802.3 or 802.11	frame.  This influences: 	o the position where the first byte of the initial hcf_put_data is stored 	o Only in case of the 802.3 frame type, hcf_put_data checks whether the frame is an Ethernet-II rather 	  than an "official" 802.3 frame. The E-II check is based on the length/type field in the MAC header. If 	  this field has a value larger than 1500, E-II is assumed. The implementation of this test fails if the	  length/type field is split over 2 hcf_put_data calls.	  If E-II is recognized, the length field HFS_LEN_ABS is skipped for the time being and a SNAP header is	  inserted starting at HFS_DAT_ABS. This SNAP header represents either RFC1042 or Bridge-Tunnel	  encapsulation, depending on whether the type is absent or present in enc_trans_tbl. 	o In case of the 802.11 frame type, hcf_put_data checks whether the complete header + length field is 	  written (note that part of the header may be written by previous hcf_put_data calls and part may be 	  written by this call).  If so, the next byte is written at HFS_DAT_ABS (the 802.3 header area is skipped)	It is allowed to write the 802.3 header, 802.11 header and/or data in fragments, e.g. the first	hcf_put_data call writes 18 bytes starting at location HFS_ADDR_1_ABS and the second call writes 6 more	bytes starting at location HFS_ADDR_4. Although Address part #4 is not present in some 802.11 headers,	all 4 addressing parts and the length field must be written in case of 802.11. Once the complete header	is written, the data part is written starting from offset HFS_DAT_ABS.	Hcf_put_data does not check for transmit buffer overflow because the Hermes does this protection.	In case of a transmit buffer overflow, the surplus which does not fit in the buffer is simply dropped.	Note that this possibly results in the transmission of incomplete frames..DIAGRAM1*: If the card is not present, prevent all I/O because "our" I/O base may have been given away to someone	else in a CS/SS environment.  Also no I/O should be performed if the NIC is not enabled. However	an MSF which calls hcf_put_data while the NIC is not enabled probably contains a logic flaw (or has a	strategy which was not foreseen at the time this was written)10* HCF_PUT_DATA_RESET discards all the data put by preceeding hcf_put_data calls and resets the HCF	housekeeping just the same as after an hcf_send triggered allocate event.	Note: To make the WCI fail-safe, invalid port numbers are silently rejected by treating them as 	HCF_PUT_DATA_RESET. Note that the assumption is that this should never ever occure in a debugged MSF and 	that during debugging the ASSERT is sufficient support to help the MSF programmer.2*:	This statement is only true at the first hcf_put_data call after an hcf_send result or hcf_enable	The housekeeping is done. 	o the PIFRscInd is cleared, so the MSF can not begin another hcf_put_data/hcf_send sequence	before completing the current one 	o the Tx Encoding flag (TxFrameType) is cleared 	o the index to the first free position in the FID (IFB_PIFLoadIdx) is initialized based on IFB_FSBase. 	  IFB_FSBase is initialized when hcf_action is called with HCF_ACT_802_3 or HCF_ACT_802_113*:	Pay Attention: it may seem attractive to change this code, e.g. to save the superfluous call to	hcfio_out_string when the Destination and Source address are written by the preceeding call and the	current call starts at the length/type field. However this code is "reasonably carefully" crafted	to take in account all boundary conditions. It is very easy to make a change which does not work under	all feasible split ups of the message in fragments.	First IFB_PIFLoadIdx is checked.	  - If IFB_PIFLoadIdx points past HFS_LEN_ABS, the preceeding call(s) to hcf_put_data already passed the	  length/type field. As a consequence the fragment can be concatenated to the data already copied to	  NIC RAM.	  - If IFB_PIFLoadIdx does not point past HFS_LEN_ABS, the current fragment may or may not contain part of	  the Destination and/or Source Address and it may or may not contain the length/type field.	  If the fragment contains addressing information or -in case of 802.11- length info , this information	  is copied/concatenated to the NIC RAM buffer. The working variables (pointer and length of fragment) as	  well as the IFB_PIFLoadIdx are adjusted.	The semi-obscure differences in the boundary testing are caused by:	  o 802.11: the "below the boundary" area is Addr1, Addr2, Addr3, Ctrl, Adrr4 + DataLen and the "above"	  	area is the "real" data	  o 802.3: the "below the boundary" area is DestAddr + SrcAddr and the "above" area is the length +	  	"real" data	  o E-II: the "below the boundary" area is DestAddr + SrcAddr, then there is a "virtual" area with the	  	SNAP header (which will in the end include the HCF calculated length)  and the "above" area is the	  	"protocol stack length" (is in reality the type code) + "real" data4*:	If there is still data left, IFB_PIFLoadIdx may need adjustment (802.11 and E-II encapsulation).  Again	note that this length check is crucial to prevent mis-manipulation of IFB_PIFLoadIdx in case the header	is written in multiple fragments.	In case of 802.3, the E-II check is done. In case of E-II, the encapsulation type (RFC1042 versus	Bridge-Tunnel) is determined and the corresponding SNAP header is written to NIC RAM and	IFB_PIFLoadIdx is adjusted.6*:	All data which is not already copied under 3*, is copied here.	In case of 802.11, the HFS_DAT field is the first field written by this code.	In case of 802.3, the HFS_LEN field is the first field written by this code.	In case of E-II encapsulation, the HFS_TYPE field is the first field written by this code.	Note that in case of E-II encapsulation, the HFS_LEN field is not written by hcf_put_data at all, but by	hcf_send because the data length is not	known till all fragments have been processed.	.NOTE		The possible split of a single hcf_put_data call into 2 calls to hcfio_out_string results in 2 calls	to bap_ini, which may be unexpected while you are debugging, but is never the less the intended behavior.	Along the same line a call of hcfio_out_string with a value of 0 for parameter len may be unexpected, e.g.	when the len parameter of hcf_put_data is either 1 or 2, the latter depending on the odd/even aspects of	IFB_PIFLoadIdx.				.NOTE	The test on PIFRscInd to distinguish the initial hcf_put_data from subsequent calls is not thread safe.	It is assumed that threaded MSFs have their own mechanism to assure that hcf_put_data calls belonging to	a single frame are atomic with respect to each other. It is also assumed that the MSF takes care that	the hcf_put_data calls of multiple frames do not run concurrent		.ENDOC				END DOCUMENTATION-------------------------------------------------------------------------------------------------------------*/void hcf_put_data( IFBP ifbp, wci_bufp bufp, int len, hcf_16 port ) {int		idx;				//working index into Tx Frame structure, presume MSF control//int		tlen;				//working type/length of frame, working length for partial copy of frame		if ( ifbp->IFB_CardStat & CARD_STAT_PRESENT ) {															/* 1 */			if ( ifbp->IFB_PIFRscInd ) {																	/* 2 */				ifbp->IFB_PIFRscInd = 0;				ifbp->IFB_PIFLoadIdx = ifbp->IFB_FSBase;    //;?<HCF_L> should result in 0			}						idx = ifbp->IFB_PIFLoadIdx;			ifbp->IFB_PIFLoadIdx += (hcf_16)len;			(void)hcfio_string( ifbp, BAP_0, ifbp->IFB_PIF_FID, idx, bufp, 0, len, IO_OUT);		/* 6 */	}	return;}/* hcf_put_data *//************************************************************************************************************** Name:	hcf_put_info Summary: Transfers operation information and transient and persistent 	configuration information to the Card. Parameters:  ifbp	address of the Interface Block  type	specifies the RID (as defined by Hermes I/F)  bufp	address in NIC RAM where record data is located   len	length of data (in bytes).NARRATIVE Remarks:	CFG_NOTIFY: only runs after hcf_enable

⌨️ 快捷键说明

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