📄 rclanmtl.c
字号:
/*** ******************************************************************************* R C L A N M T L . C $Revision: 6 $****** RedCreek I2O LAN Message Transport Layer program module.**** ---------------------------------------------------------------------** --- Copyright (c) 1997-1999, RedCreek Communications Inc. ---** --- All rights reserved. ---** ---------------------------------------------------------------------**** File Description:**** Host side I2O (Intelligent I/O) LAN message transport layer.**** This program is free software; you can redistribute it and/or modify** it under the terms of the GNU General Public License as published by** the Free Software Foundation; either version 2 of the License, or** (at your option) any later version.** This program is distributed in the hope that it will be useful,** but WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the** GNU General Public License for more details.** You should have received a copy of the GNU General Public License** along with this program; if not, write to the Free Software** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.**** 1998-1999, LAN API was modified and enhanced by Alice Hennessy.**** Sometime in 1997, LAN API was written from scratch by Wendell Nichols.** **************************************************************************/#define DEBUG 1#define RC_LINUX_MODULE#include "rclanmtl.h" /* RedCreek LAN device Target ID */#define RC_LAN_TARGET_ID 0x10 /* RedCreek's OSM default LAN receive Initiator */#define DEFAULT_RECV_INIT_CONTEXT 0xA17/*** I2O message structures*/#define I2O_TID_SZ 12#define I2O_FUNCTION_SZ 8/* Transaction Reply Lists (TRL) Control Word structure */#define I2O_TRL_FLAGS_SINGLE_FIXED_LENGTH 0x00#define I2O_TRL_FLAGS_SINGLE_VARIABLE_LENGTH 0x40#define I2O_TRL_FLAGS_MULTIPLE_FIXED_LENGTH 0x80/* LAN Class specific functions */#define I2O_LAN_PACKET_SEND 0x3B#define I2O_LAN_SDU_SEND 0x3D#define I2O_LAN_RECEIVE_POST 0x3E#define I2O_LAN_RESET 0x35#define I2O_LAN_SHUTDOWN 0x37/* Private Class specfic function */#define I2O_PRIVATE 0xFF/* I2O Executive Function Codes. */#define I2O_EXEC_ADAPTER_ASSIGN 0xB3#define I2O_EXEC_ADAPTER_READ 0xB2#define I2O_EXEC_ADAPTER_RELEASE 0xB5#define I2O_EXEC_BIOS_INFO_SET 0xA5#define I2O_EXEC_BOOT_DEVICE_SET 0xA7#define I2O_EXEC_CONFIG_VALIDATE 0xBB#define I2O_EXEC_CONN_SETUP 0xCA#define I2O_EXEC_DEVICE_ASSIGN 0xB7#define I2O_EXEC_DEVICE_RELEASE 0xB9#define I2O_EXEC_HRT_GET 0xA8#define I2O_EXEC_IOP_CLEAR 0xBE#define I2O_EXEC_IOP_CONNECT 0xC9#define I2O_EXEC_IOP_RESET 0xBD#define I2O_EXEC_LCT_NOTIFY 0xA2#define I2O_EXEC_OUTBOUND_INIT 0xA1#define I2O_EXEC_PATH_ENABLE 0xD3#define I2O_EXEC_PATH_QUIESCE 0xC5#define I2O_EXEC_PATH_RESET 0xD7#define I2O_EXEC_STATIC_MF_CREATE 0xDD#define I2O_EXEC_STATIC_MF_RELEASE 0xDF#define I2O_EXEC_STATUS_GET 0xA0#define I2O_EXEC_SW_DOWNLOAD 0xA9#define I2O_EXEC_SW_UPLOAD 0xAB#define I2O_EXEC_SW_REMOVE 0xAD#define I2O_EXEC_SYS_ENABLE 0xD1#define I2O_EXEC_SYS_MODIFY 0xC1#define I2O_EXEC_SYS_QUIESCE 0xC3#define I2O_EXEC_SYS_TAB_SET 0xA3 /* Init Outbound Q status */#define I2O_EXEC_OUTBOUND_INIT_IN_PROGRESS 0x01#define I2O_EXEC_OUTBOUND_INIT_REJECTED 0x02#define I2O_EXEC_OUTBOUND_INIT_FAILED 0x03#define I2O_EXEC_OUTBOUND_INIT_COMPLETE 0x04#define I2O_UTIL_NOP 0x00/* I2O Get Status State values */#define I2O_IOP_STATE_INITIALIZING 0x01#define I2O_IOP_STATE_RESET 0x02#define I2O_IOP_STATE_HOLD 0x04#define I2O_IOP_STATE_READY 0x05#define I2O_IOP_STATE_OPERATIONAL 0x08#define I2O_IOP_STATE_FAILED 0x10#define I2O_IOP_STATE_FAULTED 0x11/* Defines for Request Status Codes: Table 3-1 Reply Status Codes. */#define I2O_REPLY_STATUS_SUCCESS 0x00#define I2O_REPLY_STATUS_ABORT_DIRTY 0x01#define I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER 0x02#define I2O_REPLY_STATUS_ABORT_PARTIAL_TRANSFER 0x03#define I2O_REPLY_STATUS_ERROR_DIRTY 0x04#define I2O_REPLY_STATUS_ERROR_NO_DATA_TRANSFER 0x05#define I2O_REPLY_STATUS_ERROR_PARTIAL_TRANSFER 0x06#define I2O_REPLY_STATUS_PROCESS_ABORT_DIRTY 0x07#define I2O_REPLY_STATUS_PROCESS_ABORT_NO_DATA_TRANSFER 0x08#define I2O_REPLY_STATUS_PROCESS_ABORT_PARTIAL_TRANSFER 0x09#define I2O_REPLY_STATUS_TRANSACTION_ERROR 0x0A#define I2O_REPLY_STATUS_PROGRESS_REPORT 0x80/* DetailedStatusCode defines for ALL messages: Table 3-2 Detailed Status Codes.*/#define I2O_DETAIL_STATUS_SUCCESS 0x0000#define I2O_DETAIL_STATUS_BAD_KEY 0x0001#define I2O_DETAIL_STATUS_CHAIN_BUFFER_TOO_LARGE 0x0002#define I2O_DETAIL_STATUS_DEVICE_BUSY 0x0003#define I2O_DETAIL_STATUS_DEVICE_LOCKED 0x0004#define I2O_DETAIL_STATUS_DEVICE_NOT_AVAILABLE 0x0005#define I2O_DETAIL_STATUS_DEVICE_RESET 0x0006#define I2O_DETAIL_STATUS_INAPPROPRIATE_FUNCTION 0x0007#define I2O_DETAIL_STATUS_INSUFFICIENT_RESOURCE_HARD 0x0008#define I2O_DETAIL_STATUS_INSUFFICIENT_RESOURCE_SOFT 0x0009#define I2O_DETAIL_STATUS_INVALID_INITIATOR_ADDRESS 0x000A#define I2O_DETAIL_STATUS_INVALID_MESSAGE_FLAGS 0x000B#define I2O_DETAIL_STATUS_INVALID_OFFSET 0x000C#define I2O_DETAIL_STATUS_INVALID_PARAMETER 0x000D#define I2O_DETAIL_STATUS_INVALID_REQUEST 0x000E#define I2O_DETAIL_STATUS_INVALID_TARGET_ADDRESS 0x000F#define I2O_DETAIL_STATUS_MESSAGE_TOO_LARGE 0x0010#define I2O_DETAIL_STATUS_MESSAGE_TOO_SMALL 0x0011#define I2O_DETAIL_STATUS_MISSING_PARAMETER 0x0012#define I2O_DETAIL_STATUS_NO_SUCH_PAGE 0x0013#define I2O_DETAIL_STATUS_REPLY_BUFFER_FULL 0x0014#define I2O_DETAIL_STATUS_TCL_ERROR 0x0015#define I2O_DETAIL_STATUS_TIMEOUT 0x0016#define I2O_DETAIL_STATUS_UNKNOWN_ERROR 0x0017#define I2O_DETAIL_STATUS_UNKNOWN_FUNCTION 0x0018#define I2O_DETAIL_STATUS_UNSUPPORTED_FUNCTION 0x0019#define I2O_DETAIL_STATUS_UNSUPPORTED_VERSION 0x001A /* I2O msg header defines for VersionOffset */#define I2OMSGVER_1_5 0x0001#define SGL_OFFSET_0 I2OMSGVER_1_5#define SGL_OFFSET_4 (0x0040 | I2OMSGVER_1_5)#define TRL_OFFSET_5 (0x0050 | I2OMSGVER_1_5)#define TRL_OFFSET_6 (0x0060 | I2OMSGVER_1_5) /* I2O msg header defines for MsgFlags */#define MSG_STATIC 0x0100#define MSG_64BIT_CNTXT 0x0200#define MSG_MULTI_TRANS 0x1000#define MSG_FAIL 0x2000#define MSG_LAST 0x4000#define MSG_REPLY 0x8000 /* normal LAN request message MsgFlags and VersionOffset (0x1041) */#define LAN_MSG_REQST (MSG_MULTI_TRANS | SGL_OFFSET_4) /* minimum size msg */#define THREE_WORD_MSG_SIZE 0x00030000#define FOUR_WORD_MSG_SIZE 0x00040000#define FIVE_WORD_MSG_SIZE 0x00050000#define SIX_WORD_MSG_SIZE 0x00060000#define SEVEN_WORD_MSG_SIZE 0x00070000#define EIGHT_WORD_MSG_SIZE 0x00080000#define NINE_WORD_MSG_SIZE 0x00090000/* Special TID Assignments */#define I2O_IOP_TID 0#define I2O_HOST_TID 0xB91 /* RedCreek I2O private message codes */#define RC_PRIVATE_GET_MAC_ADDR 0x0001/**/ /* OBSOLETE */#define RC_PRIVATE_SET_MAC_ADDR 0x0002#define RC_PRIVATE_GET_NIC_STATS 0x0003#define RC_PRIVATE_GET_LINK_STATUS 0x0004#define RC_PRIVATE_SET_LINK_SPEED 0x0005#define RC_PRIVATE_SET_IP_AND_MASK 0x0006/* #define RC_PRIVATE_GET_IP_AND_MASK 0x0007 *//* OBSOLETE */#define RC_PRIVATE_GET_LINK_SPEED 0x0008#define RC_PRIVATE_GET_FIRMWARE_REV 0x0009/* #define RC_PRIVATE_GET_MAC_ADDR 0x000A */#define RC_PRIVATE_GET_IP_AND_MASK 0x000B#define RC_PRIVATE_DEBUG_MSG 0x000C#define RC_PRIVATE_REPORT_DRIVER_CAPABILITY 0x000D#define RC_PRIVATE_SET_PROMISCUOUS_MODE 0x000e#define RC_PRIVATE_GET_PROMISCUOUS_MODE 0x000f#define RC_PRIVATE_SET_BROADCAST_MODE 0x0010#define RC_PRIVATE_GET_BROADCAST_MODE 0x0011#define RC_PRIVATE_REBOOT 0x00FF/* I2O message header */typedef struct _I2O_MESSAGE_FRAME { U8 VersionOffset; U8 MsgFlags; U16 MessageSize; BF TargetAddress:I2O_TID_SZ; BF InitiatorAddress:I2O_TID_SZ; BF Function:I2O_FUNCTION_SZ; U32 InitiatorContext; /* SGL[] */} I2O_MESSAGE_FRAME, *PI2O_MESSAGE_FRAME; /* assumed a 16K minus 256 byte space for outbound queue message frames */#define MSG_FRAME_SIZE 512#define NMBR_MSG_FRAMES 30 /* ** in reserved space right after PAB in host memory is area for returning ** values from card *//*** typedef NICSTAT**** Data structure for NIC statistics retruned from PCI card. Data copied from** here to user allocated RCLINKSTATS (see rclanmtl.h) structure.*/typedef struct tag_NicStat { unsigned long TX_good; unsigned long TX_maxcol; unsigned long TX_latecol; unsigned long TX_urun; unsigned long TX_crs; /* lost carrier sense */ unsigned long TX_def; /* transmit deferred */ unsigned long TX_singlecol; /* single collisions */ unsigned long TX_multcol; unsigned long TX_totcol; unsigned long Rcv_good; unsigned long Rcv_CRCerr; unsigned long Rcv_alignerr; unsigned long Rcv_reserr; /* rnr'd pkts */ unsigned long Rcv_orun; unsigned long Rcv_cdt; unsigned long Rcv_runt; unsigned long dump_status; /* last field directly from the chip */} NICSTAT, *P_NICSTAT;#define DUMP_DONE 0x0000A005 /* completed statistical dump */#define DUMP_CLEAR 0x0000A007 /* completed stat dump and clear counters */static volatile int msgFlag;/* local function prototypes */static void ProcessOutboundI2OMsg (PPAB pPab, U32 phyMsgAddr);static int FillI2OMsgSGLFromTCB (PU32 pMsg, PRCTCB pXmitCntrlBlock);static int GetI2OStatus (PPAB pPab);static int SendI2OOutboundQInitMsg (PPAB pPab);static int SendEnableSysMsg (PPAB pPab);/*** =========================================================================** RCInitI2OMsgLayer()**** Initialize the RedCreek I2O Module and adapter.**** Inputs: dev - the devices net_device struct** TransmitCallbackFunction - address of transmit callback function** ReceiveCallbackFunction - address of receive callback function**** private message block is allocated by user. It must be in locked pages.** p_msgbuf and p_phymsgbuf point to the same location. Must be contigous** memory block of a minimum of 16K byte and long word aligned.** =========================================================================*/RC_RETURNRCInitI2OMsgLayer (struct net_device *dev, PFNTXCALLBACK TransmitCallbackFunction, PFNRXCALLBACK ReceiveCallbackFunction, PFNCALLBACK RebootCallbackFunction){ int result; PPAB pPab; PDPA pDpa = dev->priv; U32 pciBaseAddr = dev->base_addr; PU8 p_msgbuf = pDpa->PLanApiPA; PU8 p_phymsgbuf = (PU8) virt_to_bus ((void *) p_msgbuf); dprintk ("InitI2O: Adapter:0x%x ATU:0x%x msgbuf:0x%x phymsgbuf:0x%x\n" "TransmitCallbackFunction:0x%x ReceiveCallbackFunction:0x%x\n", pDpa->id, pciBaseAddr, (u32) p_msgbuf, (u32) p_phymsgbuf, (u32) TransmitCallbackFunction, (u32) ReceiveCallbackFunction); /* Check if this interface already initialized - if so, shut it down */ if (pDpa->pPab != NULL) { dprintk (KERN_WARNING "pDpa->pPab [%d] != NULL\n", pDpa->id);/* RCResetLANCard(pDpa->id, 0, (PU32)NULL, (PFNCALLBACK)NULL); */ pDpa->pPab = NULL; } /* store adapter instance values in adapter block. * Adapter block is at beginning of message buffer */ pPab = kmalloc (sizeof (*pPab), GFP_KERNEL); if (!pPab) { dprintk (KERN_ERR "RCInitI2OMsgLayer: Could not allocate memory for PAB struct!\n"); result = RC_RTN_MALLOC_ERROR; goto err_out; } memset (pPab, 0, sizeof (*pPab)); pDpa->pPab = pPab; pPab->p_atu = (PATU) pciBaseAddr; pPab->pPci45LinBaseAddr = (PU8) pciBaseAddr; /* Set outbound message frame addr */ pPab->outMsgBlockPhyAddr = (U32) p_phymsgbuf; pPab->pLinOutMsgBlock = (PU8) p_msgbuf; /* store callback function addresses */ pPab->pTransCallbackFunc = TransmitCallbackFunction; pPab->pRecvCallbackFunc = ReceiveCallbackFunction; pPab->pRebootCallbackFunc = RebootCallbackFunction; pPab->pCallbackFunc = (PFNCALLBACK) NULL; /* ** Initialize I2O IOP */ result = GetI2OStatus (pPab); if (result != RC_RTN_NO_ERROR) goto err_out_dealloc; if (pPab->IOPState == I2O_IOP_STATE_OPERATIONAL) { dprintk (KERN_INFO "pPab->IOPState == op: resetting adapter\n"); RCResetLANCard (dev, 0, (PU32) NULL, (PFNCALLBACK) NULL); } result = SendI2OOutboundQInitMsg (pPab); if (result != RC_RTN_NO_ERROR) goto err_out_dealloc; result = SendEnableSysMsg (pPab); if (result != RC_RTN_NO_ERROR) goto err_out_dealloc; return RC_RTN_NO_ERROR; err_out_dealloc: kfree (pPab); err_out: return result;}/*** =========================================================================** 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_RETURNRCDisableI2OInterrupts (struct net_device * dev){ PPAB pPab = ((PDPA) dev->priv)->pPab; 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_RETURNRCEnableI2OInterrupts (struct net_device * dev){ PPAB pPab = ((PDPA) dev->priv)->pPab; 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 (struct net_device * dev, U32 InitiatorContext, PRCTCB pTransCtrlBlock){ U32 msgOffset; PU32 pMsg; int size; PPAB pPab = ((PDPA) dev->priv)->pPab; dprintk ("RCI2OSendPacket()...\n"); 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 ("RCI2OSendPacket(): 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 processing TCB - send NOP msg */ dprintk ("RCI2OSendPacket(): Error Rrocess TCB!\n"); 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 (struct net_device * dev, PRCTCB pTransCtrlBlock){ U32 msgOffset;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -