/* ETHIO.H - Ethernet IO - Functions * * Language: DECUS-C * Author: Juergen Pinkow * Date: August '89 * * Notes: Include DLXDF.H, EPMDF.H CHRDF.H and ERRCHK.H * prior to this file. * */ #define CHRHLN 8 /* Minimum header length of characteristics buffer */ /* (in bytes) */ /* Word-Offsets within characteristics buffer for reception */ #define C_SAD 4 /* Source Address Offset */ #define C_DAD 11 /* Destination Address Offset */ #define C_PRO 18 /* Protocol Type Offset */ #define ETHLUN 4 /* Logical unit number for Ethernet port */ #define ETHDEV "QNA-0" /* Ethernet controller device name */ #define USRPRO 0x0660 /* DEC-User Protocol Type */ word rviosb[2]; /* Global IO-Status Block for usage in rcveth() & rcvast() */ /* *** Open Ethernet *** * * Opens a port for Ethernet transmission and reception * * Arguments : Address of Ethernet device name * Address of characteristics block * * Global references: ETHLUN */ opneth(devnam,cp) char devnam[]; word *cp; { word devpar[6], iosb[2], dsw; dsw = alunx(ETHLUN,"NX",0); /* Assign a LUN to DLX */ cmperr("Assign ETHLUN to NX:",dsw,0); /* Initialize characteristics block for IO_XOP */ cp[C_TYP] = CC_FMO; /* Define Ethernet frame format */ cp[C_DATI] = 2; cp[C_DATO] = 0; cp[C_STAT] = 0; cp[C_CHRL] = NX$ETH; devpar[0] = devnam; /* Address of device name */ devpar[1] = strlen(devnam); /* Length of device name */ devpar[2] = 0; /* Timeout in seconds */ devpar[3] = (char*)cp; /* Address of characteristics buffer */ devpar[4] = CHRHLN + 2; /* Length of characteristics buffer */ dsw = qiow(IO_XOP,ETHLUN,1,iosb,0,devpar); /* Open Port */ cmperr("IO_XOP failed",dsw,iosb); chrerr("IO_XOP : Block CC_FMO failed",cp[C_STAT]); /* Initialize characteristics block for IO_XSC */ cp[C_TYP] = CC_DST; /* Define Ethernet Protocol Type */ cp[C_DATI] = 4; cp[C_DATO] = 0; cp[C_STAT] = 0; cp[C_CHRL] = USRPRO; /* Protocol Type */ cp[C_CHRL+1] = LF$EXC | LF$PAD; /* Enable exclusive protocol mode */ /* and padding */ devpar[0] = (char*)cp; /* Start address of characteristics buffer */ devpar[1] = CHRHLN + 4; /* Length of characteristics buffer */ dsw = qiow(IO_XSC,ETHLUN,1,iosb,0,devpar); /* Set characteristics */ cmperr("IO_XSC failed",dsw,iosb); chrerr("IO_XSC : Block CC_DST failed",cp[C_STAT]); } /* *** Close Ethernet Port *** * * Arguments: None * Global references: ETHLUN */ cloeth() { word dsw, iosb[2]; dsw = qiow(IO_XCL,ETHLUN,1,iosb,0,0); cmperr("IO_XCL failed",dsw,iosb); } /* *** Receive via Ethernet *** * * The AST-routine rcvast() is set up as a completion-ast, * so ethernet frame reception will be enabled. * Event flag 2 is used to signal completion. * * Arguments : - Address of buffer for received user-data * - Size of user-data buffer * - Address of characteristics buffer * - Address of completion ast function * * Global references: * - rviosb[] IO-status block for completion status * This variable must not be local, because it * would be lost for the completion-ast when * rcveth() returns ! * - ETHLUN */ rcveth(buffer,bufsiz,cp0,cmpast) char *buffer; int bufsiz; word *cp0; int (*cmpast)(); { static word devpar[6]; word *cp1,*cp2; /* Initialize the characteristics buffer for IO_XRC */ cp0[C_TYP] = CC_ADR; /* Return Ethernet Source Address */ cp0[C_DATI] = 6; cp0[C_DATO] = 0; cp0[C_STAT] = 0; cp0[C_CHRL] = 0; /* Here the address will be returned */ cp0[C_CHRL+1] = 0; cp0[C_CHRL+2] = 0; cp1 = cp0 + 7; /* Set cp1 to beginning of next characteristic block */ cp1[C_TYP] = CC_DAD; /* Return Ethernet Destination Address */ cp1[C_DATI] = 6; cp1[C_DATO] = 0; cp1[C_STAT] = 0; cp1[C_CHRL] = 0; /* Here the address will be returned */ cp1[C_CHRL+1] = 0; cp1[C_CHRL+2] = 0; cp2 = cp1 + 7; /* Set cp1 to beginning of next characteristic block */ cp2[C_TYP] = CC_PRO; /* Return Protocol Type */ cp2[C_DATI] = 2; cp2[C_DATO] = 0; cp2[C_STAT] = 0; cp2[C_CHRL] = 0; /* Here the protocol type will be returned */ devpar[0] = buffer; /* Address of buffer for received data */ devpar[1] = bufsiz; /* Length of receive buffer */ devpar[2] = (char*)cp0; /* Address of characteristics buffer */ devpar[3] = 3 * CHRHLN + 14;/* Total length of characteristics buffer */ qio(IO_XRC,ETHLUN,2,rviosb,cmpast,devpar); } /* *** Send via Ethernet *** * * Send a message to an open port. * * Arguments: - Address of the user buffer that contains the * message to transmit * - Length of the message to transmit * - Address of a blank characteristics buffer for transmit * - Ethernet destination address as an array of * three words * - Protocol type in word format * * Global references: ETHLUN */ sndeth(msg,msglen,cp0,dstadr,protyp) char *msg; int msglen; word *cp0, /* Pointer to characteristics buffer */ dstadr[], /* Destination Address */ protyp; /* Protocol Type */ { word devpar[6], iosb[2], dsw, *cp1,*cp2; cp0[C_TYP] = CC_ADR; /* Ethernet Destination Address */ cp0[C_DATI] = 6; cp0[C_DATO] = 0; cp0[C_STAT] = 0; cp0[C_CHRL] = dstadr[0]; /* Destination address */ cp0[C_CHRL+1] = dstadr[1]; cp0[C_CHRL+2] = dstadr[2]; cp1 = cp0 + 7; /* Set cp1 to beginning of next characteristic block */ cp1[C_TYP] = CC_FMM; /* Frame Format for Message */ cp1[C_DATI] = 2; cp1[C_DATO] = 0; cp1[C_STAT] = 0; cp1[C_CHRL] = NX$ETH; cp2 = cp1 + 5; /* Set cp2 to beginning of next characteristic block */ cp2[C_TYP] = CC_PRO; /* Protocol Type */ cp2[C_DATI] = 2; cp2[C_DATO] = 0; cp2[C_STAT] = 0; cp2[C_CHRL] = protyp; devpar[0] = msg; /* Address of buffer for data to be send */ devpar[1] = msglen; /* Length of data */ devpar[2] = (char*)cp0; /* Address of characteristics buffer */ devpar[3] = 3 * CHRHLN + 10; /* Total length of characteristics buffer */ dsw = qiow(IO_XTM,ETHLUN,1,iosb,0,devpar); cmperr("IO_XTM failed",dsw,iosb); chrerr("IO_XTM : Block CC_ADR failed",cp0[C_STAT]); chrerr("IO_XTM : Block CC_FMM failed",cp1[C_STAT]); chrerr("IO_XTM : Block CC_PRO failed",cp2[C_STAT]); }