U32 C_DM9000::DeviceReadDataWithoutIncrement(void) { U32 value,tmp; ENTER_CRITICAL_SECTION VALIDATE_ADDR_PORT(DM9_MRCMDX); switch (m_nIoMode) { case BYTE_MODE: NdisRawReadPortUchar( m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, (PU8)&tmp); NdisRawReadPortUchar( m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, (PU8)&value); value = (value&0x000000FF); break; case WORD_MODE: NdisRawReadPortUshort( m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, (PU16)&tmp); NdisRawReadPortUshort( m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, (PU16)&value); value = (value&0x0000FFFF); break; case DWORD_MODE: NdisRawReadPortUlong( m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, (PU32)&tmp); NdisRawReadPortUlong( m_szCurrentSettings[SID_PORT_BASE_ADDRESS] + DM9000_DATA_OFFSET, (PU32)&value); break; default: break; } // of switch LEAVE_CRITICAL_SECTION return value; }
VOID NTAPI MiniportISR ( OUT PBOOLEAN InterruptRecognized, OUT PBOOLEAN QueueMiniportHandleInterrupt, IN NDIS_HANDLE MiniportAdapterContext ) { PRTL_ADAPTER adapter = (PRTL_ADAPTER)MiniportAdapterContext; ULONG csConfig; // // FIXME: We need to synchronize with this ISR for changes to InterruptPending, // LinkChange, MediaState, and LinkSpeedMbps. We can get away with IRQL // synchronization on non-SMP machines because we run a DIRQL here. // adapter->InterruptPending |= NICInterruptRecognized(adapter, InterruptRecognized); if (!(*InterruptRecognized)) { // // This is not ours. // *QueueMiniportHandleInterrupt = FALSE; return; } // // We have to check for a special link change interrupt before acknowledging // if (adapter->InterruptPending & R_I_RXUNDRUN) { NdisRawReadPortUlong(adapter->IoBase + R_CSCFG, &csConfig); if (csConfig & R_CSCR_LINKCHNG) { adapter->LinkChange = TRUE; NICUpdateLinkStatus(adapter); } } // // Acknowledge the interrupt and mark the events pending service // NICAcknowledgeInterrupts(adapter); *QueueMiniportHandleInterrupt = TRUE; }
u32 cf_read32(struct intf_hdl *pintfhdl, u32 addr) { _irqL irqL; uint res; u32 val; 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); NdisRawReadPortUlong((u32)(iobase_addr+addr), (u32 *)&val); }else{ synccontext.pintfpriv = pintfpriv; synccontext.lbusaddr = addr; synccontext.bytecnt = 4; // 4-byte synccontext.pdata=(u8 *)&val; irqL = KeGetCurrentIrql(); if ( irqL <= DISPATCH_LEVEL ) res = NdisMSynchronizeWithInterrupt(&pcfiodev->interrupt, cfbus_read, (void *)&synccontext); else//IRQL > DISPATCH_LEVEL res = cfbus_read((void *)&synccontext); } #endif _exit_hwio_critical(&pintfpriv->rwlock, &irqL); _func_exit_; return val; }
void cf_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem) { _irqL irqL; u32 i, r_cnt, loop_cnt; struct intf_priv *pintfpriv = pintfhdl->pintfpriv; u32 *pdata = (u32 *)rmem; u32 maxlen = pintfpriv->max_recvsz; struct dvobj_priv * pcfiodev = (struct dvobj_priv * )(pintfpriv->intf_dev); u32 iobase_addr = pcfiodev->io_base_address; // Please remember, you just can't only use lock/unlock to // protect the rw functions... // since, i/o is quite common in call-back and isr routines... _func_enter_; if ((cnt == 0) || (addr != HRFF0DR)) return; #ifdef PLATFORM_WINDOWS addr = (addr&0x00003FFF);//Convert addr to CFIO Interface local offset addr do { r_cnt = (cnt > maxlen) ? maxlen: cnt;//actually cnt must be <= maxlen loop_cnt = (r_cnt/4) + (((r_cnt%4) >0)?1:0); for(i=0; i<loop_cnt; i++) { NdisRawReadPortUlong((u32)(iobase_addr+addr), (u32 *)pdata); pdata++; } cnt -= r_cnt; }while(cnt > 0); #endif _func_exit_; return; }
static uint cfbus_read(void *context) { #ifdef PLATFORM_WINDOWS u32 iobase_addr, len, addr, HAARValue, Read_Data; u8 *pdata; USHORT readCF_HAAR; u32 counter=0; struct _SyncContext *psynccontext = (struct _SyncContext *)context; struct intf_priv *pintfpriv = (struct intf_priv *)psynccontext->pintfpriv; struct dvobj_priv * pcfiodev = (struct dvobj_priv *)pintfpriv->intf_dev; //u8 *rwmem = (u8 *)pintfpriv->rw_mem; iobase_addr = pcfiodev->io_base_address; len = psynccontext ->bytecnt; addr = psynccontext->lbusaddr; pdata = psynccontext->pdata; _func_enter_; //if the address is in HCI local register, to skip it if( addr >= RTL8711_HCICTRL_ && addr <= (RTL8711_HCICTRL_+0x1FFFF) ) { _func_exit_; return _FAIL; } HAARValue = HAARSetting(len, IO_READ, addr); // 1.Write HAAR NdisRawWritePortUlong( (ULONG)(iobase_addr+HAAR), HAARValue); // 2.Polling HAAR Ready do { if(counter > HAAR_POLLING_CNT){ //RT_TRACE(COMP_DBG, DBG_LOUD, ("\n\nCFIOReadReg: Poll HAAR Ready too long, LBus = 0x%X checkRegRWCnt(1) = %d currentIRQL = %x, read HAAR=%x, HAARValue=%x.\n\n",c->LexraBusAddr, checkRegRWCnt, currentIRQL, test32, HAARValue )); _func_exit_; return _FAIL; } if(addr == CR9346) NdisStallExecution(50); //Considering CFIO default mode is 16-bit mode, we use 16-bit reading NdisRawReadPortUshort( (ULONG)(iobase_addr+HAAR+0x0002), &readCF_HAAR); counter++; }while(((readCF_HAAR >> 14) & 0x3) != 0x3); //while READY has not been set // 3.Read HRADR NdisRawReadPortUlong( (ULONG)(iobase_addr+HRADR), (ULONG *)&Read_Data); NdisMoveMemory(pdata , (u8 *)&Read_Data, len); #endif _func_exit_; return _SUCCESS; }
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); }