📄 rclanmtl.c
字号:
pPab->pRebootCallbackFunc = RebootCallbackFunction; pPab->pCallbackFunc = (PFNCALLBACK)NULL; /* ** Initialize I2O IOP */ result = GetI2OStatus(pPab); if (result != RC_RTN_NO_ERROR) return result; if (pPab->IOPState == I2O_IOP_STATE_OPERATIONAL) { printk("pPab->IOPState == op: resetting adapter\n"); RCResetLANCard(AdapterID, 0, (PU32)NULL, (PFNCALLBACK)NULL); } result = SendI2OOutboundQInitMsg(pPab); if (result != RC_RTN_NO_ERROR) return result; result = SendEnableSysMsg(pPab); if (result != RC_RTN_NO_ERROR) return result; PCIAdapterBlock[AdapterID] = pPab; return RC_RTN_NO_ERROR;}/*** =========================================================================** Disable and Enable I2O interrupts. I2O interrupts are enabled at Init time** but can be disabled and re-enabled through these two function calls.** Packets will still be put into any posted received buffers and packets will** be sent through RCI2OSendPacket() functions. Disabling I2O interrupts** will prevent hardware interrupt to host even though the outbound I2O msg** queue is not emtpy.** =========================================================================*/#define i960_OUT_POST_Q_INT_BIT 0x0008 /* bit set masks interrupts */RC_RETURN RCDisableI2OInterrupts(U16 AdapterID){ PPAB pPab; pPab = PCIAdapterBlock[AdapterID]; if (pPab == NULL) return RC_RTN_ADPTR_NOT_REGISTERED; pPab->p_atu->OutIntMask |= i960_OUT_POST_Q_INT_BIT; return RC_RTN_NO_ERROR;}RC_RETURN RCEnableI2OInterrupts(U16 AdapterID){ PPAB pPab; pPab = PCIAdapterBlock[AdapterID]; if (pPab == NULL) return RC_RTN_ADPTR_NOT_REGISTERED; pPab->p_atu->OutIntMask &= ~i960_OUT_POST_Q_INT_BIT; return RC_RTN_NO_ERROR;}/*** =========================================================================** RCI2OSendPacket()** =========================================================================*/RC_RETURNRCI2OSendPacket(U16 AdapterID, U32 InitiatorContext, PRCTCB pTransCtrlBlock){ U32 msgOffset; PU32 pMsg; int size; PPAB pPab;#ifdef DEBUG kprintf("RCI2OSendPacket()...\n");#endif /* DEBUG */ pPab = PCIAdapterBlock[AdapterID]; if (pPab == NULL) return RC_RTN_ADPTR_NOT_REGISTERED; /* get Inbound free Q entry - reading from In Q gets free Q entry */ /* offset to Msg Frame in PCI msg block */ msgOffset = pPab->p_atu->InQueue; if (msgOffset == 0xFFFFFFFF) {#ifdef DEBUG kprintf("RCI2OSendPacket(): Inbound Free Q empty!\n");#endif /* DEBUG */ return RC_RTN_FREE_Q_EMPTY; } /* calc virual address of msg - virual already mapped to physical */ pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset); size = FillI2OMsgSGLFromTCB(pMsg + 4, pTransCtrlBlock); if (size == -1) /* error processing TCB - send NOP msg */ {#ifdef DEBUG kprintf("RCI2OSendPacket(): Error Rrocess TCB!\n");#endif /* DEBUG */ pMsg[0] = THREE_WORD_MSG_SIZE | SGL_OFFSET_0; pMsg[1] = I2O_UTIL_NOP << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID; return RC_RTN_TCB_ERROR; } else /* send over msg header */ { pMsg[0] = (size + 4) << 16 | LAN_MSG_REQST; /* send over message size and flags */ pMsg[1] = I2O_LAN_PACKET_SEND << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID; pMsg[2] = InitiatorContext; pMsg[3] = 0; /* batch reply */ /* post to Inbound Post Q */ pPab->p_atu->InQueue = msgOffset; return RC_RTN_NO_ERROR; }} /*** =========================================================================** RCI2OPostRecvBuffer()**** inputs: pBufrCntrlBlock - pointer to buffer control block**** returns TRUE if successful in sending message, else FALSE.** =========================================================================*/RC_RETURNRCPostRecvBuffers(U16 AdapterID, PRCTCB pTransCtrlBlock){ U32 msgOffset; PU32 pMsg; int size; PPAB pPab;#ifdef DEBUG kprintf("RCPostRecvBuffers()...\n");#endif /* DEBUG */ /* search for DeviceHandle */ pPab = PCIAdapterBlock[AdapterID]; if (pPab == NULL) return RC_RTN_ADPTR_NOT_REGISTERED; /* get Inbound free Q entry - reading from In Q gets free Q entry */ /* offset to Msg Frame in PCI msg block */ msgOffset = pPab->p_atu->InQueue; if (msgOffset == 0xFFFFFFFF) {#ifdef DEBUG kprintf("RCPostRecvBuffers(): Inbound Free Q empty!\n");#endif /* DEBUG */ return RC_RTN_FREE_Q_EMPTY; } /* calc virual address of msg - virual already mapped to physical */ pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset); size = FillI2OMsgSGLFromTCB(pMsg + 4, pTransCtrlBlock); if (size == -1) /* error prcessing TCB - send 3 DWORD private msg == NOP */ {#ifdef DEBUG kprintf("RCPostRecvBuffers(): Error Processing TCB! size = %d\n", size);#endif /* DEBUG */ pMsg[0] = THREE_WORD_MSG_SIZE | SGL_OFFSET_0; pMsg[1] = I2O_UTIL_NOP << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID; /* post to Post Q */ pPab->p_atu->InQueue = msgOffset; return RC_RTN_TCB_ERROR; } else /* send over size msg header */ { pMsg[0] = (size + 4) << 16 | LAN_MSG_REQST; /* send over message size and flags */ pMsg[1] = I2O_LAN_RECEIVE_POST << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID; pMsg[2] = DEFAULT_RECV_INIT_CONTEXT; pMsg[3] = *(PU32)pTransCtrlBlock; /* number of packet buffers */ /* post to Post Q */ pPab->p_atu->InQueue = msgOffset; return RC_RTN_NO_ERROR; }}/*** =========================================================================** RCProcI2OMsgQ()**** Process I2O outbound message queue until empty.** =========================================================================*/void RCProcI2OMsgQ(U16 AdapterID){ U32 phyAddrMsg; PU8 p8Msg; PU32 p32; U16 count; PPAB pPab; unsigned char debug_msg[20]; pPab = PCIAdapterBlock[AdapterID]; if (pPab == NULL) return; phyAddrMsg = pPab->p_atu->OutQueue; while (phyAddrMsg != 0xFFFFFFFF) { p8Msg = pPab->pLinOutMsgBlock + (phyAddrMsg - pPab->outMsgBlockPhyAddr); p32 = (PU32)p8Msg; //printk(" msg: 0x%x 0x%x \n", p8Msg[7], p32[5]); /* ** Send Packet Reply Msg */ if (I2O_LAN_PACKET_SEND == p8Msg[7]) /* function code byte */ { count = *(PU16)(p8Msg+2); count -= p8Msg[0] >> 4; /* status, count, context[], adapter */ (*pPab->pTransCallbackFunc)(p8Msg[19], count, p32+5, AdapterID); } /* ** Receive Packet Reply Msg */ else if (I2O_LAN_RECEIVE_POST == p8Msg[7]) {#ifdef DEBUG kprintf("I2O_RECV_REPLY pPab:0x%08.8ulx p8Msg:0x%08.8ulx p32:0x%08.8ulx\n", pPab, p8Msg, p32); kprintf("msg: 0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[0], p32[1], p32[2], p32[3]); kprintf(" 0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[4], p32[5], p32[6], p32[7]); kprintf(" 0x%08.8ulx:0X%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[8], p32[9], p32[10], p32[11]);#endif /* status, count, buckets remaining, packetParmBlock, adapter */ (*pPab->pRecvCallbackFunc)(p8Msg[19], p8Msg[12], p32[5], p32+6, AdapterID); } else if (I2O_LAN_RESET == p8Msg[7] || I2O_LAN_SHUTDOWN == p8Msg[7]) { if (pPab->pCallbackFunc) { (*pPab->pCallbackFunc)(p8Msg[19],0,0,AdapterID); } else { pPab->pCallbackFunc = (PFNCALLBACK) 1; } //PCIAdapterBlock[AdapterID] = 0; } else if (I2O_PRIVATE == p8Msg[7]) { //printk("i2o private 0x%x, 0x%x \n", p8Msg[7], p32[5]); switch (p32[5]) { case RC_PRIVATE_DEBUG_MSG: msgFlag = 1; /*printk("Received I2O_PRIVATE msg\n");*/ debug_msg[15] = (p32[6]&0xff000000) >> 24; debug_msg[14] = (p32[6]&0x00ff0000) >> 16; debug_msg[13] = (p32[6]&0x0000ff00) >> 8; debug_msg[12] = (p32[6]&0x000000ff); debug_msg[11] = (p32[7]&0xff000000) >> 24; debug_msg[10] = (p32[7]&0x00ff0000) >> 16; debug_msg[ 9] = (p32[7]&0x0000ff00) >> 8; debug_msg[ 8] = (p32[7]&0x000000ff); debug_msg[ 7] = (p32[8]&0xff000000) >> 24; debug_msg[ 6] = (p32[8]&0x00ff0000) >> 16; debug_msg[ 5] = (p32[8]&0x0000ff00) >> 8; debug_msg[ 4] = (p32[8]&0x000000ff); debug_msg[ 3] = (p32[9]&0xff000000) >> 24; debug_msg[ 2] = (p32[9]&0x00ff0000) >> 16; debug_msg[ 1] = (p32[9]&0x0000ff00) >> 8; debug_msg[ 0] = (p32[9]&0x000000ff); debug_msg[16] = '\0'; printk (debug_msg); break; case RC_PRIVATE_REBOOT: printk("Adapter reboot initiated...\n"); if (pPab->pRebootCallbackFunc) { (*pPab->pRebootCallbackFunc)(0,0,0,AdapterID); } break; default: printk("Unknown private I2O msg received: 0x%lx\n", p32[5]); break; } } /* ** Process other Msg's */ else { ProcessOutboundI2OMsg(pPab, phyAddrMsg); } /* return MFA to outbound free Q*/ pPab->p_atu->OutQueue = phyAddrMsg; /* any more msgs? */ phyAddrMsg = pPab->p_atu->OutQueue; }}/*** =========================================================================** Returns LAN interface statistical counters to space provided by caller at** StatsReturnAddr. Returns 0 if success, else RC_RETURN code.** This function will call the WaitCallback function provided by** user while waiting for card to respond.** =========================================================================*/RC_RETURNRCGetLinkStatistics(U16 AdapterID, P_RCLINKSTATS StatsReturnAddr, PFNWAITCALLBACK WaitCallback){ U32 msgOffset; volatile U32 timeout; volatile PU32 pMsg; volatile PU32 p32, pReturnAddr; P_NICSTAT pStats; int i; PPAB pPab;/*kprintf("Get82558Stats() StatsReturnAddr:0x%08.8ulx\n", StatsReturnAddr);*/ pPab = PCIAdapterBlock[AdapterID]; if (pPab == NULL) return RC_RTN_ADPTR_NOT_REGISTERED; msgOffset = pPab->p_atu->InQueue; if (msgOffset == 0xFFFFFFFF) {#ifdef DEBUG kprintf("Get8255XStats(): Inbound Free Q empty!\n");#endif return RC_RTN_FREE_Q_EMPTY; } /* calc virual address of msg - virual already mapped to physical */ pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);/*dprintf("Get82558Stats - pMsg = 0x%08ulx, InQ msgOffset = 0x%08ulx\n", pMsg, msgOffset);*//*dprintf("Get82558Stats - pMsg = 0x%08X, InQ msgOffset = 0x%08X\n", pMsg, msgOffset);*/ pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0; pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID; pMsg[2] = DEFAULT_RECV_INIT_CONTEXT; pMsg[3] = 0x112; /* transaction context */ pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_NIC_STATS; pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB); p32 = (PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB)); pStats = (P_NICSTAT)p32; pStats->dump_status = 0xFFFFFFFF; /* post to Inbound Post Q */ pPab->p_atu->InQueue = msgOffset; timeout = 100000; while (1) { if (WaitCallback) (*WaitCallback)(); for (i = 0; i < 1000; i++) ; if (pStats->dump_status != 0xFFFFFFFF) break; if (!timeout--) {#ifdef DEBUG kprintf("RCGet82558Stats() Timeout waiting for NIC statistics\n");#endif return RC_RTN_MSG_REPLY_TIMEOUT; } } pReturnAddr = (PU32)StatsReturnAddr; /* copy Nic stats to user's structure */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -