Import 2.3.18pre1
[davej-history.git] / drivers / net / rclanmtl.c
blob504cd865e006578761f389d498680666d848a5d8
1 /*
2 ** *************************************************************************
3 **
4 **
5 ** R C L A N M T L . C $Revision: 6 $
6 **
7 **
8 ** RedCreek I2O LAN Message Transport Layer program module.
9 **
10 ** ---------------------------------------------------------------------
11 ** --- Copyright (c) 1997-1999, RedCreek Communications Inc. ---
12 ** --- All rights reserved. ---
13 ** ---------------------------------------------------------------------
15 ** File Description:
17 ** Host side I2O (Intelligent I/O) LAN message transport layer.
19 ** This program is free software; you can redistribute it and/or modify
20 ** it under the terms of the GNU General Public License as published by
21 ** the Free Software Foundation; either version 2 of the License, or
22 ** (at your option) any later version.
24 ** This program is distributed in the hope that it will be useful,
25 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
26 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 ** GNU General Public License for more details.
29 ** You should have received a copy of the GNU General Public License
30 ** along with this program; if not, write to the Free Software
31 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33 ** 1998-1999, LAN API was modified and enhanced by Alice Hennessy.
35 ** Sometime in 1997, LAN API was written from scratch by Wendell Nichols.
36 ** *************************************************************************
39 #undef DEBUG
41 #define RC_LINUX_MODULE
42 #include "rclanmtl.h"
44 #define dprintf kprintf
46 extern int printk(const char * fmt, ...);
48 /* RedCreek LAN device Target ID */
49 #define RC_LAN_TARGET_ID 0x10
50 /* RedCreek's OSM default LAN receive Initiator */
51 #define DEFAULT_RECV_INIT_CONTEXT 0xA17
55 ** I2O message structures
58 #define I2O_TID_SZ 12
59 #define I2O_FUNCTION_SZ 8
61 /* Transaction Reply Lists (TRL) Control Word structure */
63 #define I2O_TRL_FLAGS_SINGLE_FIXED_LENGTH 0x00
64 #define I2O_TRL_FLAGS_SINGLE_VARIABLE_LENGTH 0x40
65 #define I2O_TRL_FLAGS_MULTIPLE_FIXED_LENGTH 0x80
67 /* LAN Class specific functions */
69 #define I2O_LAN_PACKET_SEND 0x3B
70 #define I2O_LAN_SDU_SEND 0x3D
71 #define I2O_LAN_RECEIVE_POST 0x3E
72 #define I2O_LAN_RESET 0x35
73 #define I2O_LAN_SHUTDOWN 0x37
75 /* Private Class specfic function */
76 #define I2O_PRIVATE 0xFF
78 /* I2O Executive Function Codes. */
80 #define I2O_EXEC_ADAPTER_ASSIGN 0xB3
81 #define I2O_EXEC_ADAPTER_READ 0xB2
82 #define I2O_EXEC_ADAPTER_RELEASE 0xB5
83 #define I2O_EXEC_BIOS_INFO_SET 0xA5
84 #define I2O_EXEC_BOOT_DEVICE_SET 0xA7
85 #define I2O_EXEC_CONFIG_VALIDATE 0xBB
86 #define I2O_EXEC_CONN_SETUP 0xCA
87 #define I2O_EXEC_DEVICE_ASSIGN 0xB7
88 #define I2O_EXEC_DEVICE_RELEASE 0xB9
89 #define I2O_EXEC_HRT_GET 0xA8
90 #define I2O_EXEC_IOP_CLEAR 0xBE
91 #define I2O_EXEC_IOP_CONNECT 0xC9
92 #define I2O_EXEC_IOP_RESET 0xBD
93 #define I2O_EXEC_LCT_NOTIFY 0xA2
94 #define I2O_EXEC_OUTBOUND_INIT 0xA1
95 #define I2O_EXEC_PATH_ENABLE 0xD3
96 #define I2O_EXEC_PATH_QUIESCE 0xC5
97 #define I2O_EXEC_PATH_RESET 0xD7
98 #define I2O_EXEC_STATIC_MF_CREATE 0xDD
99 #define I2O_EXEC_STATIC_MF_RELEASE 0xDF
100 #define I2O_EXEC_STATUS_GET 0xA0
101 #define I2O_EXEC_SW_DOWNLOAD 0xA9
102 #define I2O_EXEC_SW_UPLOAD 0xAB
103 #define I2O_EXEC_SW_REMOVE 0xAD
104 #define I2O_EXEC_SYS_ENABLE 0xD1
105 #define I2O_EXEC_SYS_MODIFY 0xC1
106 #define I2O_EXEC_SYS_QUIESCE 0xC3
107 #define I2O_EXEC_SYS_TAB_SET 0xA3
110 /* Init Outbound Q status */
111 #define I2O_EXEC_OUTBOUND_INIT_IN_PROGRESS 0x01
112 #define I2O_EXEC_OUTBOUND_INIT_REJECTED 0x02
113 #define I2O_EXEC_OUTBOUND_INIT_FAILED 0x03
114 #define I2O_EXEC_OUTBOUND_INIT_COMPLETE 0x04
117 #define I2O_UTIL_NOP 0x00
120 /* I2O Get Status State values */
122 #define I2O_IOP_STATE_INITIALIZING 0x01
123 #define I2O_IOP_STATE_RESET 0x02
124 #define I2O_IOP_STATE_HOLD 0x04
125 #define I2O_IOP_STATE_READY 0x05
126 #define I2O_IOP_STATE_OPERATIONAL 0x08
127 #define I2O_IOP_STATE_FAILED 0x10
128 #define I2O_IOP_STATE_FAULTED 0x11
131 /* Defines for Request Status Codes: Table 3-1 Reply Status Codes. */
133 #define I2O_REPLY_STATUS_SUCCESS 0x00
134 #define I2O_REPLY_STATUS_ABORT_DIRTY 0x01
135 #define I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER 0x02
136 #define I2O_REPLY_STATUS_ABORT_PARTIAL_TRANSFER 0x03
137 #define I2O_REPLY_STATUS_ERROR_DIRTY 0x04
138 #define I2O_REPLY_STATUS_ERROR_NO_DATA_TRANSFER 0x05
139 #define I2O_REPLY_STATUS_ERROR_PARTIAL_TRANSFER 0x06
140 #define I2O_REPLY_STATUS_PROCESS_ABORT_DIRTY 0x07
141 #define I2O_REPLY_STATUS_PROCESS_ABORT_NO_DATA_TRANSFER 0x08
142 #define I2O_REPLY_STATUS_PROCESS_ABORT_PARTIAL_TRANSFER 0x09
143 #define I2O_REPLY_STATUS_TRANSACTION_ERROR 0x0A
144 #define I2O_REPLY_STATUS_PROGRESS_REPORT 0x80
147 /* DetailedStatusCode defines for ALL messages: Table 3-2 Detailed Status Codes.*/
149 #define I2O_DETAIL_STATUS_SUCCESS 0x0000
150 #define I2O_DETAIL_STATUS_BAD_KEY 0x0001
151 #define I2O_DETAIL_STATUS_CHAIN_BUFFER_TOO_LARGE 0x0002
152 #define I2O_DETAIL_STATUS_DEVICE_BUSY 0x0003
153 #define I2O_DETAIL_STATUS_DEVICE_LOCKED 0x0004
154 #define I2O_DETAIL_STATUS_DEVICE_NOT_AVAILABLE 0x0005
155 #define I2O_DETAIL_STATUS_DEVICE_RESET 0x0006
156 #define I2O_DETAIL_STATUS_INAPPROPRIATE_FUNCTION 0x0007
157 #define I2O_DETAIL_STATUS_INSUFFICIENT_RESOURCE_HARD 0x0008
158 #define I2O_DETAIL_STATUS_INSUFFICIENT_RESOURCE_SOFT 0x0009
159 #define I2O_DETAIL_STATUS_INVALID_INITIATOR_ADDRESS 0x000A
160 #define I2O_DETAIL_STATUS_INVALID_MESSAGE_FLAGS 0x000B
161 #define I2O_DETAIL_STATUS_INVALID_OFFSET 0x000C
162 #define I2O_DETAIL_STATUS_INVALID_PARAMETER 0x000D
163 #define I2O_DETAIL_STATUS_INVALID_REQUEST 0x000E
164 #define I2O_DETAIL_STATUS_INVALID_TARGET_ADDRESS 0x000F
165 #define I2O_DETAIL_STATUS_MESSAGE_TOO_LARGE 0x0010
166 #define I2O_DETAIL_STATUS_MESSAGE_TOO_SMALL 0x0011
167 #define I2O_DETAIL_STATUS_MISSING_PARAMETER 0x0012
168 #define I2O_DETAIL_STATUS_NO_SUCH_PAGE 0x0013
169 #define I2O_DETAIL_STATUS_REPLY_BUFFER_FULL 0x0014
170 #define I2O_DETAIL_STATUS_TCL_ERROR 0x0015
171 #define I2O_DETAIL_STATUS_TIMEOUT 0x0016
172 #define I2O_DETAIL_STATUS_UNKNOWN_ERROR 0x0017
173 #define I2O_DETAIL_STATUS_UNKNOWN_FUNCTION 0x0018
174 #define I2O_DETAIL_STATUS_UNSUPPORTED_FUNCTION 0x0019
175 #define I2O_DETAIL_STATUS_UNSUPPORTED_VERSION 0x001A
177 /* I2O msg header defines for VersionOffset */
178 #define I2OMSGVER_1_5 0x0001
179 #define SGL_OFFSET_0 I2OMSGVER_1_5
180 #define SGL_OFFSET_4 (0x0040 | I2OMSGVER_1_5)
181 #define TRL_OFFSET_5 (0x0050 | I2OMSGVER_1_5)
182 #define TRL_OFFSET_6 (0x0060 | I2OMSGVER_1_5)
184 /* I2O msg header defines for MsgFlags */
185 #define MSG_STATIC 0x0100
186 #define MSG_64BIT_CNTXT 0x0200
187 #define MSG_MULTI_TRANS 0x1000
188 #define MSG_FAIL 0x2000
189 #define MSG_LAST 0x4000
190 #define MSG_REPLY 0x8000
192 /* normal LAN request message MsgFlags and VersionOffset (0x1041) */
193 #define LAN_MSG_REQST (MSG_MULTI_TRANS | SGL_OFFSET_4)
195 /* minimum size msg */
196 #define THREE_WORD_MSG_SIZE 0x00030000
197 #define FOUR_WORD_MSG_SIZE 0x00040000
198 #define FIVE_WORD_MSG_SIZE 0x00050000
199 #define SIX_WORD_MSG_SIZE 0x00060000
200 #define SEVEN_WORD_MSG_SIZE 0x00070000
201 #define EIGHT_WORD_MSG_SIZE 0x00080000
202 #define NINE_WORD_MSG_SIZE 0x00090000
204 /* Special TID Assignments */
206 #define I2O_IOP_TID 0
207 #define I2O_HOST_TID 0xB91
209 /* RedCreek I2O private message codes */
210 #define RC_PRIVATE_GET_MAC_ADDR 0x0001/**/ /* OBSOLETE */
211 #define RC_PRIVATE_SET_MAC_ADDR 0x0002
212 #define RC_PRIVATE_GET_NIC_STATS 0x0003
213 #define RC_PRIVATE_GET_LINK_STATUS 0x0004
214 #define RC_PRIVATE_SET_LINK_SPEED 0x0005
215 #define RC_PRIVATE_SET_IP_AND_MASK 0x0006
216 /* #define RC_PRIVATE_GET_IP_AND_MASK 0x0007 */ /* OBSOLETE */
217 #define RC_PRIVATE_GET_LINK_SPEED 0x0008
218 #define RC_PRIVATE_GET_FIRMWARE_REV 0x0009
219 /* #define RC_PRIVATE_GET_MAC_ADDR 0x000A *//**/
220 #define RC_PRIVATE_GET_IP_AND_MASK 0x000B /**/
221 #define RC_PRIVATE_DEBUG_MSG 0x000C
222 #define RC_PRIVATE_REPORT_DRIVER_CAPABILITY 0x000D
223 #define RC_PRIVATE_SET_PROMISCUOUS_MODE 0x000e
224 #define RC_PRIVATE_GET_PROMISCUOUS_MODE 0x000f
225 #define RC_PRIVATE_SET_BROADCAST_MODE 0x0010
226 #define RC_PRIVATE_GET_BROADCAST_MODE 0x0011
228 #define RC_PRIVATE_REBOOT 0x00FF
231 /* I2O message header */
232 typedef struct _I2O_MESSAGE_FRAME
234 U8 VersionOffset;
235 U8 MsgFlags;
236 U16 MessageSize;
237 BF TargetAddress:I2O_TID_SZ;
238 BF InitiatorAddress:I2O_TID_SZ;
239 BF Function:I2O_FUNCTION_SZ;
240 U32 InitiatorContext;
241 /* SGL[] */
243 I2O_MESSAGE_FRAME, *PI2O_MESSAGE_FRAME;
246 /* assumed a 16K minus 256 byte space for outbound queue message frames */
247 #define MSG_FRAME_SIZE 512
248 #define NMBR_MSG_FRAMES 30
251 ** Message Unit CSR definitions for RedCreek PCI45 board
253 typedef struct tag_rcatu
255 volatile unsigned long APICRegSel; /* APIC Register Select */
256 volatile unsigned long reserved0;
257 volatile unsigned long APICWinReg; /* APIC Window Register */
258 volatile unsigned long reserved1;
259 volatile unsigned long InMsgReg0; /* inbound message register 0 */
260 volatile unsigned long InMsgReg1; /* inbound message register 1 */
261 volatile unsigned long OutMsgReg0; /* outbound message register 0 */
262 volatile unsigned long OutMsgReg1; /* outbound message register 1 */
263 volatile unsigned long InDoorReg; /* inbound doorbell register */
264 volatile unsigned long InIntStat; /* inbound interrupt status register */
265 volatile unsigned long InIntMask; /* inbound interrupt mask register */
266 volatile unsigned long OutDoorReg; /* outbound doorbell register */
267 volatile unsigned long OutIntStat; /* outbound interrupt status register */
268 volatile unsigned long OutIntMask; /* outbound interrupt mask register */
269 volatile unsigned long reserved2;
270 volatile unsigned long reserved3;
271 volatile unsigned long InQueue; /* inbound queue port */
272 volatile unsigned long OutQueue; /* outbound queue port */
273 volatile unsigned long reserved4;
274 volatile unsigned long reserver5;
275 /* RedCreek extension */
276 volatile unsigned long EtherMacLow;
277 volatile unsigned long EtherMacHi;
278 volatile unsigned long IPaddr;
279 volatile unsigned long IPmask;
281 ATU, *PATU;
284 ** typedef PAB
286 ** PCI Adapter Block - holds instance specific information and is located
287 ** in a reserved space at the start of the message buffer allocated by user.
289 typedef struct
291 PATU p_atu; /* ptr to ATU register block */
292 PU8 pPci45LinBaseAddr;
293 PU8 pLinOutMsgBlock;
294 U32 outMsgBlockPhyAddr;
295 PFNTXCALLBACK pTransCallbackFunc;
296 PFNRXCALLBACK pRecvCallbackFunc;
297 PFNCALLBACK pRebootCallbackFunc;
298 PFNCALLBACK pCallbackFunc;
299 U16 IOPState;
300 U16 InboundMFrameSize;
302 PAB, *PPAB;
305 ** in reserved space right after PAB in host memory is area for returning
306 ** values from card
310 ** Array of pointers to PCI Adapter Blocks.
311 ** Indexed by a zero based (0-31) interface number.
313 #define MAX_ADAPTERS 32
314 static PPAB PCIAdapterBlock[MAX_ADAPTERS] =
316 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
317 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
318 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
319 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
324 ** typedef NICSTAT
326 ** Data structure for NIC statistics retruned from PCI card. Data copied from
327 ** here to user allocated RCLINKSTATS (see rclanmtl.h) structure.
329 typedef struct tag_NicStat
331 unsigned long TX_good;
332 unsigned long TX_maxcol;
333 unsigned long TX_latecol;
334 unsigned long TX_urun;
335 unsigned long TX_crs; /* lost carrier sense */
336 unsigned long TX_def; /* transmit deferred */
337 unsigned long TX_singlecol; /* single collisions */
338 unsigned long TX_multcol;
339 unsigned long TX_totcol;
340 unsigned long Rcv_good;
341 unsigned long Rcv_CRCerr;
342 unsigned long Rcv_alignerr;
343 unsigned long Rcv_reserr; /* rnr'd pkts */
344 unsigned long Rcv_orun;
345 unsigned long Rcv_cdt;
346 unsigned long Rcv_runt;
347 unsigned long dump_status; /* last field directly from the chip */
349 NICSTAT, *P_NICSTAT;
352 #define DUMP_DONE 0x0000A005 /* completed statistical dump */
353 #define DUMP_CLEAR 0x0000A007 /* completed stat dump and clear counters */
356 static volatile int msgFlag;
359 /* local function prototypes */
360 static void ProcessOutboundI2OMsg(PPAB pPab, U32 phyMsgAddr);
361 static int FillI2OMsgSGLFromTCB(PU32 pMsg, PRCTCB pXmitCntrlBlock);
362 static int GetI2OStatus(PPAB pPab);
363 static int SendI2OOutboundQInitMsg(PPAB pPab);
364 static int SendEnableSysMsg(PPAB pPab);
367 /* 1st 100h bytes of message block is reserved for messenger instance */
368 #define ADAPTER_BLOCK_RESERVED_SPACE 0x100
371 ** =========================================================================
372 ** RCInitI2OMsgLayer()
374 ** Initialize the RedCreek I2O Module and adapter.
376 ** Inputs: AdapterID - interface number from 0 to 15
377 ** pciBaseAddr - virual base address of PCI (set by BIOS)
378 ** p_msgbuf - virual address to private message block (min. 16K)
379 ** p_phymsgbuf - physical address of private message block
380 ** TransmitCallbackFunction - address of transmit callback function
381 ** ReceiveCallbackFunction - address of receive callback function
383 ** private message block is allocated by user. It must be in locked pages.
384 ** p_msgbuf and p_phymsgbuf point to the same location. Must be contigous
385 ** memory block of a minimum of 16K byte and long word aligned.
386 ** =========================================================================
388 RC_RETURN
389 RCInitI2OMsgLayer(U16 AdapterID, U32 pciBaseAddr,
390 PU8 p_msgbuf, PU8 p_phymsgbuf,
391 PFNTXCALLBACK TransmitCallbackFunction,
392 PFNRXCALLBACK ReceiveCallbackFunction,
393 PFNCALLBACK RebootCallbackFunction)
395 int result;
396 PPAB pPab;
398 #ifdef DEBUG
399 kprintf("InitI2O: Adapter:0x%04.4ux ATU:0x%08.8ulx msgbuf:0x%08.8ulx phymsgbuf:0x%08.8ulx\n"
400 "TransmitCallbackFunction:0x%08.8ulx ReceiveCallbackFunction:0x%08.8ulx\n",
401 AdapterID, pciBaseAddr, p_msgbuf, p_phymsgbuf, TransmitCallbackFunction, ReceiveCallbackFunction);
402 #endif /* DEBUG */
405 /* Check if this interface already initialized - if so, shut it down */
406 if (PCIAdapterBlock[AdapterID] != NULL)
408 printk("PCIAdapterBlock[%d]!=NULL\n", AdapterID);
409 // RCResetLANCard(AdapterID, 0, (PU32)NULL, (PFNCALLBACK)NULL);
410 PCIAdapterBlock[AdapterID] = NULL;
414 ** store adapter instance values in adapter block.
415 ** Adapter block is at beginning of message buffer
417 pPab = (PPAB)p_msgbuf;
419 pPab->p_atu = (PATU)pciBaseAddr;
420 pPab->pPci45LinBaseAddr = (PU8)pciBaseAddr;
422 /* Set outbound message frame addr - skip over Adapter Block */
423 pPab->outMsgBlockPhyAddr = (U32)(p_phymsgbuf + ADAPTER_BLOCK_RESERVED_SPACE);
424 pPab->pLinOutMsgBlock = (PU8)(p_msgbuf + ADAPTER_BLOCK_RESERVED_SPACE);
426 /* store callback function addresses */
427 pPab->pTransCallbackFunc = TransmitCallbackFunction;
428 pPab->pRecvCallbackFunc = ReceiveCallbackFunction;
429 pPab->pRebootCallbackFunc = RebootCallbackFunction;
430 pPab->pCallbackFunc = (PFNCALLBACK)NULL;
433 ** Initialize I2O IOP
435 result = GetI2OStatus(pPab);
437 if (result != RC_RTN_NO_ERROR)
438 return result;
440 if (pPab->IOPState == I2O_IOP_STATE_OPERATIONAL)
442 printk("pPab->IOPState == op: resetting adapter\n");
443 RCResetLANCard(AdapterID, 0, (PU32)NULL, (PFNCALLBACK)NULL);
446 result = SendI2OOutboundQInitMsg(pPab);
448 if (result != RC_RTN_NO_ERROR)
449 return result;
451 result = SendEnableSysMsg(pPab);
453 if (result != RC_RTN_NO_ERROR)
454 return result;
456 PCIAdapterBlock[AdapterID] = pPab;
457 return RC_RTN_NO_ERROR;
461 ** =========================================================================
462 ** Disable and Enable I2O interrupts. I2O interrupts are enabled at Init time
463 ** but can be disabled and re-enabled through these two function calls.
464 ** Packets will still be put into any posted received buffers and packets will
465 ** be sent through RCI2OSendPacket() functions. Disabling I2O interrupts
466 ** will prevent hardware interrupt to host even though the outbound I2O msg
467 ** queue is not emtpy.
468 ** =========================================================================
470 #define i960_OUT_POST_Q_INT_BIT 0x0008 /* bit set masks interrupts */
472 RC_RETURN RCDisableI2OInterrupts(U16 AdapterID)
474 PPAB pPab;
477 pPab = PCIAdapterBlock[AdapterID];
479 if (pPab == NULL)
480 return RC_RTN_ADPTR_NOT_REGISTERED;
482 pPab->p_atu->OutIntMask |= i960_OUT_POST_Q_INT_BIT;
484 return RC_RTN_NO_ERROR;
487 RC_RETURN RCEnableI2OInterrupts(U16 AdapterID)
489 PPAB pPab;
491 pPab = PCIAdapterBlock[AdapterID];
493 if (pPab == NULL)
494 return RC_RTN_ADPTR_NOT_REGISTERED;
496 pPab->p_atu->OutIntMask &= ~i960_OUT_POST_Q_INT_BIT;
498 return RC_RTN_NO_ERROR;
504 ** =========================================================================
505 ** RCI2OSendPacket()
506 ** =========================================================================
508 RC_RETURN
509 RCI2OSendPacket(U16 AdapterID, U32 InitiatorContext, PRCTCB pTransCtrlBlock)
511 U32 msgOffset;
512 PU32 pMsg;
513 int size;
514 PPAB pPab;
516 #ifdef DEBUG
517 kprintf("RCI2OSendPacket()...\n");
518 #endif /* DEBUG */
520 pPab = PCIAdapterBlock[AdapterID];
522 if (pPab == NULL)
523 return RC_RTN_ADPTR_NOT_REGISTERED;
525 /* get Inbound free Q entry - reading from In Q gets free Q entry */
526 /* offset to Msg Frame in PCI msg block */
528 msgOffset = pPab->p_atu->InQueue;
530 if (msgOffset == 0xFFFFFFFF)
532 #ifdef DEBUG
533 kprintf("RCI2OSendPacket(): Inbound Free Q empty!\n");
534 #endif /* DEBUG */
535 return RC_RTN_FREE_Q_EMPTY;
538 /* calc virual address of msg - virual already mapped to physical */
539 pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
541 size = FillI2OMsgSGLFromTCB(pMsg + 4, pTransCtrlBlock);
543 if (size == -1) /* error processing TCB - send NOP msg */
545 #ifdef DEBUG
546 kprintf("RCI2OSendPacket(): Error Rrocess TCB!\n");
547 #endif /* DEBUG */
548 pMsg[0] = THREE_WORD_MSG_SIZE | SGL_OFFSET_0;
549 pMsg[1] = I2O_UTIL_NOP << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
550 return RC_RTN_TCB_ERROR;
552 else /* send over msg header */
554 pMsg[0] = (size + 4) << 16 | LAN_MSG_REQST; /* send over message size and flags */
555 pMsg[1] = I2O_LAN_PACKET_SEND << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
556 pMsg[2] = InitiatorContext;
557 pMsg[3] = 0; /* batch reply */
558 /* post to Inbound Post Q */
559 pPab->p_atu->InQueue = msgOffset;
560 return RC_RTN_NO_ERROR;
566 ** =========================================================================
567 ** RCI2OPostRecvBuffer()
569 ** inputs: pBufrCntrlBlock - pointer to buffer control block
571 ** returns TRUE if successful in sending message, else FALSE.
572 ** =========================================================================
574 RC_RETURN
575 RCPostRecvBuffers(U16 AdapterID, PRCTCB pTransCtrlBlock)
577 U32 msgOffset;
578 PU32 pMsg;
579 int size;
580 PPAB pPab;
582 #ifdef DEBUG
583 kprintf("RCPostRecvBuffers()...\n");
584 #endif /* DEBUG */
586 /* search for DeviceHandle */
587 pPab = PCIAdapterBlock[AdapterID];
589 if (pPab == NULL)
590 return RC_RTN_ADPTR_NOT_REGISTERED;
593 /* get Inbound free Q entry - reading from In Q gets free Q entry */
594 /* offset to Msg Frame in PCI msg block */
595 msgOffset = pPab->p_atu->InQueue;
597 if (msgOffset == 0xFFFFFFFF)
599 #ifdef DEBUG
600 kprintf("RCPostRecvBuffers(): Inbound Free Q empty!\n");
601 #endif /* DEBUG */
602 return RC_RTN_FREE_Q_EMPTY;
605 /* calc virual address of msg - virual already mapped to physical */
606 pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
608 size = FillI2OMsgSGLFromTCB(pMsg + 4, pTransCtrlBlock);
610 if (size == -1) /* error prcessing TCB - send 3 DWORD private msg == NOP */
612 #ifdef DEBUG
613 kprintf("RCPostRecvBuffers(): Error Processing TCB! size = %d\n", size);
614 #endif /* DEBUG */
615 pMsg[0] = THREE_WORD_MSG_SIZE | SGL_OFFSET_0;
616 pMsg[1] = I2O_UTIL_NOP << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
617 /* post to Post Q */
618 pPab->p_atu->InQueue = msgOffset;
619 return RC_RTN_TCB_ERROR;
621 else /* send over size msg header */
623 pMsg[0] = (size + 4) << 16 | LAN_MSG_REQST; /* send over message size and flags */
624 pMsg[1] = I2O_LAN_RECEIVE_POST << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
625 pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
626 pMsg[3] = *(PU32)pTransCtrlBlock; /* number of packet buffers */
627 /* post to Post Q */
628 pPab->p_atu->InQueue = msgOffset;
629 return RC_RTN_NO_ERROR;
635 ** =========================================================================
636 ** RCProcI2OMsgQ()
638 ** Process I2O outbound message queue until empty.
639 ** =========================================================================
641 void
642 RCProcI2OMsgQ(U16 AdapterID)
644 U32 phyAddrMsg;
645 PU8 p8Msg;
646 PU32 p32;
647 U16 count;
648 PPAB pPab;
649 unsigned char debug_msg[20];
651 pPab = PCIAdapterBlock[AdapterID];
653 if (pPab == NULL)
654 return;
656 phyAddrMsg = pPab->p_atu->OutQueue;
658 while (phyAddrMsg != 0xFFFFFFFF)
660 p8Msg = pPab->pLinOutMsgBlock + (phyAddrMsg - pPab->outMsgBlockPhyAddr);
661 p32 = (PU32)p8Msg;
663 //printk(" msg: 0x%x 0x%x \n", p8Msg[7], p32[5]);
666 ** Send Packet Reply Msg
668 if (I2O_LAN_PACKET_SEND == p8Msg[7]) /* function code byte */
670 count = *(PU16)(p8Msg+2);
671 count -= p8Msg[0] >> 4;
672 /* status, count, context[], adapter */
673 (*pPab->pTransCallbackFunc)(p8Msg[19], count, p32+5, AdapterID);
676 ** Receive Packet Reply Msg */
677 else if (I2O_LAN_RECEIVE_POST == p8Msg[7])
679 #ifdef DEBUG
680 kprintf("I2O_RECV_REPLY pPab:0x%08.8ulx p8Msg:0x%08.8ulx p32:0x%08.8ulx\n", pPab, p8Msg, p32);
681 kprintf("msg: 0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n",
682 p32[0], p32[1], p32[2], p32[3]);
683 kprintf(" 0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n",
684 p32[4], p32[5], p32[6], p32[7]);
685 kprintf(" 0x%08.8ulx:0X%08.8ulx:0x%08.8ulx:0x%08.8ulx\n",
686 p32[8], p32[9], p32[10], p32[11]);
687 #endif
688 /* status, count, buckets remaining, packetParmBlock, adapter */
689 (*pPab->pRecvCallbackFunc)(p8Msg[19], p8Msg[12], p32[5], p32+6, AdapterID);
693 else if (I2O_LAN_RESET == p8Msg[7] || I2O_LAN_SHUTDOWN == p8Msg[7])
695 if (pPab->pCallbackFunc)
697 (*pPab->pCallbackFunc)(p8Msg[19],0,0,AdapterID);
699 else
701 pPab->pCallbackFunc = (PFNCALLBACK) 1;
703 //PCIAdapterBlock[AdapterID] = 0;
705 else if (I2O_PRIVATE == p8Msg[7])
707 //printk("i2o private 0x%x, 0x%x \n", p8Msg[7], p32[5]);
708 switch (p32[5])
710 case RC_PRIVATE_DEBUG_MSG:
711 msgFlag = 1;
712 /*printk("Received I2O_PRIVATE msg\n");*/
713 debug_msg[15] = (p32[6]&0xff000000) >> 24;
714 debug_msg[14] = (p32[6]&0x00ff0000) >> 16;
715 debug_msg[13] = (p32[6]&0x0000ff00) >> 8;
716 debug_msg[12] = (p32[6]&0x000000ff);
718 debug_msg[11] = (p32[7]&0xff000000) >> 24;
719 debug_msg[10] = (p32[7]&0x00ff0000) >> 16;
720 debug_msg[ 9] = (p32[7]&0x0000ff00) >> 8;
721 debug_msg[ 8] = (p32[7]&0x000000ff);
723 debug_msg[ 7] = (p32[8]&0xff000000) >> 24;
724 debug_msg[ 6] = (p32[8]&0x00ff0000) >> 16;
725 debug_msg[ 5] = (p32[8]&0x0000ff00) >> 8;
726 debug_msg[ 4] = (p32[8]&0x000000ff);
728 debug_msg[ 3] = (p32[9]&0xff000000) >> 24;
729 debug_msg[ 2] = (p32[9]&0x00ff0000) >> 16;
730 debug_msg[ 1] = (p32[9]&0x0000ff00) >> 8;
731 debug_msg[ 0] = (p32[9]&0x000000ff);
733 debug_msg[16] = '\0';
734 printk (debug_msg);
735 break;
736 case RC_PRIVATE_REBOOT:
737 printk("Adapter reboot initiated...\n");
738 if (pPab->pRebootCallbackFunc)
740 (*pPab->pRebootCallbackFunc)(0,0,0,AdapterID);
742 break;
743 default:
744 printk("Unknown private I2O msg received: 0x%x\n",
745 p32[5]);
746 break;
751 ** Process other Msg's
753 else
755 ProcessOutboundI2OMsg(pPab, phyAddrMsg);
758 /* return MFA to outbound free Q*/
759 pPab->p_atu->OutQueue = phyAddrMsg;
761 /* any more msgs? */
762 phyAddrMsg = pPab->p_atu->OutQueue;
768 ** =========================================================================
769 ** Returns LAN interface statistical counters to space provided by caller at
770 ** StatsReturnAddr. Returns 0 if success, else RC_RETURN code.
771 ** This function will call the WaitCallback function provided by
772 ** user while waiting for card to respond.
773 ** =========================================================================
775 RC_RETURN
776 RCGetLinkStatistics(U16 AdapterID,
777 P_RCLINKSTATS StatsReturnAddr,
778 PFNWAITCALLBACK WaitCallback)
780 U32 msgOffset;
781 volatile U32 timeout;
782 volatile PU32 pMsg;
783 volatile PU32 p32, pReturnAddr;
784 P_NICSTAT pStats;
785 int i;
786 PPAB pPab;
788 /*kprintf("Get82558Stats() StatsReturnAddr:0x%08.8ulx\n", StatsReturnAddr);*/
790 pPab = PCIAdapterBlock[AdapterID];
792 if (pPab == NULL)
793 return RC_RTN_ADPTR_NOT_REGISTERED;
795 msgOffset = pPab->p_atu->InQueue;
797 if (msgOffset == 0xFFFFFFFF)
799 #ifdef DEBUG
800 kprintf("Get8255XStats(): Inbound Free Q empty!\n");
801 #endif
802 return RC_RTN_FREE_Q_EMPTY;
805 /* calc virual address of msg - virual already mapped to physical */
806 pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
808 /*dprintf("Get82558Stats - pMsg = 0x%08ulx, InQ msgOffset = 0x%08ulx\n", pMsg, msgOffset);*/
809 /*dprintf("Get82558Stats - pMsg = 0x%08X, InQ msgOffset = 0x%08X\n", pMsg, msgOffset);*/
811 pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
812 pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
813 pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
814 pMsg[3] = 0x112; /* transaction context */
815 pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_NIC_STATS;
816 pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB);
818 p32 = (PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
820 pStats = (P_NICSTAT)p32;
821 pStats->dump_status = 0xFFFFFFFF;
823 /* post to Inbound Post Q */
824 pPab->p_atu->InQueue = msgOffset;
826 timeout = 100000;
827 while (1)
829 if (WaitCallback)
830 (*WaitCallback)();
832 for (i = 0; i < 1000; i++)
835 if (pStats->dump_status != 0xFFFFFFFF)
836 break;
838 if (!timeout--)
840 #ifdef DEBUG
841 kprintf("RCGet82558Stats() Timeout waiting for NIC statistics\n");
842 #endif
843 return RC_RTN_MSG_REPLY_TIMEOUT;
847 pReturnAddr = (PU32)StatsReturnAddr;
849 /* copy Nic stats to user's structure */
850 for (i = 0; i < (int) sizeof(RCLINKSTATS) / 4; i++)
851 pReturnAddr[i] = p32[i];
853 return RC_RTN_NO_ERROR;
858 ** =========================================================================
859 ** Get82558LinkStatus()
860 ** =========================================================================
862 RC_RETURN
863 RCGetLinkStatus(U16 AdapterID, PU32 ReturnAddr, PFNWAITCALLBACK WaitCallback)
865 U32 msgOffset;
866 volatile U32 timeout;
867 volatile PU32 pMsg;
868 volatile PU32 p32;
869 PPAB pPab;
871 /*kprintf("Get82558LinkStatus() ReturnPhysAddr:0x%08.8ulx\n", ReturnAddr);*/
873 pPab = PCIAdapterBlock[AdapterID];
875 if (pPab == NULL)
876 return RC_RTN_ADPTR_NOT_REGISTERED;
878 msgOffset = pPab->p_atu->InQueue;
880 if (msgOffset == 0xFFFFFFFF)
882 #ifdef DEBUG
883 dprintf("Get82558LinkStatus(): Inbound Free Q empty!\n");
884 #endif
885 return RC_RTN_FREE_Q_EMPTY;
888 /* calc virual address of msg - virual already mapped to physical */
889 pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
890 /*dprintf("Get82558LinkStatus - pMsg = 0x%08ulx, InQ msgOffset = 0x%08ulx\n", pMsg, msgOffset);*/
891 /*dprintf("Get82558LinkStatus - pMsg = 0x%08X, InQ msgOffset = 0x%08X\n", pMsg, msgOffset);*/
893 pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
894 pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
895 pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
896 pMsg[3] = 0x112; /* transaction context */
897 pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_LINK_STATUS;
898 pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB);
900 p32 = (PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
901 *p32 = 0xFFFFFFFF;
903 /* post to Inbound Post Q */
904 pPab->p_atu->InQueue = msgOffset;
906 timeout = 100000;
907 while (1)
909 U32 i;
911 if (WaitCallback)
912 (*WaitCallback)();
914 for (i = 0; i < 1000; i++)
917 if (*p32 != 0xFFFFFFFF)
918 break;
920 if (!timeout--)
922 #ifdef DEBUG
923 kprintf("Timeout waiting for link status\n");
924 #endif
925 return RC_RTN_MSG_REPLY_TIMEOUT;
929 *ReturnAddr = *p32; /* 1 = up 0 = down */
931 return RC_RTN_NO_ERROR;
936 ** =========================================================================
937 ** RCGetMAC()
939 ** get the MAC address the adapter is listening for in non-promiscous mode.
940 ** MAC address is in media format.
941 ** =========================================================================
943 RC_RETURN
944 RCGetMAC(U16 AdapterID, PU8 mac, PFNWAITCALLBACK WaitCallback)
946 unsigned i, timeout;
947 U32 off;
948 PU32 p;
949 U32 temp[2];
950 PPAB pPab;
951 PATU p_atu;
953 pPab = PCIAdapterBlock[AdapterID];
955 if (pPab == NULL)
956 return RC_RTN_ADPTR_NOT_REGISTERED;
958 p_atu = pPab->p_atu;
960 p_atu->EtherMacLow = 0; /* first zero return data */
961 p_atu->EtherMacHi = 0;
963 off = p_atu->InQueue; /* get addresss of message */
965 if (0xFFFFFFFF == off)
966 return RC_RTN_FREE_Q_EMPTY;
968 p = (PU32)(pPab->pPci45LinBaseAddr + off);
970 #ifdef RCDEBUG
971 printk("RCGetMAC: p_atu 0x%08x, off 0x%08x, p 0x%08x\n",
972 (uint)p_atu, (uint)off, (uint)p);
973 #endif /* RCDEBUG */
974 /* setup private message */
975 p[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0;
976 p[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
977 p[2] = 0; /* initiator context */
978 p[3] = 0x218; /* transaction context */
979 p[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_MAC_ADDR;
982 p_atu->InQueue = off; /* send it to the I2O device */
983 #ifdef RCDEBUG
984 printk("RCGetMAC: p_atu 0x%08x, off 0x%08x, p 0x%08x\n",
985 (uint)p_atu, (uint)off, (uint)p);
986 #endif /* RCDEBUG */
988 /* wait for the rcpci45 board to update the info */
989 timeout = 1000000;
990 while (0 == p_atu->EtherMacLow)
992 if (WaitCallback)
993 (*WaitCallback)();
995 for (i = 0; i < 1000; i++)
998 if (!timeout--)
1000 printk("rc_getmac: Timeout\n");
1001 return RC_RTN_MSG_REPLY_TIMEOUT;
1005 /* read the mac address */
1006 temp[0] = p_atu->EtherMacLow;
1007 temp[1] = p_atu->EtherMacHi;
1008 memcpy((char *)mac, (char *)temp, 6);
1011 #ifdef RCDEBUG
1012 // printk("rc_getmac: 0x%X\n", ptr);
1013 #endif /* RCDEBUG */
1015 return RC_RTN_NO_ERROR;
1020 ** =========================================================================
1021 ** RCSetMAC()
1023 ** set MAC address the adapter is listening for in non-promiscous mode.
1024 ** MAC address is in media format.
1025 ** =========================================================================
1027 RC_RETURN
1028 RCSetMAC(U16 AdapterID, PU8 mac)
1030 U32 off;
1031 PU32 pMsg;
1032 PPAB pPab;
1035 pPab = PCIAdapterBlock[AdapterID];
1037 if (pPab == NULL)
1038 return RC_RTN_ADPTR_NOT_REGISTERED;
1040 off = pPab->p_atu->InQueue; /* get addresss of message */
1042 if (0xFFFFFFFF == off)
1043 return RC_RTN_FREE_Q_EMPTY;
1045 pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
1047 /* setup private message */
1048 pMsg[0] = SEVEN_WORD_MSG_SIZE | SGL_OFFSET_0;
1049 pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
1050 pMsg[2] = 0; /* initiator context */
1051 pMsg[3] = 0x219; /* transaction context */
1052 pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_MAC_ADDR;
1053 pMsg[5] = *(unsigned *)mac; /* first four bytes */
1054 pMsg[6] = *(unsigned *)(mac + 4); /* last two bytes */
1056 pPab->p_atu->InQueue = off; /* send it to the I2O device */
1058 return RC_RTN_NO_ERROR ;
1063 ** =========================================================================
1064 ** RCSetLinkSpeed()
1066 ** set ethernet link speed.
1067 ** input: speedControl - determines action to take as follows
1068 ** 0 = reset and auto-negotiate (NWay)
1069 ** 1 = Full Duplex 100BaseT
1070 ** 2 = Half duplex 100BaseT
1071 ** 3 = Full Duplex 10BaseT
1072 ** 4 = Half duplex 10BaseT
1073 ** all other values are ignore (do nothing)
1074 ** =========================================================================
1076 RC_RETURN
1077 RCSetLinkSpeed(U16 AdapterID, U16 LinkSpeedCode)
1079 U32 off;
1080 PU32 pMsg;
1081 PPAB pPab;
1084 pPab =PCIAdapterBlock[AdapterID];
1086 if (pPab == NULL)
1087 return RC_RTN_ADPTR_NOT_REGISTERED;
1089 off = pPab->p_atu->InQueue; /* get addresss of message */
1091 if (0xFFFFFFFF == off)
1092 return RC_RTN_FREE_Q_EMPTY;
1094 pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
1096 /* setup private message */
1097 pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
1098 pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
1099 pMsg[2] = 0; /* initiator context */
1100 pMsg[3] = 0x219; /* transaction context */
1101 pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_LINK_SPEED;
1102 pMsg[5] = LinkSpeedCode; /* link speed code */
1104 pPab->p_atu->InQueue = off; /* send it to the I2O device */
1106 return RC_RTN_NO_ERROR ;
1109 ** =========================================================================
1110 ** RCSetPromiscuousMode()
1112 ** Defined values for Mode:
1113 ** 0 - turn off promiscuous mode
1114 ** 1 - turn on promiscuous mode
1116 ** =========================================================================
1118 RC_RETURN
1119 RCSetPromiscuousMode(U16 AdapterID, U16 Mode)
1121 U32 off;
1122 PU32 pMsg;
1123 PPAB pPab;
1125 pPab =PCIAdapterBlock[AdapterID];
1127 if (pPab == NULL)
1128 return RC_RTN_ADPTR_NOT_REGISTERED;
1130 off = pPab->p_atu->InQueue; /* get addresss of message */
1132 if (0xFFFFFFFF == off)
1133 return RC_RTN_FREE_Q_EMPTY;
1135 pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
1137 /* setup private message */
1138 pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
1139 pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
1140 pMsg[2] = 0; /* initiator context */
1141 pMsg[3] = 0x219; /* transaction context */
1142 pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_PROMISCUOUS_MODE;
1143 pMsg[5] = Mode; /* promiscuous mode setting */
1145 pPab->p_atu->InQueue = off; /* send it to the device */
1147 return RC_RTN_NO_ERROR ;
1150 ** =========================================================================
1151 ** RCGetPromiscuousMode()
1153 ** get promiscuous mode setting
1155 ** Possible return values placed in pMode:
1156 ** 0 = promisuous mode not set
1157 ** 1 = promisuous mode is set
1159 ** =========================================================================
1161 RC_RETURN
1162 RCGetPromiscuousMode(U16 AdapterID, PU32 pMode, PFNWAITCALLBACK WaitCallback)
1164 U32 msgOffset, timeout;
1165 PU32 pMsg;
1166 volatile PU32 p32;
1167 PPAB pPab;
1169 pPab =PCIAdapterBlock[AdapterID];
1172 msgOffset = pPab->p_atu->InQueue;
1175 if (msgOffset == 0xFFFFFFFF)
1177 kprintf("RCGetLinkSpeed(): Inbound Free Q empty!\n");
1178 return RC_RTN_FREE_Q_EMPTY;
1181 /* calc virtual address of msg - virtual already mapped to physical */
1182 pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
1184 /* virtual pointer to return buffer - clear first two dwords */
1185 p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
1186 p32[0] = 0xff;
1188 /* setup private message */
1189 pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
1190 pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
1191 pMsg[2] = 0; /* initiator context */
1192 pMsg[3] = 0x219; /* transaction context */
1193 pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_PROMISCUOUS_MODE;
1194 /* phys address to return status - area right after PAB */
1195 pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB);
1197 /* post to Inbound Post Q */
1199 pPab->p_atu->InQueue = msgOffset;
1201 /* wait for response */
1202 timeout = 1000000;
1203 while(1)
1205 int i;
1207 if (WaitCallback)
1208 (*WaitCallback)();
1210 for (i = 0; i < 1000; i++) /* please don't hog the bus!!! */
1213 if (p32[0] != 0xff)
1214 break;
1216 if (!timeout--)
1218 kprintf("Timeout waiting for promiscuous mode from adapter\n");
1219 kprintf("0x%08.8ulx\n", p32[0]);
1220 return RC_RTN_NO_LINK_SPEED;
1224 /* get mode */
1225 *pMode = (U8)((volatile PU8)p32)[0] & 0x0f;
1227 return RC_RTN_NO_ERROR;
1230 ** =========================================================================
1231 ** RCSetBroadcastMode()
1233 ** Defined values for Mode:
1234 ** 0 - turn off promiscuous mode
1235 ** 1 - turn on promiscuous mode
1237 ** =========================================================================
1239 RC_RETURN
1240 RCSetBroadcastMode(U16 AdapterID, U16 Mode)
1242 U32 off;
1243 PU32 pMsg;
1244 PPAB pPab;
1246 pPab =PCIAdapterBlock[AdapterID];
1248 if (pPab == NULL)
1249 return RC_RTN_ADPTR_NOT_REGISTERED;
1251 off = pPab->p_atu->InQueue; /* get addresss of message */
1253 if (0xFFFFFFFF == off)
1254 return RC_RTN_FREE_Q_EMPTY;
1256 pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
1258 /* setup private message */
1259 pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
1260 pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
1261 pMsg[2] = 0; /* initiator context */
1262 pMsg[3] = 0x219; /* transaction context */
1263 pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_BROADCAST_MODE;
1264 pMsg[5] = Mode; /* promiscuous mode setting */
1266 pPab->p_atu->InQueue = off; /* send it to the device */
1268 return RC_RTN_NO_ERROR ;
1271 ** =========================================================================
1272 ** RCGetBroadcastMode()
1274 ** get promiscuous mode setting
1276 ** Possible return values placed in pMode:
1277 ** 0 = promisuous mode not set
1278 ** 1 = promisuous mode is set
1280 ** =========================================================================
1282 RC_RETURN
1283 RCGetBroadcastMode(U16 AdapterID, PU32 pMode, PFNWAITCALLBACK WaitCallback)
1285 U32 msgOffset, timeout;
1286 PU32 pMsg;
1287 volatile PU32 p32;
1288 PPAB pPab;
1290 pPab =PCIAdapterBlock[AdapterID];
1293 msgOffset = pPab->p_atu->InQueue;
1296 if (msgOffset == 0xFFFFFFFF)
1298 kprintf("RCGetLinkSpeed(): Inbound Free Q empty!\n");
1299 return RC_RTN_FREE_Q_EMPTY;
1302 /* calc virtual address of msg - virtual already mapped to physical */
1303 pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
1305 /* virtual pointer to return buffer - clear first two dwords */
1306 p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
1307 p32[0] = 0xff;
1309 /* setup private message */
1310 pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
1311 pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
1312 pMsg[2] = 0; /* initiator context */
1313 pMsg[3] = 0x219; /* transaction context */
1314 pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_BROADCAST_MODE;
1315 /* phys address to return status - area right after PAB */
1316 pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB);
1318 /* post to Inbound Post Q */
1320 pPab->p_atu->InQueue = msgOffset;
1322 /* wait for response */
1323 timeout = 1000000;
1324 while(1)
1326 int i;
1328 if (WaitCallback)
1329 (*WaitCallback)();
1331 for (i = 0; i < 1000; i++) /* please don't hog the bus!!! */
1334 if (p32[0] != 0xff)
1335 break;
1337 if (!timeout--)
1339 kprintf("Timeout waiting for promiscuous mode from adapter\n");
1340 kprintf("0x%08.8ulx\n", p32[0]);
1341 return RC_RTN_NO_LINK_SPEED;
1345 /* get mode */
1346 *pMode = (U8)((volatile PU8)p32)[0] & 0x0f;
1348 return RC_RTN_NO_ERROR;
1352 ** =========================================================================
1353 ** RCGetLinkSpeed()
1355 ** get ethernet link speed.
1357 ** 0 = Unknown
1358 ** 1 = Full Duplex 100BaseT
1359 ** 2 = Half duplex 100BaseT
1360 ** 3 = Full Duplex 10BaseT
1361 ** 4 = Half duplex 10BaseT
1363 ** =========================================================================
1365 RC_RETURN
1366 RCGetLinkSpeed(U16 AdapterID, PU32 pLinkSpeedCode, PFNWAITCALLBACK WaitCallback)
1368 U32 msgOffset, timeout;
1369 PU32 pMsg;
1370 volatile PU32 p32;
1371 U8 IOPLinkSpeed;
1372 PPAB pPab;
1374 pPab =PCIAdapterBlock[AdapterID];
1377 msgOffset = pPab->p_atu->InQueue;
1380 if (msgOffset == 0xFFFFFFFF)
1382 kprintf("RCGetLinkSpeed(): Inbound Free Q empty!\n");
1383 return RC_RTN_FREE_Q_EMPTY;
1386 /* calc virtual address of msg - virtual already mapped to physical */
1387 pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
1389 /* virtual pointer to return buffer - clear first two dwords */
1390 p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
1391 p32[0] = 0xff;
1393 /* setup private message */
1394 pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
1395 pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
1396 pMsg[2] = 0; /* initiator context */
1397 pMsg[3] = 0x219; /* transaction context */
1398 pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_LINK_SPEED;
1399 /* phys address to return status - area right after PAB */
1400 pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB);
1402 /* post to Inbound Post Q */
1404 pPab->p_atu->InQueue = msgOffset;
1406 /* wait for response */
1407 timeout = 1000000;
1408 while(1)
1410 int i;
1412 if (WaitCallback)
1413 (*WaitCallback)();
1415 for (i = 0; i < 1000; i++) /* please don't hog the bus!!! */
1418 if (p32[0] != 0xff)
1419 break;
1421 if (!timeout--)
1423 kprintf("Timeout waiting for link speed from IOP\n");
1424 kprintf("0x%08.8ulx\n", p32[0]);
1425 return RC_RTN_NO_LINK_SPEED;
1429 /* get Link speed */
1430 IOPLinkSpeed = (U8)((volatile PU8)p32)[0] & 0x0f;
1432 *pLinkSpeedCode= IOPLinkSpeed;
1434 return RC_RTN_NO_ERROR;
1438 ** =========================================================================
1439 ** RCReportDriverCapability(U16 AdapterID, U32 capability)
1441 ** Currently defined bits:
1442 ** WARM_REBOOT_CAPABLE 0x01
1444 ** =========================================================================
1446 RC_RETURN
1447 RCReportDriverCapability(U16 AdapterID, U32 capability)
1449 U32 off;
1450 PU32 pMsg;
1451 PPAB pPab;
1453 pPab =PCIAdapterBlock[AdapterID];
1455 if (pPab == NULL)
1456 return RC_RTN_ADPTR_NOT_REGISTERED;
1458 off = pPab->p_atu->InQueue; /* get addresss of message */
1460 if (0xFFFFFFFF == off)
1461 return RC_RTN_FREE_Q_EMPTY;
1463 pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
1465 /* setup private message */
1466 pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
1467 pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
1468 pMsg[2] = 0; /* initiator context */
1469 pMsg[3] = 0x219; /* transaction context */
1470 pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_REPORT_DRIVER_CAPABILITY;
1471 pMsg[5] = capability;
1473 pPab->p_atu->InQueue = off; /* send it to the I2O device */
1475 return RC_RTN_NO_ERROR ;
1479 ** =========================================================================
1480 ** RCGetFirmwareVer()
1482 ** Return firmware version in the form "SoftwareVersion : Bt BootVersion"
1484 ** =========================================================================
1486 RC_RETURN
1487 RCGetFirmwareVer(U16 AdapterID, PU8 pFirmString, PFNWAITCALLBACK WaitCallback)
1489 U32 msgOffset, timeout;
1490 PU32 pMsg;
1491 volatile PU32 p32;
1492 PPAB pPab;
1494 pPab =PCIAdapterBlock[AdapterID];
1496 msgOffset = pPab->p_atu->InQueue;
1499 if (msgOffset == 0xFFFFFFFF)
1501 kprintf("RCGetFirmwareVer(): Inbound Free Q empty!\n");
1502 return RC_RTN_FREE_Q_EMPTY;
1505 /* calc virtual address of msg - virtual already mapped to physical */
1506 pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
1508 /* virtual pointer to return buffer - clear first two dwords */
1509 p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
1510 p32[0] = 0xff;
1512 /* setup private message */
1513 pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
1514 pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
1515 pMsg[2] = 0; /* initiator context */
1516 pMsg[3] = 0x219; /* transaction context */
1517 pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_FIRMWARE_REV;
1518 /* phys address to return status - area right after PAB */
1519 pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB);
1523 /* post to Inbound Post Q */
1525 pPab->p_atu->InQueue = msgOffset;
1528 /* wait for response */
1529 timeout = 1000000;
1530 while(1)
1532 int i;
1534 if (WaitCallback)
1535 (*WaitCallback)();
1537 for (i = 0; i < 1000; i++) /* please don't hog the bus!!! */
1540 if (p32[0] != 0xff)
1541 break;
1543 if (!timeout--)
1545 kprintf("Timeout waiting for link speed from IOP\n");
1546 return RC_RTN_NO_FIRM_VER;
1550 strcpy(pFirmString, (PU8)p32);
1551 return RC_RTN_NO_ERROR;
1555 ** =========================================================================
1556 ** RCResetLANCard()
1558 ** ResourceFlags indicates whether to return buffer resource explicitly
1559 ** to host or keep and reuse.
1560 ** CallbackFunction (if not NULL) is the function to be called when
1561 ** reset is complete.
1562 ** If CallbackFunction is NULL, ReturnAddr will have a 1 placed in it when
1563 ** reset is done (if not NULL).
1565 ** =========================================================================
1567 RC_RETURN
1568 RCResetLANCard(U16 AdapterID, U16 ResourceFlags, PU32 ReturnAddr, PFNCALLBACK CallbackFunction)
1570 unsigned long off;
1571 unsigned long *pMsg;
1572 PPAB pPab;
1573 int i;
1574 long timeout = 0;
1577 pPab =PCIAdapterBlock[AdapterID];
1579 if (pPab == NULL)
1580 return RC_RTN_ADPTR_NOT_REGISTERED;
1582 off = pPab->p_atu->InQueue; /* get addresss of message */
1584 if (0xFFFFFFFF == off)
1585 return RC_RTN_FREE_Q_EMPTY;
1587 pPab->pCallbackFunc = CallbackFunction;
1589 pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
1591 /* setup message */
1592 pMsg[0] = FOUR_WORD_MSG_SIZE | SGL_OFFSET_0;
1593 pMsg[1] = I2O_LAN_RESET << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
1594 pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
1595 pMsg[3] = ResourceFlags << 16; /* resource flags */
1597 pPab->p_atu->InQueue = off; /* send it to the I2O device */
1599 if (CallbackFunction == (PFNCALLBACK)NULL)
1601 /* call RCProcI2OMsgQ() until something in pPab->pCallbackFunc
1602 or until timer goes off */
1603 while (pPab->pCallbackFunc == (PFNCALLBACK)NULL)
1605 RCProcI2OMsgQ(AdapterID);
1606 for (i = 0; i < 100000; i++) /* please don't hog the bus!!! */
1608 timeout++;
1609 if (timeout > 10000)
1611 break;
1614 if (ReturnAddr != (PU32)NULL)
1615 *ReturnAddr = (U32)pPab->pCallbackFunc;
1618 return RC_RTN_NO_ERROR ;
1621 ** =========================================================================
1622 ** RCResetIOP()
1624 ** Send StatusGet Msg, wait for results return directly to buffer.
1626 ** =========================================================================
1628 RC_RETURN
1629 RCResetIOP(U16 AdapterID)
1631 U32 msgOffset, timeout;
1632 PU32 pMsg;
1633 PPAB pPab;
1634 volatile PU32 p32;
1636 pPab = PCIAdapterBlock[AdapterID];
1637 msgOffset = pPab->p_atu->InQueue;
1639 if (msgOffset == 0xFFFFFFFF)
1641 return RC_RTN_FREE_Q_EMPTY;
1644 /* calc virtual address of msg - virtual already mapped to physical */
1645 pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
1647 pMsg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_0;
1648 pMsg[1] = I2O_EXEC_IOP_RESET << 24 | I2O_HOST_TID << 12 | I2O_IOP_TID;
1649 pMsg[2] = 0; /* universal context */
1650 pMsg[3] = 0; /* universal context */
1651 pMsg[4] = 0; /* universal context */
1652 pMsg[5] = 0; /* universal context */
1653 /* phys address to return status - area right after PAB */
1654 pMsg[6] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB);
1655 pMsg[7] = 0;
1656 pMsg[8] = 1; /* return 1 byte */
1658 /* virual pointer to return buffer - clear first two dwords */
1659 p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
1660 p32[0] = 0;
1661 p32[1] = 0;
1663 /* post to Inbound Post Q */
1665 pPab->p_atu->InQueue = msgOffset;
1667 /* wait for response */
1668 timeout = 1000000;
1669 while(1)
1671 int i;
1673 for (i = 0; i < 1000; i++) /* please don't hog the bus!!! */
1676 if (p32[0] || p32[1])
1677 break;
1679 if (!timeout--)
1681 printk("RCResetIOP timeout\n");
1682 return RC_RTN_MSG_REPLY_TIMEOUT;
1685 return RC_RTN_NO_ERROR;
1689 ** =========================================================================
1690 ** RCShutdownLANCard()
1692 ** ResourceFlags indicates whether to return buffer resource explicitly
1693 ** to host or keep and reuse.
1694 ** CallbackFunction (if not NULL) is the function to be called when
1695 ** shutdown is complete.
1696 ** If CallbackFunction is NULL, ReturnAddr will have a 1 placed in it when
1697 ** shutdown is done (if not NULL).
1699 ** =========================================================================
1701 RC_RETURN
1702 RCShutdownLANCard(U16 AdapterID, U16 ResourceFlags, PU32 ReturnAddr, PFNCALLBACK CallbackFunction)
1704 volatile PU32 pMsg;
1705 U32 off;
1706 PPAB pPab;
1707 int i;
1708 long timeout = 0;
1710 pPab = PCIAdapterBlock[AdapterID];
1712 if (pPab == NULL)
1713 return RC_RTN_ADPTR_NOT_REGISTERED;
1715 off = pPab->p_atu->InQueue; /* get addresss of message */
1717 if (0xFFFFFFFF == off)
1718 return RC_RTN_FREE_Q_EMPTY;
1720 pPab->pCallbackFunc = CallbackFunction;
1722 pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
1724 /* setup message */
1725 pMsg[0] = FOUR_WORD_MSG_SIZE | SGL_OFFSET_0;
1726 pMsg[1] = I2O_LAN_SHUTDOWN << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
1727 pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
1728 pMsg[3] = ResourceFlags << 16; /* resource flags */
1730 pPab->p_atu->InQueue = off; /* send it to the I2O device */
1732 if (CallbackFunction == (PFNCALLBACK)NULL)
1734 /* call RCProcI2OMsgQ() until something in pPab->pCallbackFunc
1735 or until timer goes off */
1736 while (pPab->pCallbackFunc == (PFNCALLBACK)NULL)
1738 RCProcI2OMsgQ(AdapterID);
1739 for (i = 0; i < 100000; i++) /* please don't hog the bus!!! */
1741 timeout++;
1742 if (timeout > 10000)
1744 printk("RCShutdownLANCard(): timeout\n");
1745 break;
1748 if (ReturnAddr != (PU32)NULL)
1749 *ReturnAddr = (U32)pPab->pCallbackFunc;
1751 return RC_RTN_NO_ERROR ;
1756 ** =========================================================================
1757 ** RCSetRavlinIPandMask()
1759 ** Set the Ravlin 45/PCI cards IP address and network mask.
1761 ** IP address and mask must be in network byte order.
1762 ** For example, IP address 1.2.3.4 and mask 255.255.255.0 would be
1763 ** 0x04030201 and 0x00FFFFFF on a little endian machine.
1765 ** =========================================================================
1767 RC_RETURN
1768 RCSetRavlinIPandMask(U16 AdapterID, U32 ipAddr, U32 netMask)
1770 volatile PU32 pMsg;
1771 U32 off;
1772 PPAB pPab;
1774 pPab = PCIAdapterBlock[AdapterID];
1776 if (pPab == NULL)
1777 return RC_RTN_ADPTR_NOT_REGISTERED;
1779 off = pPab->p_atu->InQueue; /* get addresss of message */
1781 if (0xFFFFFFFF == off)
1782 return RC_RTN_FREE_Q_EMPTY;
1784 pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
1786 /* setup private message */
1787 pMsg[0] = SEVEN_WORD_MSG_SIZE | SGL_OFFSET_0;
1788 pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
1789 pMsg[2] = 0; /* initiator context */
1790 pMsg[3] = 0x219; /* transaction context */
1791 pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_IP_AND_MASK;
1792 pMsg[5] = ipAddr;
1793 pMsg[6] = netMask;
1796 pPab->p_atu->InQueue = off; /* send it to the I2O device */
1797 return RC_RTN_NO_ERROR ;
1802 ** =========================================================================
1803 ** RCGetRavlinIPandMask()
1805 ** get the IP address and MASK from the card
1807 ** =========================================================================
1809 RC_RETURN
1810 RCGetRavlinIPandMask(U16 AdapterID, PU32 pIpAddr, PU32 pNetMask,
1811 PFNWAITCALLBACK WaitCallback)
1813 unsigned i, timeout;
1814 U32 off;
1815 PU32 pMsg, p32;
1816 PPAB pPab;
1817 PATU p_atu;
1819 #ifdef DEBUG
1820 kprintf("RCGetRavlinIPandMask: pIpAddr is 0x%08.8ulx, *IpAddr is 0x%08.8ulx\n", pIpAddr, *pIpAddr);
1821 #endif /* DEBUG */
1823 pPab = PCIAdapterBlock[AdapterID];
1825 if (pPab == NULL)
1826 return RC_RTN_ADPTR_NOT_REGISTERED;
1828 p_atu = pPab->p_atu;
1829 off = p_atu->InQueue; /* get addresss of message */
1831 if (0xFFFFFFFF == off)
1832 return RC_RTN_FREE_Q_EMPTY;
1834 p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
1835 *p32 = 0xFFFFFFFF;
1837 pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
1839 #ifdef DEBUG
1840 kprintf("RCGetRavlinIPandMask: p_atu 0x%08.8ulx, off 0x%08.8ulx, p32 0x%08.8ulx\n", p_atu, off, p32);
1841 #endif /* DEBUG */
1842 /* setup private message */
1843 pMsg[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0;
1844 pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
1845 pMsg[2] = 0; /* initiator context */
1846 pMsg[3] = 0x218; /* transaction context */
1847 pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_IP_AND_MASK;
1848 pMsg[5] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB);
1850 p_atu->InQueue = off; /* send it to the I2O device */
1851 #ifdef DEBUG
1852 kprintf("RCGetRavlinIPandMask: p_atu 0x%08.8ulx, off 0x%08.8ulx, p32 0x%08.8ulx\n", p_atu, off, p32);
1853 #endif /* DEBUG */
1855 /* wait for the rcpci45 board to update the info */
1856 timeout = 100000;
1857 while (0xffffffff == *p32)
1859 if (WaitCallback)
1860 (*WaitCallback)();
1862 for (i = 0; i < 1000; i++)
1865 if (!timeout--)
1867 #ifdef DEBUG
1868 kprintf("RCGetRavlinIPandMask: Timeout\n");
1869 #endif /* DEBUG */
1870 return RC_RTN_MSG_REPLY_TIMEOUT;
1874 #ifdef DEBUG
1875 kprintf("RCGetRavlinIPandMask: after time out\n", \
1876 "p32[0] (IpAddr) 0x%08.8ulx, p32[1] (IPmask) 0x%08.8ulx\n", p32[0], p32[1]);
1877 #endif /* DEBUG */
1879 /* send IP and mask to user's space */
1880 *pIpAddr = p32[0];
1881 *pNetMask = p32[1];
1884 #ifdef DEBUG
1885 kprintf("RCGetRavlinIPandMask: pIpAddr is 0x%08.8ulx, *IpAddr is 0x%08.8ulx\n", pIpAddr, *pIpAddr);
1886 #endif /* DEBUG */
1888 return RC_RTN_NO_ERROR;
1892 ** /////////////////////////////////////////////////////////////////////////
1893 ** /////////////////////////////////////////////////////////////////////////
1895 ** local functions
1897 ** /////////////////////////////////////////////////////////////////////////
1898 ** /////////////////////////////////////////////////////////////////////////
1902 ** =========================================================================
1903 ** SendI2OOutboundQInitMsg()
1905 ** =========================================================================
1907 static int
1908 SendI2OOutboundQInitMsg(PPAB pPab)
1910 U32 msgOffset, timeout, phyOutQFrames, i;
1911 volatile PU32 pMsg;
1912 volatile PU32 p32;
1916 msgOffset = pPab->p_atu->InQueue;
1919 if (msgOffset == 0xFFFFFFFF)
1921 #ifdef DEBUG
1922 kprintf("SendI2OOutboundQInitMsg(): Inbound Free Q empty!\n");
1923 #endif /* DEBUG */
1924 return RC_RTN_FREE_Q_EMPTY;
1928 /* calc virual address of msg - virual already mapped to physical */
1929 pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
1931 #ifdef DEBUG
1932 kprintf("SendI2OOutboundQInitMsg - pMsg = 0x%08.8ulx, InQ msgOffset = 0x%08.8ulx\n", pMsg, msgOffset);
1933 #endif /* DEBUG */
1935 pMsg[0] = EIGHT_WORD_MSG_SIZE | TRL_OFFSET_6;
1936 pMsg[1] = I2O_EXEC_OUTBOUND_INIT << 24 | I2O_HOST_TID << 12 | I2O_IOP_TID;
1937 pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
1938 pMsg[3] = 0x106; /* transaction context */
1939 pMsg[4] = 4096; /* Host page frame size */
1940 pMsg[5] = MSG_FRAME_SIZE << 16 | 0x80; /* outbound msg frame size and Initcode */
1941 pMsg[6] = 0xD0000004; /* simple sgl element LE, EOB */
1942 /* phys address to return status - area right after PAB */
1943 pMsg[7] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB);
1945 /* virual pointer to return buffer - clear first two dwords */
1946 p32 = (PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
1947 p32[0] = 0;
1949 /* post to Inbound Post Q */
1950 pPab->p_atu->InQueue = msgOffset;
1952 /* wait for response */
1953 timeout = 100000;
1954 while(1)
1956 for (i = 0; i < 1000; i++) /* please don't hog the bus!!! */
1959 if (p32[0])
1960 break;
1962 if (!timeout--)
1964 #ifdef DEBUG
1965 kprintf("Timeout wait for InitOutQ InPrgress status from IOP\n");
1966 #endif /* DEBUG */
1967 return RC_RTN_NO_I2O_STATUS;
1971 timeout = 100000;
1972 while(1)
1974 for (i = 0; i < 1000; i++) /* please don't hog the bus!!! */
1977 if (p32[0] == I2O_EXEC_OUTBOUND_INIT_COMPLETE)
1978 break;
1980 if (!timeout--)
1982 #ifdef DEBUG
1983 kprintf("Timeout wait for InitOutQ Complete status from IOP\n");
1984 #endif /* DEBUG */
1985 return RC_RTN_NO_I2O_STATUS;
1989 /* load PCI outbound free Q with MF physical addresses */
1990 phyOutQFrames = pPab->outMsgBlockPhyAddr;
1992 for (i = 0; i < NMBR_MSG_FRAMES; i++)
1994 pPab->p_atu->OutQueue = phyOutQFrames;
1995 phyOutQFrames += MSG_FRAME_SIZE;
1997 return RC_RTN_NO_ERROR;
2002 ** =========================================================================
2003 ** GetI2OStatus()
2005 ** Send StatusGet Msg, wait for results return directly to buffer.
2007 ** =========================================================================
2009 static int
2010 GetI2OStatus(PPAB pPab)
2012 U32 msgOffset, timeout;
2013 PU32 pMsg;
2014 volatile PU32 p32;
2017 msgOffset = pPab->p_atu->InQueue;
2018 #ifdef DEBUG
2019 printk("GetI2OStatus: msg offset = 0x%x\n", msgOffset);
2020 #endif /* DEBUG */
2021 if (msgOffset == 0xFFFFFFFF)
2023 #ifdef DEBUG
2024 kprintf("GetI2OStatus(): Inbound Free Q empty!\n");
2025 #endif /* DEBUG */
2026 return RC_RTN_FREE_Q_EMPTY;
2029 /* calc virual address of msg - virual already mapped to physical */
2030 pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
2032 pMsg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_0;
2033 pMsg[1] = I2O_EXEC_STATUS_GET << 24 | I2O_HOST_TID << 12 | I2O_IOP_TID;
2034 pMsg[2] = 0; /* universal context */
2035 pMsg[3] = 0; /* universal context */
2036 pMsg[4] = 0; /* universal context */
2037 pMsg[5] = 0; /* universal context */
2038 /* phys address to return status - area right after PAB */
2039 pMsg[6] = pPab->outMsgBlockPhyAddr - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB);
2040 pMsg[7] = 0;
2041 pMsg[8] = 88; /* return 88 bytes */
2043 /* virual pointer to return buffer - clear first two dwords */
2044 p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
2045 p32[0] = 0;
2046 p32[1] = 0;
2048 #ifdef DEBUG
2049 kprintf("GetI2OStatus - pMsg:0x%08.8ulx, msgOffset:0x%08.8ulx, [1]:0x%08.8ulx, [6]:0x%08.8ulx\n",
2050 pMsg, msgOffset, pMsg[1], pMsg[6]);
2051 #endif /* DEBUG */
2053 /* post to Inbound Post Q */
2054 pPab->p_atu->InQueue = msgOffset;
2056 #ifdef DEBUG
2057 kprintf("Return status to p32 = 0x%08.8ulx\n", p32);
2058 #endif /* DEBUG */
2060 /* wait for response */
2061 timeout = 1000000;
2062 while(1)
2064 int i;
2066 for (i = 0; i < 1000; i++) /* please don't hog the bus!!! */
2069 if (p32[0] && p32[1])
2070 break;
2072 if (!timeout--)
2074 #ifdef DEBUG
2075 kprintf("Timeout waiting for status from IOP\n");
2076 kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[0], p32[1], p32[2], p32[3]);
2077 kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[4], p32[5], p32[6], p32[7]);
2078 kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[8], p32[9], p32[10], p32[11]);
2079 #endif /* DEBUG */
2080 return RC_RTN_NO_I2O_STATUS;
2084 #ifdef DEBUG
2085 kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[0], p32[1], p32[2], p32[3]);
2086 kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[4], p32[5], p32[6], p32[7]);
2087 kprintf("0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[8], p32[9], p32[10], p32[11]);
2088 #endif /* DEBUG */
2089 /* get IOP state */
2090 pPab->IOPState = ((volatile PU8)p32)[10];
2091 pPab->InboundMFrameSize = ((volatile PU16)p32)[6];
2093 #ifdef DEBUG
2094 kprintf("IOP state 0x%02.2x InFrameSize = 0x%04.4x\n",
2095 pPab->IOPState, pPab->InboundMFrameSize);
2096 #endif /* DEBUG */
2097 return RC_RTN_NO_ERROR;
2102 ** =========================================================================
2103 ** SendEnableSysMsg()
2106 ** =========================================================================
2108 static int
2109 SendEnableSysMsg(PPAB pPab)
2111 U32 msgOffset; // timeout;
2112 volatile PU32 pMsg;
2114 msgOffset = pPab->p_atu->InQueue;
2116 if (msgOffset == 0xFFFFFFFF)
2118 #ifdef DEBUG
2119 kprintf("SendEnableSysMsg(): Inbound Free Q empty!\n");
2120 #endif /* DEBUG */
2121 return RC_RTN_FREE_Q_EMPTY;
2124 /* calc virual address of msg - virual already mapped to physical */
2125 pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
2127 #ifdef DEBUG
2128 kprintf("SendEnableSysMsg - pMsg = 0x%08.8ulx, InQ msgOffset = 0x%08.8ulx\n", pMsg, msgOffset);
2129 #endif /* DEBUG */
2131 pMsg[0] = FOUR_WORD_MSG_SIZE | SGL_OFFSET_0;
2132 pMsg[1] = I2O_EXEC_SYS_ENABLE << 24 | I2O_HOST_TID << 12 | I2O_IOP_TID;
2133 pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
2134 pMsg[3] = 0x110; /* transaction context */
2135 pMsg[4] = 0x50657465; /* RedCreek Private */
2137 /* post to Inbound Post Q */
2138 pPab->p_atu->InQueue = msgOffset;
2140 return RC_RTN_NO_ERROR;
2145 ** =========================================================================
2146 ** FillI2OMsgFromTCB()
2148 ** inputs pMsgU32 - virual pointer (mapped to physical) of message frame
2149 ** pXmitCntrlBlock - pointer to caller buffer control block.
2151 ** fills in LAN SGL after Transaction Control Word or Bucket Count.
2152 ** =========================================================================
2154 static int
2155 FillI2OMsgSGLFromTCB(PU32 pMsgFrame, PRCTCB pTransCtrlBlock)
2157 unsigned int nmbrBuffers, nmbrSeg, nmbrDwords, context, flags;
2158 PU32 pTCB, pMsg;
2160 /* SGL element flags */
2161 #define EOB 0x40000000
2162 #define LE 0x80000000
2163 #define SIMPLE_SGL 0x10000000
2164 #define BC_PRESENT 0x01000000
2166 pTCB = (PU32)pTransCtrlBlock;
2167 pMsg = pMsgFrame;
2168 nmbrDwords = 0;
2170 #ifdef DEBUG
2171 kprintf("FillI2OMsgSGLFromTCBX\n");
2172 kprintf("TCB 0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n",
2173 pTCB[0], pTCB[1], pTCB[2], pTCB[3], pTCB[4]);
2174 kprintf("pTCB 0x%08.8ulx, pMsg 0x%08.8ulx\n", pTCB, pMsg);
2175 #endif /* DEBUG */
2177 nmbrBuffers = *pTCB++;
2179 if (!nmbrBuffers)
2181 return -1;
2186 context = *pTCB++; /* buffer tag (context) */
2187 nmbrSeg = *pTCB++; /* number of segments */
2189 if (!nmbrSeg)
2191 return -1;
2194 flags = SIMPLE_SGL | BC_PRESENT;
2196 if (1 == nmbrSeg)
2198 flags |= EOB;
2200 if (1 == nmbrBuffers)
2201 flags |= LE;
2204 /* 1st SGL buffer element has context */
2205 pMsg[0] = pTCB[0] | flags ; /* send over count (segment size) */
2206 pMsg[1] = context;
2207 pMsg[2] = pTCB[1]; /* send buffer segment physical address */
2208 nmbrDwords += 3;
2209 pMsg += 3;
2210 pTCB += 2;
2213 if (--nmbrSeg)
2217 flags = SIMPLE_SGL;
2219 if (1 == nmbrSeg)
2221 flags |= EOB;
2223 if (1 == nmbrBuffers)
2224 flags |= LE;
2227 pMsg[0] = pTCB[0] | flags; /* send over count */
2228 pMsg[1] = pTCB[1]; /* send buffer segment physical address */
2229 nmbrDwords += 2;
2230 pTCB += 2;
2231 pMsg += 2;
2233 } while (--nmbrSeg);
2236 } while (--nmbrBuffers);
2238 return nmbrDwords;
2243 ** =========================================================================
2244 ** ProcessOutboundI2OMsg()
2246 ** process I2O reply message
2247 ** * change to msg structure *
2248 ** =========================================================================
2250 static void
2251 ProcessOutboundI2OMsg(PPAB pPab, U32 phyAddrMsg)
2253 PU8 p8Msg;
2254 PU32 p32;
2255 // U16 count;
2258 p8Msg = pPab->pLinOutMsgBlock + (phyAddrMsg - pPab->outMsgBlockPhyAddr);
2259 p32 = (PU32)p8Msg;
2261 #ifdef DEBUG
2262 kprintf("VXD: ProcessOutboundI2OMsg - pPab 0x%08.8ulx, phyAdr 0x%08.8ulx, linAdr 0x%08.8ulx\n", pPab, phyAddrMsg, p8Msg);
2263 kprintf("msg :0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[0], p32[1], p32[2], p32[3]);
2264 kprintf("msg :0x%08.8ulx:0x%08.8ulx:0x%08.8ulx:0x%08.8ulx\n", p32[4], p32[5], p32[6], p32[7]);
2265 #endif /* DEBUG */
2267 if (p32[4] >> 24 != I2O_REPLY_STATUS_SUCCESS)
2269 #ifdef DEBUG
2270 kprintf("Message reply status not success\n");
2271 #endif /* DEBUG */
2272 return;
2275 switch (p8Msg[7] ) /* function code byte */
2277 case I2O_EXEC_SYS_TAB_SET:
2278 msgFlag = 1;
2279 #ifdef DEBUG
2280 kprintf("Received I2O_EXEC_SYS_TAB_SET reply\n");
2281 #endif /* DEBUG */
2282 break;
2284 case I2O_EXEC_HRT_GET:
2285 msgFlag = 1;
2286 #ifdef DEBUG
2287 kprintf("Received I2O_EXEC_HRT_GET reply\n");
2288 #endif /* DEBUG */
2289 break;
2291 case I2O_EXEC_LCT_NOTIFY:
2292 msgFlag = 1;
2293 #ifdef DEBUG
2294 kprintf("Received I2O_EXEC_LCT_NOTIFY reply\n");
2295 #endif /* DEBUG */
2296 break;
2298 case I2O_EXEC_SYS_ENABLE:
2299 msgFlag = 1;
2300 #ifdef DEBUG
2301 kprintf("Received I2O_EXEC_SYS_ENABLE reply\n");
2302 #endif /* DEBUG */
2303 break;
2305 default:
2306 #ifdef DEBUG
2307 kprintf("Received UNKNOWN reply\n");
2308 #endif /* DEBUG */
2309 break;