OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [net/] [rclanmtl.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/*
2
** *************************************************************************
3
**
4
**
5
**     R C L A N M T L . C             $Revision: 1.1 $
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
**  ---------------------------------------------------------------------
14
**
15
**  File Description:
16
**
17
**  Host side I2O (Intelligent I/O) LAN message transport layer.
18
**
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.
23
 
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.
28
 
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.
32
**
33
** 1998-1999, LAN API was modified and enhanced by Alice Hennessy.
34
**
35
** Sometime in 1997, LAN API was written from scratch by Wendell Nichols.
36
** *************************************************************************
37
*/
38
 
39
#undef DEBUG
40
 
41
#define RC_LINUX_MODULE
42
#include "rclanmtl.h"
43
 
44
#define dprintf kprintf
45
 
46
extern int printk(const char * fmt, ...);
47
 
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  
52
 
53
 
54
/*
55
** I2O message structures
56
*/
57
 
58
#define    I2O_TID_SZ                                  12
59
#define    I2O_FUNCTION_SZ                             8
60
 
61
/* Transaction Reply Lists (TRL) Control Word structure */
62
 
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
66
 
67
/* LAN Class specific functions */
68
 
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
74
 
75
/* Private Class specfic function */
76
#define    I2O_PRIVATE                                 0xFF
77
 
78
/*  I2O Executive Function Codes.  */
79
 
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
108
 
109
 
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
115
 
116
 
117
#define    I2O_UTIL_NOP                                0x00
118
 
119
 
120
/* I2O Get Status State values */
121
 
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
129
 
130
 
131
/* Defines for Request Status Codes:  Table 3-1 Reply Status Codes.  */
132
 
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
145
 
146
 
147
/* DetailedStatusCode defines for ALL messages: Table 3-2 Detailed Status Codes.*/
148
 
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
176
 
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)
183
 
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
191
 
192
  /* normal LAN request message MsgFlags and VersionOffset (0x1041) */
193
#define LAN_MSG_REQST  (MSG_MULTI_TRANS | SGL_OFFSET_4)
194
 
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
203
 
204
/* Special TID Assignments */
205
 
206
#define I2O_IOP_TID   0
207
#define I2O_HOST_TID  0xB91
208
 
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
227
 
228
#define RC_PRIVATE_REBOOT           0x00FF
229
 
230
 
231
/* I2O message header */
232
typedef struct _I2O_MESSAGE_FRAME
233
{
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[] */
242
}
243
I2O_MESSAGE_FRAME, *PI2O_MESSAGE_FRAME;
244
 
245
 
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
249
 
250
/*
251
**  Message Unit CSR definitions for RedCreek PCI45 board
252
*/
253
typedef struct tag_rcatu
254
{
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;
280
}
281
ATU, *PATU;
282
 
283
 /*
284
 ** typedef PAB
285
 **
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.
288
 */
289
typedef struct
290
{
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;
301
}
302
PAB, *PPAB;
303
 
304
 /*
305
 ** in reserved space right after PAB in host memory is area for returning
306
 ** values from card
307
 */
308
 
309
 /*
310
 ** Array of pointers to PCI Adapter Blocks.
311
 ** Indexed by a zero based (0-31) interface number.
312
 */
313
#define MAX_ADAPTERS 32
314
static PPAB  PCIAdapterBlock[MAX_ADAPTERS] =
315
{
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
320
};
321
 
322
 
323
/*
324
** typedef NICSTAT
325
**
326
** Data structure for NIC statistics retruned from PCI card.  Data copied from
327
** here to user allocated RCLINKSTATS (see rclanmtl.h) structure.
328
*/
329
typedef struct tag_NicStat
330
{
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 */
348
}
349
NICSTAT, *P_NICSTAT;
350
 
351
 
352
#define DUMP_DONE   0x0000A005      /* completed statistical dump */
353
#define DUMP_CLEAR  0x0000A007      /* completed stat dump and clear counters */
354
 
355
 
356
static volatile int msgFlag;
357
 
358
 
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);
365
 
366
 
367
/* 1st 100h bytes of message block is reserved for messenger instance */
368
#define ADAPTER_BLOCK_RESERVED_SPACE 0x100
369
 
370
/*
371
** =========================================================================
372
** RCInitI2OMsgLayer()
373
**
374
** Initialize the RedCreek I2O Module and adapter.
375
**
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
382
**
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
** =========================================================================
387
*/
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)
394
{
395
    int result;
396
    PPAB pPab;
397
 
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 */
403
 
404
 
405
    /* Check if this interface already initialized - if so, shut it down */
406
    if (PCIAdapterBlock[AdapterID] != NULL)
407
    {
408
        printk("PCIAdapterBlock[%d]!=NULL\n", AdapterID);
409
//        RCResetLANCard(AdapterID, 0, (PU32)NULL, (PFNCALLBACK)NULL);
410
        PCIAdapterBlock[AdapterID] = NULL;
411
    }
412
 
413
    /*
414
    ** store adapter instance values in adapter block.
415
    ** Adapter block is at beginning of message buffer
416
    */
417
    pPab = (PPAB)p_msgbuf;
418
 
419
    pPab->p_atu = (PATU)pciBaseAddr;
420
    pPab->pPci45LinBaseAddr =  (PU8)pciBaseAddr;
421
 
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);
425
 
426
    /* store callback function addresses */
427
    pPab->pTransCallbackFunc = TransmitCallbackFunction;
428
    pPab->pRecvCallbackFunc  = ReceiveCallbackFunction;
429
    pPab->pRebootCallbackFunc  = RebootCallbackFunction;
430
    pPab->pCallbackFunc  = (PFNCALLBACK)NULL;
431
 
432
    /*
433
    ** Initialize I2O IOP
434
    */
435
    result = GetI2OStatus(pPab);
436
 
437
    if (result != RC_RTN_NO_ERROR)
438
        return result;
439
 
440
    if (pPab->IOPState == I2O_IOP_STATE_OPERATIONAL)
441
    {
442
        printk("pPab->IOPState == op: resetting adapter\n");
443
        RCResetLANCard(AdapterID, 0, (PU32)NULL, (PFNCALLBACK)NULL);
444
    }
445
 
446
    result = SendI2OOutboundQInitMsg(pPab);
447
 
448
    if (result != RC_RTN_NO_ERROR)
449
        return result;
450
 
451
    result = SendEnableSysMsg(pPab);
452
 
453
    if (result != RC_RTN_NO_ERROR)
454
        return result;
455
 
456
    PCIAdapterBlock[AdapterID] = pPab;
457
    return RC_RTN_NO_ERROR;
458
}
459
 
460
/*
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
** =========================================================================
469
*/
470
#define i960_OUT_POST_Q_INT_BIT        0x0008 /* bit set masks interrupts */
471
 
472
RC_RETURN RCDisableI2OInterrupts(U16 AdapterID)
473
{
474
    PPAB pPab;
475
 
476
 
477
    pPab = PCIAdapterBlock[AdapterID];
478
 
479
    if (pPab == NULL)
480
        return RC_RTN_ADPTR_NOT_REGISTERED;
481
 
482
    pPab->p_atu->OutIntMask |= i960_OUT_POST_Q_INT_BIT;
483
 
484
    return RC_RTN_NO_ERROR;
485
}
486
 
487
RC_RETURN RCEnableI2OInterrupts(U16 AdapterID)
488
{
489
    PPAB pPab;
490
 
491
    pPab = PCIAdapterBlock[AdapterID];
492
 
493
    if (pPab == NULL)
494
        return RC_RTN_ADPTR_NOT_REGISTERED;
495
 
496
    pPab->p_atu->OutIntMask &= ~i960_OUT_POST_Q_INT_BIT;
497
 
498
    return RC_RTN_NO_ERROR;
499
 
500
}
501
 
502
 
503
/*
504
** =========================================================================
505
** RCI2OSendPacket()
506
** =========================================================================
507
*/
508
RC_RETURN
509
RCI2OSendPacket(U16 AdapterID, U32 InitiatorContext, PRCTCB pTransCtrlBlock)
510
{
511
    U32 msgOffset;
512
    PU32 pMsg;
513
    int size;
514
    PPAB pPab;
515
 
516
#ifdef DEBUG
517
    kprintf("RCI2OSendPacket()...\n");
518
#endif /* DEBUG */
519
 
520
    pPab = PCIAdapterBlock[AdapterID];
521
 
522
    if (pPab == NULL)
523
        return RC_RTN_ADPTR_NOT_REGISTERED;
524
 
525
    /* get Inbound free Q entry - reading from In Q gets free Q entry */
526
    /* offset to Msg Frame in PCI msg block */
527
 
528
    msgOffset = pPab->p_atu->InQueue;
529
 
530
    if (msgOffset == 0xFFFFFFFF)
531
    {
532
#ifdef DEBUG
533
        kprintf("RCI2OSendPacket(): Inbound Free Q empty!\n");
534
#endif /* DEBUG */
535
        return RC_RTN_FREE_Q_EMPTY;
536
    }
537
 
538
    /* calc virual address of msg - virual already mapped to physical */
539
    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
540
 
541
    size = FillI2OMsgSGLFromTCB(pMsg + 4, pTransCtrlBlock);
542
 
543
    if (size == -1) /* error processing TCB - send NOP msg */
544
    {
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;
551
    }
552
    else /* send over msg header */
553
    {
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;
561
    }
562
}
563
 
564
 
565
/*
566
** =========================================================================
567
** RCI2OPostRecvBuffer()
568
**
569
** inputs:  pBufrCntrlBlock - pointer to buffer control block
570
**
571
** returns TRUE if successful in sending message, else FALSE.
572
** =========================================================================
573
*/
574
RC_RETURN
575
RCPostRecvBuffers(U16 AdapterID, PRCTCB pTransCtrlBlock)
576
{
577
    U32 msgOffset;
578
    PU32 pMsg;
579
    int size;
580
    PPAB pPab;
581
 
582
#ifdef DEBUG
583
    kprintf("RCPostRecvBuffers()...\n");
584
#endif /* DEBUG */
585
 
586
    /* search for DeviceHandle */
587
    pPab = PCIAdapterBlock[AdapterID];
588
 
589
    if (pPab == NULL)
590
        return RC_RTN_ADPTR_NOT_REGISTERED;
591
 
592
 
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;
596
 
597
    if (msgOffset == 0xFFFFFFFF)
598
    {
599
#ifdef DEBUG
600
        kprintf("RCPostRecvBuffers(): Inbound Free Q empty!\n");
601
#endif /* DEBUG */
602
        return RC_RTN_FREE_Q_EMPTY;
603
 
604
    }
605
    /* calc virual address of msg - virual already mapped to physical */
606
    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
607
 
608
    size = FillI2OMsgSGLFromTCB(pMsg + 4, pTransCtrlBlock);
609
 
610
    if (size == -1) /* error prcessing TCB - send 3 DWORD private msg == NOP */
611
    {
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;
620
    }
621
    else /* send over size msg header */
622
    {
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;
630
    }
631
}
632
 
633
 
634
/*
635
** =========================================================================
636
** RCProcI2OMsgQ()
637
**
638
** Process I2O outbound message queue until empty.
639
** =========================================================================
640
*/
641
void
642
RCProcI2OMsgQ(U16 AdapterID)
643
{
644
    U32 phyAddrMsg;
645
    PU8 p8Msg;
646
    PU32 p32;
647
    U16 count;
648
    PPAB pPab;
649
    unsigned char debug_msg[20];
650
 
651
    pPab = PCIAdapterBlock[AdapterID];
652
 
653
    if (pPab == NULL)
654
        return;
655
 
656
    phyAddrMsg = pPab->p_atu->OutQueue;
657
 
658
    while (phyAddrMsg != 0xFFFFFFFF)
659
    {
660
        p8Msg = pPab->pLinOutMsgBlock + (phyAddrMsg - pPab->outMsgBlockPhyAddr);
661
        p32 = (PU32)p8Msg;
662
 
663
        //printk(" msg: 0x%x  0x%x \n", p8Msg[7], p32[5]);
664
 
665
        /*
666
        ** Send Packet Reply Msg
667
        */
668
        if (I2O_LAN_PACKET_SEND == p8Msg[7])  /* function code byte */
669
        {
670
            count = *(PU16)(p8Msg+2);
671
            count -= p8Msg[0] >> 4;
672
            /* status, count, context[], adapter */
673
            (*pPab->pTransCallbackFunc)(p8Msg[19], count, p32+5, AdapterID);
674
        }
675
        /*
676
        ** Receive Packet Reply Msg */
677
        else if (I2O_LAN_RECEIVE_POST == p8Msg[7])
678
        {
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);
690
 
691
 
692
        }
693
        else if (I2O_LAN_RESET == p8Msg[7] || I2O_LAN_SHUTDOWN == p8Msg[7])
694
        {
695
            if (pPab->pCallbackFunc)
696
            {
697
                (*pPab->pCallbackFunc)(p8Msg[19],0,0,AdapterID);
698
            }
699
            else
700
            {
701
                pPab->pCallbackFunc = (PFNCALLBACK) 1;
702
            }
703
            //PCIAdapterBlock[AdapterID] = 0;
704
        }
705
        else if (I2O_PRIVATE == p8Msg[7])
706
        {
707
            //printk("i2o private 0x%x, 0x%x \n", p8Msg[7], p32[5]);
708
            switch (p32[5])
709
            {
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);
717
 
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);
722
 
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);
727
 
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);
732
 
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)
739
                {
740
                    (*pPab->pRebootCallbackFunc)(0,0,0,AdapterID);
741
                }
742
                break;
743
            default:
744
                printk("Unknown private I2O msg received: 0x%x\n",
745
                       p32[5]);
746
                break;
747
            }
748
        }
749
 
750
        /*
751
        ** Process other Msg's
752
        */
753
        else
754
        {
755
            ProcessOutboundI2OMsg(pPab, phyAddrMsg);
756
        }
757
 
758
        /* return MFA to outbound free Q*/
759
        pPab->p_atu->OutQueue = phyAddrMsg;
760
 
761
        /* any more msgs? */
762
        phyAddrMsg = pPab->p_atu->OutQueue;
763
    }
764
}
765
 
766
 
767
/*
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
** =========================================================================
774
*/
775
RC_RETURN
776
RCGetLinkStatistics(U16 AdapterID,
777
                    P_RCLINKSTATS StatsReturnAddr,
778
                    PFNWAITCALLBACK WaitCallback)
779
{
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;
787
 
788
/*kprintf("Get82558Stats() StatsReturnAddr:0x%08.8ulx\n", StatsReturnAddr);*/
789
 
790
    pPab = PCIAdapterBlock[AdapterID];
791
 
792
    if (pPab == NULL)
793
        return RC_RTN_ADPTR_NOT_REGISTERED;
794
 
795
    msgOffset = pPab->p_atu->InQueue;
796
 
797
    if (msgOffset == 0xFFFFFFFF)
798
    {
799
#ifdef DEBUG
800
        kprintf("Get8255XStats(): Inbound Free Q empty!\n");
801
#endif
802
        return RC_RTN_FREE_Q_EMPTY;
803
    }
804
 
805
    /* calc virual address of msg - virual already mapped to physical */
806
    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
807
 
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);*/
810
 
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);
817
 
818
    p32 = (PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
819
 
820
    pStats = (P_NICSTAT)p32;
821
    pStats->dump_status = 0xFFFFFFFF;
822
 
823
    /* post to Inbound Post Q */
824
    pPab->p_atu->InQueue = msgOffset;
825
 
826
    timeout = 100000;
827
    while (1)
828
    {
829
        if (WaitCallback)
830
            (*WaitCallback)();
831
 
832
        for (i = 0; i < 1000; i++)
833
            ;
834
 
835
        if (pStats->dump_status != 0xFFFFFFFF)
836
            break;
837
 
838
        if (!timeout--)
839
        {
840
#ifdef DEBUG
841
            kprintf("RCGet82558Stats() Timeout waiting for NIC statistics\n");
842
#endif
843
            return RC_RTN_MSG_REPLY_TIMEOUT;
844
        }
845
    }
846
 
847
    pReturnAddr = (PU32)StatsReturnAddr;
848
 
849
    /* copy Nic stats to user's structure */
850
    for (i = 0; i < (int) sizeof(RCLINKSTATS) / 4; i++)
851
        pReturnAddr[i] = p32[i];
852
 
853
    return RC_RTN_NO_ERROR;
854
}
855
 
856
 
857
/*
858
** =========================================================================
859
** Get82558LinkStatus()
860
** =========================================================================
861
*/
862
RC_RETURN
863
RCGetLinkStatus(U16 AdapterID, PU32 ReturnAddr, PFNWAITCALLBACK WaitCallback)
864
{
865
    U32 msgOffset;
866
    volatile U32 timeout;
867
    volatile PU32 pMsg;
868
    volatile PU32 p32;
869
    PPAB pPab;
870
 
871
/*kprintf("Get82558LinkStatus() ReturnPhysAddr:0x%08.8ulx\n", ReturnAddr);*/
872
 
873
    pPab = PCIAdapterBlock[AdapterID];
874
 
875
    if (pPab == NULL)
876
        return RC_RTN_ADPTR_NOT_REGISTERED;
877
 
878
    msgOffset = pPab->p_atu->InQueue;
879
 
880
    if (msgOffset == 0xFFFFFFFF)
881
    {
882
#ifdef DEBUG
883
        dprintf("Get82558LinkStatus(): Inbound Free Q empty!\n");
884
#endif
885
        return RC_RTN_FREE_Q_EMPTY;
886
    }
887
 
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);*/
892
 
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);
899
 
900
    p32 = (PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
901
    *p32 = 0xFFFFFFFF;
902
 
903
    /* post to Inbound Post Q */
904
    pPab->p_atu->InQueue = msgOffset;
905
 
906
    timeout = 100000;
907
    while (1)
908
    {
909
        U32 i;
910
 
911
        if (WaitCallback)
912
            (*WaitCallback)();
913
 
914
        for (i = 0; i < 1000; i++)
915
            ;
916
 
917
        if (*p32 != 0xFFFFFFFF)
918
            break;
919
 
920
        if (!timeout--)
921
        {
922
#ifdef DEBUG
923
            kprintf("Timeout waiting for link status\n");
924
#endif    
925
            return RC_RTN_MSG_REPLY_TIMEOUT;
926
        }
927
    }
928
 
929
    *ReturnAddr = *p32; /* 1 = up 0 = down */
930
 
931
    return RC_RTN_NO_ERROR;
932
 
933
}
934
 
935
/*
936
** =========================================================================
937
** RCGetMAC()
938
**
939
** get the MAC address the adapter is listening for in non-promiscous mode.
940
** MAC address is in media format.
941
** =========================================================================
942
*/
943
RC_RETURN
944
RCGetMAC(U16 AdapterID, PU8 mac, PFNWAITCALLBACK WaitCallback)
945
{
946
    unsigned i, timeout;
947
    U32      off;
948
    PU32     p;
949
    U32      temp[2];
950
    PPAB     pPab;
951
    PATU     p_atu;
952
 
953
    pPab = PCIAdapterBlock[AdapterID];
954
 
955
    if (pPab == NULL)
956
        return RC_RTN_ADPTR_NOT_REGISTERED;
957
 
958
    p_atu = pPab->p_atu;
959
 
960
    p_atu->EtherMacLow = 0;     /* first zero return data */
961
    p_atu->EtherMacHi = 0;
962
 
963
    off = p_atu->InQueue;   /* get addresss of message */
964
 
965
    if (0xFFFFFFFF == off)
966
        return RC_RTN_FREE_Q_EMPTY;
967
 
968
    p = (PU32)(pPab->pPci45LinBaseAddr + off);
969
 
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;
980
 
981
 
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 */
987
 
988
    /* wait for the rcpci45 board to update the info */
989
    timeout = 1000000;
990
    while (0 == p_atu->EtherMacLow)
991
    {
992
        if (WaitCallback)
993
            (*WaitCallback)();
994
 
995
        for (i = 0; i < 1000; i++)
996
            ;
997
 
998
        if (!timeout--)
999
        {
1000
            printk("rc_getmac: Timeout\n");
1001
            return RC_RTN_MSG_REPLY_TIMEOUT;
1002
        }
1003
    }
1004
 
1005
    /* read the mac address  */
1006
    temp[0] = p_atu->EtherMacLow;
1007
    temp[1] = p_atu->EtherMacHi;
1008
    memcpy((char *)mac, (char *)temp, 6);
1009
 
1010
 
1011
#ifdef RCDEBUG
1012
//    printk("rc_getmac: 0x%X\n", ptr);
1013
#endif /* RCDEBUG */
1014
 
1015
    return RC_RTN_NO_ERROR;
1016
}
1017
 
