//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // // Routine Name: NetFlexISR // // Description: // This routine is the ISR for this Netflx mac driver. // This routine determines if the interrupt is for it // and if so, it clears the system interrupt bit of // the sifint register. // // Input: // Context - Our Driver Context for this adapter or head. // // Output: // Returns TRUE if the interrupt belongs to the // adapter and returns FALSE if it does not // belong to the adapter. // // Called By: // Miniport Wrapper // //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ VOID NetFlexISR( OUT PBOOLEAN InterruptRecognized, OUT PBOOLEAN QueueDpc, IN PVOID Context ) { PACB acb; USHORT sifint_reg; USHORT actl_reg; acb = (PACB) Context; // // Read the Sifint register. // NdisRawReadPortUshort( acb->SifIntPort, &sifint_reg); // // See if the System Interrupt bit is set. If it is, this is an // interrupt for us. // if (sifint_reg & SIFINT_SYSINT) { // // Acknowledge and Clear Int // if (!acb->InterruptsDisabled) { actl_reg = acb->actl_reg & ~ACTL_SINTEN; NdisRawWritePortUshort(acb->SifActlPort, actl_reg); DebugPrint(3,("NF(%d)(D)\n",acb->anum)); acb->InterruptsDisabled = TRUE; // // Return that we recognize it // *InterruptRecognized = TRUE; *QueueDpc = TRUE; } else { // // It appears that a second head is generating // the interrupt, and we have a DPC queued to // process our int, return that we don't recognize it // so that the oterh head's isr gets called... // *InterruptRecognized = FALSE; *QueueDpc = FALSE; } } else { // Return that we don't recognize it // *InterruptRecognized = FALSE; *QueueDpc = FALSE; } }
void cf_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val) { _irqL irqL; uint res; struct _SyncContext synccontext; struct intf_priv *pintfpriv = pintfhdl->pintfpriv; struct dvobj_priv * pcfiodev = (struct dvobj_priv * )(pintfpriv->intf_dev); u32 iobase_addr = pcfiodev->io_base_address; _func_enter_; _enter_hwio_critical(&pintfpriv->rwlock, &irqL); #ifdef PLATFORM_WINDOWS if( addr >= RTL8711_HCICTRL_ && addr <= (RTL8711_HCICTRL_+0x1FFFF) ) { //the address is in HCI local register addr = (addr&0x00003FFF); NdisRawWritePortUshort((u32)(iobase_addr+addr), val); }else{ synccontext.pintfpriv = pintfpriv; synccontext.lbusaddr = addr; synccontext.bytecnt = 2; // 2-byte synccontext.pdata=(u8 *)&val; irqL = KeGetCurrentIrql(); if ( irqL <= DISPATCH_LEVEL ) res = NdisMSynchronizeWithInterrupt(&pcfiodev->interrupt, cfbus_write, (void *)&synccontext); else//IRQL > DISPATCH_LEVEL res = cfbus_write((void *)&synccontext); } #endif _exit_hwio_critical(&pintfpriv->rwlock, &irqL); _func_exit_; }
BOOLEAN LanceHardwareDetails( IN PLANCE_ADAPTER Adapter ) /*++ Routine Description: This routine gets the network address from the hardware. Arguments: Adapter - Where to store the network address. Return Value: TRUE - if successful. --*/ { UCHAR Signature[] = { 0xff, 0x00, 0x55, 0xaa, 0xff, 0x00, 0x55, 0xaa}; UCHAR BytesRead[8]; UINT ReadCount; UINT Place; // // Reset E-PROM state // // To do this we first read from the E-PROM address until the // specific signature is reached (then the next bytes read from // the E-PROM address will be the ethernet address of the card). // // // Read first part of the signature // for (Place=0; Place < 8; Place++){ NdisRawReadPortUchar((ULONG)(Adapter->NetworkHardwareAddress), &(BytesRead[Place])); } ReadCount = 8; // // This advances to the front of the circular buffer. // while (ReadCount < 40) { // // Check if we have read the signature. // for (Place = 0; Place < 8; Place++){ if (BytesRead[Place] != Signature[Place]){ Place = 10; break; } } // // If we have read the signature, stop. // if (Place != 10){ break; } // // else, move all the bytes down one and read then // next byte. // for (Place = 0; Place < 7; Place++){ BytesRead[Place] = BytesRead[Place+1]; } NdisRawReadPortUchar((ULONG)(Adapter->NetworkHardwareAddress), &(BytesRead[7])); ReadCount++; } if (ReadCount == 40){ return(FALSE); } // // Now read the ethernet address of the card. // NdisRawReadPortUchar( (ULONG)(Adapter->NetworkHardwareAddress), &(Adapter->NetworkAddress[0]) ); NdisRawReadPortUchar( (ULONG)(Adapter->NetworkHardwareAddress), &(Adapter->NetworkAddress[1]) ); NdisRawReadPortUchar( (ULONG)(Adapter->NetworkHardwareAddress), &(Adapter->NetworkAddress[2]) ); NdisRawReadPortUchar( (ULONG)(Adapter->NetworkHardwareAddress), &(Adapter->NetworkAddress[3]) ); NdisRawReadPortUchar( (ULONG)(Adapter->NetworkHardwareAddress), &(Adapter->NetworkAddress[4]) ); NdisRawReadPortUchar( (ULONG)(Adapter->NetworkHardwareAddress), &(Adapter->NetworkAddress[5]) ); if (!(Adapter->LanceCard & (LANCE_DE201 | LANCE_DE422))) { if (Adapter->LanceCard == LANCE_DEPCA){ // // Reset Lan Interface port. // NdisRawWritePortUchar( (ULONG)(LANCE_DEPCA_LAN_CFG_OFFSET + Adapter->Nicsr), 0x00); // // Reset Network Interface Control Status Register // NdisRawWritePortUshort((ULONG)(Adapter->Nicsr), 0x00); } return(TRUE); } // // Now do the EPROM Hardware check as outlined in the tech ref. // // // Check for NULL address. // for (Place = 0; Place < 6; Place++) { if (Adapter->NetworkAddress[Place] != 0) { Place = 10; break; } } if (Place != 10) { return(FALSE); } // // Check that bit 0 is not a 1 // if (Adapter->NetworkAddress[0] & 0x1) { return(FALSE); } // // Check that octet[0]->octet[7] == octet[15]->octet[8] // NdisRawReadPortUchar( (ULONG)(Adapter->NetworkHardwareAddress), &(BytesRead[6]) ); NdisRawReadPortUchar( (ULONG)(Adapter->NetworkHardwareAddress), &(BytesRead[7]) ); NdisRawReadPortUchar( (ULONG)(Adapter->NetworkHardwareAddress), &(BytesRead[0]) ); NdisRawReadPortUchar( (ULONG)(Adapter->NetworkHardwareAddress), &(BytesRead[1]) ); if ((BytesRead[7] != BytesRead[0]) || (BytesRead[6] != BytesRead[1])) { return(FALSE); } NdisRawReadPortUchar( (ULONG)(Adapter->NetworkHardwareAddress), &(BytesRead[5]) ); NdisRawReadPortUchar( (ULONG)(Adapter->NetworkHardwareAddress), &(BytesRead[4]) ); NdisRawReadPortUchar( (ULONG)(Adapter->NetworkHardwareAddress), &(BytesRead[3]) ); NdisRawReadPortUchar( (ULONG)(Adapter->NetworkHardwareAddress), &(BytesRead[2]) ); NdisRawReadPortUchar( (ULONG)(Adapter->NetworkHardwareAddress), &(BytesRead[1]) ); NdisRawReadPortUchar( (ULONG)(Adapter->NetworkHardwareAddress), &(BytesRead[0]) ); for (Place = 0; Place < 6; Place++) { if (BytesRead[Place] != (UCHAR)(Adapter->NetworkAddress[Place])) { return(FALSE); } } // // Check that octet[0]->octet[8] == octet[16]->octet[23] // NdisRawReadPortUchar( (ULONG)(Adapter->NetworkHardwareAddress), &(BytesRead[0]) ); NdisRawReadPortUchar( (ULONG)(Adapter->NetworkHardwareAddress), &(BytesRead[1]) ); NdisRawReadPortUchar( (ULONG)(Adapter->NetworkHardwareAddress), &(BytesRead[2]) ); NdisRawReadPortUchar( (ULONG)(Adapter->NetworkHardwareAddress), &(BytesRead[3]) ); NdisRawReadPortUchar( (ULONG)(Adapter->NetworkHardwareAddress), &(BytesRead[4]) ); NdisRawReadPortUchar( (ULONG)(Adapter->NetworkHardwareAddress), &(BytesRead[5]) ); for (Place = 0; Place < 6; Place++) { if (BytesRead[Place] != (UCHAR)(Adapter->NetworkAddress[Place])) { return(FALSE); } } NdisRawReadPortUchar( (ULONG)(Adapter->NetworkHardwareAddress), &(BytesRead[0]) ); NdisRawReadPortUchar( (ULONG)(Adapter->NetworkHardwareAddress), &(BytesRead[1]) ); if ((BytesRead[6] != BytesRead[0]) || (BytesRead[7] != BytesRead[1])) { return(FALSE); } // // Check that octet[24] -> octet[31] == signature bytes // for (Place = 0; Place < 8; Place++){ NdisRawReadPortUchar( (ULONG)(Adapter->NetworkHardwareAddress), &(BytesRead[Place]) ); if (BytesRead[Place] != Signature[Place]){ #if DBG DbgPrint("Lance: Hardware failure\n"); #endif return(FALSE); } } if (Adapter->LanceCard == LANCE_DEPCA){ // // Reset Lan Interface port. // NdisRawWritePortUchar( (ULONG)(LANCE_DEPCA_LAN_CFG_OFFSET + Adapter->Nicsr), 0x00); // // Reset Network Interface Control Status Register // NdisRawWritePortUshort((ULONG)(Adapter->Nicsr), 0x00); } if (Adapter->LanceCard & (LANCE_DE201 | LANCE_DE422)) { // // Reset Network Interface Control Status Register // NdisRawWritePortUshort((ULONG)(Adapter->Nicsr), 0x00); } return(TRUE); }
VOID NTAPI MiniportHandleInterrupt ( IN NDIS_HANDLE MiniportAdapterContext ) { PRTL_ADAPTER adapter = (PRTL_ADAPTER)MiniportAdapterContext; ULONG txStatus; UCHAR command; PPACKET_HEADER nicHeader; PETH_HEADER ethHeader; NdisDprAcquireSpinLock(&adapter->Lock); NDIS_DbgPrint(MAX_TRACE, ("Interrupts pending: 0x%x\n", adapter->InterruptPending)); // // Handle a link change // if (adapter->LinkChange) { NdisDprReleaseSpinLock(&adapter->Lock); NdisMIndicateStatus(adapter->MiniportAdapterHandle, adapter->MediaState == NdisMediaStateConnected ? NDIS_STATUS_MEDIA_CONNECT : NDIS_STATUS_MEDIA_DISCONNECT, NULL, 0); NdisMIndicateStatusComplete(adapter->MiniportAdapterHandle); NdisDprAcquireSpinLock(&adapter->Lock); adapter->LinkChange = FALSE; } // // Handle a TX interrupt // if (adapter->InterruptPending & (R_I_TXOK | R_I_TXERR)) { while (adapter->TxFull || adapter->DirtyTxDesc != adapter->CurrentTxDesc) { NdisRawReadPortUlong(adapter->IoBase + R_TXSTS0 + (adapter->DirtyTxDesc * sizeof(ULONG)), &txStatus); if (!(txStatus & (R_TXS_STATOK | R_TXS_UNDERRUN | R_TXS_ABORTED))) { // // Not sent yet // break; } NDIS_DbgPrint(MAX_TRACE, ("Transmission for desc %d complete: 0x%x\n", adapter->DirtyTxDesc, txStatus)); if (txStatus & R_TXS_STATOK) { adapter->TransmitOk++; } else { adapter->TransmitError++; } adapter->DirtyTxDesc++; adapter->DirtyTxDesc %= TX_DESC_COUNT; adapter->InterruptPending &= ~(R_I_TXOK | R_I_TXERR); adapter->TxFull = FALSE; } } // // Handle a good RX interrupt // if (adapter->InterruptPending & (R_I_RXOK | R_I_RXERR)) { for (;;) { NdisRawReadPortUchar(adapter->IoBase + R_CMD, &command); if (command & R_CMD_RXEMPTY) { // // The buffer is empty // adapter->InterruptPending &= ~(R_I_RXOK | R_I_RXERR); break; } adapter->ReceiveOffset %= RECEIVE_BUFFER_SIZE; NDIS_DbgPrint(MAX_TRACE, ("Looking for a packet at offset 0x%x\n", adapter->ReceiveOffset)); nicHeader = (PPACKET_HEADER)(adapter->ReceiveBuffer + adapter->ReceiveOffset); if (!(nicHeader->Status & RSR_ROK)) { // // Receive failed // NDIS_DbgPrint(MIN_TRACE, ("Receive failed: 0x%x\n", nicHeader->Status)); if (nicHeader->Status & RSR_FAE) { adapter->ReceiveAlignmentError++; } else if (nicHeader->Status & RSR_CRC) { adapter->ReceiveCrcError++; } adapter->ReceiveError++; goto NextPacket; } NDIS_DbgPrint(MAX_TRACE, ("Indicating %d byte packet to NDIS\n", nicHeader->PacketLength - RECV_CRC_LENGTH)); ethHeader = (PETH_HEADER)(nicHeader + 1); NdisMEthIndicateReceive(adapter->MiniportAdapterHandle, NULL, (PVOID)(ethHeader), sizeof(ETH_HEADER), (PVOID)(ethHeader + 1), nicHeader->PacketLength - sizeof(ETH_HEADER) - RECV_CRC_LENGTH, nicHeader->PacketLength - sizeof(ETH_HEADER) - RECV_CRC_LENGTH); adapter->ReceiveOk++; NextPacket: adapter->ReceiveOffset += nicHeader->PacketLength + sizeof(PACKET_HEADER); adapter->ReceiveOffset = (adapter->ReceiveOffset + 3) & ~3; NdisRawWritePortUshort(adapter->IoBase + R_CAPR, adapter->ReceiveOffset - 0x10); if (adapter->InterruptPending & (R_I_RXOVRFLW | R_I_FIFOOVR)) { // // We can only clear these interrupts once CAPR has been reset // NdisRawWritePortUshort(adapter->IoBase + R_IS, R_I_RXOVRFLW | R_I_FIFOOVR); adapter->InterruptPending &= ~(R_I_RXOVRFLW | R_I_FIFOOVR); } } NdisMEthIndicateReceiveComplete(adapter->MiniportAdapterHandle); } NdisDprReleaseSpinLock(&adapter->Lock); }
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // // Routine Name: NetFlexHandleInterrupt // // Description: // This routine is the deferred processing // routine for all adapter interrupts. // // Input: // acb - Our Driver Context for this adapter or head. // // Output: // None // // Called By: // Miniport Wrapper // //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ VOID NetFlexHandleInterrupt( IN NDIS_HANDLE MiniportAdapterContext ) { USHORT sifint_reg; USHORT tmp_reg; USHORT ReceivesProcessed = 0; PACB acb = (PACB) MiniportAdapterContext; // // Read the SifInt // NdisRawReadPortUshort( acb->SifIntPort, &sifint_reg); while (sifint_reg & SIFINT_SYSINT) { // // Ack the interrupt // sifint_reg &= ~SIFINT_SYSINT; NdisRawWritePortUshort( acb->SifIntPort, sifint_reg); // // mask off the int code // sifint_reg &= INT_CODES; // // See if there are any recieves to do... // if (acb->acb_rcv_head->RCV_CSTAT & RCSTAT_COMPLETE) { // // Increment the interrupt count. // acb->acb_int_count++; // // yes, do them... // acb->handled_interrupts++; ReceivesProcessed += acb->ProcessReceiveHandler(acb); } // // See if there are any transmits to do... // NetFlexProcessXmit(acb); switch (sifint_reg) { case INT_SCBCLEAR: acb->acb_scbclearout = FALSE; // // Is the SCB really clear? // // If the SCB is clear, send a SCB command off now. // Otherwise, if we are not currently waiting for an SCB clear // interrupt, signal the adapter to send us a SCB clear interrupt // when it is done with the SCB. // if (acb->acb_scb_virtptr->SCB_Cmd == 0) { NetFlexSendNextSCB(acb); } else if ((acb->acb_xmit_whead) || (acb->acb_rcv_whead) || (acb->acb_scbreq_next)) { acb->acb_scbclearout = TRUE; NdisRawWritePortUshort( acb->SifIntPort, (USHORT)SIFINT_SCBREQST); } break; case INT_COMMAND: NetFlexCommand(acb); // // Do we have any commands to complete? // if (acb->acb_confirm_qhead != NULL) { NetFlexProcessMacReq(acb); } break; case INT_ADPCHECK: // // Read the Adapter Check Status @ 1.05e0 // NdisRawWritePortUshort(acb->SifAddrxPort, (USHORT) 1); NdisRawWritePortUshort(acb->SifAddrPort, (USHORT) 0x5e0); NdisRawReadPortUshort( acb->SifDIncPort, &tmp_reg); DebugPrint(1,("NF(%d): Adapter Check - 0x%x\n",acb->anum,tmp_reg)); // // Reset has failed, errorlog an entry. // NdisWriteErrorLogEntry( acb->acb_handle, EVENT_NDIS_ADAPTER_CHECK_ERROR, 2, NETFLEX_ADAPTERCHECK_ERROR_CODE, tmp_reg ); // // Set the variables up showing that the hardware has an unrecoverable // error. // acb->acb_state = AS_HARDERROR; break; case INT_RINGSTAT: NetFlexRingStatus(acb); break; case INT_RECEIVE: break; case INT_TRANSMIT: // // If we reached the end of the xmit lists, // then the xmit status will indicate COMMAND_COMPLETE. // The transmiter will be stalled until another transmit // command is issued with a valid list. // if (acb->acb_ssb_virtptr->SSB_Status & XSTAT_LERROR) { // // We have a list error... // NetFlexTransmitStatus(acb); } default: break; } // // Issue a ssb clear. After this we may see SIFCMD interrupts. // NdisRawWritePortUshort(acb->SifIntPort, SIFINT_SSBCLEAR); // // Read the SifInt // NdisRawReadPortUshort(acb->SifIntPort, &sifint_reg); } // // Processed any receives which need IndicateReceiveComplete? // if (ReceivesProcessed) { if (acb->acb_gen_objs.media_type_in_use == NdisMedium802_5) { // Token Ring // NdisMTrIndicateReceiveComplete(acb->acb_handle); } else { // Ethernet // NdisMEthIndicateReceiveComplete(acb->acb_handle); } } }
PU8 C_DM9000::DeviceWriteString( PU8 ptrBuffer, int nLength) { int count; count = (nLength + m_nIoMaxPad) / m_nIoMode; #if defined(PREEMPTIVE_TX_WRITE) switch (m_nIoMode) { case BYTE_MODE: { PU8 pcurr=(PU8)ptrBuffer; for(;count--;pcurr++) { ENTER_CRITICAL_SECTION VALIDATE_ADDR_PORT(DM9_MWCMD); NdisRawWritePortUchar( m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, *pcurr); LEAVE_CRITICAL_SECTION } } break; case WORD_MODE: { PU16 pcurr=(PU16)ptrBuffer; for(;count--;pcurr++) { ENTER_CRITICAL_SECTION VALIDATE_ADDR_PORT(DM9_MWCMD); NdisRawWritePortUshort( m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, *pcurr); LEAVE_CRITICAL_SECTION } } break; case DWORD_MODE: { PU32 pcurr=(PU32)ptrBuffer; for(;count--;pcurr++) { ENTER_CRITICAL_SECTION VALIDATE_ADDR_PORT(DM9_MWCMD); NdisRawWritePortUlong( m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, *pcurr); LEAVE_CRITICAL_SECTION } } break; default: break; } // of switch #else // !PREEMPTIVE_TX_WRITE // select port to be read from ENTER_CRITICAL_SECTION VALIDATE_ADDR_PORT(DM9_MWCMD); switch (m_nIoMode) { case BYTE_MODE: NdisRawWritePortBufferUchar( m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, ptrBuffer,count); break; case WORD_MODE: NdisRawWritePortBufferUshort( m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, (PU16)ptrBuffer,count); break; case DWORD_MODE: NdisRawWritePortBufferUlong( m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, (PU32)ptrBuffer,count); break; default: break; } // of switch LEAVE_CRITICAL_SECTION #endif return ptrBuffer; }