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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [net/] [rclanmtl.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
** *************************************************************************
3
**
4
**
5
**     R C L A N M T L . C             $Revision: 1.1.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
#define DEBUG 1
40
 
41
#define RC_LINUX_MODULE
42
#include "rclanmtl.h"
43
 
44
 /* RedCreek LAN device Target ID */
45
#define RC_LAN_TARGET_ID  0x10
46
 /* RedCreek's OSM default LAN receive Initiator */
47
#define DEFAULT_RECV_INIT_CONTEXT  0xA17
48
 
49
/*
50
** I2O message structures
51
*/
52
 
53
#define    I2O_TID_SZ                                  12
54
#define    I2O_FUNCTION_SZ                             8
55
 
56
/* Transaction Reply Lists (TRL) Control Word structure */
57
 
58
#define    I2O_TRL_FLAGS_SINGLE_FIXED_LENGTH           0x00
59
#define    I2O_TRL_FLAGS_SINGLE_VARIABLE_LENGTH        0x40
60
#define    I2O_TRL_FLAGS_MULTIPLE_FIXED_LENGTH         0x80
61
 
62
/* LAN Class specific functions */
63
 
64
#define    I2O_LAN_PACKET_SEND                         0x3B
65
#define    I2O_LAN_SDU_SEND                            0x3D
66
#define    I2O_LAN_RECEIVE_POST                        0x3E
67
#define    I2O_LAN_RESET                               0x35
68
#define    I2O_LAN_SHUTDOWN                            0x37
69
 
70
/* Private Class specfic function */
71
#define    I2O_PRIVATE                                 0xFF
72
 
73
/*  I2O Executive Function Codes.  */
74
 
75
#define    I2O_EXEC_ADAPTER_ASSIGN                     0xB3
76
#define    I2O_EXEC_ADAPTER_READ                       0xB2
77
#define    I2O_EXEC_ADAPTER_RELEASE                    0xB5
78
#define    I2O_EXEC_BIOS_INFO_SET                      0xA5
79
#define    I2O_EXEC_BOOT_DEVICE_SET                    0xA7
80
#define    I2O_EXEC_CONFIG_VALIDATE                    0xBB
81
#define    I2O_EXEC_CONN_SETUP                         0xCA
82
#define    I2O_EXEC_DEVICE_ASSIGN                      0xB7
83
#define    I2O_EXEC_DEVICE_RELEASE                     0xB9
84
#define    I2O_EXEC_HRT_GET                            0xA8
85
#define    I2O_EXEC_IOP_CLEAR                          0xBE
86
#define    I2O_EXEC_IOP_CONNECT                        0xC9
87
#define    I2O_EXEC_IOP_RESET                          0xBD
88
#define    I2O_EXEC_LCT_NOTIFY                         0xA2
89
#define    I2O_EXEC_OUTBOUND_INIT                      0xA1
90
#define    I2O_EXEC_PATH_ENABLE                        0xD3
91
#define    I2O_EXEC_PATH_QUIESCE                       0xC5
92
#define    I2O_EXEC_PATH_RESET                         0xD7
93
#define    I2O_EXEC_STATIC_MF_CREATE                   0xDD
94
#define    I2O_EXEC_STATIC_MF_RELEASE                  0xDF
95
#define    I2O_EXEC_STATUS_GET                         0xA0
96
#define    I2O_EXEC_SW_DOWNLOAD                        0xA9
97
#define    I2O_EXEC_SW_UPLOAD                          0xAB
98
#define    I2O_EXEC_SW_REMOVE                          0xAD
99
#define    I2O_EXEC_SYS_ENABLE                         0xD1
100
#define    I2O_EXEC_SYS_MODIFY                         0xC1
101
#define    I2O_EXEC_SYS_QUIESCE                        0xC3
102
#define    I2O_EXEC_SYS_TAB_SET                        0xA3
103
 
104
 /* Init Outbound Q status */
105
#define    I2O_EXEC_OUTBOUND_INIT_IN_PROGRESS          0x01
106
#define    I2O_EXEC_OUTBOUND_INIT_REJECTED             0x02
107
#define    I2O_EXEC_OUTBOUND_INIT_FAILED               0x03
108
#define    I2O_EXEC_OUTBOUND_INIT_COMPLETE             0x04
109
 
110
#define    I2O_UTIL_NOP                                0x00
111
 
112
/* I2O Get Status State values */
113
 
114
#define    I2O_IOP_STATE_INITIALIZING                  0x01
115
#define    I2O_IOP_STATE_RESET                         0x02
116
#define    I2O_IOP_STATE_HOLD                          0x04
117
#define    I2O_IOP_STATE_READY                         0x05
118
#define    I2O_IOP_STATE_OPERATIONAL                   0x08
119
#define    I2O_IOP_STATE_FAILED                        0x10
120
#define    I2O_IOP_STATE_FAULTED                       0x11
121
 
122
/* Defines for Request Status Codes:  Table 3-1 Reply Status Codes.  */
123
 
124
#define    I2O_REPLY_STATUS_SUCCESS                    0x00
125
#define    I2O_REPLY_STATUS_ABORT_DIRTY                0x01
126
#define    I2O_REPLY_STATUS_ABORT_NO_DATA_TRANSFER     0x02
127
#define    I2O_REPLY_STATUS_ABORT_PARTIAL_TRANSFER     0x03
128
#define    I2O_REPLY_STATUS_ERROR_DIRTY                0x04
129
#define    I2O_REPLY_STATUS_ERROR_NO_DATA_TRANSFER     0x05
130
#define    I2O_REPLY_STATUS_ERROR_PARTIAL_TRANSFER     0x06
131
#define    I2O_REPLY_STATUS_PROCESS_ABORT_DIRTY        0x07
132
#define    I2O_REPLY_STATUS_PROCESS_ABORT_NO_DATA_TRANSFER   0x08
133
#define    I2O_REPLY_STATUS_PROCESS_ABORT_PARTIAL_TRANSFER   0x09
134
#define    I2O_REPLY_STATUS_TRANSACTION_ERROR          0x0A
135
#define    I2O_REPLY_STATUS_PROGRESS_REPORT            0x80
136
 
137
/* DetailedStatusCode defines for ALL messages: Table 3-2 Detailed Status Codes.*/
138
 
139
#define    I2O_DETAIL_STATUS_SUCCESS                        0x0000
140
#define    I2O_DETAIL_STATUS_BAD_KEY                        0x0001
141
#define    I2O_DETAIL_STATUS_CHAIN_BUFFER_TOO_LARGE         0x0002
142
#define    I2O_DETAIL_STATUS_DEVICE_BUSY                    0x0003
143
#define    I2O_DETAIL_STATUS_DEVICE_LOCKED                  0x0004
144
#define    I2O_DETAIL_STATUS_DEVICE_NOT_AVAILABLE           0x0005
145
#define    I2O_DETAIL_STATUS_DEVICE_RESET                   0x0006
146
#define    I2O_DETAIL_STATUS_INAPPROPRIATE_FUNCTION         0x0007
147
#define    I2O_DETAIL_STATUS_INSUFFICIENT_RESOURCE_HARD     0x0008
148
#define    I2O_DETAIL_STATUS_INSUFFICIENT_RESOURCE_SOFT     0x0009
149
#define    I2O_DETAIL_STATUS_INVALID_INITIATOR_ADDRESS      0x000A
150
#define    I2O_DETAIL_STATUS_INVALID_MESSAGE_FLAGS          0x000B
151
#define    I2O_DETAIL_STATUS_INVALID_OFFSET                 0x000C
152
#define    I2O_DETAIL_STATUS_INVALID_PARAMETER              0x000D
153
#define    I2O_DETAIL_STATUS_INVALID_REQUEST                0x000E
154
#define    I2O_DETAIL_STATUS_INVALID_TARGET_ADDRESS         0x000F
155
#define    I2O_DETAIL_STATUS_MESSAGE_TOO_LARGE              0x0010
156
#define    I2O_DETAIL_STATUS_MESSAGE_TOO_SMALL              0x0011
157
#define    I2O_DETAIL_STATUS_MISSING_PARAMETER              0x0012
158
#define    I2O_DETAIL_STATUS_NO_SUCH_PAGE                   0x0013
159
#define    I2O_DETAIL_STATUS_REPLY_BUFFER_FULL              0x0014
160
#define    I2O_DETAIL_STATUS_TCL_ERROR                      0x0015
161
#define    I2O_DETAIL_STATUS_TIMEOUT                        0x0016
162
#define    I2O_DETAIL_STATUS_UNKNOWN_ERROR                  0x0017
163
#define    I2O_DETAIL_STATUS_UNKNOWN_FUNCTION               0x0018
164
#define    I2O_DETAIL_STATUS_UNSUPPORTED_FUNCTION           0x0019
165
#define    I2O_DETAIL_STATUS_UNSUPPORTED_VERSION            0x001A
166
 
167
 /* I2O msg header defines for VersionOffset */
168
#define I2OMSGVER_1_5   0x0001
169
#define SGL_OFFSET_0    I2OMSGVER_1_5
170
#define SGL_OFFSET_4    (0x0040 | I2OMSGVER_1_5)
171
#define TRL_OFFSET_5    (0x0050 | I2OMSGVER_1_5)
172
#define TRL_OFFSET_6    (0x0060 | I2OMSGVER_1_5)
173
 
174
 /* I2O msg header defines for MsgFlags */
175
#define MSG_STATIC      0x0100
176
#define MSG_64BIT_CNTXT 0x0200
177
#define MSG_MULTI_TRANS 0x1000
178
#define MSG_FAIL        0x2000
179
#define MSG_LAST        0x4000
180
#define MSG_REPLY       0x8000
181
 
182
  /* normal LAN request message MsgFlags and VersionOffset (0x1041) */
183
#define LAN_MSG_REQST  (MSG_MULTI_TRANS | SGL_OFFSET_4)
184
 
185
 /* minimum size msg */
186
#define THREE_WORD_MSG_SIZE 0x00030000
187
#define FOUR_WORD_MSG_SIZE  0x00040000
188
#define FIVE_WORD_MSG_SIZE  0x00050000
189
#define SIX_WORD_MSG_SIZE   0x00060000
190
#define SEVEN_WORD_MSG_SIZE 0x00070000
191
#define EIGHT_WORD_MSG_SIZE 0x00080000
192
#define NINE_WORD_MSG_SIZE  0x00090000
193
 
194
/* Special TID Assignments */
195
 
196
#define I2O_IOP_TID   0
197
#define I2O_HOST_TID  0xB91
198
 
199
 /* RedCreek I2O private message codes */
200
#define RC_PRIVATE_GET_MAC_ADDR     0x0001/**/  /* OBSOLETE */
201
#define RC_PRIVATE_SET_MAC_ADDR     0x0002
202
#define RC_PRIVATE_GET_NIC_STATS    0x0003
203
#define RC_PRIVATE_GET_LINK_STATUS  0x0004
204
#define RC_PRIVATE_SET_LINK_SPEED   0x0005
205
#define RC_PRIVATE_SET_IP_AND_MASK  0x0006
206
/* #define RC_PRIVATE_GET_IP_AND_MASK  0x0007 *//* OBSOLETE */
207
#define RC_PRIVATE_GET_LINK_SPEED   0x0008
208
#define RC_PRIVATE_GET_FIRMWARE_REV 0x0009
209
/* #define RC_PRIVATE_GET_MAC_ADDR     0x000A */
210
#define RC_PRIVATE_GET_IP_AND_MASK  0x000B
211
#define RC_PRIVATE_DEBUG_MSG        0x000C
212
#define RC_PRIVATE_REPORT_DRIVER_CAPABILITY  0x000D
213
#define RC_PRIVATE_SET_PROMISCUOUS_MODE  0x000e
214
#define RC_PRIVATE_GET_PROMISCUOUS_MODE  0x000f
215
#define RC_PRIVATE_SET_BROADCAST_MODE    0x0010
216
#define RC_PRIVATE_GET_BROADCAST_MODE    0x0011
217
 
218
#define RC_PRIVATE_REBOOT           0x00FF
219
 
220
/* I2O message header */
221
typedef struct _I2O_MESSAGE_FRAME {
222
        U8 VersionOffset;
223
        U8 MsgFlags;
224
        U16 MessageSize;
225
        BF TargetAddress:I2O_TID_SZ;
226
        BF InitiatorAddress:I2O_TID_SZ;
227
        BF Function:I2O_FUNCTION_SZ;
228
        U32 InitiatorContext;
229
        /* SGL[] */
230
} I2O_MESSAGE_FRAME, *PI2O_MESSAGE_FRAME;
231
 
232
 /* assumed a 16K minus 256 byte space for outbound queue message frames */
233
#define MSG_FRAME_SIZE  512
234
#define NMBR_MSG_FRAMES 30
235
 
236
 /*
237
    ** in reserved space right after PAB in host memory is area for returning
238
    ** values from card
239
  */
240
 
241
/*
242
** typedef NICSTAT
243
**
244
** Data structure for NIC statistics retruned from PCI card.  Data copied from
245
** here to user allocated RCLINKSTATS (see rclanmtl.h) structure.
246
*/
247
typedef struct tag_NicStat {
248
        unsigned long TX_good;
249
        unsigned long TX_maxcol;
250
        unsigned long TX_latecol;
251
        unsigned long TX_urun;
252
        unsigned long TX_crs;   /* lost carrier sense */
253
        unsigned long TX_def;   /* transmit deferred */
254
        unsigned long TX_singlecol;     /* single collisions */
255
        unsigned long TX_multcol;
256
        unsigned long TX_totcol;
257
        unsigned long Rcv_good;
258
        unsigned long Rcv_CRCerr;
259
        unsigned long Rcv_alignerr;
260
        unsigned long Rcv_reserr;       /* rnr'd pkts */
261
        unsigned long Rcv_orun;
262
        unsigned long Rcv_cdt;
263
        unsigned long Rcv_runt;
264
        unsigned long dump_status;      /* last field directly from the chip */
265
} NICSTAT, *P_NICSTAT;
266
 
267
#define DUMP_DONE   0x0000A005  /* completed statistical dump */
268
#define DUMP_CLEAR  0x0000A007  /* completed stat dump and clear counters */
269
 
270
static volatile int msgFlag;
271
 
272
/* local function prototypes */
273
static void ProcessOutboundI2OMsg (PPAB pPab, U32 phyMsgAddr);
274
static int FillI2OMsgSGLFromTCB (PU32 pMsg, PRCTCB pXmitCntrlBlock);
275
static int GetI2OStatus (PPAB pPab);
276
static int SendI2OOutboundQInitMsg (PPAB pPab);
277
static int SendEnableSysMsg (PPAB pPab);
278
 
279
/*
280
** =========================================================================
281
** RCInitI2OMsgLayer()
282
**
283
** Initialize the RedCreek I2O Module and adapter.
284
**
285
** Inputs:  dev - the devices net_device struct
286
**          TransmitCallbackFunction - address of transmit callback function
287
**          ReceiveCallbackFunction  - address of receive  callback function
288
**
289
** private message block is allocated by user.  It must be in locked pages.
290
** p_msgbuf and p_phymsgbuf point to the same location.  Must be contigous
291
** memory block of a minimum of 16K byte and long word aligned.
292
** =========================================================================
293
*/
294
RC_RETURN
295
RCInitI2OMsgLayer (struct net_device *dev,
296
                   PFNTXCALLBACK TransmitCallbackFunction,
297
                   PFNRXCALLBACK ReceiveCallbackFunction,
298
                   PFNCALLBACK RebootCallbackFunction)
299
{
300
        int result;
301
        PPAB pPab;
302
        PDPA pDpa = dev->priv;
303
        U32 pciBaseAddr = dev->base_addr;
304
        PU8 p_msgbuf = pDpa->PLanApiPA;
305
        PU8 p_phymsgbuf = (PU8) virt_to_bus ((void *) p_msgbuf);
306
 
307
        dprintk
308
            ("InitI2O: Adapter:0x%x ATU:0x%x msgbuf:0x%x phymsgbuf:0x%x\n"
309
             "TransmitCallbackFunction:0x%x  ReceiveCallbackFunction:0x%x\n",
310
             pDpa->id, pciBaseAddr, (u32) p_msgbuf, (u32) p_phymsgbuf,
311
             (u32) TransmitCallbackFunction, (u32) ReceiveCallbackFunction);
312
 
313
        /* Check if this interface already initialized - if so, shut it down */
314
        if (pDpa->pPab != NULL) {
315
                dprintk (KERN_WARNING
316
                        "pDpa->pPab [%d] != NULL\n",
317
                        pDpa->id);
318
/*          RCResetLANCard(pDpa->id, 0, (PU32)NULL, (PFNCALLBACK)NULL); */
319
                pDpa->pPab = NULL;
320
        }
321
 
322
        /* store adapter instance values in adapter block.
323
         * Adapter block is at beginning of message buffer */
324
 
325
        pPab = kmalloc (sizeof (*pPab), GFP_KERNEL);
326
        if (!pPab) {
327
                dprintk (KERN_ERR
328
                                "RCInitI2OMsgLayer: Could not allocate memory for PAB struct!\n");
329
                result = RC_RTN_MALLOC_ERROR;
330
                goto err_out;
331
        }
332
 
333
        memset (pPab, 0, sizeof (*pPab));
334
        pDpa->pPab = pPab;
335
        pPab->p_atu = (PATU) pciBaseAddr;
336
        pPab->pPci45LinBaseAddr = (PU8) pciBaseAddr;
337
 
338
        /* Set outbound message frame addr */
339
        pPab->outMsgBlockPhyAddr = (U32) p_phymsgbuf;
340
        pPab->pLinOutMsgBlock = (PU8) p_msgbuf;
341
 
342
        /* store callback function addresses */
343
        pPab->pTransCallbackFunc = TransmitCallbackFunction;
344
        pPab->pRecvCallbackFunc = ReceiveCallbackFunction;
345
        pPab->pRebootCallbackFunc = RebootCallbackFunction;
346
        pPab->pCallbackFunc = (PFNCALLBACK) NULL;
347
 
348
        /*
349
           ** Initialize I2O IOP
350
         */
351
        result = GetI2OStatus (pPab);
352
 
353
        if (result != RC_RTN_NO_ERROR)
354
                goto err_out_dealloc;
355
 
356
        if (pPab->IOPState == I2O_IOP_STATE_OPERATIONAL) {
357
                dprintk (KERN_INFO "pPab->IOPState == op: resetting adapter\n");
358
                RCResetLANCard (dev, 0, (PU32) NULL, (PFNCALLBACK) NULL);
359
        }
360
 
361
        result = SendI2OOutboundQInitMsg (pPab);
362
 
363
        if (result != RC_RTN_NO_ERROR)
364
                goto err_out_dealloc;
365
 
366
        result = SendEnableSysMsg (pPab);
367
 
368
        if (result != RC_RTN_NO_ERROR)
369
                goto err_out_dealloc;
370
 
371
        return RC_RTN_NO_ERROR;
372
 
373
      err_out_dealloc:
374
        kfree (pPab);
375
      err_out:
376
        return result;
377
}
378
 
379
/*
380
** =========================================================================
381
** Disable and Enable I2O interrupts.  I2O interrupts are enabled at Init time
382
** but can be disabled and re-enabled through these two function calls.
383
** Packets will still be put into any posted received buffers and packets will
384
** be sent through RCI2OSendPacket() functions.  Disabling I2O interrupts
385
** will prevent hardware interrupt to host even though the outbound I2O msg
386
** queue is not emtpy.
387
** =========================================================================
388
*/
389
#define i960_OUT_POST_Q_INT_BIT        0x0008   /* bit set masks interrupts */
390
 
391
RC_RETURN
392
RCDisableI2OInterrupts (struct net_device * dev)
393
{
394
        PPAB pPab = ((PDPA) dev->priv)->pPab;
395
 
396
        if (pPab == NULL)
397
                return RC_RTN_ADPTR_NOT_REGISTERED;
398
 
399
        pPab->p_atu->OutIntMask |= i960_OUT_POST_Q_INT_BIT;
400
 
401
        return RC_RTN_NO_ERROR;
402
}
403
 
404
RC_RETURN
405
RCEnableI2OInterrupts (struct net_device * dev)
406
{
407
        PPAB pPab = ((PDPA) dev->priv)->pPab;
408
 
409
        if (pPab == NULL)
410
                return RC_RTN_ADPTR_NOT_REGISTERED;
411
 
412
        pPab->p_atu->OutIntMask &= ~i960_OUT_POST_Q_INT_BIT;
413
 
414
        return RC_RTN_NO_ERROR;
415
 
416
}
417
 
418
/*
419
** =========================================================================
420
** RCI2OSendPacket()
421
** =========================================================================
422
*/
423
RC_RETURN
424
RCI2OSendPacket (struct net_device * dev, U32 InitiatorContext,
425
                 PRCTCB pTransCtrlBlock)
426
{
427
        U32 msgOffset;
428
        PU32 pMsg;
429
        int size;
430
        PPAB pPab = ((PDPA) dev->priv)->pPab;
431
 
432
        dprintk ("RCI2OSendPacket()...\n");
433
 
434
        if (pPab == NULL)
435
                return RC_RTN_ADPTR_NOT_REGISTERED;
436
 
437
        /* get Inbound free Q entry - reading from In Q gets free Q entry */
438
        /* offset to Msg Frame in PCI msg block */
439
 
440
        msgOffset = pPab->p_atu->InQueue;
441
 
442
        if (msgOffset == 0xFFFFFFFF) {
443
                dprintk ("RCI2OSendPacket(): Inbound Free Q empty!\n");
444
                return RC_RTN_FREE_Q_EMPTY;
445
        }
446
 
447
        /* calc virtual address of msg - virtual already mapped to physical */
448
        pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
449
 
450
        size = FillI2OMsgSGLFromTCB (pMsg + 4, pTransCtrlBlock);
451
 
452
        if (size == -1) {       /* error processing TCB - send NOP msg */
453
                dprintk ("RCI2OSendPacket(): Error Rrocess TCB!\n");
454
                pMsg[0] = THREE_WORD_MSG_SIZE | SGL_OFFSET_0;
455
                pMsg[1] =
456
                    I2O_UTIL_NOP << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
457
                return RC_RTN_TCB_ERROR;
458
        } else {                /* send over msg header */
459
 
460
                pMsg[0] = (size + 4) << 16 | LAN_MSG_REQST;      /* send over message size and flags */
461
                pMsg[1] =
462
                    I2O_LAN_PACKET_SEND << 24 | I2O_HOST_TID << 12 |
463
                    RC_LAN_TARGET_ID;
464
                pMsg[2] = InitiatorContext;
465
                pMsg[3] = 0;     /* batch reply */
466
                /* post to Inbound Post Q */
467
                pPab->p_atu->InQueue = msgOffset;
468
                return RC_RTN_NO_ERROR;
469
        }
470
}
471
 
472
/*
473
** =========================================================================
474
** RCI2OPostRecvBuffer()
475
**
476
** inputs:  pBufrCntrlBlock - pointer to buffer control block
477
**
478
** returns TRUE if successful in sending message, else FALSE.
479
** =========================================================================
480
*/
481
RC_RETURN
482
RCPostRecvBuffers (struct net_device * dev, PRCTCB pTransCtrlBlock)
483
{
484
        U32 msgOffset;
485
        PU32 pMsg;
486
        int size;
487
        PPAB pPab = ((PDPA) dev->priv)->pPab;
488
 
489
        dprintk ("RCPostRecvBuffers()...\n");
490
 
491
        /* search for DeviceHandle */
492
 
493
        if (pPab == NULL)
494
                return RC_RTN_ADPTR_NOT_REGISTERED;
495
 
496
        /* get Inbound free Q entry - reading from In Q gets free Q entry */
497
        /* offset to Msg Frame in PCI msg block */
498
        msgOffset = pPab->p_atu->InQueue;
499
 
500
        if (msgOffset == 0xFFFFFFFF) {
501
                dprintk ("RCPostRecvBuffers(): Inbound Free Q empty!\n");
502
                return RC_RTN_FREE_Q_EMPTY;
503
        }
504
        /* calc virtual address of msg - virtual already mapped to physical */
505
        pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
506
 
507
        size = FillI2OMsgSGLFromTCB (pMsg + 4, pTransCtrlBlock);
508
 
509
        if (size == -1) {       /* error prcessing TCB - send 3 DWORD private msg == NOP */
510
                dprintk
511
                    ("RCPostRecvBuffers(): Error Processing TCB! size = %d\n",
512
                     size);
513
                pMsg[0] = THREE_WORD_MSG_SIZE | SGL_OFFSET_0;
514
                pMsg[1] =
515
                    I2O_UTIL_NOP << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
516
                /* post to Post Q */
517
                pPab->p_atu->InQueue = msgOffset;
518
                return RC_RTN_TCB_ERROR;
519
        } else {                /* send over size msg header */
520
 
521
                pMsg[0] = (size + 4) << 16 | LAN_MSG_REQST;      /* send over message size and flags */
522
                pMsg[1] =
523
                    I2O_LAN_RECEIVE_POST << 24 | I2O_HOST_TID << 12 |
524
                    RC_LAN_TARGET_ID;
525
                pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
526
                pMsg[3] = *(PU32) pTransCtrlBlock;      /* number of packet buffers */
527
                /* post to Post Q */
528
                pPab->p_atu->InQueue = msgOffset;
529
                return RC_RTN_NO_ERROR;
530
        }
531
}
532
 
533
/*
534
** =========================================================================
535
** RCProcI2OMsgQ()
536
**
537
** Process I2O outbound message queue until empty.
538
** =========================================================================
539
*/
540
void
541
RCProcI2OMsgQ (struct net_device *dev)
542
{
543
        U32 phyAddrMsg;
544
        PU8 p8Msg;
545
        PU32 p32;
546
        U16 count;
547
        PPAB pPab = ((PDPA) dev->priv)->pPab;
548
        unsigned char debug_msg[20];
549
 
550
        if (pPab == NULL)
551
                return;
552
 
553
        phyAddrMsg = pPab->p_atu->OutQueue;
554
 
555
        while (phyAddrMsg != 0xFFFFFFFF) {
556
                p8Msg =
557
                    pPab->pLinOutMsgBlock + (phyAddrMsg -
558
                                             pPab->outMsgBlockPhyAddr);
559
                p32 = (PU32) p8Msg;
560
 
561
                dprintk ("msg: 0x%x  0x%x \n", p8Msg[7], p32[5]);
562
 
563
                /* Send Packet Reply Msg */
564
                if (I2O_LAN_PACKET_SEND == p8Msg[7]) {  /* function code byte */
565
                        count = *(PU16) (p8Msg + 2);
566
                        count -= p8Msg[0] >> 4;
567
                        /* status, count, context[], adapter */
568
                        (*pPab->pTransCallbackFunc) (p8Msg[19], count, p32 + 5,
569
                                                     dev);
570
                } else if (I2O_LAN_RECEIVE_POST == p8Msg[7]) {  /* Receive Packet Reply Msg */
571
                        dprintk
572
                            ("I2O_RECV_REPLY pPab:0x%x p8Msg:0x%x p32:0x%x\n",
573
                             (u32) pPab, (u32) p8Msg, (u32) p32);
574
                        dprintk ("msg: 0x%x:0x%x:0x%x:0x%x\n",
575
                                 p32[0], p32[1], p32[2], p32[3]);
576
                        dprintk ("     0x%x:0x%x:0x%x:0x%x\n",
577
                                 p32[4], p32[5], p32[6], p32[7]);
578
                        dprintk ("     0x%x:0X%x:0x%x:0x%x\n",
579
                                 p32[8], p32[9], p32[10], p32[11]);
580
                        /*  status, count, buckets remaining, packetParmBlock, adapter */
581
                        (*pPab->pRecvCallbackFunc) (p8Msg[19], p8Msg[12],
582
                                                    p32[5], p32 + 6, dev);
583
                } else if (I2O_LAN_RESET == p8Msg[7]
584
                           || I2O_LAN_SHUTDOWN == p8Msg[7])
585
                        if (pPab->pCallbackFunc)
586
                                (*pPab->pCallbackFunc) (p8Msg[19], 0, 0, dev);
587
                        else
588
                                pPab->pCallbackFunc = (PFNCALLBACK) 1;
589
                else if (I2O_PRIVATE == p8Msg[7]) {
590
                        dprintk ("i2o private 0x%x, 0x%x \n", p8Msg[7], p32[5]);
591
                        switch (p32[5]) {
592
                        case RC_PRIVATE_DEBUG_MSG:
593
                                msgFlag = 1;
594
                                dprintk ("Received I2O_PRIVATE msg\n");
595
                                debug_msg[15] = (p32[6] & 0xff000000) >> 24;
596
                                debug_msg[14] = (p32[6] & 0x00ff0000) >> 16;
597
                                debug_msg[13] = (p32[6] & 0x0000ff00) >> 8;
598
                                debug_msg[12] = (p32[6] & 0x000000ff);
599
 
600
                                debug_msg[11] = (p32[7] & 0xff000000) >> 24;
601
                                debug_msg[10] = (p32[7] & 0x00ff0000) >> 16;
602
                                debug_msg[9] = (p32[7] & 0x0000ff00) >> 8;
603
                                debug_msg[8] = (p32[7] & 0x000000ff);
604
 
605
                                debug_msg[7] = (p32[8] & 0xff000000) >> 24;
606
                                debug_msg[6] = (p32[8] & 0x00ff0000) >> 16;
607
                                debug_msg[5] = (p32[8] & 0x0000ff00) >> 8;
608
                                debug_msg[4] = (p32[8] & 0x000000ff);
609
 
610
                                debug_msg[3] = (p32[9] & 0xff000000) >> 24;
611
                                debug_msg[2] = (p32[9] & 0x00ff0000) >> 16;
612
                                debug_msg[1] = (p32[9] & 0x0000ff00) >> 8;
613
                                debug_msg[0] = (p32[9] & 0x000000ff);
614
 
615
                                debug_msg[16] = '\0';
616
                                dprintk ("%s", debug_msg);
617
                                break;
618
                        case RC_PRIVATE_REBOOT:
619
                                dprintk ("Adapter reboot initiated...\n");
620
                                if (pPab->pRebootCallbackFunc)
621
                                        (*pPab->pRebootCallbackFunc) (0, 0, 0,
622
                                                                      dev);
623
                                break;
624
                        default:
625
                                dprintk (KERN_WARNING
626
                                        "Unknown private I2O msg received: 0x%x\n",
627
                                        p32[5]);
628
                                break;
629
                        }
630
                }
631
 
632
                /*
633
                   ** Process other Msg's
634
                 */
635
                else
636
                        ProcessOutboundI2OMsg (pPab, phyAddrMsg);
637
 
638
                /* return MFA to outbound free Q */
639
                pPab->p_atu->OutQueue = phyAddrMsg;
640
 
641
                /* any more msgs? */
642
                phyAddrMsg = pPab->p_atu->OutQueue;
643
        }
644
}
645
 
646
/*
647
** =========================================================================
648
**  Returns LAN interface statistical counters to space provided by caller at
649
**  StatsReturnAddr.  Returns 0 if success, else RC_RETURN code.
650
**  This function will call the WaitCallback function provided by
651
**  user while waiting for card to respond.
652
** =========================================================================
653
*/
654
RC_RETURN
655
RCGetLinkStatistics (struct net_device *dev,
656
                     P_RCLINKSTATS StatsReturnAddr,
657
                     PFNWAITCALLBACK WaitCallback)
658
{
659
        U32 msgOffset;
660
        volatile PU32 pMsg;
661
        volatile PU32 p32, pReturnAddr;
662
        P_NICSTAT pStats;
663
        int i;
664
        PPAB pPab = ((PDPA) dev->priv)->pPab;
665
 
666
/*dprintk("Get82558Stats() StatsReturnAddr:0x%x\n", StatsReturnAddr); */
667
 
668
        if (pPab == NULL)
669
                return RC_RTN_ADPTR_NOT_REGISTERED;
670
 
671
        msgOffset = pPab->p_atu->InQueue;
672
 
673
        if (msgOffset == 0xFFFFFFFF) {
674
                dprintk ("Get8255XStats(): Inbound Free Q empty!\n");
675
                return RC_RTN_FREE_Q_EMPTY;
676
        }
677
 
678
        /* calc virtual address of msg - virtual already mapped to physical */
679
        pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
680
 
681
/*dprintk("Get82558Stats - pMsg = 0x%x, InQ msgOffset = 0x%x\n", pMsg, msgOffset);*/
682
/*dprintk("Get82558Stats - pMsg = 0x%08X, InQ msgOffset = 0x%08X\n", pMsg, msgOffset);*/
683
 
684
        pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
685
        pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
686
        pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
687
        pMsg[3] = 0x112;        /* transaction context */
688
        pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_NIC_STATS;
689
        pMsg[5] = pPab->outMsgBlockPhyAddr;
690
 
691
//      p32 = (PU32) pPab->outMsgBlockPhyAddr;
692
        p32 = (PU32)pPab->pLinOutMsgBlock;
693
        pStats = (P_NICSTAT) pPab->pLinOutMsgBlock;
694
        pStats->dump_status = 0xFFFFFFFF;
695
 
696
        /* post to Inbound Post Q */
697
        pPab->p_atu->InQueue = msgOffset;
698
 
699
        i = 0;
700
        while (pStats->dump_status == 0xFFFFFFFF) {
701
                if (i++ > 0xff) {
702
                        dprintk ("Timeout waiting for NIC statistics\n");
703
                        return RC_RTN_MSG_REPLY_TIMEOUT;
704
                }
705
                udelay(50);
706
        }
707
        pReturnAddr = (PU32) StatsReturnAddr;
708
 
709
        /* copy Nic stats to user's structure */
710
        for (i = 0; i < (int) sizeof (RCLINKSTATS) / 4; i++)
711
                pReturnAddr[i] = p32[i];
712
 
713
        return RC_RTN_NO_ERROR;
714
}
715
 
716
/*
717
** =========================================================================
718
** Get82558LinkStatus()
719
** =========================================================================
720
*/
721
RC_RETURN
722
RCGetLinkStatus (struct net_device * dev, PU32 ReturnAddr,
723
                 PFNWAITCALLBACK WaitCallback)
724
{
725
        int i;
726
        U32 msgOffset;
727
        volatile PU32 pMsg;
728
        volatile PU32 p32;
729
        PPAB pPab = ((PDPA) dev->priv)->pPab;
730
 
731
        dprintk ("Get82558LinkStatus() ReturnPhysAddr:0x%x\n",
732
                 (u32) ReturnAddr);
733
 
734
        if (pPab == NULL)
735
                return RC_RTN_ADPTR_NOT_REGISTERED;
736
 
737
        msgOffset = pPab->p_atu->InQueue;
738
 
739
        if (msgOffset == 0xFFFFFFFF) {
740
                dprintk ("Get82558LinkStatus(): Inbound Free Q empty!\n");
741
                return RC_RTN_FREE_Q_EMPTY;
742
        }
743
 
744
        /* calc virtual address of msg - virtual already mapped to physical */
745
        pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
746
/*dprintk("Get82558LinkStatus - pMsg = 0x%x, InQ msgOffset = 0x%x\n", pMsg, msgOffset);*/
747
/*dprintk("Get82558LinkStatus - pMsg = 0x%08X, InQ msgOffset = 0x%08X\n", pMsg, msgOffset);*/
748
 
749
        pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
750
        pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
751
        pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
752
        pMsg[3] = 0x112;        /* transaction context */
753
        pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_LINK_STATUS;
754
        pMsg[5] = pPab->outMsgBlockPhyAddr;
755
 
756
        p32 = (PU32) pPab->pLinOutMsgBlock;
757
        *p32 = 0xFFFFFFFF;
758
 
759
        /* post to Inbound Post Q */
760
        pPab->p_atu->InQueue = msgOffset;
761
 
762
        i = 0;
763
        while (*p32 == 0xFFFFFFFF) {
764
                if (i++ > 0xff) {
765
                        dprintk ("Timeout waiting for link status\n");
766
                        return RC_RTN_MSG_REPLY_TIMEOUT;
767
                }
768
                udelay(50);
769
        }
770
 
771
        *ReturnAddr = *p32;     /* 1 = up 0 = down */
772
 
773
        return RC_RTN_NO_ERROR;
774
 
775
}
776
 
777
/*
778
** =========================================================================
779
** RCGetMAC()
780
**
781
** get the MAC address the adapter is listening for in non-promiscous mode.
782
** MAC address is in media format.
783
** =========================================================================
784
*/
785
RC_RETURN
786
RCGetMAC (struct net_device * dev, PFNWAITCALLBACK WaitCallback)
787
{
788
        U32 off, i;
789
        PU8 mac = dev->dev_addr;
790
        PU32 p;
791
        U32 temp[2];
792
        PPAB pPab = ((PDPA) dev->priv)->pPab;
793
        PATU p_atu;
794
 
795
        if (pPab == NULL)
796
                return RC_RTN_ADPTR_NOT_REGISTERED;
797
 
798
        p_atu = pPab->p_atu;
799
 
800
        p_atu->EtherMacLow = 0;  /* first zero return data */
801
        p_atu->EtherMacHi = 0;
802
 
803
        off = p_atu->InQueue;   /* get addresss of message */
804
 
805
        if (0xFFFFFFFF == off)
806
                return RC_RTN_FREE_Q_EMPTY;
807
 
808
        p = (PU32) (pPab->pPci45LinBaseAddr + off);
809
 
810
        dprintk ("RCGetMAC: p_atu 0x%08x, off 0x%08x, p 0x%08x\n",
811
                 (uint) p_atu, (uint) off, (uint) p);
812
        /* setup private message */
813
        p[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0;
814
        p[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
815
        p[2] = 0;                /* initiator context */
816
        p[3] = 0x218;           /* transaction context */
817
        p[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_MAC_ADDR;
818
 
819
        p_atu->InQueue = off;   /* send it to the I2O device */
820
        dprintk ("RCGetMAC: p_atu 0x%08x, off 0x%08x, p 0x%08x\n",
821
                 (uint) p_atu, (uint) off, (uint) p);
822
 
823
        /* wait for the rcpci45 board to update the info */
824
        i = 0;
825
        while (0 == p_atu->EtherMacLow) {
826
                if (i++ > 0xff) {
827
                        dprintk ("rc_getmac: Timeout\n");
828
                        return RC_RTN_MSG_REPLY_TIMEOUT;
829
                }
830
                udelay(50);
831
        }
832
 
833
        /* read the mac address  */
834
        temp[0] = p_atu->EtherMacLow;
835
        temp[1] = p_atu->EtherMacHi;
836
        memcpy ((char *) mac, (char *) temp, 6);
837
 
838
        dprintk ("rc_getmac: 0x%x\n", (u32) mac);
839
 
840
        return RC_RTN_NO_ERROR;
841
}
842
 
843
/*
844
** =========================================================================
845
** RCSetMAC()
846
**
847
** set MAC address the adapter is listening for in non-promiscous mode.
848
** MAC address is in media format.
849
** =========================================================================
850
*/
851
RC_RETURN
852
RCSetMAC (struct net_device * dev, PU8 mac)
853
{
854
        U32 off;
855
        PU32 pMsg;
856
        PPAB pPab = ((PDPA) dev->priv)->pPab;
857
 
858
        if (pPab == NULL)
859
                return RC_RTN_ADPTR_NOT_REGISTERED;
860
 
861
        off = pPab->p_atu->InQueue;     /* get addresss of message */
862
 
863
        if (0xFFFFFFFF == off)
864
                return RC_RTN_FREE_Q_EMPTY;
865
 
866
        pMsg = (PU32) (pPab->pPci45LinBaseAddr + off);
867
 
868
        /* setup private message */
869
        pMsg[0] = SEVEN_WORD_MSG_SIZE | SGL_OFFSET_0;
870
        pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
871
        pMsg[2] = 0;             /* initiator context */
872
        pMsg[3] = 0x219;        /* transaction context */
873
        pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_MAC_ADDR;
874
        pMsg[5] = *(unsigned *) mac;    /* first four bytes */
875
        pMsg[6] = *(unsigned *) (mac + 4);      /* last two bytes */
876
 
877
        pPab->p_atu->InQueue = off;     /* send it to the I2O device */
878
 
879
        return RC_RTN_NO_ERROR;
880
}
881
 
882
/*
883
** =========================================================================
884
** RCSetLinkSpeed()
885
**
886
** set ethernet link speed.
887
** input: speedControl - determines action to take as follows
888
**          0 = reset and auto-negotiate (NWay)
889
**          1 = Full Duplex 100BaseT
890
**          2 = Half duplex 100BaseT
891
**          3 = Full Duplex  10BaseT
892
**          4 = Half duplex  10BaseT
893
**          all other values are ignore (do nothing)
894
** =========================================================================
895
*/
896
RC_RETURN
897
RCSetLinkSpeed (struct net_device * dev, U16 LinkSpeedCode)
898
{
899
        U32 off;
900
        PU32 pMsg;
901
        PPAB pPab = ((PDPA) dev->priv)->pPab;
902
 
903
        if (pPab == NULL)
904
                return RC_RTN_ADPTR_NOT_REGISTERED;
905
 
906
        off = pPab->p_atu->InQueue;     /* get addresss of message */
907
 
908
        if (0xFFFFFFFF == off)
909
                return RC_RTN_FREE_Q_EMPTY;
910
 
911
        pMsg = (PU32) (pPab->pPci45LinBaseAddr + off);
912
 
913
        /* setup private message */
914
        pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
915
        pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
916
        pMsg[2] = 0;             /* initiator context */
917
        pMsg[3] = 0x219;        /* transaction context */
918
        pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_LINK_SPEED;
919
        pMsg[5] = LinkSpeedCode;        /* link speed code */
920
 
921
        pPab->p_atu->InQueue = off;     /* send it to the I2O device */
922
 
923
        return RC_RTN_NO_ERROR;
924
}
925
 
926
/*
927
** =========================================================================
928
** RCSetPromiscuousMode()
929
**
930
** Defined values for Mode:
931
**  0 - turn off promiscuous mode
932
**  1 - turn on  promiscuous mode
933
**
934
** =========================================================================
935
*/
936
RC_RETURN
937
RCSetPromiscuousMode (struct net_device * dev, U16 Mode)
938
{
939
        U32 off;
940
        PU32 pMsg;
941
        PPAB pPab = ((PDPA) dev->priv)->pPab;
942
 
943
        if (pPab == NULL)
944
                return RC_RTN_ADPTR_NOT_REGISTERED;
945
 
946
        off = pPab->p_atu->InQueue;     /* get addresss of message */
947
 
948
        if (0xFFFFFFFF == off)
949
                return RC_RTN_FREE_Q_EMPTY;
950
 
951
        pMsg = (PU32) (pPab->pPci45LinBaseAddr + off);
952
 
953
        /* setup private message */
954
        pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
955
        pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
956
        pMsg[2] = 0;             /* initiator context */
957
        pMsg[3] = 0x219;        /* transaction context */
958
        pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_PROMISCUOUS_MODE;
959
        pMsg[5] = Mode;         /* promiscuous mode setting */
960
 
961
        pPab->p_atu->InQueue = off;     /* send it to the device */
962
 
963
        return RC_RTN_NO_ERROR;
964
}
965
 
966
/*
967
** =========================================================================
968
** RCGetPromiscuousMode()
969
**
970
** get promiscuous mode setting
971
**
972
** Possible return values placed in pMode:
973
**  0 = promisuous mode not set
974
**  1 = promisuous mode is set
975
**
976
** =========================================================================
977
*/
978
RC_RETURN
979
RCGetPromiscuousMode (struct net_device * dev, PU32 pMode,
980
                      PFNWAITCALLBACK WaitCallback)
981
{
982
        PU32 pMsg;
983
        volatile PU32 p32;
984
        U32 msgOffset, i;
985
        PPAB pPab = ((PDPA) dev->priv)->pPab;
986
 
987
        msgOffset = pPab->p_atu->InQueue;
988
 
989
        if (msgOffset == 0xFFFFFFFF) {
990
                dprintk (KERN_WARNING
991
                        "RCGetLinkSpeed(): Inbound Free Q empty!\n");
992
                return RC_RTN_FREE_Q_EMPTY;
993
        }
994
 
995
        /* calc virtual address of msg - virtual already mapped to physical */
996
        pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
997
 
998
        /* virtual pointer to return buffer - clear first two dwords */
999
        p32 = (volatile PU32) pPab->pLinOutMsgBlock;
1000
        p32[0] = 0xff;
1001
 
1002
        /* setup private message */
1003
        pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
1004
        pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
1005
        pMsg[2] = 0;             /* initiator context */
1006
        pMsg[3] = 0x219;        /* transaction context */
1007
        pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_PROMISCUOUS_MODE;
1008
        /* phys address to return status - area right after PAB */
1009
        pMsg[5] = pPab->outMsgBlockPhyAddr;
1010
 
1011
        /* post to Inbound Post Q */
1012
 
1013
        pPab->p_atu->InQueue = msgOffset;
1014
 
1015
        i = 0;
1016
 
1017
        /* wait for response */
1018
        while (p32[0] == 0xff) {
1019
                if (i++ > 0xff) {
1020
                        dprintk ("Timeout waiting for promiscuous mode\n");
1021
                        return RC_RTN_NO_LINK_SPEED;
1022
                }
1023
                udelay(50);
1024
        }
1025
 
1026
        /* get mode */
1027
        *pMode = (U8) ((volatile PU8) p32)[0] & 0x0f;
1028
 
1029
        return RC_RTN_NO_ERROR;
1030
}
1031
 
1032
/*
1033
** =========================================================================
1034
** RCSetBroadcastMode()
1035
**
1036
** Defined values for Mode:
1037
**  0 - turn off promiscuous mode
1038
**  1 - turn on  promiscuous mode
1039
**
1040
** =========================================================================
1041
*/
1042
RC_RETURN
1043
RCSetBroadcastMode (struct net_device * dev, U16 Mode)
1044
{
1045
        U32 off;
1046
        PU32 pMsg;
1047
        PPAB pPab = ((PDPA) dev->priv)->pPab;
1048
 
1049
        if (pPab == NULL)
1050
                return RC_RTN_ADPTR_NOT_REGISTERED;
1051
 
1052
        off = pPab->p_atu->InQueue;     /* get addresss of message */
1053
 
1054
        if (0xFFFFFFFF == off)
1055
                return RC_RTN_FREE_Q_EMPTY;
1056
 
1057
        pMsg = (PU32) (pPab->pPci45LinBaseAddr + off);
1058
 
1059
        /* setup private message */
1060
        pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
1061
        pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
1062
        pMsg[2] = 0;             /* initiator context */
1063
        pMsg[3] = 0x219;        /* transaction context */
1064
        pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_BROADCAST_MODE;
1065
        pMsg[5] = Mode;         /* promiscuous mode setting */
1066
 
1067
        pPab->p_atu->InQueue = off;     /* send it to the device */
1068
 
1069
        return RC_RTN_NO_ERROR;
1070
}
1071
 
1072
/*
1073
** =========================================================================
1074
** RCGetBroadcastMode()
1075
**
1076
** get promiscuous mode setting
1077
**
1078
** Possible return values placed in pMode:
1079
**  0 = promisuous mode not set
1080
**  1 = promisuous mode is set
1081
**
1082
** =========================================================================
1083
*/
1084
RC_RETURN
1085
RCGetBroadcastMode (struct net_device * dev, PU32 pMode,
1086
                    PFNWAITCALLBACK WaitCallback)
1087
{
1088
        U32 msgOffset;
1089
        PU32 pMsg;
1090
        volatile PU32 p32;
1091
        PPAB pPab = ((PDPA) dev->priv)->pPab;
1092
 
1093
        msgOffset = pPab->p_atu->InQueue;
1094
 
1095
        if (msgOffset == 0xFFFFFFFF) {
1096
                dprintk (KERN_WARNING
1097
                        "RCGetLinkSpeed(): Inbound Free Q empty!\n");
1098
                return RC_RTN_FREE_Q_EMPTY;
1099
        }
1100
 
1101
        /* calc virtual address of msg - virtual already mapped to physical */
1102
        pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
1103
 
1104
        /* virtual pointer to return buffer - clear first two dwords */
1105
        p32 = (volatile PU32) pPab->pLinOutMsgBlock;
1106
        p32[0] = 0xff;
1107
 
1108
        /* setup private message */
1109
        pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
1110
        pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
1111
        pMsg[2] = 0;             /* initiator context */
1112
        pMsg[3] = 0x219;        /* transaction context */
1113
        pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_BROADCAST_MODE;
1114
        /* phys address to return status - area right after PAB */
1115
        pMsg[5] = pPab->outMsgBlockPhyAddr;
1116
 
1117
        /* post to Inbound Post Q */
1118
 
1119
        pPab->p_atu->InQueue = msgOffset;
1120
 
1121
        /* wait for response */
1122
        if (p32[0] == 0xff) {
1123
                dprintk (KERN_WARNING
1124
                        "Timeout waiting for promiscuous mode\n");
1125
                return RC_RTN_NO_LINK_SPEED;
1126
        }
1127
 
1128
        /* get mode */
1129
        *pMode = (U8) ((volatile PU8) p32)[0] & 0x0f;
1130
 
1131
        return RC_RTN_NO_ERROR;
1132
}
1133
 
1134
/*
1135
** =========================================================================
1136
** RCGetLinkSpeed()
1137
**
1138
** get ethernet link speed.
1139
**
1140
** 0 = Unknown
1141
** 1 = Full Duplex 100BaseT
1142
** 2 = Half duplex 100BaseT
1143
** 3 = Full Duplex  10BaseT
1144
** 4 = Half duplex  10BaseT
1145
**
1146
** =========================================================================
1147
*/
1148
RC_RETURN
1149
RCGetLinkSpeed (struct net_device * dev, PU32 pLinkSpeedCode,
1150
                PFNWAITCALLBACK WaitCallback)
1151
{
1152
        U32 msgOffset, i;
1153
        PU32 pMsg;
1154
        volatile PU32 p32;
1155
        U8 IOPLinkSpeed;
1156
        PPAB pPab = ((PDPA) dev->priv)->pPab;
1157
 
1158
        msgOffset = pPab->p_atu->InQueue;
1159
 
1160
        if (msgOffset == 0xFFFFFFFF) {
1161
                dprintk (KERN_WARNING
1162
                        "RCGetLinkSpeed(): Inbound Free Q empty!\n");
1163
                return RC_RTN_FREE_Q_EMPTY;
1164
        }
1165
 
1166
        /* calc virtual address of msg - virtual already mapped to physical */
1167
        pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
1168
 
1169
        /* virtual pointer to return buffer - clear first two dwords */
1170
        p32 = (volatile PU32) pPab->pLinOutMsgBlock;
1171
        p32[0] = 0xff;
1172
 
1173
        /* setup private message */
1174
        pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
1175
        pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
1176
        pMsg[2] = 0;             /* initiator context */
1177
        pMsg[3] = 0x219;        /* transaction context */
1178
        pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_LINK_SPEED;
1179
        /* phys address to return status - area right after PAB */
1180
        pMsg[5] = pPab->outMsgBlockPhyAddr;
1181
 
1182
        /* post to Inbound Post Q */
1183
 
1184
        pPab->p_atu->InQueue = msgOffset;
1185
 
1186
        /* wait for response */
1187
        i = 0;
1188
        while (p32[0] == 0xff) {
1189
                if (i++ > 0xff) {
1190
                        dprintk ("Timeout waiting for link speed\n");
1191
                        return RC_RTN_NO_LINK_SPEED;
1192
                }
1193
                udelay(50);
1194
        }
1195
        /* get Link speed */
1196
        IOPLinkSpeed = (U8) ((volatile PU8) p32)[0] & 0x0f;
1197
        *pLinkSpeedCode = IOPLinkSpeed;
1198
 
1199
        return RC_RTN_NO_ERROR;
1200
}
1201
 
1202
/*
1203
** =========================================================================
1204
** RCReportDriverCapability(struct net_device *dev, U32 capability)
1205
**
1206
** Currently defined bits:
1207
** WARM_REBOOT_CAPABLE   0x01
1208
**
1209
** =========================================================================
1210
*/
1211
RC_RETURN
1212
RCReportDriverCapability (struct net_device * dev, U32 capability)
1213
{
1214
        U32 off;
1215
        PU32 pMsg;
1216
        PPAB pPab = ((PDPA) dev->priv)->pPab;
1217
 
1218
        if (pPab == NULL)
1219
                return RC_RTN_ADPTR_NOT_REGISTERED;
1220
 
1221
        off = pPab->p_atu->InQueue;     /* get addresss of message */
1222
 
1223
        if (0xFFFFFFFF == off)
1224
                return RC_RTN_FREE_Q_EMPTY;
1225
 
1226
        pMsg = (PU32) (pPab->pPci45LinBaseAddr + off);
1227
 
1228
        /* setup private message */
1229
        pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
1230
        pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
1231
        pMsg[2] = 0;             /* initiator context */
1232
        pMsg[3] = 0x219;        /* transaction context */
1233
        pMsg[4] =
1234
            RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_REPORT_DRIVER_CAPABILITY;
1235
        pMsg[5] = capability;
1236
 
1237
        pPab->p_atu->InQueue = off;     /* send it to the I2O device */
1238
 
1239
        return RC_RTN_NO_ERROR;
1240
}
1241
 
1242
/*
1243
** =========================================================================
1244
** RCGetFirmwareVer()
1245
**
1246
** Return firmware version in the form "SoftwareVersion : Bt BootVersion"
1247
**
1248
** =========================================================================
1249
*/
1250
RC_RETURN
1251
RCGetFirmwareVer (struct net_device * dev, PU8 pFirmString,
1252
                  PFNWAITCALLBACK WaitCallback)
1253
{
1254
        U32 msgOffset, i;
1255
        PU32 pMsg;
1256
        volatile PU32 p32;
1257
        PPAB pPab = ((PDPA) dev->priv)->pPab;
1258
 
1259
        msgOffset = pPab->p_atu->InQueue;
1260
        if (msgOffset == 0xFFFFFFFF) {
1261
                dprintk ("RCGetFirmwareVer(): Inbound Free Q empty!\n");
1262
                return RC_RTN_FREE_Q_EMPTY;
1263
        }
1264
 
1265
        /* calc virtual address of msg - virtual already mapped to physical */
1266
        pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
1267
 
1268
        /* virtual pointer to return buffer - clear first two dwords */
1269
        p32 = (volatile PU32) pPab->pLinOutMsgBlock;
1270
        p32[0] = 0xff;
1271
 
1272
        /* setup private message */
1273
        pMsg[0] = SIX_WORD_MSG_SIZE | SGL_OFFSET_0;
1274
        pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
1275
        pMsg[2] = 0;             /* initiator context */
1276
        pMsg[3] = 0x219;        /* transaction context */
1277
        pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_FIRMWARE_REV;
1278
        /* phys address to return status - area right after PAB */
1279
        pMsg[5] = pPab->outMsgBlockPhyAddr;
1280
 
1281
        /* post to Inbound Post Q */
1282
 
1283
        pPab->p_atu->InQueue = msgOffset;
1284
 
1285
        /* wait for response */
1286
        i = 0;
1287
        while (p32[0] == 0xff) {
1288
                if (i++ > 0xff) {
1289
                        dprintk ("Timeout waiting for link speed\n");
1290
                        return RC_RTN_NO_FIRM_VER;
1291
                }
1292
                udelay(50);
1293
        }
1294
        strcpy (pFirmString, (PU8) p32);
1295
        return RC_RTN_NO_ERROR;
1296
}
1297
 
1298
/*
1299
** =========================================================================
1300
** RCResetLANCard()
1301
**
1302
** ResourceFlags indicates whether to return buffer resource explicitly
1303
** to host or keep and reuse.
1304
** CallbackFunction (if not NULL) is the function to be called when
1305
** reset is complete.
1306
** If CallbackFunction is NULL, ReturnAddr will have a 1 placed in it when
1307
** reset is done (if not NULL).
1308
**
1309
** =========================================================================
1310
*/
1311
RC_RETURN
1312
RCResetLANCard (struct net_device * dev, U16 ResourceFlags, PU32 ReturnAddr,
1313
                PFNCALLBACK CallbackFunction)
1314
{
1315
        unsigned long off;
1316
        PU32 pMsg;
1317
        PPAB pPab = ((PDPA) dev->priv)->pPab;
1318
        long timeout = 0;
1319
 
1320
        if (pPab == NULL)
1321
                return RC_RTN_ADPTR_NOT_REGISTERED;
1322
 
1323
        off = pPab->p_atu->InQueue;     /* get addresss of message */
1324
 
1325
        if (0xFFFFFFFF == off)
1326
                return RC_RTN_FREE_Q_EMPTY;
1327
 
1328
        pPab->pCallbackFunc = CallbackFunction;
1329
 
1330
        pMsg = (PU32) (pPab->pPci45LinBaseAddr + off);
1331
 
1332
        /* setup message */
1333
        pMsg[0] = FOUR_WORD_MSG_SIZE | SGL_OFFSET_0;
1334
        pMsg[1] = I2O_LAN_RESET << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
1335
        pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
1336
        pMsg[3] = ResourceFlags << 16;  /* resource flags */
1337
 
1338
        pPab->p_atu->InQueue = off;     /* send it to the I2O device */
1339
 
1340
        if (CallbackFunction == (PFNCALLBACK) NULL) {
1341
                /* call RCProcI2OMsgQ() until something in pPab->pCallbackFunc
1342
                   or until timer goes off */
1343
                while (pPab->pCallbackFunc == (PFNCALLBACK) NULL) {
1344
                        RCProcI2OMsgQ (dev);
1345
                        mdelay (1);
1346
                        timeout++;
1347
                        if (timeout > 200) {
1348
                                break;
1349
                        }
1350
                }
1351
                if (ReturnAddr != (PU32) NULL)
1352
                        *ReturnAddr = (U32) pPab->pCallbackFunc;
1353
        }
1354
 
1355
        return RC_RTN_NO_ERROR;
1356
}
1357
 
1358
/*
1359
** =========================================================================
1360
** RCResetIOP()
1361
**
1362
** Send StatusGet Msg, wait for results return directly to buffer.
1363
**
1364
** =========================================================================
1365
*/
1366
RC_RETURN
1367
RCResetIOP (struct net_device * dev)
1368
{
1369
        U32 msgOffset, i;
1370
        PU32 pMsg;
1371
        PPAB pPab = ((PDPA) dev->priv)->pPab;
1372
        volatile PU32 p32;
1373
 
1374
        msgOffset = pPab->p_atu->InQueue;
1375
 
1376
        if (msgOffset == 0xFFFFFFFF) {
1377
                return RC_RTN_FREE_Q_EMPTY;
1378
        }
1379
 
1380
        /* calc virtual address of msg - virtual already mapped to physical */
1381
        pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
1382
 
1383
        pMsg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_0;
1384
        pMsg[1] = I2O_EXEC_IOP_RESET << 24 | I2O_HOST_TID << 12 | I2O_IOP_TID;
1385
        pMsg[2] = 0;             /* universal context */
1386
        pMsg[3] = 0;             /* universal context */
1387
        pMsg[4] = 0;             /* universal context */
1388
        pMsg[5] = 0;             /* universal context */
1389
        /* phys address to return status - area right after PAB */
1390
        pMsg[6] = pPab->outMsgBlockPhyAddr;
1391
        pMsg[7] = 0;
1392
        pMsg[8] = 1;            /*  return 1 byte */
1393
 
1394
        /* virtual pointer to return buffer - clear first two dwords */
1395
        p32 = (volatile PU32) pPab->pLinOutMsgBlock;
1396
        p32[0] = 0;
1397
        p32[1] = 0;
1398
 
1399
        /* post to Inbound Post Q */
1400
 
1401
        pPab->p_atu->InQueue = msgOffset;
1402
 
1403
        /* wait for response */
1404
        i = 0;
1405
        while (!p32[0] && !p32[1]) {
1406
                if (i++ > 0xff) {
1407
                        dprintk ("RCResetIOP timeout\n");
1408
                        return RC_RTN_MSG_REPLY_TIMEOUT;
1409
                }
1410
                udelay(100);
1411
        }
1412
        return RC_RTN_NO_ERROR;
1413
}
1414
 
1415
/*
1416
** =========================================================================
1417
** RCShutdownLANCard()
1418
**
1419
** ResourceFlags indicates whether to return buffer resource explicitly
1420
** to host or keep and reuse.
1421
** CallbackFunction (if not NULL) is the function to be called when
1422
** shutdown is complete.
1423
** If CallbackFunction is NULL, ReturnAddr will have a 1 placed in it when
1424
** shutdown is done (if not NULL).
1425
**
1426
** =========================================================================
1427
*/
1428
RC_RETURN
1429
RCShutdownLANCard (struct net_device * dev, U16 ResourceFlags,
1430
                   PU32 ReturnAddr, PFNCALLBACK CallbackFunction)
1431
{
1432
        volatile PU32 pMsg;
1433
        U32 off;
1434
        PPAB pPab = ((PDPA) dev->priv)->pPab;
1435
        long timeout = 0;
1436
 
1437
        if (pPab == NULL)
1438
                return RC_RTN_ADPTR_NOT_REGISTERED;
1439
 
1440
        off = pPab->p_atu->InQueue;     /* get addresss of message */
1441
 
1442
        if (0xFFFFFFFF == off)
1443
                return RC_RTN_FREE_Q_EMPTY;
1444
 
1445
        pPab->pCallbackFunc = CallbackFunction;
1446
 
1447
        pMsg = (PU32) (pPab->pPci45LinBaseAddr + off);
1448
 
1449
        /* setup message */
1450
        pMsg[0] = FOUR_WORD_MSG_SIZE | SGL_OFFSET_0;
1451
        pMsg[1] =
1452
            I2O_LAN_SHUTDOWN << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
1453
        pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
1454
        pMsg[3] = ResourceFlags << 16;  /* resource flags */
1455
 
1456
        pPab->p_atu->InQueue = off;     /* send it to the I2O device */
1457
 
1458
        if (CallbackFunction == (PFNCALLBACK) NULL) {
1459
                /* call RCProcI2OMsgQ() until something in pPab->pCallbackFunc
1460
                   or until timer goes off */
1461
                while (pPab->pCallbackFunc == (PFNCALLBACK) NULL) {
1462
                        RCProcI2OMsgQ (dev);
1463
                        mdelay (1);
1464
                        timeout++;
1465
                        if (timeout > 200) {
1466
                                dprintk (KERN_WARNING
1467
                                        "RCShutdownLANCard(): timeout\n");
1468
                                break;
1469
                        }
1470
                }
1471
                if (ReturnAddr != (PU32) NULL)
1472
                        *ReturnAddr = (U32) pPab->pCallbackFunc;
1473
        }
1474
        return RC_RTN_NO_ERROR;
1475
}
1476
 
1477
/*
1478
** =========================================================================
1479
** RCSetRavlinIPandMask()
1480
**
1481
** Set the Ravlin 45/PCI cards IP address and network mask.
1482
**
1483
** IP address and mask must be in network byte order.
1484
** For example, IP address 1.2.3.4 and mask 255.255.255.0 would be
1485
** 0x04030201 and 0x00FFFFFF on a little endian machine.
1486
**
1487
** =========================================================================
1488
*/
1489
RC_RETURN
1490
RCSetRavlinIPandMask (struct net_device * dev, U32 ipAddr, U32 netMask)
1491
{
1492
        volatile PU32 pMsg;
1493
        U32 off;
1494
        PPAB pPab = ((PDPA) dev->priv)->pPab;
1495
 
1496
        if (pPab == NULL)
1497
                return RC_RTN_ADPTR_NOT_REGISTERED;
1498
 
1499
        off = pPab->p_atu->InQueue;     /* get addresss of message */
1500
 
1501
        if (0xFFFFFFFF == off)
1502
                return RC_RTN_FREE_Q_EMPTY;
1503
 
1504
        pMsg = (PU32) (pPab->pPci45LinBaseAddr + off);
1505
 
1506
        /* setup private message */
1507
        pMsg[0] = SEVEN_WORD_MSG_SIZE | SGL_OFFSET_0;
1508
        pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
1509
        pMsg[2] = 0;             /* initiator context */
1510
        pMsg[3] = 0x219;        /* transaction context */
1511
        pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_SET_IP_AND_MASK;
1512
        pMsg[5] = ipAddr;
1513
        pMsg[6] = netMask;
1514
 
1515
        pPab->p_atu->InQueue = off;     /* send it to the I2O device */
1516
        return RC_RTN_NO_ERROR;
1517
 
1518
}
1519
 
1520
/*
1521
** =========================================================================
1522
** RCGetRavlinIPandMask()
1523
**
1524
** get the IP address and MASK from the card
1525
**
1526
** =========================================================================
1527
*/
1528
RC_RETURN
1529
RCGetRavlinIPandMask (struct net_device * dev, PU32 pIpAddr, PU32 pNetMask,
1530
                      PFNWAITCALLBACK WaitCallback)
1531
{
1532
        U32 off, i;
1533
        PU32 pMsg, p32;
1534
        PPAB pPab = ((PDPA) dev->priv)->pPab;
1535
        PATU p_atu;
1536
 
1537
        dprintk
1538
            ("RCGetRavlinIPandMask: pIpAddr is 0x%x, *IpAddr is 0x%x\n",
1539
             (u32) pIpAddr, *pIpAddr);
1540
 
1541
        if (pPab == NULL)
1542
                return RC_RTN_ADPTR_NOT_REGISTERED;
1543
 
1544
        p_atu = pPab->p_atu;
1545
        off = p_atu->InQueue;   /* get addresss of message */
1546
 
1547
        if (0xFFFFFFFF == off)
1548
                return RC_RTN_FREE_Q_EMPTY;
1549
 
1550
        p32 = (volatile PU32) pPab->pLinOutMsgBlock;
1551
        *p32 = 0xFFFFFFFF;
1552
 
1553
        pMsg = (PU32) (pPab->pPci45LinBaseAddr + off);
1554
 
1555
        dprintk
1556
            ("RCGetRavlinIPandMask: p_atu 0x%x, off 0x%x, p32 0x%x\n",
1557
             (u32) p_atu, off, (u32) p32);
1558
        /* setup private message */
1559
        pMsg[0] = FIVE_WORD_MSG_SIZE | SGL_OFFSET_0;
1560
        pMsg[1] = I2O_PRIVATE << 24 | I2O_HOST_TID << 12 | RC_LAN_TARGET_ID;
1561
        pMsg[2] = 0;             /* initiator context */
1562
        pMsg[3] = 0x218;        /* transaction context */
1563
        pMsg[4] = RC_PCI45_VENDOR_ID << 16 | RC_PRIVATE_GET_IP_AND_MASK;
1564
        pMsg[5] = pPab->outMsgBlockPhyAddr;
1565
 
1566
        p_atu->InQueue = off;   /* send it to the I2O device */
1567
        dprintk
1568
            ("RCGetRavlinIPandMask: p_atu 0x%x, off 0x%x, p32 0x%x\n",
1569
             (u32) p_atu, off, (u32) p32);
1570
 
1571
        /* wait for the rcpci45 board to update the info */
1572
        i = 0;
1573
        while (0xffffffff == *p32) {
1574
                if (i++ > 0xff) {
1575
                        dprintk ("RCGetRavlinIPandMask: Timeout\n");
1576
                        return RC_RTN_MSG_REPLY_TIMEOUT;
1577
                }
1578
                udelay(50);
1579
        }
1580
 
1581
        dprintk
1582
            ("RCGetRavlinIPandMask: after time out\np32[0] (IpAddr) 0x%x, p32[1] (IPmask) 0x%x\n",
1583
             p32[0], p32[1]);
1584
 
1585
        /* send IP and mask to user's space  */
1586
        *pIpAddr = p32[0];
1587
        *pNetMask = p32[1];
1588
 
1589
        dprintk
1590
            ("RCGetRavlinIPandMask: pIpAddr is 0x%x, *IpAddr is 0x%x\n",
1591
             (u32) pIpAddr, *pIpAddr);
1592
 
1593
        return RC_RTN_NO_ERROR;
1594
}
1595
 
1596
/*
1597
** /////////////////////////////////////////////////////////////////////////
1598
** /////////////////////////////////////////////////////////////////////////
1599
**
1600
**                        local functions
1601
**
1602
** /////////////////////////////////////////////////////////////////////////
1603
** /////////////////////////////////////////////////////////////////////////
1604
*/
1605
 
1606
/*
1607
** =========================================================================
1608
** SendI2OOutboundQInitMsg()
1609
**
1610
** =========================================================================
1611
*/
1612
static int
1613
SendI2OOutboundQInitMsg (PPAB pPab)
1614
{
1615
        U32 msgOffset, phyOutQFrames, i;
1616
        volatile PU32 pMsg;
1617
        volatile PU32 p32;
1618
 
1619
        msgOffset = pPab->p_atu->InQueue;
1620
 
1621
        if (msgOffset == 0xFFFFFFFF) {
1622
                dprintk ("SendI2OOutboundQInitMsg(): Inbound Free Q empty!\n");
1623
                return RC_RTN_FREE_Q_EMPTY;
1624
        }
1625
 
1626
        /* calc virtual address of msg - virtual already mapped to physical */
1627
        pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
1628
 
1629
        dprintk
1630
            ("SendI2OOutboundQInitMsg - pMsg = 0x%x, InQ msgOffset = 0x%x\n",
1631
             (u32) pMsg, msgOffset);
1632
 
1633
        pMsg[0] = EIGHT_WORD_MSG_SIZE | TRL_OFFSET_6;
1634
        pMsg[1] =
1635
            I2O_EXEC_OUTBOUND_INIT << 24 | I2O_HOST_TID << 12 | I2O_IOP_TID;
1636
        pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
1637
        pMsg[3] = 0x106;        /* transaction context */
1638
        pMsg[4] = 4096;         /* Host page frame size */
1639
        pMsg[5] = MSG_FRAME_SIZE << 16 | 0x80;  /* outbound msg frame size and Initcode */
1640
        pMsg[6] = 0xD0000004;   /* simple sgl element LE, EOB */
1641
        /* phys address to return status - area right after PAB */
1642
        pMsg[7] = pPab->outMsgBlockPhyAddr;
1643
 
1644
        /* virtual pointer to return buffer - clear first two dwords */
1645
        p32 = (PU32) pPab->pLinOutMsgBlock;
1646
        p32[0] = 0;
1647
 
1648
        /* post to Inbound Post Q */
1649
        pPab->p_atu->InQueue = msgOffset;
1650
 
1651
        /* wait for response */
1652
        i = 0;
1653
        while (!p32[0]) {
1654
                if (i++ > 0xff) {
1655
                        printk("rc: InitOutQ timeout\n");
1656
                        return RC_RTN_NO_I2O_STATUS;
1657
                }
1658
                udelay(50);
1659
        }
1660
        if (p32[0] != I2O_EXEC_OUTBOUND_INIT_COMPLETE) {
1661
                printk("rc: exec outbound init failed (%x)\n",
1662
                                p32[0]);
1663
                return RC_RTN_NO_I2O_STATUS;
1664
        }
1665
        /* load PCI outbound free Q with MF physical addresses */
1666
        phyOutQFrames = pPab->outMsgBlockPhyAddr;
1667
 
1668
        for (i = 0; i < NMBR_MSG_FRAMES; i++) {
1669
                pPab->p_atu->OutQueue = phyOutQFrames;
1670
                phyOutQFrames += MSG_FRAME_SIZE;
1671
        }
1672
        return RC_RTN_NO_ERROR;
1673
}
1674
 
1675
/*
1676
** =========================================================================
1677
** GetI2OStatus()
1678
**
1679
** Send StatusGet Msg, wait for results return directly to buffer.
1680
**
1681
** =========================================================================
1682
*/
1683
static int
1684
GetI2OStatus (PPAB pPab)
1685
{
1686
        U32 msgOffset, i;
1687
        PU32 pMsg;
1688
        volatile PU32 p32;
1689
 
1690
        msgOffset = pPab->p_atu->InQueue;
1691
        dprintk ("GetI2OStatus: msg offset = 0x%x\n", msgOffset);
1692
        if (msgOffset == 0xFFFFFFFF) {
1693
                dprintk ("GetI2OStatus(): Inbound Free Q empty!\n");
1694
                return RC_RTN_FREE_Q_EMPTY;
1695
        }
1696
 
1697
        /* calc virtual address of msg - virtual already mapped to physical */
1698
        pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
1699
 
1700
        pMsg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_0;
1701
        pMsg[1] = I2O_EXEC_STATUS_GET << 24 | I2O_HOST_TID << 12 | I2O_IOP_TID;
1702
        pMsg[2] = 0;             /* universal context */
1703
        pMsg[3] = 0;             /* universal context */
1704
        pMsg[4] = 0;             /* universal context */
1705
        pMsg[5] = 0;             /* universal context */
1706
        /* phys address to return status - area right after PAB */
1707
        pMsg[6] = pPab->outMsgBlockPhyAddr;
1708
        pMsg[7] = 0;
1709
        pMsg[8] = 88;           /*  return 88 bytes */
1710
 
1711
        /* virtual pointer to return buffer - clear first two dwords */
1712
        p32 = (volatile PU32) pPab->pLinOutMsgBlock;
1713
        p32[0] = 0;
1714
        p32[1] = 0;
1715
 
1716
        dprintk
1717
            ("GetI2OStatus - pMsg:0x%x, msgOffset:0x%x, [1]:0x%x, [6]:0x%x\n",
1718
             (u32) pMsg, msgOffset, pMsg[1], pMsg[6]);
1719
 
1720
        /* post to Inbound Post Q */
1721
        pPab->p_atu->InQueue = msgOffset;
1722
 
1723
        dprintk ("Return status to p32 = 0x%x\n", (u32) p32);
1724
 
1725
        /* wait for response */
1726
        i = 0;
1727
        while (!p32[0] || !p32[1]) {
1728
                if (i++ > 0xff) {
1729
                        dprintk ("Timeout waiting for status from IOP\n");
1730
                        return RC_RTN_NO_I2O_STATUS;
1731
                }
1732
                udelay(50);
1733
        }
1734
 
1735
        dprintk ("0x%x:0x%x:0x%x:0x%x\n", p32[0], p32[1],
1736
                 p32[2], p32[3]);
1737
        dprintk ("0x%x:0x%x:0x%x:0x%x\n", p32[4], p32[5],
1738
                 p32[6], p32[7]);
1739
        dprintk ("0x%x:0x%x:0x%x:0x%x\n", p32[8], p32[9],
1740
                 p32[10], p32[11]);
1741
        /* get IOP state */
1742
        pPab->IOPState = ((volatile PU8) p32)[10];
1743
        pPab->InboundMFrameSize = ((volatile PU16) p32)[6];
1744
 
1745
        dprintk ("IOP state 0x%x InFrameSize = 0x%x\n",
1746
                 pPab->IOPState, pPab->InboundMFrameSize);
1747
        return RC_RTN_NO_ERROR;
1748
}
1749
 
1750
/*
1751
** =========================================================================
1752
** SendEnableSysMsg()
1753
**
1754
**
1755
** =========================================================================
1756
*/
1757
static int
1758
SendEnableSysMsg (PPAB pPab)
1759
{
1760
        U32 msgOffset;
1761
        volatile PU32 pMsg;
1762
 
1763
        msgOffset = pPab->p_atu->InQueue;
1764
 
1765
        if (msgOffset == 0xFFFFFFFF) {
1766
                dprintk ("SendEnableSysMsg(): Inbound Free Q empty!\n");
1767
                return RC_RTN_FREE_Q_EMPTY;
1768
        }
1769
 
1770
        /* calc virtual address of msg - virtual already mapped to physical */
1771
        pMsg = (PU32) (pPab->pPci45LinBaseAddr + msgOffset);
1772
 
1773
        dprintk
1774
            ("SendEnableSysMsg - pMsg = 0x%x, InQ msgOffset = 0x%x\n",
1775
             (u32) pMsg, msgOffset);
1776
 
1777
        pMsg[0] = FOUR_WORD_MSG_SIZE | SGL_OFFSET_0;
1778
        pMsg[1] = I2O_EXEC_SYS_ENABLE << 24 | I2O_HOST_TID << 12 | I2O_IOP_TID;
1779
        pMsg[2] = DEFAULT_RECV_INIT_CONTEXT;
1780
        pMsg[3] = 0x110;        /* transaction context */
1781
        pMsg[4] = 0x50657465;   /*  RedCreek Private */
1782
 
1783
        /* post to Inbound Post Q */
1784
        pPab->p_atu->InQueue = msgOffset;
1785
 
1786
        return RC_RTN_NO_ERROR;
1787
}
1788
 
1789
/*
1790
** =========================================================================
1791
** FillI2OMsgFromTCB()
1792
**
1793
** inputs   pMsgU32 - virtual pointer (mapped to physical) of message frame
1794
**          pXmitCntrlBlock - pointer to caller buffer control block.
1795
**
1796
** fills in LAN SGL after Transaction Control Word or Bucket Count.
1797
** =========================================================================
1798
*/
1799
static int
1800
FillI2OMsgSGLFromTCB (PU32 pMsgFrame, PRCTCB pTransCtrlBlock)
1801
{
1802
        unsigned int nmbrBuffers, nmbrSeg, nmbrDwords, context, flags;
1803
        PU32 pTCB, pMsg;
1804
 
1805
        /* SGL element flags */
1806
#define EOB        0x40000000
1807
#define LE         0x80000000
1808
#define SIMPLE_SGL 0x10000000
1809
#define BC_PRESENT 0x01000000
1810
 
1811
        pTCB = (PU32) pTransCtrlBlock;
1812
        pMsg = pMsgFrame;
1813
        nmbrDwords = 0;
1814
 
1815
        dprintk ("FillI2OMsgSGLFromTCBX\n");
1816
        dprintk ("TCB  0x%x:0x%x:0x%x:0x%x:0x%x\n",
1817
                 pTCB[0], pTCB[1], pTCB[2], pTCB[3], pTCB[4]);
1818
        dprintk ("pTCB 0x%x, pMsg 0x%x\n", (u32) pTCB, (u32) pMsg);
1819
 
1820
        nmbrBuffers = *pTCB++;
1821
 
1822
        if (!nmbrBuffers) {
1823
                return -1;
1824
        }
1825
 
1826
        do {
1827
                context = *pTCB++;      /* buffer tag (context) */
1828
                nmbrSeg = *pTCB++;      /* number of segments */
1829
 
1830
                if (!nmbrSeg) {
1831
                        return -1;
1832
                }
1833
 
1834
                flags = SIMPLE_SGL | BC_PRESENT;
1835
 
1836
                if (1 == nmbrSeg) {
1837
                        flags |= EOB;
1838
 
1839
                        if (1 == nmbrBuffers)
1840
                                flags |= LE;
1841
                }
1842
 
1843
                /* 1st SGL buffer element has context */
1844
                pMsg[0] = pTCB[0] | flags;        /* send over count (segment size) */
1845
                pMsg[1] = context;
1846
                pMsg[2] = pTCB[1];      /* send buffer segment physical address */
1847
                nmbrDwords += 3;
1848
                pMsg += 3;
1849
                pTCB += 2;
1850
 
1851
                if (--nmbrSeg) {
1852
                        do {
1853
                                flags = SIMPLE_SGL;
1854
 
1855
                                if (1 == nmbrSeg) {
1856
                                        flags |= EOB;
1857
 
1858
                                        if (1 == nmbrBuffers)
1859
                                                flags |= LE;
1860
                                }
1861
 
1862
                                pMsg[0] = pTCB[0] | flags;        /* send over count */
1863
                                pMsg[1] = pTCB[1];      /* send buffer segment physical address */
1864
                                nmbrDwords += 2;
1865
                                pTCB += 2;
1866
                                pMsg += 2;
1867
 
1868
                        } while (--nmbrSeg);
1869
                }
1870
 
1871
        } while (--nmbrBuffers);
1872
 
1873
        return nmbrDwords;
1874
}
1875
 
1876
/*
1877
** =========================================================================
1878
** ProcessOutboundI2OMsg()
1879
**
1880
** process I2O reply message
1881
** * change to msg structure *
1882
** =========================================================================
1883
*/
1884
static void
1885
ProcessOutboundI2OMsg (PPAB pPab, U32 phyAddrMsg)
1886
{
1887
        PU8 p8Msg;
1888
        PU32 p32;
1889
/*      U16 count; */
1890
 
1891
        p8Msg = pPab->pLinOutMsgBlock + (phyAddrMsg - pPab->outMsgBlockPhyAddr);
1892
        p32 = (PU32) p8Msg;
1893
 
1894
        dprintk
1895
            ("VXD: ProcessOutboundI2OMsg - pPab 0x%x, phyAdr 0x%x, linAdr 0x%x\n",
1896
             (u32) pPab, phyAddrMsg, (u32) p8Msg);
1897
        dprintk ("msg :0x%x:0x%x:0x%x:0x%x\n", p32[0], p32[1],
1898
                 p32[2], p32[3]);
1899
        dprintk ("msg :0x%x:0x%x:0x%x:0x%x\n", p32[4], p32[5],
1900
                 p32[6], p32[7]);
1901
 
1902
        if (p32[4] >> 24 != I2O_REPLY_STATUS_SUCCESS) {
1903
                dprintk ("Message reply status not success\n");
1904
                return;
1905
        }
1906
 
1907
        switch (p8Msg[7]) {     /* function code byte */
1908
        case I2O_EXEC_SYS_TAB_SET:
1909
                msgFlag = 1;
1910
                dprintk ("Received I2O_EXEC_SYS_TAB_SET reply\n");
1911
                break;
1912
 
1913
        case I2O_EXEC_HRT_GET:
1914
                msgFlag = 1;
1915
                dprintk ("Received I2O_EXEC_HRT_GET reply\n");
1916
                break;
1917
 
1918
        case I2O_EXEC_LCT_NOTIFY:
1919
                msgFlag = 1;
1920
                dprintk ("Received I2O_EXEC_LCT_NOTIFY reply\n");
1921
                break;
1922
 
1923
        case I2O_EXEC_SYS_ENABLE:
1924
                msgFlag = 1;
1925
                dprintk ("Received I2O_EXEC_SYS_ENABLE reply\n");
1926
                break;
1927
 
1928
        default:
1929
                dprintk ("Received UNKNOWN reply\n");
1930
                break;
1931
        }
1932
}

powered by: WebSVN 2.1.0

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