2 ** *************************************************************************
5 ** R C L A N M T L . C $Revision: 6 $
8 ** RedCreek I2O LAN Message Transport Layer program module.
10 ** ---------------------------------------------------------------------
11 ** --- Copyright (c) 1997-1999, RedCreek Communications Inc. ---
12 ** --- All rights reserved. ---
13 ** ---------------------------------------------------------------------
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 ** *************************************************************************
41 #define RC_LINUX_MODULE
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
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
237 BF TargetAddress
:I2O_TID_SZ
;
238 BF InitiatorAddress
:I2O_TID_SZ
;
239 BF Function
:I2O_FUNCTION_SZ
;
240 U32 InitiatorContext
;
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
;
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.
291 PATU p_atu
; /* ptr to ATU register block */
292 PU8 pPci45LinBaseAddr
;
294 U32 outMsgBlockPhyAddr
;
295 PFNTXCALLBACK pTransCallbackFunc
;
296 PFNRXCALLBACK pRecvCallbackFunc
;
297 PFNCALLBACK pRebootCallbackFunc
;
298 PFNCALLBACK pCallbackFunc
;
300 U16 InboundMFrameSize
;
305 ** in reserved space right after PAB in host memory is area for returning
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
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 */
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 ** =========================================================================
389 RCInitI2OMsgLayer(U16 AdapterID
, U32 pciBaseAddr
,
390 PU8 p_msgbuf
, PU8 p_phymsgbuf
,
391 PFNTXCALLBACK TransmitCallbackFunction
,
392 PFNRXCALLBACK ReceiveCallbackFunction
,
393 PFNCALLBACK RebootCallbackFunction
)
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
);
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
)
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
)
451 result
= SendEnableSysMsg(pPab
);
453 if (result
!= RC_RTN_NO_ERROR
)
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
)
477 pPab
= PCIAdapterBlock
[AdapterID
];
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
)
491 pPab
= PCIAdapterBlock
[AdapterID
];
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 ** =========================================================================
506 ** =========================================================================
509 RCI2OSendPacket(U16 AdapterID
, U32 InitiatorContext
, PRCTCB pTransCtrlBlock
)
517 kprintf("RCI2OSendPacket()...\n");
520 pPab
= PCIAdapterBlock
[AdapterID
];
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)
533 kprintf("RCI2OSendPacket(): Inbound Free Q empty!\n");
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 */
546 kprintf("RCI2OSendPacket(): Error Rrocess TCB!\n");
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 ** =========================================================================
575 RCPostRecvBuffers(U16 AdapterID
, PRCTCB pTransCtrlBlock
)
583 kprintf("RCPostRecvBuffers()...\n");
586 /* search for DeviceHandle */
587 pPab
= PCIAdapterBlock
[AdapterID
];
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)
600 kprintf("RCPostRecvBuffers(): Inbound Free Q empty!\n");
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 */
613 kprintf("RCPostRecvBuffers(): Error Processing TCB! size = %d\n", size
);
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
;
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 */
628 pPab
->p_atu
->InQueue
= msgOffset
;
629 return RC_RTN_NO_ERROR
;
635 ** =========================================================================
638 ** Process I2O outbound message queue until empty.
639 ** =========================================================================
642 RCProcI2OMsgQ(U16 AdapterID
)
649 unsigned char debug_msg
[20];
651 pPab
= PCIAdapterBlock
[AdapterID
];
656 phyAddrMsg
= pPab
->p_atu
->OutQueue
;
658 while (phyAddrMsg
!= 0xFFFFFFFF)
660 p8Msg
= pPab
->pLinOutMsgBlock
+ (phyAddrMsg
- pPab
->outMsgBlockPhyAddr
);
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])
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]);
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
);
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]);
710 case RC_PRIVATE_DEBUG_MSG
:
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';
736 case RC_PRIVATE_REBOOT
:
737 printk("Adapter reboot initiated...\n");
738 if (pPab
->pRebootCallbackFunc
)
740 (*pPab
->pRebootCallbackFunc
)(0,0,0,AdapterID
);
744 printk("Unknown private I2O msg received: 0x%lx\n",
751 ** Process other Msg's
755 ProcessOutboundI2OMsg(pPab
, phyAddrMsg
);
758 /* return MFA to outbound free Q*/
759 pPab
->p_atu
->OutQueue
= phyAddrMsg
;
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 ** =========================================================================
776 RCGetLinkStatistics(U16 AdapterID
,
777 P_RCLINKSTATS StatsReturnAddr
,
778 PFNWAITCALLBACK WaitCallback
)
781 volatile U32 timeout
;
783 volatile PU32 p32
, pReturnAddr
;
788 /*kprintf("Get82558Stats() StatsReturnAddr:0x%08.8ulx\n", StatsReturnAddr);*/
790 pPab
= PCIAdapterBlock
[AdapterID
];
793 return RC_RTN_ADPTR_NOT_REGISTERED
;
795 msgOffset
= pPab
->p_atu
->InQueue
;
797 if (msgOffset
== 0xFFFFFFFF)
800 kprintf("Get8255XStats(): Inbound Free Q empty!\n");
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
;
832 for (i
= 0; i
< 1000; i
++)
835 if (pStats
->dump_status
!= 0xFFFFFFFF)
841 kprintf("RCGet82558Stats() Timeout waiting for NIC statistics\n");
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 ** =========================================================================
863 RCGetLinkStatus(U16 AdapterID
, PU32 ReturnAddr
, PFNWAITCALLBACK WaitCallback
)
866 volatile U32 timeout
;
871 /*kprintf("Get82558LinkStatus() ReturnPhysAddr:0x%08.8ulx\n", ReturnAddr);*/
873 pPab
= PCIAdapterBlock
[AdapterID
];
876 return RC_RTN_ADPTR_NOT_REGISTERED
;
878 msgOffset
= pPab
->p_atu
->InQueue
;
880 if (msgOffset
== 0xFFFFFFFF)
883 dprintf("Get82558LinkStatus(): Inbound Free Q empty!\n");
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
));
903 /* post to Inbound Post Q */
904 pPab
->p_atu
->InQueue
= msgOffset
;
914 for (i
= 0; i
< 1000; i
++)
917 if (*p32
!= 0xFFFFFFFF)
923 kprintf("Timeout waiting for link status\n");
925 return RC_RTN_MSG_REPLY_TIMEOUT
;
929 *ReturnAddr
= *p32
; /* 1 = up 0 = down */
931 return RC_RTN_NO_ERROR
;
936 ** =========================================================================
939 ** get the MAC address the adapter is listening for in non-promiscous mode.
940 ** MAC address is in media format.
941 ** =========================================================================
944 RCGetMAC(U16 AdapterID
, PU8 mac
, PFNWAITCALLBACK WaitCallback
)
953 pPab
= PCIAdapterBlock
[AdapterID
];
956 return RC_RTN_ADPTR_NOT_REGISTERED
;
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
);
971 printk("RCGetMAC: p_atu 0x%08x, off 0x%08x, p 0x%08x\n",
972 (uint
)p_atu
, (uint
)off
, (uint
)p
);
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 */
984 printk("RCGetMAC: p_atu 0x%08x, off 0x%08x, p 0x%08x\n",
985 (uint
)p_atu
, (uint
)off
, (uint
)p
);
988 /* wait for the rcpci45 board to update the info */
990 while (0 == p_atu
->EtherMacLow
)
995 for (i
= 0; i
< 1000; i
++)
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);
1012 // printk("rc_getmac: 0x%X\n", ptr);
1013 #endif /* RCDEBUG */
1015 return RC_RTN_NO_ERROR
;
1020 ** =========================================================================
1023 ** set MAC address the adapter is listening for in non-promiscous mode.
1024 ** MAC address is in media format.
1025 ** =========================================================================
1028 RCSetMAC(U16 AdapterID
, PU8 mac
)
1035 pPab
= PCIAdapterBlock
[AdapterID
];
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 ** =========================================================================
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 ** =========================================================================
1077 RCSetLinkSpeed(U16 AdapterID
, U16 LinkSpeedCode
)
1084 pPab
=PCIAdapterBlock
[AdapterID
];
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 ** =========================================================================
1119 RCSetPromiscuousMode(U16 AdapterID
, U16 Mode
)
1125 pPab
=PCIAdapterBlock
[AdapterID
];
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 ** =========================================================================
1162 RCGetPromiscuousMode(U16 AdapterID
, PU32 pMode
, PFNWAITCALLBACK WaitCallback
)
1164 U32 msgOffset
, timeout
;
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
));
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 */
1210 for (i
= 0; i
< 1000; i
++) /* please don't hog the bus!!! */
1218 kprintf("Timeout waiting for promiscuous mode from adapter\n");
1219 kprintf("0x%8.8lx\n", p32
[0]);
1220 return RC_RTN_NO_LINK_SPEED
;
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 ** =========================================================================
1240 RCSetBroadcastMode(U16 AdapterID
, U16 Mode
)
1246 pPab
=PCIAdapterBlock
[AdapterID
];
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 ** =========================================================================
1283 RCGetBroadcastMode(U16 AdapterID
, PU32 pMode
, PFNWAITCALLBACK WaitCallback
)
1285 U32 msgOffset
, timeout
;
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
));
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 */
1331 for (i
= 0; i
< 1000; i
++) /* please don't hog the bus!!! */
1339 kprintf("Timeout waiting for promiscuous mode from adapter\n");
1340 kprintf("0x%8.8lx\n", p32
[0]);
1341 return RC_RTN_NO_LINK_SPEED
;
1346 *pMode
= (U8
)((volatile PU8
)p32
)[0] & 0x0f;
1348 return RC_RTN_NO_ERROR
;
1352 ** =========================================================================
1355 ** get ethernet link speed.
1358 ** 1 = Full Duplex 100BaseT
1359 ** 2 = Half duplex 100BaseT
1360 ** 3 = Full Duplex 10BaseT
1361 ** 4 = Half duplex 10BaseT
1363 ** =========================================================================
1366 RCGetLinkSpeed(U16 AdapterID
, PU32 pLinkSpeedCode
, PFNWAITCALLBACK WaitCallback
)
1368 U32 msgOffset
, timeout
;
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
));
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 */
1415 for (i
= 0; i
< 1000; i
++) /* please don't hog the bus!!! */
1423 kprintf("Timeout waiting for link speed from IOP\n");
1424 kprintf("0x%8.8lx\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 ** =========================================================================
1447 RCReportDriverCapability(U16 AdapterID
, U32 capability
)
1453 pPab
=PCIAdapterBlock
[AdapterID
];
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 ** =========================================================================
1487 RCGetFirmwareVer(U16 AdapterID
, PU8 pFirmString
, PFNWAITCALLBACK WaitCallback
)
1489 U32 msgOffset
, timeout
;
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
));
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 */
1537 for (i
= 0; i
< 1000; i
++) /* please don't hog the bus!!! */
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 ** =========================================================================
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 ** =========================================================================
1568 RCResetLANCard(U16 AdapterID
, U16 ResourceFlags
, PU32 ReturnAddr
, PFNCALLBACK CallbackFunction
)
1571 unsigned long *pMsg
;
1577 pPab
=PCIAdapterBlock
[AdapterID
];
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
);
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!!! */
1609 if (timeout
> 10000)
1614 if (ReturnAddr
!= (PU32
)NULL
)
1615 *ReturnAddr
= (U32
)pPab
->pCallbackFunc
;
1618 return RC_RTN_NO_ERROR
;
1621 ** =========================================================================
1624 ** Send StatusGet Msg, wait for results return directly to buffer.
1626 ** =========================================================================
1629 RCResetIOP(U16 AdapterID
)
1631 U32 msgOffset
, timeout
;
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
);
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
));
1663 /* post to Inbound Post Q */
1665 pPab
->p_atu
->InQueue
= msgOffset
;
1667 /* wait for response */
1673 for (i
= 0; i
< 1000; i
++) /* please don't hog the bus!!! */
1676 if (p32
[0] || p32
[1])
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 ** =========================================================================
1702 RCShutdownLANCard(U16 AdapterID
, U16 ResourceFlags
, PU32 ReturnAddr
, PFNCALLBACK CallbackFunction
)
1710 pPab
= PCIAdapterBlock
[AdapterID
];
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
);
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!!! */
1742 if (timeout
> 10000)
1744 printk("RCShutdownLANCard(): timeout\n");
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 ** =========================================================================
1768 RCSetRavlinIPandMask(U16 AdapterID
, U32 ipAddr
, U32 netMask
)
1774 pPab
= PCIAdapterBlock
[AdapterID
];
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
;
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 ** =========================================================================
1810 RCGetRavlinIPandMask(U16 AdapterID
, PU32 pIpAddr
, PU32 pNetMask
,
1811 PFNWAITCALLBACK WaitCallback
)
1813 unsigned i
, timeout
;
1820 kprintf("RCGetRavlinIPandMask: pIpAddr is 0x%08.8ulx, *IpAddr is 0x%08.8ulx\n", pIpAddr
, *pIpAddr
);
1823 pPab
= PCIAdapterBlock
[AdapterID
];
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
));
1837 pMsg
= (PU32
)(pPab
->pPci45LinBaseAddr
+ off
);
1840 kprintf("RCGetRavlinIPandMask: p_atu 0x%08.8ulx, off 0x%08.8ulx, p32 0x%08.8ulx\n", p_atu
, off
, p32
);
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 */
1852 kprintf("RCGetRavlinIPandMask: p_atu 0x%08.8ulx, off 0x%08.8ulx, p32 0x%08.8ulx\n", p_atu
, off
, p32
);
1855 /* wait for the rcpci45 board to update the info */
1857 while (0xffffffff == *p32
)
1862 for (i
= 0; i
< 1000; i
++)
1868 kprintf("RCGetRavlinIPandMask: Timeout\n");
1870 return RC_RTN_MSG_REPLY_TIMEOUT
;
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]);
1879 /* send IP and mask to user's space */
1885 kprintf("RCGetRavlinIPandMask: pIpAddr is 0x%08.8ulx, *IpAddr is 0x%08.8ulx\n", pIpAddr
, *pIpAddr
);
1888 return RC_RTN_NO_ERROR
;
1892 ** /////////////////////////////////////////////////////////////////////////
1893 ** /////////////////////////////////////////////////////////////////////////
1897 ** /////////////////////////////////////////////////////////////////////////
1898 ** /////////////////////////////////////////////////////////////////////////
1902 ** =========================================================================
1903 ** SendI2OOutboundQInitMsg()
1905 ** =========================================================================
1908 SendI2OOutboundQInitMsg(PPAB pPab
)
1910 U32 msgOffset
, timeout
, phyOutQFrames
, i
;
1916 msgOffset
= pPab
->p_atu
->InQueue
;
1919 if (msgOffset
== 0xFFFFFFFF)
1922 kprintf("SendI2OOutboundQInitMsg(): Inbound Free Q empty!\n");
1924 return RC_RTN_FREE_Q_EMPTY
;
1928 /* calc virual address of msg - virual already mapped to physical */
1929 pMsg
= (PU32
)(pPab
->pPci45LinBaseAddr
+ msgOffset
);
1932 kprintf("SendI2OOutboundQInitMsg - pMsg = 0x%08.8ulx, InQ msgOffset = 0x%08.8ulx\n", pMsg
, msgOffset
);
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
));
1949 /* post to Inbound Post Q */
1950 pPab
->p_atu
->InQueue
= msgOffset
;
1952 /* wait for response */
1956 for (i
= 0; i
< 1000; i
++) /* please don't hog the bus!!! */
1965 kprintf("Timeout wait for InitOutQ InPrgress status from IOP\n");
1967 return RC_RTN_NO_I2O_STATUS
;
1974 for (i
= 0; i
< 1000; i
++) /* please don't hog the bus!!! */
1977 if (p32
[0] == I2O_EXEC_OUTBOUND_INIT_COMPLETE
)
1983 kprintf("Timeout wait for InitOutQ Complete status from IOP\n");
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 ** =========================================================================
2005 ** Send StatusGet Msg, wait for results return directly to buffer.
2007 ** =========================================================================
2010 GetI2OStatus(PPAB pPab
)
2012 U32 msgOffset
, timeout
;
2017 msgOffset
= pPab
->p_atu
->InQueue
;
2019 printk("GetI2OStatus: msg offset = 0x%x\n", msgOffset
);
2021 if (msgOffset
== 0xFFFFFFFF)
2024 kprintf("GetI2OStatus(): Inbound Free Q empty!\n");
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
);
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
));
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]);
2053 /* post to Inbound Post Q */
2054 pPab
->p_atu
->InQueue
= msgOffset
;
2057 kprintf("Return status to p32 = 0x%08.8ulx\n", p32
);
2060 /* wait for response */
2066 for (i
= 0; i
< 1000; i
++) /* please don't hog the bus!!! */
2069 if (p32
[0] && p32
[1])
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]);
2080 return RC_RTN_NO_I2O_STATUS
;
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]);
2090 pPab
->IOPState
= ((volatile PU8
)p32
)[10];
2091 pPab
->InboundMFrameSize
= ((volatile PU16
)p32
)[6];
2094 kprintf("IOP state 0x%02.2x InFrameSize = 0x%04.4x\n",
2095 pPab
->IOPState
, pPab
->InboundMFrameSize
);
2097 return RC_RTN_NO_ERROR
;
2102 ** =========================================================================
2103 ** SendEnableSysMsg()
2106 ** =========================================================================
2109 SendEnableSysMsg(PPAB pPab
)
2111 U32 msgOffset
; // timeout;
2114 msgOffset
= pPab
->p_atu
->InQueue
;
2116 if (msgOffset
== 0xFFFFFFFF)
2119 kprintf("SendEnableSysMsg(): Inbound Free Q empty!\n");
2121 return RC_RTN_FREE_Q_EMPTY
;
2124 /* calc virual address of msg - virual already mapped to physical */
2125 pMsg
= (PU32
)(pPab
->pPci45LinBaseAddr
+ msgOffset
);
2128 kprintf("SendEnableSysMsg - pMsg = 0x%08.8ulx, InQ msgOffset = 0x%08.8ulx\n", pMsg
, msgOffset
);
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 ** =========================================================================
2155 FillI2OMsgSGLFromTCB(PU32 pMsgFrame
, PRCTCB pTransCtrlBlock
)
2157 unsigned int nmbrBuffers
, nmbrSeg
, nmbrDwords
, context
, flags
;
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
;
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
);
2177 nmbrBuffers
= *pTCB
++;
2186 context
= *pTCB
++; /* buffer tag (context) */
2187 nmbrSeg
= *pTCB
++; /* number of segments */
2194 flags
= SIMPLE_SGL
| BC_PRESENT
;
2200 if (1 == nmbrBuffers
)
2204 /* 1st SGL buffer element has context */
2205 pMsg
[0] = pTCB
[0] | flags
; /* send over count (segment size) */
2207 pMsg
[2] = pTCB
[1]; /* send buffer segment physical address */
2223 if (1 == nmbrBuffers
)
2227 pMsg
[0] = pTCB
[0] | flags
; /* send over count */
2228 pMsg
[1] = pTCB
[1]; /* send buffer segment physical address */
2233 } while (--nmbrSeg
);
2236 } while (--nmbrBuffers
);
2243 ** =========================================================================
2244 ** ProcessOutboundI2OMsg()
2246 ** process I2O reply message
2247 ** * change to msg structure *
2248 ** =========================================================================
2251 ProcessOutboundI2OMsg(PPAB pPab
, U32 phyAddrMsg
)
2258 p8Msg
= pPab
->pLinOutMsgBlock
+ (phyAddrMsg
- pPab
->outMsgBlockPhyAddr
);
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]);
2267 if (p32
[4] >> 24 != I2O_REPLY_STATUS_SUCCESS
)
2270 kprintf("Message reply status not success\n");
2275 switch (p8Msg
[7] ) /* function code byte */
2277 case I2O_EXEC_SYS_TAB_SET
:
2280 kprintf("Received I2O_EXEC_SYS_TAB_SET reply\n");
2284 case I2O_EXEC_HRT_GET
:
2287 kprintf("Received I2O_EXEC_HRT_GET reply\n");
2291 case I2O_EXEC_LCT_NOTIFY
:
2294 kprintf("Received I2O_EXEC_LCT_NOTIFY reply\n");
2298 case I2O_EXEC_SYS_ENABLE
:
2301 kprintf("Received I2O_EXEC_SYS_ENABLE reply\n");
2307 kprintf("Received UNKNOWN reply\n");