1018
 
1019
/*
1020
** =========================================================================
1021
** RCSetMAC()
1022
**
1023
** set MAC address the adapter is listening for in non-promiscous mode.
1024
** MAC address is in media format.
1025
** =========================================================================
1026
*/
1027
RC_RETURN
1028
RCSetMAC(U16 AdapterID, PU8 mac)
1029
{
1030
    U32  off;
1031
    PU32 pMsg;
1032
    PPAB pPab;
1033
 
1034
 
1035
    pPab = PCIAdapterBlock[AdapterID];
1036
 
1037
    if (pPab == NULL)
1038
        return RC_RTN_ADPTR_NOT_REGISTERED;
1039
 
1040
    off = pPab->p_atu->InQueue; /* get addresss of message */
1041
 
1042
    if (0xFFFFFFFF == off)
1043
        return RC_RTN_FREE_Q_EMPTY;
1044
 
1045
    pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
1046
 
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 */
1055
 
1056
    pPab->p_atu->InQueue = off;   /* send it to the I2O device */
1057
 
1058
    return RC_RTN_NO_ERROR ;
1059
}
1060
 
1061
 
1062
/*
1063
** =========================================================================
1064
** RCSetLinkSpeed()
1065
**
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
** =========================================================================
1075
*/
1076
RC_RETURN
1077
RCSetLinkSpeed(U16 AdapterID, U16 LinkSpeedCode)
1078
{
1079
    U32  off;
1080
    PU32 pMsg;
1081
    PPAB pPab;
1082
 
1083
 
1084
    pPab =PCIAdapterBlock[AdapterID];
1085
 
1086
    if (pPab == NULL)
1087
        return RC_RTN_ADPTR_NOT_REGISTERED;
1088
 
1089
    off = pPab->p_atu->InQueue; /* get addresss of message */
1090
 
1091
    if (0xFFFFFFFF == off)
1092
        return RC_RTN_FREE_Q_EMPTY;
1093
 
1094
    pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
1095
 
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 */
1103
 
1104
    pPab->p_atu->InQueue = off;   /* send it to the I2O device */
1105
 
1106
    return RC_RTN_NO_ERROR ;
1107
}
1108
/*
1109
** =========================================================================
1110
** RCSetPromiscuousMode()
1111
**
1112
** Defined values for Mode:
1113
**  0 - turn off promiscuous mode
1114
**  1 - turn on  promiscuous mode
1115
**
1116
** =========================================================================
1117
*/
1118
RC_RETURN
1119
RCSetPromiscuousMode(U16 AdapterID, U16 Mode)
1120
{
1121
    U32  off;
1122
    PU32 pMsg;
1123
    PPAB pPab;
1124
 
1125
    pPab =PCIAdapterBlock[AdapterID];
1126
 
1127
    if (pPab == NULL)
1128
        return RC_RTN_ADPTR_NOT_REGISTERED;
1129
 
1130
    off = pPab->p_atu->InQueue; /* get addresss of message */
1131
 
1132
    if (0xFFFFFFFF == off)
1133
        return RC_RTN_FREE_Q_EMPTY;
1134
 
1135
    pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
1136
 
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 */
1144
 
1145
    pPab->p_atu->InQueue = off;   /* send it to the device */
1146
 
1147
    return RC_RTN_NO_ERROR ;
1148
}
1149
/*
1150
** =========================================================================
1151
** RCGetPromiscuousMode()
1152
**
1153
** get promiscuous mode setting
1154
**
1155
** Possible return values placed in pMode:
1156
**  0 = promisuous mode not set
1157
**  1 = promisuous mode is set
1158
**
1159
** =========================================================================
1160
*/
1161
RC_RETURN
1162
RCGetPromiscuousMode(U16 AdapterID, PU32 pMode, PFNWAITCALLBACK WaitCallback)
1163
{
1164
    U32 msgOffset, timeout;
1165
    PU32 pMsg;
1166
    volatile PU32 p32;
1167
    PPAB pPab;
1168
 
1169
    pPab =PCIAdapterBlock[AdapterID];
1170
 
1171
 
1172
    msgOffset = pPab->p_atu->InQueue;
1173
 
1174
 
1175
    if (msgOffset == 0xFFFFFFFF)
1176
    {
1177
        kprintf("RCGetLinkSpeed(): Inbound Free Q empty!\n");
1178
        return RC_RTN_FREE_Q_EMPTY;
1179
    }
1180
 
1181
    /* calc virtual address of msg - virtual already mapped to physical */
1182
    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
1183
 
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;
1187
 
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);
1196
 
1197
    /* post to Inbound Post Q */
1198
 
1199
    pPab->p_atu->InQueue = msgOffset;
1200
 
1201
    /* wait for response */
1202
    timeout = 1000000;
1203
    while(1)
1204
    {
1205
        int i;
1206
 
1207
        if (WaitCallback)
1208
            (*WaitCallback)();
1209
 
1210
        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
1211
            ;
1212
 
1213
        if (p32[0] != 0xff)
1214
            break;
1215
 
1216
        if (!timeout--)
1217
        {
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;
1221
        }
1222
    }
1223
 
1224
    /* get mode */
1225
    *pMode = (U8)((volatile PU8)p32)[0] & 0x0f;
1226
 
1227
    return RC_RTN_NO_ERROR;
1228
}
1229
/*
1230
** =========================================================================
1231
** RCSetBroadcastMode()
1232
**
1233
** Defined values for Mode:
1234
**  0 - turn off promiscuous mode
1235
**  1 - turn on  promiscuous mode
1236
**
1237
** =========================================================================
1238
*/
1239
RC_RETURN
1240
RCSetBroadcastMode(U16 AdapterID, U16 Mode)
1241
{
1242
    U32  off;
1243
    PU32 pMsg;
1244
    PPAB pPab;
1245
 
1246
    pPab =PCIAdapterBlock[AdapterID];
1247
 
1248
    if (pPab == NULL)
1249
        return RC_RTN_ADPTR_NOT_REGISTERED;
1250
 
1251
    off = pPab->p_atu->InQueue; /* get addresss of message */
1252
 
1253
    if (0xFFFFFFFF == off)
1254
        return RC_RTN_FREE_Q_EMPTY;
1255
 
1256
    pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
1257
 
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 */
1265
 
1266
    pPab->p_atu->InQueue = off;   /* send it to the device */
1267
 
1268
    return RC_RTN_NO_ERROR ;
1269
}
1270
/*
1271
** =========================================================================
1272
** RCGetBroadcastMode()
1273
**
1274
** get promiscuous mode setting
1275
**
1276
** Possible return values placed in pMode:
1277
**  0 = promisuous mode not set
1278
**  1 = promisuous mode is set
1279
**
1280
** =========================================================================
1281
*/
1282
RC_RETURN
1283
RCGetBroadcastMode(U16 AdapterID, PU32 pMode, PFNWAITCALLBACK WaitCallback)
1284
{
1285
    U32 msgOffset, timeout;
1286
    PU32 pMsg;
1287
    volatile PU32 p32;
1288
    PPAB pPab;
1289
 
1290
    pPab =PCIAdapterBlock[AdapterID];
1291
 
1292
 
1293
    msgOffset = pPab->p_atu->InQueue;
1294
 
1295
 
1296
    if (msgOffset == 0xFFFFFFFF)
1297
    {
1298
        kprintf("RCGetLinkSpeed(): Inbound Free Q empty!\n");
1299
        return RC_RTN_FREE_Q_EMPTY;
1300
    }
1301
 
1302
    /* calc virtual address of msg - virtual already mapped to physical */
1303
    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
1304
 
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;
1308
 
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);
1317
 
1318
    /* post to Inbound Post Q */
1319
 
1320
    pPab->p_atu->InQueue = msgOffset;
1321
 
1322
    /* wait for response */
1323
    timeout = 1000000;
1324
    while(1)
1325
    {
1326
        int i;
1327
 
1328
        if (WaitCallback)
1329
            (*WaitCallback)();
1330
 
1331
        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
1332
            ;
1333
 
1334
        if (p32[0] != 0xff)
1335
            break;
1336
 
1337
        if (!timeout--)
1338
        {
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;
1342
        }
1343
    }
1344
 
1345
    /* get mode */
1346
    *pMode = (U8)((volatile PU8)p32)[0] & 0x0f;
1347
 
1348
    return RC_RTN_NO_ERROR;
1349
}
1350
 
1351
/*
1352
** =========================================================================
1353
** RCGetLinkSpeed()
1354
**
1355
** get ethernet link speed.
1356
**
1357
** 0 = Unknown
1358
** 1 = Full Duplex 100BaseT
1359
** 2 = Half duplex 100BaseT
1360
** 3 = Full Duplex  10BaseT
1361
** 4 = Half duplex  10BaseT
1362
**
1363
** =========================================================================
1364
*/
1365
RC_RETURN
1366
RCGetLinkSpeed(U16 AdapterID, PU32 pLinkSpeedCode, PFNWAITCALLBACK WaitCallback)
1367
{
1368
    U32 msgOffset, timeout;
1369
    PU32 pMsg;
1370
    volatile PU32 p32;
1371
    U8 IOPLinkSpeed;
1372
    PPAB pPab;
1373
 
1374
    pPab =PCIAdapterBlock[AdapterID];
1375
 
1376
 
1377
    msgOffset = pPab->p_atu->InQueue;
1378
 
1379
 
1380
    if (msgOffset == 0xFFFFFFFF)
1381
    {
1382
        kprintf("RCGetLinkSpeed(): Inbound Free Q empty!\n");
1383
        return RC_RTN_FREE_Q_EMPTY;
1384
    }
1385
 
1386
    /* calc virtual address of msg - virtual already mapped to physical */
1387
    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
1388
 
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;
1392
 
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);
1401
 
1402
    /* post to Inbound Post Q */
1403
 
1404
    pPab->p_atu->InQueue = msgOffset;
1405
 
1406
    /* wait for response */
1407
    timeout = 1000000;
1408
    while(1)
1409
    {
1410
        int i;
1411
 
1412
        if (WaitCallback)
1413
            (*WaitCallback)();
1414
 
1415
        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
1416
            ;
1417
 
1418
        if (p32[0] != 0xff)
1419
            break;
1420
 
1421
        if (!timeout--)
1422
        {
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;
1426
        }
1427
    }
1428
 
1429
    /* get Link speed */
1430
    IOPLinkSpeed = (U8)((volatile PU8)p32)[0] & 0x0f;
1431
 
1432
    *pLinkSpeedCode= IOPLinkSpeed;
1433
 
1434
    return RC_RTN_NO_ERROR;
1435
}
1436
 
1437
/*
1438
** =========================================================================
1439
** RCReportDriverCapability(U16 AdapterID, U32 capability)
1440
**
1441
** Currently defined bits:
1442
** WARM_REBOOT_CAPABLE   0x01
1443
**
1444
** =========================================================================
1445
*/
1446
RC_RETURN
1447
RCReportDriverCapability(U16 AdapterID, U32 capability)
1448
{
1449
    U32  off;
1450
    PU32 pMsg;
1451
    PPAB pPab;
1452
 
1453
    pPab =PCIAdapterBlock[AdapterID];
1454
 
1455
    if (pPab == NULL)
1456
        return RC_RTN_ADPTR_NOT_REGISTERED;
1457
 
1458
    off = pPab->p_atu->InQueue; /* get addresss of message */
1459
 
1460
    if (0xFFFFFFFF == off)
1461
        return RC_RTN_FREE_Q_EMPTY;
1462
 
1463
    pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
1464
 
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;
1472
 
1473
    pPab->p_atu->InQueue = off;   /* send it to the I2O device */
1474
 
1475
    return RC_RTN_NO_ERROR ;
1476
}
1477
 
1478
/*
1479
** =========================================================================
1480
** RCGetFirmwareVer()
1481
**
1482
** Return firmware version in the form "SoftwareVersion : Bt BootVersion"
1483
**
1484
** =========================================================================
1485
*/
1486
RC_RETURN
1487
RCGetFirmwareVer(U16 AdapterID, PU8 pFirmString, PFNWAITCALLBACK WaitCallback)
1488
{
1489
    U32 msgOffset, timeout;
1490
    PU32 pMsg;
1491
    volatile PU32 p32;
1492
    PPAB pPab;
1493
 
1494
    pPab =PCIAdapterBlock[AdapterID];
1495
 
1496
    msgOffset = pPab->p_atu->InQueue;
1497
 
1498
 
1499
    if (msgOffset == 0xFFFFFFFF)
1500
    {
1501
        kprintf("RCGetFirmwareVer(): Inbound Free Q empty!\n");
1502
        return RC_RTN_FREE_Q_EMPTY;
1503
    }
1504
 
1505
    /* calc virtual address of msg - virtual already mapped to physical */
1506
    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
1507
 
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;
1511
 
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);
1520
 
1521
 
1522
 
1523
    /* post to Inbound Post Q */
1524
 
1525
    pPab->p_atu->InQueue = msgOffset;
1526
 
1527
 
1528
    /* wait for response */
1529
    timeout = 1000000;
1530
    while(1)
1531
    {
1532
        int i;
1533
 
1534
        if (WaitCallback)
1535
            (*WaitCallback)();
1536
 
1537
        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
1538
            ;
1539
 
1540
        if (p32[0] != 0xff)
1541
            break;
1542
 
1543
        if (!timeout--)
1544
        {
1545
            kprintf("Timeout waiting for link speed from IOP\n");
1546
            return RC_RTN_NO_FIRM_VER;
1547
        }
1548
    }
1549
 
1550
    strcpy(pFirmString, (PU8)p32);
1551
    return RC_RTN_NO_ERROR;
1552
}
1553
 
1554
/*
1555
** =========================================================================
1556
** RCResetLANCard()
1557
**
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).
1564
**
1565
** =========================================================================
1566
*/
1567
RC_RETURN
1568
RCResetLANCard(U16 AdapterID, U16 ResourceFlags, PU32 ReturnAddr, PFNCALLBACK CallbackFunction)
1569
{
1570
    unsigned long off;
1571
    unsigned long *pMsg;
1572
    PPAB pPab;
1573
    int i;
1574
    long timeout = 0;
1575
 
1576
 
1577
    pPab =PCIAdapterBlock[AdapterID];
1578
 
1579
    if (pPab == NULL)
1580
        return RC_RTN_ADPTR_NOT_REGISTERED;
1581
 
1582
    off = pPab->p_atu->InQueue; /* get addresss of message */
1583
 
1584
    if (0xFFFFFFFF == off)
1585
        return RC_RTN_FREE_Q_EMPTY;
1586
 
1587
    pPab->pCallbackFunc = CallbackFunction;
1588
 
1589
    pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
1590
 
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 */
1596
 
1597
    pPab->p_atu->InQueue = off;   /* send it to the I2O device */
1598
 
1599
    if (CallbackFunction == (PFNCALLBACK)NULL)
1600
    {
1601
        /* call RCProcI2OMsgQ() until something in pPab->pCallbackFunc
1602
           or until timer goes off */
1603
        while (pPab->pCallbackFunc == (PFNCALLBACK)NULL)
1604
        {
1605
            RCProcI2OMsgQ(AdapterID);
1606
            for (i = 0; i < 100000; i++)     /* please don't hog the bus!!! */
1607
                ;
1608
            timeout++;
1609
            if (timeout > 10000)
1610
            {
1611
                break;
1612
            }
1613
        }
1614
        if (ReturnAddr != (PU32)NULL)
1615
            *ReturnAddr = (U32)pPab->pCallbackFunc;
1616
    }
1617
 
1618
    return RC_RTN_NO_ERROR ;
1619
}
1620
/*
1621
** =========================================================================
1622
** RCResetIOP()
1623
**
1624
** Send StatusGet Msg, wait for results return directly to buffer.
1625
**
1626
** =========================================================================
1627
*/
1628
RC_RETURN
1629
RCResetIOP(U16 AdapterID)
1630
{
1631
    U32 msgOffset, timeout;
1632
    PU32 pMsg;
1633
    PPAB pPab;
1634
    volatile PU32 p32;
1635
 
1636
    pPab = PCIAdapterBlock[AdapterID];
1637
    msgOffset = pPab->p_atu->InQueue;
1638
 
1639
    if (msgOffset == 0xFFFFFFFF)
1640
    {
1641
        return RC_RTN_FREE_Q_EMPTY;
1642
    }
1643
 
1644
    /* calc virtual address of msg - virtual already mapped to physical */
1645
    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
1646
 
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 */
1657
 
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;
1662
 
1663
    /* post to Inbound Post Q */
1664
 
1665
    pPab->p_atu->InQueue = msgOffset;
1666
 
1667
    /* wait for response */
1668
    timeout = 1000000;
1669
    while(1)
1670
    {
1671
        int i;
1672
 
1673
        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
1674
            ;
1675
 
1676
        if (p32[0] || p32[1])
1677
            break;
1678
 
1679
        if (!timeout--)
1680
        {
1681
            printk("RCResetIOP timeout\n");
1682
            return RC_RTN_MSG_REPLY_TIMEOUT;
1683
        }
1684
    }
1685
    return RC_RTN_NO_ERROR;
1686
}
1687
 
1688
/*
1689
** =========================================================================
1690
** RCShutdownLANCard()
1691
**
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).
1698
**
1699
** =========================================================================
1700
*/
1701
RC_RETURN
1702
RCShutdownLANCard(U16 AdapterID, U16 ResourceFlags, PU32 ReturnAddr, PFNCALLBACK CallbackFunction)
1703
{
1704
    volatile PU32 pMsg;
1705
    U32 off;
1706
    PPAB pPab;
1707
    int i;
1708
    long timeout = 0;
1709
 
1710
    pPab = PCIAdapterBlock[AdapterID];
1711
 
1712
    if (pPab == NULL)
1713
        return RC_RTN_ADPTR_NOT_REGISTERED;
1714
 
1715
    off = pPab->p_atu->InQueue; /* get addresss of message */
1716
 
1717
    if (0xFFFFFFFF == off)
1718
        return RC_RTN_FREE_Q_EMPTY;
1719
 
1720
    pPab->pCallbackFunc = CallbackFunction;
1721
 
1722
    pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
1723
 
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 */
1729
 
1730
    pPab->p_atu->InQueue = off;   /* send it to the I2O device */
1731
 
1732
    if (CallbackFunction == (PFNCALLBACK)NULL)
1733
    {
1734
        /* call RCProcI2OMsgQ() until something in pPab->pCallbackFunc
1735
           or until timer goes off */
1736
        while (pPab->pCallbackFunc == (PFNCALLBACK)NULL)
1737
        {
1738
            RCProcI2OMsgQ(AdapterID);
1739
            for (i = 0; i < 100000; i++)     /* please don't hog the bus!!! */
1740
                ;
1741
            timeout++;
1742
            if (timeout > 10000)
1743
            {
1744
                                printk("RCShutdownLANCard(): timeout\n");
1745
                break;
1746
            }
1747
        }
1748
        if (ReturnAddr != (PU32)NULL)
1749
            *ReturnAddr = (U32)pPab->pCallbackFunc;
1750
    }
1751
    return RC_RTN_NO_ERROR ;
1752
}
1753
 
1754
 
1755
/*
1756
** =========================================================================
1757
** RCSetRavlinIPandMask()
1758
**
1759
** Set the Ravlin 45/PCI cards IP address and network mask.
1760
**
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.
1764
**
1765
** =========================================================================
1766
*/
1767
RC_RETURN
1768
RCSetRavlinIPandMask(U16 AdapterID, U32 ipAddr, U32 netMask)
1769
{
1770
    volatile PU32 pMsg;
1771
    U32 off;
1772
    PPAB pPab;
1773
 
1774
    pPab = PCIAdapterBlock[AdapterID];
1775
 
1776
    if (pPab == NULL)
1777
        return RC_RTN_ADPTR_NOT_REGISTERED;
1778
 
1779
    off = pPab->p_atu->InQueue; /* get addresss of message */
1780
 
1781
    if (0xFFFFFFFF == off)
1782
        return RC_RTN_FREE_Q_EMPTY;
1783
 
1784
    pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
1785
 
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;
1794
 
1795
 
1796
    pPab->p_atu->InQueue = off;   /* send it to the I2O device */
1797
    return RC_RTN_NO_ERROR ;
1798
 
1799
}
1800
 
1801
/*
1802
** =========================================================================
1803
** RCGetRavlinIPandMask()
1804
**
1805
** get the IP address and MASK from the card
1806
**
1807
** =========================================================================
1808
*/
1809
RC_RETURN
1810
RCGetRavlinIPandMask(U16 AdapterID, PU32 pIpAddr, PU32 pNetMask,
1811
                     PFNWAITCALLBACK WaitCallback)
1812
{
1813
    unsigned i, timeout;
1814
    U32      off;
1815
    PU32     pMsg, p32;
1816
    PPAB     pPab;
1817
    PATU     p_atu;
1818
 
1819
#ifdef DEBUG
1820
    kprintf("RCGetRavlinIPandMask: pIpAddr is 0x%08.8ulx, *IpAddr is 0x%08.8ulx\n", pIpAddr, *pIpAddr);
1821
#endif /* DEBUG */
1822
 
1823
    pPab = PCIAdapterBlock[AdapterID];
1824
 
1825
    if (pPab == NULL)
1826
        return RC_RTN_ADPTR_NOT_REGISTERED;
1827
 
1828
    p_atu = pPab->p_atu;
1829
    off = p_atu->InQueue;   /* get addresss of message */
1830
 
1831
    if (0xFFFFFFFF == off)
1832
        return RC_RTN_FREE_Q_EMPTY;
1833
 
1834
    p32 = (volatile PU32)(pPab->pLinOutMsgBlock - ADAPTER_BLOCK_RESERVED_SPACE + sizeof(PAB));
1835
    *p32 = 0xFFFFFFFF;
1836
 
1837
    pMsg = (PU32)(pPab->pPci45LinBaseAddr + off);
1838
 
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);
1849
 
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 */
1854
 
1855
    /* wait for the rcpci45 board to update the info */
1856
    timeout = 100000;
1857
    while (0xffffffff == *p32)
1858
    {
1859
        if (WaitCallback)
1860
            (*WaitCallback)();
1861
 
1862
        for (i = 0; i < 1000; i++)
1863
            ;
1864
 
1865
        if (!timeout--)
1866
        {
1867
#ifdef DEBUG
1868
            kprintf("RCGetRavlinIPandMask: Timeout\n");
1869
#endif /* DEBUG */
1870
            return RC_RTN_MSG_REPLY_TIMEOUT;
1871
        }
1872
    }
1873
 
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 */
1878
 
1879
    /* send IP and mask to user's space  */
1880
    *pIpAddr  = p32[0];
1881
    *pNetMask = p32[1];
1882
 
1883
 
1884
#ifdef DEBUG
1885
    kprintf("RCGetRavlinIPandMask: pIpAddr is 0x%08.8ulx, *IpAddr is 0x%08.8ulx\n", pIpAddr, *pIpAddr);
1886
#endif /* DEBUG */
1887
 
1888
    return RC_RTN_NO_ERROR;
1889
}
1890
 
1891
/*
1892
** /////////////////////////////////////////////////////////////////////////
1893
** /////////////////////////////////////////////////////////////////////////
1894
**
1895
**                        local functions
1896
**
1897
** /////////////////////////////////////////////////////////////////////////
1898
** /////////////////////////////////////////////////////////////////////////
1899
*/
1900
 
1901
/*
1902
** =========================================================================
1903
** SendI2OOutboundQInitMsg()
1904
**
1905
** =========================================================================
1906
*/
1907
static int
1908
SendI2OOutboundQInitMsg(PPAB pPab)
1909
{
1910
    U32 msgOffset, timeout, phyOutQFrames, i;
1911
    volatile PU32 pMsg;
1912
    volatile PU32 p32;
1913
 
1914
 
1915
 
1916
    msgOffset = pPab->p_atu->InQueue;
1917
 
1918
 
1919
    if (msgOffset == 0xFFFFFFFF)
1920
    {
1921
#ifdef DEBUG
1922
        kprintf("SendI2OOutboundQInitMsg(): Inbound Free Q empty!\n");
1923
#endif /* DEBUG */
1924
        return RC_RTN_FREE_Q_EMPTY;
1925
    }
1926
 
1927
 
1928
    /* calc virual address of msg - virual already mapped to physical */
1929
    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
1930
 
1931
#ifdef DEBUG
1932
    kprintf("SendI2OOutboundQInitMsg - pMsg = 0x%08.8ulx, InQ msgOffset = 0x%08.8ulx\n", pMsg, msgOffset);
1933
#endif /* DEBUG */
1934
 
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);
1944
 
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;
1948
 
1949
    /* post to Inbound Post Q */
1950
    pPab->p_atu->InQueue = msgOffset;
1951
 
1952
    /* wait for response */
1953
    timeout = 100000;
1954
    while(1)
1955
    {
1956
        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
1957
            ;
1958
 
1959
        if (p32[0])
1960
            break;
1961
 
1962
        if (!timeout--)
1963
        {
1964
#ifdef DEBUG
1965
            kprintf("Timeout wait for InitOutQ InPrgress status from IOP\n");
1966
#endif /* DEBUG */
1967
            return RC_RTN_NO_I2O_STATUS;
1968
        }
1969
    }
1970
 
1971
    timeout = 100000;
1972
    while(1)
1973
    {
1974
        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
1975
            ;
1976
 
1977
        if (p32[0] == I2O_EXEC_OUTBOUND_INIT_COMPLETE)
1978
            break;
1979
 
1980
        if (!timeout--)
1981
        {
1982
#ifdef DEBUG
1983
            kprintf("Timeout wait for InitOutQ Complete status from IOP\n");
1984
#endif /* DEBUG */
1985
            return RC_RTN_NO_I2O_STATUS;
1986
        }
1987
    }
1988
 
1989
    /* load PCI outbound free Q with MF physical addresses */
1990
    phyOutQFrames = pPab->outMsgBlockPhyAddr;
1991
 
1992
    for (i = 0; i < NMBR_MSG_FRAMES; i++)
1993
    {
1994
        pPab->p_atu->OutQueue = phyOutQFrames;
1995
        phyOutQFrames += MSG_FRAME_SIZE;
1996
    }
1997
    return RC_RTN_NO_ERROR;
1998
}
1999
 
2000
 
2001
/*
2002
** =========================================================================
2003
** GetI2OStatus()
2004
**
2005
** Send StatusGet Msg, wait for results return directly to buffer.
2006
**
2007
** =========================================================================
2008
*/
2009
static int
2010
GetI2OStatus(PPAB pPab)
2011
{
2012
    U32 msgOffset, timeout;
2013
    PU32 pMsg;
2014
    volatile PU32 p32;
2015
 
2016
 
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)
2022
    {
2023
#ifdef DEBUG
2024
        kprintf("GetI2OStatus(): Inbound Free Q empty!\n");
2025
#endif /* DEBUG */
2026
        return RC_RTN_FREE_Q_EMPTY;
2027
    }
2028
 
2029
    /* calc virual address of msg - virual already mapped to physical */
2030
    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
2031
 
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 */
2042
 
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;
2047
 
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 */
2052
 
2053
    /* post to Inbound Post Q */
2054
    pPab->p_atu->InQueue = msgOffset;
2055
 
2056
#ifdef DEBUG
2057
    kprintf("Return status to p32 = 0x%08.8ulx\n", p32);
2058
#endif /* DEBUG */
2059
 
2060
    /* wait for response */
2061
    timeout = 1000000;
2062
    while(1)
2063
    {
2064
        int i;
2065
 
2066
        for (i = 0; i < 1000; i++)      /* please don't hog the bus!!! */
2067
            ;
2068
 
2069
        if (p32[0] && p32[1])
2070
            break;
2071
 
2072
        if (!timeout--)
2073
        {
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;
2081
        }
2082
    }
2083
 
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];
2092
 
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;
2098
}
2099
 
2100
 
2101
/*
2102
** =========================================================================
2103
** SendEnableSysMsg()
2104
**
2105
**
2106
** =========================================================================
2107
*/
2108
static int
2109
SendEnableSysMsg(PPAB pPab)
2110
{
2111
    U32 msgOffset; // timeout;
2112
    volatile PU32 pMsg;
2113
 
2114
    msgOffset = pPab->p_atu->InQueue;
2115
 
2116
    if (msgOffset == 0xFFFFFFFF)
2117
    {
2118
#ifdef DEBUG
2119
        kprintf("SendEnableSysMsg(): Inbound Free Q empty!\n");
2120
#endif /* DEBUG */
2121
        return RC_RTN_FREE_Q_EMPTY;
2122
    }
2123
 
2124
    /* calc virual address of msg - virual already mapped to physical */
2125
    pMsg = (PU32)(pPab->pPci45LinBaseAddr + msgOffset);
2126
 
2127
#ifdef DEBUG
2128
    kprintf("SendEnableSysMsg - pMsg = 0x%08.8ulx, InQ msgOffset = 0x%08.8ulx\n", pMsg, msgOffset);
2129
#endif /* DEBUG */
2130
 
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 */
2136
 
2137
    /* post to Inbound Post Q */
2138
    pPab->p_atu->InQueue = msgOffset;
2139
 
2140
    return RC_RTN_NO_ERROR;
2141
}
2142
 
2143
 
2144
/*
2145
** =========================================================================
2146
** FillI2OMsgFromTCB()
2147
**
2148
** inputs   pMsgU32 - virual pointer (mapped to physical) of message frame
2149
**          pXmitCntrlBlock - pointer to caller buffer control block.
2150
**
2151
** fills in LAN SGL after Transaction Control Word or Bucket Count.
2152
** =========================================================================
2153
*/
2154
static int
2155
FillI2OMsgSGLFromTCB(PU32 pMsgFrame, PRCTCB pTransCtrlBlock)
2156
{
2157
    unsigned int nmbrBuffers, nmbrSeg, nmbrDwords, context, flags;
2158
    PU32 pTCB, pMsg;
2159
 
2160
    /* SGL element flags */
2161
#define EOB        0x40000000
2162
#define LE         0x80000000
2163
#define SIMPLE_SGL 0x10000000
2164
#define BC_PRESENT 0x01000000
2165
 
2166
    pTCB = (PU32)pTransCtrlBlock;
2167
    pMsg = pMsgFrame;
2168
    nmbrDwords = 0;
2169
 
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 */
2176
 
2177
    nmbrBuffers = *pTCB++;
2178
 
2179
    if (!nmbrBuffers)
2180
    {
2181
        return -1;
2182
    }
2183
 
2184
    do
2185
    {
2186
        context = *pTCB++; /* buffer tag (context) */
2187
        nmbrSeg = *pTCB++; /* number of segments */
2188
 
2189
        if (!nmbrSeg)
2190
        {
2191
            return -1;
2192
        }
2193
 
2194
        flags = SIMPLE_SGL | BC_PRESENT;
2195
 
2196
        if (1 == nmbrSeg)
2197
        {
2198
            flags |= EOB;
2199
 
2200
            if (1 == nmbrBuffers)
2201
                flags |= LE;
2202
        }
2203
 
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;
2211
 
2212
 
2213
        if (--nmbrSeg)
2214
        {
2215
            do
2216
            {
2217
                flags = SIMPLE_SGL;
2218
 
2219
                if (1 == nmbrSeg)
2220
                {
2221
                    flags |= EOB;
2222
 
2223
                    if (1 == nmbrBuffers)
2224
                        flags |= LE;
2225
                }
2226
 
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;
2232
 
2233
            } while (--nmbrSeg);
2234
        }
2235
 
2236
    } while (--nmbrBuffers);
2237
 
2238
    return nmbrDwords;
2239
}
2240
 
2241
 
2242
/*
2243
** =========================================================================
2244
** ProcessOutboundI2OMsg()
2245
**
2246
** process I2O reply message
2247
** * change to msg structure *
2248
** =========================================================================
2249
*/
2250
static void
2251
ProcessOutboundI2OMsg(PPAB pPab, U32 phyAddrMsg)
2252
{
2253
    PU8 p8Msg;
2254
    PU32 p32;
2255
    //  U16 count;
2256
 
2257
 
2258
    p8Msg = pPab->pLinOutMsgBlock + (phyAddrMsg - pPab->outMsgBlockPhyAddr);
2259
    p32 = (PU32)p8Msg;
2260
 
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 */
2266
 
2267
    if (p32[4] >> 24 != I2O_REPLY_STATUS_SUCCESS)
2268
    {
2269
#ifdef DEBUG
2270
        kprintf("Message reply status not success\n");
2271
#endif /* DEBUG */
2272
        return;
2273
    }
2274
 
2275
    switch (p8Msg[7] )  /* function code byte */
2276
    {
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;
2283
 
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;
2290
 
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;
2297
 
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;
2304
 
2305
    default:
2306
#ifdef DEBUG
2307
        kprintf("Received UNKNOWN reply\n");
2308
#endif /* DEBUG */
2309
        break;
2310
    }
2311
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.