📄 wvlan_hcf.c
字号:
Remarks: Configuration information is copied from the provided data structure into the Card. The exact layout of the provided data structure depends on the action code. Also the mechanism used to copy the data to the card depends on the action code. In order to make the changes which are based on the Access command (see support routine put_info) sustain over activities like hcf_diagnose and recovery from PCMCIA card insertion, the data associated with these particular action codes, is saved in the IF-block. The codes for this type are "cleverly" chosen to be identical to the RID. bufp is defined as a pointer to items of type hcf_16 because of the correlation with the Hermes definition .DIAGRAM.NOTICE Future enhancements in the functionality offered by the WCI and/or implementation aspects of the HCF may warrant filtering on the type-field of the LTV to recognize non-MSF accessible records, e.g. CFG_TICK **************************************************************************************************************/int hcf_put_info( IFBP ifbp, LTVP ltvp /*number identifying the type of change<PRE> CFG_INFO_FRAME_MIN lowest value representing an Information Frame CFG_NOTIFY Handover Address CFG_TALLIES Communications Tallies CFG_SCAN Scan results CFG_LINK_STAT Link Status CFG_ASSOC_STAT Association Status </PRE> */ ) {//int cnt = 3;//hcf_16 i = ltvp->len - 1;int rc = HCF_SUCCESS; if ( CFG_RID_CFG_MIN <= ltvp->typ && ltvp->typ <= CFG_RID_CFG_MAX ) { //all codes between 0xFC00 and 0xFCFF are passed to Hermes)// if ( ( ifbp->IFB_CardStat & CARD_STAT_PRI_STA_PRES ) == CARD_STAT_PRESENT ) {// do {// rc = hcfio_string( ifbp, BAP_1,// ltvp->typ, 0, (wci_bufp)ltvp, 2, MUL_BY_2(ltvp->len + 1), IO_OUT_CHECK );// } while ( cnt-- && rc != HCF_SUCCESS );// if ( rc == HCF_SUCCESS ) rc = cmd_wait( ifbp, HCMD_ACCESS + HCMD_ACCESS_WRITE, ltvp->typ );// if ( rc == HCF_SUCCESS ) rc = put_info( ifbp, ltvp ); rc = put_info( ifbp, ltvp );// } } return rc;}/* hcf_put_info *//******************************************************************************************************************.MODULE hcf_send.LIBRARY HCF.TYPE function.SYSTEM msdos.SYSTEM unix.SYSTEM NW4.APPLICATION Data Transfer Function for WaveLAN based drivers and utilities.DESCRIPTION Transmit a message on behalf of the protocol stack.ARGUMENTS void hcf_send( IFBP ifbp , hcf_send_type type ) Card Interrupts disabled.RETURNS void MSF-accessible fields of Result Block: -.NARRATIVE Hcf_send transmits the Protocol Stack message loaded in NIC RAM by the preceeding hcf_put_data calls..DIAGRAM1: The actual data length (the number of bytes in the Tx Frame structure following the 802.3/802.11 Header Info blocks, is determined by IFB_PIFLoadIdx, the index in the Transmit Frame Structure to store the "next" byte. Note that this value must be compensated for the header info by subtracting HFS_DAT.2/3:TxFrameType - which is based on the preceding hcf_put_data calls - defines whether the actual data length is written to the 802.11 or 802.3 Header Info block.2: In case of 802.11, the entry parameter type is augmented to reflect 802.11 before it is written to the Control Field block.3: In case of 802.3, the actual length must be converted from the native format of the Host (Little Endian in case of an 80x86) to Big Endian before it is written to the 802.3 Header Info block.4: The actual send+reclaim command is performed by the routine send.7: The return status of hcfio_in_string can be ignored, because when it fails, cmd_wait will fail via the IFB_TimStat mechanism.NOTICE ;?This comment is definitely out of date The choice to let hcf_send calculate the actual data length as IFB_PIFLoadIdx - HFS_DAT, implies that hcf_put_data with the HFS_LUCENT mechanism MUST be used to write the Data Info Block. A change in this I/F will impact hcf_send as well. An alternative would be to have a parameter datlen. If datlen is zero, the current behavior is used. If datlen has a non-zero value, its value is used as the actual data length (without validating against HCF_MAX_MSG and without validating the total number of bytes put by hcf_put_data)..NOTICE hcf_put_data/send leave the responsibility to only send messages on enabled ports at the MSF level. This is considered the strategy which is sufficiently adequate for all "robust" MSFs, have the least processor utilization and being still acceptable robust at the WCI !!!!!.ENDOC END DOCUMENTATION------------------------------------------------------------------------------------------------------------*/int hcf_send( IFBP ifbp , hcf_16 port ) { //;?note that port is unused due to ambivalence about what the "right" I/F isint rc = HCF_SUCCESS; if ( ifbp->IFB_CardStat & CARD_STAT_PRESENT ) { /* 1 */ /* H/W Pointer problem detection */ if ( ifbp->IFB_BAP_0[0] != ifbp->IFB_FSBase ) { //;?<HCF _L> should BE HARD CODED, also add to send diag msg /* 30*/ rc = hcfio_string( ifbp, BAP_0, ifbp->IFB_PIF_FID, ifbp->IFB_PIFLoadIdx, NULL, 0, 0, IO_OUT_CHECK ); if ( rc == HCF_FAILURE ) { ifbp->IFB_PIFRscInd = 1; } } if ( rc == HCF_SUCCESS ) { if ( /*ifbp->IFB_FrameType == ENC_802_11 || */ ifbp->IFB_TxFrameType == ENC_TX_E_II ) { /* 2 */ ifbp->IFB_PIFLoadIdx -= HFS_DAT_ABS; //actual length of frame /* 1 */ CNV_INT_TO_BIG_NP(&ifbp->IFB_PIFLoadIdx); //;?is it worthwhile to have this additional macro (void)hcfio_string( ifbp, BAP_0, ifbp->IFB_PIF_FID, HFS_LEN_ABS, (wci_bufp)&ifbp->IFB_PIFLoadIdx, 0, 2, IO_OUT ); /* 7 */ }// send( ifbp, ifbp->IFB_PIF_FID, port | ifbp->IFB_FrameType ); /* 4 */ (void)cmd_wait( ifbp, HCMD_TX + HCMD_RECL, ifbp->IFB_PIF_FID ); //justify "void" } /* reset the BAP pointer for the Tx Framestructure, note that we access the BAP not the NIC RAM * after we relinguished control of the Tx FID to the Hermes */ (void)hcfio_string( ifbp, BAP_0, ifbp->IFB_PIF_FID, ifbp->IFB_FSBase, NULL, 0, 0, IO_IN ); } return rc;} /* hcf_send *//*******************************************************************************************************************.MODULE hcf_send_diag_msg.LIBRARY HCF.TYPE function.SYSTEM msdos.SYSTEM unix.SYSTEM NW4.APPLICATION Data Transfer Function for WaveLAN based drivers and utilities.DESCRIPTION Transmit a message on behalf of the Driver-Utility I/F.ARGUMENTS void hcf_send_diag_msg( IFBP ifbp, wci_bufp bufp, hcf_16 len ) Card Interrupts disabled.RETURNS void MSF-accessible fields of Result Block: -.NARRATIVE Hcf_send_diag_msg transmits the message.DIAGRAM 2: 4: Based on the assumption that hcf_send_diag_msg is called at a low frequency, HFS_TX_CNTL_ABS is written on each call rather than using an IFB-field to remember the previous value and update only if needed.ENDOC END DOCUMENTATION-------------------------------------------------------------------------------------------------------------*/int hcf_send_diag_msg( IFBP ifbp, hcf_16 type, wci_bufp bufp, int len ) {int rc = HCF_SUCCESS; if ( ifbp->IFB_CardStat & CARD_STAT_PRESENT ) { rc = HCF_ERR_BUSY; //;?more appropriate value needed if ( ifbp->IFB_DUIFRscInd ) { /* 2 */ rc = hcfio_string( ifbp, BAP_0, ifbp->IFB_DUIF_FID, HFS_ADDR_DEST_ABS, bufp, 0, len, IO_OUT_CHECK ); if ( rc == HCF_SUCCESS ) { ifbp->IFB_DUIFRscInd = 0; (void)hcfio_string( ifbp, BAP_0, ifbp->IFB_PIF_FID, HFS_TX_CNTL_ABS, //justify void (wci_bufp)&type, 1, 2, IO_OUT ); /* 4 */ (void)cmd_wait( ifbp, HCMD_TX + HCMD_RECL, ifbp->IFB_DUIF_FID ); } } } return rc;} /* hcf_send_diag_msg *//*******************************************************************************************************************.MODULE hcf_service_nic.LIBRARY HCF.TYPE function.SYSTEM msdos.APPLICATION Data Transfer Function for WaveLAN based drivers and utilities.DESCRIPTION Provides received message and link status information.ARGUMENTS int hcf_service_nic(IFBP ifbp ) Card Interrupts disabled.RETURNS int all the bits of the Hermes evitable register, which are encountered during execution of hcf_service_nic the "pseudo"-events HREG_EV_NO_CARD, HREG_EV_DUIF_RX MSF-accessible fields of Result Block IFB_RxLen 0 or Frame size as reported by LAN Controller IFB_RxStat IFB_MBInfoLen IFB_PIFRscInd IFB_DUIFRscInd IFB_NotifyRscInd IFB_HCF_Tallies.NARRATIVE hcf_service_nic is primarily intended to be part of the Interrupt Service Routine. hcf_service_nic is presumed to neither interrupt other HCF-tasks nor to be interrupted by other HCF-tasks. A way to achieve this is to precede hcf_service_nic as well as all other HCF-tasks with a call to hcf_action to disable the card interrupts and, after all work is completed, with a call to hcf_action to restore (which is not necessarily the same as enabling) the card interrupts. In case of a polled environment, it is assumed that the MSF programmer is sufficiently familiar with the specific requirements of that environment to translate the interrupt strategy to a polled strategy. hcf_service_nic services the following Hermes events: HREG_EV_INFO Asynchronous Information Frame HREG_EV_INFO_DROP WMAC did not have sufficient RAM to build Unsolicited Information Frame HREG_EV_ALLOC Asynchronous part of Allocation/Reclaim completed HREG_EV_RX the detection of the availability of received messages If a message is available, its length is reflected by the IFB_RxLen field of the IFB. This length reflects the 802.3 message length (i.e. the data itself but not the Destination Address, Source Address, DataLength field nor the SAP-header in case of decapsulation by the HCF). If no message is available, IFB_RxLen is zero. **Buffer free strategy When hcf_service_nic reports the availability of a message, the MSF can access that message or parts thereof, by means of hcf_get_data calls till the next call of hcf_service_nic. Therefore it must be prevented that the LAN Controller writes new data in the buffer associated with the last hcf_service_nic report. As a consequence hcf_service_nic is the only procedure which can free receive buffers for re-use by the LAN Controller. Freeing a buffer is done implicitly by acknowledging the Rx event to the Hermes. The strategy of hcf_service_nic is to free the buffer it has reported as containing an available message in the preceeding call (assuming there was an available message). A consequence of this strategy is that the Interrupt Service Routine of the MSF must repeatedly call hcf_service_nic till hcf_service_nic returns "no message available". It can be reasoned that hcf_action( INT_ON ) should not be given before the MSF has completely processed a reported Rx-frame. The reason is that the INT_ON action is guaranteed to cause a (Rx-)interrupt (the MSF is processing a Rx-frame, hence the Rx-event bit in the Hermes register must be active). This interrupt will cause hcf_service_nic to be called, which will cause the ack-ing of the "last" Rx-event to the Hermes, causing the Hermes to discard the associated NIC RAM buffer..DIAGRAM 2: IFB_RxLen and IFB_RxStat must be cleared before the NIC presence check otherwise these values may stay non-zero if the NIC is pulled out at an inconvenient moment 4: 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. The MSF may have considerable latency in informing the HCF of the card removal by means of an hcf_disable. To prevent that hcf_service_nic reports bogus information to the MSF with all - possibly difficult to debug - undesirable side effects, hcf_service_nic pays performance wise the prize to use the momentanuous NIC presence test by checking the contents of the Hermes register HREG_SW_0 against the value HCF_MAGIC. 6: The return status of hcf_service_nic is defined as reflecting all interrupt causes this call has run into, hence an accumulator is needed. This return status services ONLY to help the MSF programmer to debug the total system. When the card is removed, the pseudo event HREG_EV_NO_CARD is reported. NOTE, the HREG_EV_NO_CARD bit is explicitly not intended for the MSF to detect NIC removal. The MSF must use its own - environment specific - means for that.10:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -