📄 rclanmtl.c
字号:
PU32 pMsg; int size; PPAB pPab = ((PDPA) dev->priv)->pPab; dprintk ("RCPostRecvBuffers()...\n"); /* search for DeviceHandle */ 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) { dprintk ("RCPostRecvBuffers(): Inbound Free Q empty!\n"); return RC_RTN_FREE_Q_EMPTY; } /* calc virtual address of msg - virtual 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 */ dprintk ("RCPostRecvBuffers(): Error Processing TCB! size = %d\n", size); 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.** =========================================================================*/voidRCProcI2OMsgQ (struct net_device *dev){ U32 phyAddrMsg; PU8 p8Msg; PU32 p32; U16 count; PPAB pPab = ((PDPA) dev->priv)->pPab; unsigned char debug_msg[20]; if (pPab == NULL) return; phyAddrMsg = pPab->p_atu->OutQueue; while (phyAddrMsg != 0xFFFFFFFF) { p8Msg = pPab->pLinOutMsgBlock + (phyAddrMsg - pPab->outMsgBlockPhyAddr); p32 = (PU32) p8Msg; dprintk ("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, dev); } else if (I2O_LAN_RECEIVE_POST == p8Msg[7]) { /* Receive Packet Reply Msg */ dprintk ("I2O_RECV_REPLY pPab:0x%x p8Msg:0x%x p32:0x%x\n", (u32) pPab, (u32) p8Msg, (u32) p32); dprintk ("msg: 0x%x:0x%x:0x%x:0x%x\n", p32[0], p32[1], p32[2], p32[3]); dprintk (" 0x%x:0x%x:0x%x:0x%x\n", p32[4], p32[5], p32[6], p32[7]); dprintk (" 0x%x:0X%x:0x%x:0x%x\n", p32[8], p32[9], p32[10], p32[11]); /* status, count, buckets remaining, packetParmBlock, adapter */ (*pPab->pRecvCallbackFunc) (p8Msg[19], p8Msg[12], p32[5], p32 + 6, dev); } else if (I2O_LAN_RESET == p8Msg[7] || I2O_LAN_SHUTDOWN == p8Msg[7]) if (pPab->pCallbackFunc) (*pPab->pCallbackFunc) (p8Msg[19], 0, 0, dev); else pPab->pCallbackFunc = (PFNCALLBACK) 1; else if (I2O_PRIVATE == p8Msg[7]) { dprintk ("i2o private 0x%x, 0x%x \n", p8Msg[7], p32[5]); switch (p32[5]) { case RC_PRIVATE_DEBUG_MSG: msgFlag = 1; dprintk ("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'; dprintk ("%s", debug_msg); break; case RC_PRIVATE_REBOOT: dprintk ("Adapter reboot initiated...\n"); if (pPab->pRebootCallbackFunc) (*pPab->pRebootCallbackFunc) (0, 0, 0, dev); break; default: dprintk (KERN_WARNING "Unknown private I2O msg received: 0x%x\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 (struct net_device *dev, P_RCLINKSTATS StatsReturnAddr, PFNWAITCALLBACK WaitCallback){ U32 msgOffset; volatile PU32 pMsg; volatile PU32 p32, pReturnAddr; P_NICSTAT pStats; int i; PPAB pPab = ((PDPA) dev->priv)->pPab;/*dprintk("Get82558Stats() StatsReturnAddr:0x%x\n", StatsReturnAddr); */ if (pPab == NULL) return RC_RTN_ADPTR_NOT_REGISTERED; msgOffset = pPab->p_atu->InQueue; if (msgOffset == 0xFFFFFFFF) { dprintk ("Get8255XStats(): Inbound Free Q empty!\n"); return RC_RTN_FREE_Q_EMPTY; } /* calc virtual address of msg - virtual already mapped to physical */ pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);/*dprintk("Get82558Stats - pMsg = 0x%x, InQ msgOffset = 0x%x\n", pMsg, msgOffset);*//*dprintk("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;// p32 = (PU32) pPab->outMsgBlockPhyAddr; p32 = (PU32)pPab->pLinOutMsgBlock; pStats = (P_NICSTAT) pPab->pLinOutMsgBlock; pStats->dump_status = 0xFFFFFFFF; /* post to Inbound Post Q */ pPab->p_atu->InQueue = msgOffset; i = 0; while (pStats->dump_status == 0xFFFFFFFF) { if (i++ > 0xff) { dprintk ("Timeout waiting for NIC statistics\n"); return RC_RTN_MSG_REPLY_TIMEOUT; } udelay(50); } pReturnAddr = (PU32) StatsReturnAddr; /* copy Nic stats to user's structure */ for (i = 0; i < (int) sizeof (RCLINKSTATS) / 4; i++) pReturnAddr[i] = p32[i]; return RC_RTN_NO_ERROR;}/*** =========================================================================** Get82558LinkStatus()** =========================================================================*/RC_RETURNRCGetLinkStatus (struct net_device * dev, PU32 ReturnAddr, PFNWAITCALLBACK WaitCallback){ int i; U32 msgOffset; volatile PU32 pMsg; volatile PU32 p32; PPAB pPab = ((PDPA) dev->priv)->pPab; dprintk ("Get82558LinkStatus() ReturnPhysAddr:0x%x\n", (u32) ReturnAddr); if (pPab == NULL) return RC_RTN_ADPTR_NOT_REGISTERED; msgOffset = pPab->p_atu->InQueue; if (msgOffset == 0xFFFFFFFF) { dprintk ("Get82558LinkStatus(): Inbound Free Q empty!\n"); return RC_RTN_FREE_Q_EMPTY; } /* calc virtual address of msg - virtual already mapped to physical */ pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);/*dprintk("Get82558LinkStatus - pMsg = 0x%x, InQ msgOffset = 0x%x\n", pMsg, msgOffset);*//*dprintk("Get82558LinkStatus - 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_LINK_STATUS; pMsg[5] = pPab->outMsgBlockPhyAddr; p32 = (PU32) pPab->pLinOutMsgBlock; *p32 = 0xFFFFFFFF; /* post to Inbound Post Q */ pPab->p_atu->InQueue = msgOffset; i = 0; while (*p32 == 0xFFFFFFFF) { if (i++ > 0xff) { dprintk ("Timeout waiting for link status\n"); return RC_RTN_MSG_REPLY_TIMEOUT; } udelay(50); } *ReturnAddr = *p32; /* 1 = up 0 = down */ return RC_RTN_NO_ERROR;}/*** =========================================================================** RCGetMAC()**** get the MAC address the adapter is listening for in non-promiscous mode.** MAC address is in media format.** =========================================================================*/RC_RETURNRCGetMAC (struct net_device * dev, PFNWAITCALLBACK WaitCallback){ U32 off, i; PU8 mac = dev->dev_addr; PU32 p; U32 temp[2]; PPAB pPab = ((PDPA) dev->priv)->pPab; PATU p_atu; if (pPab == NULL) return RC_RTN_ADPTR_NOT_REGISTERED; p_atu = pPab->p_atu; p_atu->EtherMacLow = 0; /* first zero return data */ p_atu->EtherMacHi = 0; off = p_atu->InQueue; /* get addresss of message */ if (0xFFFFFFFF == off) return RC_RTN_FREE_Q_EMPTY; p = (PU32) (pPab->pPci45LinBaseAddr + off); dprintk ("RCGetMAC: p_atu 0x%08x, off 0x%08x, p 0x%08x\n", (uint) p_atu, (uint) off, (uint) p); /* setup private message */ p[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0; p[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID; p[2] = 0; /* initiator context */ p[3] = 0x218; /* transaction context */ p[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_MAC_ADDR; p_atu->InQueue = off; /* send it to the I2O device */ dprintk ("RCGetMAC: p_atu 0x%08x, off 0x%08x, p 0x%08x\n", (uint) p_atu, (uint) off, (uint) p); /* wait for the rcpci45 board to update the info */ i = 0; while (0 == p_atu->EtherMacLow) { if (i++ > 0xff) { dprintk ("rc_getmac: Timeout\n"); return RC_RTN_MSG_REPLY_TIMEOUT; } udelay(50); } /* read the mac address */ temp[0] = p_atu->EtherMacLow; temp[1] = p_atu->EtherMacHi; memcpy ((char *) mac, (char *) temp, 6); dprintk ("rc_getmac: 0x%x\n", (u32) mac); return RC_RTN_NO_ERROR;}/*** =========================================================================** RCSetMAC()**** set MAC address the adapter is listening for in non-promiscous mode.** MAC address is in media format.** =========================================================================*/RC_RETURNRCSetMAC (struct net_device * dev, PU8 mac){ U32 off; PU32 pMsg; PPAB pPab = ((PDPA) dev->priv)->pPab; if (pPab == NULL) return RC_RTN_ADPTR_NOT_REGISTERED; off = pPab->p_atu->InQueue; /* get addresss of message */ if (0xFFFFFFFF == off) return RC_RTN_FREE_Q_EMPTY; pMsg = (PU32) (pPab->pPci45LinBaseAddr + off); /* setup private message */ pMsg[0] = SEVEN_WORD_MSG_SIZE | SGL_OFFSET_0; pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID; pMsg[2] = 0; /* initiator context */ pMsg[3] = 0x219; /* transaction context */ pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_MAC_ADDR; pMsg[5] = *(unsigned *) mac; /* first four bytes */ pMsg[6] = *(unsigned *) (mac + 4); /* last two bytes */ pPab->p_atu->InQueue = off; /* send it to the I2O device */ return RC_RTN_NO_ERROR;}/*** =========================================================================** RCSetLinkSpeed()**** set ethernet link speed. ** input: speedControl - determines action to take as follows** 0 = reset and auto-negotiate (NWay)** 1 = Full Duplex 100BaseT** 2 = Half duplex 100BaseT** 3 = Full Duplex 10BaseT** 4 = Half duplex 10BaseT** all other values are ignore (do nothing)** =========================================================================*/RC_RETURNRCSetLinkSpeed (struct net_device * dev, U16 LinkSpeedCode){ U32 off; PU32 pMsg; PPAB pPab = ((PDPA) dev->priv)->pPab; if (pPab == NULL) return RC_RTN_ADPTR_NOT_REGISTERED; off = pPab->p_atu->InQueue; /* get addresss of message */ if (0xFFFFFFFF == off) return RC_RTN_FREE_Q_EMPTY; pMsg = (PU32) (pPab->pPci45LinBaseAddr + off); /* setup private message */ pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0; pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID; pMsg[2] = 0; /* initiator context */ pMsg[3] = 0x219; /* transaction context */ pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_LINK_SPEED; pMsg[5] = LinkSpeedCode; /* link speed code */ pPab->p_atu->InQueue = off; /* send it to the I2O device */ return RC_RTN_NO_ERROR;}/*** =========================================================================** RCSetPromiscuousMode()**** Defined values for Mode:** 0 - turn off promiscuous mode** 1 - turn on promiscuous mode**** =========================================================================*/RC_RETURNRCSetPromiscuousMode (struct net_device * dev, U16 Mode){ U32 off; PU32 pMsg; PPAB pPab = ((PDPA) dev->priv)->pPab; if (pPab == NULL) return RC_RTN_ADPTR_NOT_REGISTERED; off = pPab->p_atu->InQueue; /* get addresss of message */ if (0xFFFFFFFF == off) return RC_RTN_FREE_Q_EMPTY; pMsg = (PU32) (pPab->pPci45LinBaseAddr + off); /* setup private message */ pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0; pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID; pMsg[2] = 0; /* initiator context */ pMsg[3] = 0x219; /* transaction context */ pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_PROMISCUOUS_MODE; pMsg[5] = Mode; /* promiscuous mode setting */ pPab->p_atu->InQueue = off; /* send it to the device */ return RC_RTN_NO_ERROR;}/*** =========================================================================** RCGetPromiscuousMode()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -