3 Copyright (C) 2001-2005 Neil Cafferkey
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23 #include <exec/memory.h>
24 #include <exec/execbase.h>
25 #include <exec/errors.h>
27 #include <proto/exec.h>
29 #include <proto/alib.h>
31 #include <clib/alib_protos.h>
33 #include <proto/utility.h>
34 #include <proto/timer.h>
37 #include "etherlink3.h"
40 #include "unit_protos.h"
41 #include "request_protos.h"
44 #define TASK_PRIORITY 0
45 #define STACK_SIZE 4096
47 (EL3INTF_UPDATESTATS | EL3INTF_RXCOMPLETE | EL3INTF_TXAVAIL \
49 #define DMA_INT_MASK \
50 (EL3INTF_UPDONE | EL3INTF_DOWNDONE | EL3INTF_UPDATESTATS \
56 #define AbsExecBase (*(struct ExecBase **)4)
60 #define AddTask(task, initial_pc, final_pc) \
61 IExec->AddTask(task, initial_pc, final_pc, NULL)
64 VOID
SelectMedium(struct DevUnit
*unit
, UWORD transceiver
,
65 struct DevBase
*base
);
66 static struct AddressRange
*FindMulticastRange(struct DevUnit
*unit
,
67 ULONG lower_bound_left
, UWORD lower_bound_right
, ULONG upper_bound_left
,
68 UWORD upper_bound_right
, struct DevBase
*base
);
69 static VOID
RXInt(REG(a1
, struct DevUnit
*unit
), REG(a5
, APTR int_code
));
70 static VOID
CopyPacket(struct DevUnit
*unit
, struct IOSana2Req
*request
,
71 UWORD packet_size
, UWORD packet_type
, UBYTE
*buffer
, BOOL all_read
,
72 struct DevBase
*base
);
73 static BOOL
AddressFilter(struct DevUnit
*unit
, UBYTE
*address
,
74 struct DevBase
*base
);
75 static VOID
TXInt(REG(a1
, struct DevUnit
*unit
), REG(a5
, APTR int_code
));
76 static VOID
TxError(struct DevUnit
*unit
, struct DevBase
*base
);
77 static VOID
DMARXInt(REG(a1
, struct DevUnit
*unit
),
78 REG(a5
, APTR int_code
));
79 static VOID
DMATXInt(REG(a1
, struct DevUnit
*unit
),
80 REG(a5
, APTR int_code
));
81 static VOID
DMATXEndInt(REG(a1
, struct DevUnit
*unit
),
82 REG(a5
, APTR int_code
));
83 static VOID
ReportEvents(struct DevUnit
*unit
, ULONG events
,
84 struct DevBase
*base
);
85 static VOID
UnitTask();
86 static UWORD
ReadEEPROM(struct DevUnit
*unit
, UWORD index
,
87 struct DevBase
*base
);
88 static BOOL
ReadMII(struct DevUnit
*unit
, UWORD phy_no
, UWORD reg_no
,
89 UWORD
*value
, struct DevBase
*base
);
91 static VOID
WriteMII(struct DevUnit
*unit
, UWORD phy_no
, UWORD reg_no
,
92 UWORD value
, struct DevBase
*base
);
94 static ULONG
ReadMIIBits(struct DevUnit
*unit
, UBYTE count
,
95 struct DevBase
*base
);
96 static VOID
WriteMIIBits(struct DevUnit
*unit
, ULONG value
, UBYTE count
,
97 struct DevBase
*base
);
98 static BOOL
ReadMIIBit(struct DevUnit
*unit
, struct DevBase
*base
);
99 static VOID
WriteMIIBit(struct DevUnit
*unit
, BOOL is_one
,
100 struct DevBase
*base
);
102 static VOID
DoMIIZCycle(struct DevUnit
*unit
, struct DevBase
*base
);
104 static VOID
BusyMicroDelay(ULONG micros
, struct DevBase
*base
);
107 static const UBYTE port_choices
[] =
109 /* EL3XCVR_AUTONEG,*/
118 static const UBYTE port_masks
[] =
120 EL3REG_MEDIAOPTIONSF_10BASET
,
121 EL3REG_MEDIAOPTIONSF_AUI
,
123 EL3REG_MEDIAOPTIONSF_10BASE2
,
124 EL3REG_MEDIAOPTIONSF_100BASETX
,
125 EL3REG_MEDIAOPTIONSF_100BASEFX
,
126 EL3REG_MEDIAOPTIONSF_MII
,
128 EL3REG_MEDIAOPTIONSF_100BASETX
| EL3REG_MEDIAOPTIONSF_10BASET
132 /****i* etherlink3.device/CreateUnit ***************************************
135 * CreateUnit -- Create a unit.
138 * unit = CreateUnit(index, card, io_tags, generation,
141 * struct DevUnit *CreateUnit(ULONG, APTR, struct TagItem *, UWORD,
145 * Creates a new unit.
147 ****************************************************************************
151 struct DevUnit
*CreateUnit(ULONG index
, APTR card
,
152 const struct TagItem
*io_tags
, UWORD generation
, UWORD bus
,
153 struct DevBase
*base
)
156 struct DevUnit
*unit
;
158 struct MsgPort
*port
;
161 ULONG
*upd
, *next_upd
, *fragment
, dma_size
;
162 APTR rx_int_function
, tx_int_function
;
164 unit
= AllocMem(sizeof(struct DevUnit
), MEMF_CLEAR
| MEMF_PUBLIC
);
170 InitSemaphore(&unit
->access_lock
);
171 NewList((APTR
)&unit
->openers
);
172 NewList((APTR
)&unit
->type_trackers
);
173 NewList((APTR
)&unit
->multicast_ranges
);
178 unit
->generation
= generation
;
181 (APTR
)GetTagData(IOTAG_ByteIn
, (UPINT
)NULL
, io_tags
);
183 (APTR
)GetTagData(IOTAG_LongIn
, (UPINT
)NULL
, io_tags
);
185 (APTR
)GetTagData(IOTAG_ByteOut
, (UPINT
)NULL
, io_tags
);
187 (APTR
)GetTagData(IOTAG_WordOut
, (UPINT
)NULL
, io_tags
);
189 (APTR
)GetTagData(IOTAG_LongOut
, (UPINT
)NULL
, io_tags
);
191 (APTR
)GetTagData(IOTAG_LongsIn
, (UPINT
)NULL
, io_tags
);
193 (APTR
)GetTagData(IOTAG_LongsOut
, (UPINT
)NULL
, io_tags
);
195 (APTR
)GetTagData(IOTAG_BEWordOut
, (UPINT
)NULL
, io_tags
);
197 (APTR
)GetTagData(IOTAG_LEWordIn
, (UPINT
)NULL
, io_tags
);
199 (APTR
)GetTagData(IOTAG_LELongIn
, (UPINT
)NULL
, io_tags
);
201 (APTR
)GetTagData(IOTAG_LEWordOut
, (UPINT
)NULL
, io_tags
);
203 (APTR
)GetTagData(IOTAG_LELongOut
, (UPINT
)NULL
, io_tags
);
205 (APTR
)GetTagData(IOTAG_AllocDMAMem
, (UPINT
)NULL
, io_tags
);
207 (APTR
)GetTagData(IOTAG_FreeDMAMem
, (UPINT
)NULL
, io_tags
);
208 if(unit
->ByteIn
== NULL
|| unit
->LongIn
== NULL
209 || unit
->ByteOut
== NULL
210 || unit
->WordOut
== NULL
|| unit
->LongOut
== NULL
211 || unit
->LongsIn
== NULL
|| unit
->LongsOut
== NULL
212 || unit
->BEWordOut
== NULL
|| unit
->LEWordIn
== NULL
213 || unit
->LELongIn
== NULL
|| unit
->LEWordOut
== NULL
214 || unit
->LELongOut
== NULL
215 || generation
>= BOOMERANG_GEN
216 && (unit
->AllocDMAMem
== NULL
|| unit
->FreeDMAMem
== NULL
))
222 if(unit
->generation
>= VORTEX_GEN
)
223 unit
->size_shift
= 2;
225 InitialiseAdapter(unit
, FALSE
, base
);
226 unit
->flags
|= UNITF_HAVEADAPTER
;
228 /* Set up packet filter command */
230 unit
->rx_filter_cmd
= EL3CMD_SETRXFILTER
| EL3CMD_SETRXFILTERF_BCAST
231 | EL3CMD_SETRXFILTERF_UCAST
;
233 /* Set up interrupt mask */
235 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
236 unit
->int_mask
= DMA_INT_MASK
;
238 unit
->int_mask
= INT_MASK
;
240 /* Disable statistics interrupts for PCMCIA because they can't be
243 if(bus
== PCCARD_BUS
)
244 unit
->int_mask
&= ~EL3INTF_UPDATESTATS
;
246 /* Store location of registers that were originally in window 1 */
248 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
249 unit
->window1_offset
+= EL3_WINDOWSIZE
;
251 /* Create the message ports for queuing requests */
253 for(i
= 0; i
< REQUEST_QUEUE_COUNT
; i
++)
255 unit
->request_ports
[i
] = port
= AllocMem(sizeof(struct MsgPort
),
256 MEMF_PUBLIC
| MEMF_CLEAR
);
262 NewList(&port
->mp_MsgList
);
263 port
->mp_Flags
= PA_IGNORE
;
264 port
->mp_SigTask
= &unit
->tx_int
;
268 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
270 unit
->rx_buffer
= unit
->AllocDMAMem(unit
->card
,
271 ETH_MAXPACKETSIZE
* RX_SLOT_COUNT
, 1);
273 unit
->AllocDMAMem(unit
->card
, ETH_MAXPACKETSIZE
, 1);
278 AllocVec((ETH_MAXPACKETSIZE
+ 3) & ~3, MEMF_PUBLIC
);
279 unit
->tx_buffer
= AllocVec(ETH_MAXPACKETSIZE
, MEMF_PUBLIC
);
282 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
284 unit
->tx_requests
= AllocVec(sizeof(APTR
) * TX_SLOT_COUNT
,
286 unit
->headers
= unit
->AllocDMAMem(unit
->card
,
287 ETH_HEADERSIZE
* TX_SLOT_COUNT
, 1);
289 unit
->AllocDMAMem(unit
->card
, DPD_SIZE
* TX_SLOT_COUNT
, 8);
290 next_upd
= unit
->upds
=
291 unit
->AllocDMAMem(unit
->card
, UPD_SIZE
* RX_SLOT_COUNT
, 8);
292 if(unit
->tx_requests
== NULL
|| unit
->headers
== NULL
293 || unit
->dpds
== NULL
|| next_upd
== NULL
)
297 if(unit
->rx_buffer
== NULL
|| unit
->tx_buffer
== NULL
)
303 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
305 /* Construct RX ring */
307 buffer
= unit
->rx_buffer
;
308 for(i
= 0; i
< RX_SLOT_COUNT
; i
++)
311 next_upd
= upd
+ UPD_SIZE
/ sizeof(ULONG
);
312 upd
[EL3UPD_NEXT
] = MakeLELong((ULONG
)next_upd
);
313 upd
[EL3UPD_STATUS
] = 0;
314 fragment
= upd
+ EL3UPD_FIRSTFRAG
;
315 fragment
[EL3FRAG_ADDR
] = MakeLELong((ULONG
)buffer
);
316 fragment
[EL3FRAG_LEN
] =
317 MakeLELong(EL3FRAG_LENF_LAST
| ETH_MAXPACKETSIZE
);
318 buffer
+= ETH_MAXPACKETSIZE
;
320 upd
[EL3UPD_NEXT
] = MakeLELong((ULONG
)unit
->upds
);
321 unit
->next_upd
= unit
->upds
;
323 dma_size
= UPD_SIZE
* RX_SLOT_COUNT
;
324 CachePreDMA(unit
->upds
, &dma_size
, 0);
325 dma_size
= ETH_MAXPACKETSIZE
* RX_SLOT_COUNT
;
326 CachePreDMA(unit
->rx_buffer
, &dma_size
, 0);
329 /* Record maximum speed in BPS */
331 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_100MBPS
) != 0)
332 unit
->speed
= 100000000;
334 unit
->speed
= 10000000;
336 /* Initialise status, transmit and receive interrupts */
338 unit
->status_int
.is_Node
.ln_Name
=
339 base
->device
.dd_Library
.lib_Node
.ln_Name
;
340 unit
->status_int
.is_Code
= (APTR
)StatusInt
;
341 unit
->status_int
.is_Data
= unit
;
343 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
344 rx_int_function
= DMARXInt
;
346 rx_int_function
= RXInt
;
347 unit
->rx_int
.is_Node
.ln_Name
=
348 base
->device
.dd_Library
.lib_Node
.ln_Name
;
349 unit
->rx_int
.is_Code
= rx_int_function
;
350 unit
->rx_int
.is_Data
= unit
;
352 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
353 tx_int_function
= DMATXInt
;
355 tx_int_function
= TXInt
;
356 unit
->tx_int
.is_Node
.ln_Name
=
357 base
->device
.dd_Library
.lib_Node
.ln_Name
;
358 unit
->tx_int
.is_Code
= tx_int_function
;
359 unit
->tx_int
.is_Data
= unit
;
361 unit
->tx_end_int
.is_Node
.ln_Name
=
362 base
->device
.dd_Library
.lib_Node
.ln_Name
;
363 unit
->tx_end_int
.is_Code
= DMATXEndInt
;
364 unit
->tx_end_int
.is_Data
= unit
;
366 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_SOFTINT
;
371 /* Create a new task */
374 AllocMem(sizeof(struct Task
), MEMF_PUBLIC
| MEMF_CLEAR
);
381 stack
= AllocMem(STACK_SIZE
, MEMF_PUBLIC
);
388 /* Initialise and start task */
390 task
->tc_Node
.ln_Type
= NT_TASK
;
391 task
->tc_Node
.ln_Pri
= TASK_PRIORITY
;
392 task
->tc_Node
.ln_Name
=
393 base
->device
.dd_Library
.lib_Node
.ln_Name
;
394 task
->tc_SPUpper
= stack
+ STACK_SIZE
;
395 task
->tc_SPLower
= stack
;
396 task
->tc_SPReg
= stack
+ STACK_SIZE
;
397 NewList(&task
->tc_MemEntry
);
399 if(AddTask(task
, UnitTask
, NULL
) == NULL
)
403 /* Send the unit to the new task */
406 task
->tc_UserData
= unit
;
410 DeleteUnit(unit
, base
);
419 /****i* etherlink3.device/DeleteUnit ***************************************
422 * DeleteUnit -- Delete a unit.
427 * VOID DeleteUnit(struct DevUnit *);
433 * unit - Device unit (can be NULL).
446 ****************************************************************************
450 VOID
DeleteUnit(struct DevUnit
*unit
, struct DevBase
*base
)
460 if(task
->tc_UserData
!= NULL
)
463 FreeMem(task
->tc_SPLower
, STACK_SIZE
);
465 FreeMem(task
, sizeof(struct Task
));
468 for(i
= 0; i
< REQUEST_QUEUE_COUNT
; i
++)
470 if(unit
->request_ports
[i
] != NULL
)
471 FreeMem(unit
->request_ports
[i
], sizeof(struct MsgPort
));
474 if((unit
->flags
& UNITF_HAVEADAPTER
) != 0) /* Needed! */
475 GoOffline(unit
, base
);
477 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
479 unit
->FreeDMAMem(unit
->card
, unit
->upds
);
480 unit
->FreeDMAMem(unit
->card
, unit
->dpds
);
481 unit
->FreeDMAMem(unit
->card
, unit
->headers
);
482 FreeVec(unit
->tx_requests
);
485 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
487 unit
->FreeDMAMem(unit
->card
, unit
->tx_buffer
);
488 unit
->FreeDMAMem(unit
->card
, unit
->rx_buffer
);
492 FreeVec(unit
->tx_buffer
);
493 FreeVec(unit
->rx_buffer
);
496 FreeMem(unit
, sizeof(struct DevUnit
));
504 /****i* etherlink3.device/InitialiseAdapter ********************************
507 * InitialiseAdapter -- .
510 * InitialiseAdapter(unit, reinsertion)
512 * BOOL InitialiseAdapter(struct DevUnit *, BOOL);
531 ****************************************************************************
535 BOOL
InitialiseAdapter(struct DevUnit
*unit
, BOOL reinsertion
,
536 struct DevBase
*base
)
539 UWORD address_part
, links
= 0, ports
, new_ports
, tp_ports
,
540 media_status
, transceiver
, status
, advert
, ability
, modes
;
544 /* Reset card. We avoid resetting the receive logic because it stops the
545 link status working in the MII Status register */
547 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
548 EL3CMD_RXRESET
| EL3CMD_RXRESETF_SKIPNETWORK
);
549 while((unit
->LEWordIn(unit
->card
, EL3REG_STATUS
) &
550 EL3REG_STATUSF_CMDINPROGRESS
) != 0);
551 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_TXRESET
);
552 while((unit
->LEWordIn(unit
->card
, EL3REG_STATUS
) &
553 EL3REG_STATUSF_CMDINPROGRESS
) != 0);
555 /* Select IO addresses and interrupt for PCCard */
557 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 0);
558 if(unit
->bus
== PCCARD_BUS
)
559 unit
->LEWordOut(unit
->card
, EL3REG_RESCONFIG
, 0x3f00);
560 if(unit
->bus
== ISA_BUS
)
561 unit
->LEWordOut(unit
->card
, EL3REG_RESCONFIG
, (10 << 12) | 0xf00);
563 /* Fully enable an ISA card */
565 if(unit
->bus
== ISA_BUS
)
566 unit
->LEWordOut(unit
->card
, EL3REG_CONFIG
, EL3REG_CONFIGF_ENABLE
);
568 /* Get card capabilities */
570 unit
->capabilities
= ReadEEPROM(unit
, EL3ROM_CAPABILITIES
, base
);
572 /* Get default MAC address */
574 p
= unit
->default_address
;
576 for(i
= 0; i
< ETH_ADDRESSSIZE
/ 2; i
++)
578 address_part
= ReadEEPROM(unit
, EL3ROM_ALTADDRESS0
+ i
, base
);
579 *p
++ = address_part
>> 8;
580 *p
++ = address_part
& 0xff;
583 /* Get available transceivers */
585 if(unit
->bus
== PCCARD_BUS
|| unit
->bus
== ISA_BUS
)
587 config
= unit
->LEWordIn(unit
->card
, EL3REG_CONFIG
);
588 ports
= (config
>> 8) &
589 (EL3REG_MEDIAOPTIONSF_AUI
| EL3REG_MEDIAOPTIONSF_10BASE2
);
590 if((config
& EL3REG_CONFIGF_10BASET
) != 0)
591 ports
|= EL3REG_MEDIAOPTIONSF_10BASET
;
595 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 3);
596 ports
= unit
->LEWordIn(unit
->card
, EL3REG_MEDIAOPTIONS
);
599 ports
= EL3REG_MEDIAOPTIONSF_MII
; /* fix for 3c916? */
603 /* Get transceiver choice from EEPROM */
605 if(unit
->bus
== PCI_BUS
)
607 config
= unit
->LELongIn(unit
->card
, EL3REG_INTERNALCONFIG
);
609 (config
& EL3REG_INTERNALCONFIGF_XCVR
)
610 >> EL3REG_INTERNALCONFIGB_XCVR
;
611 autoselect
= (config
& EL3REG_INTERNALCONFIGF_AUTOXCVR
) != 0;
615 config
= ReadEEPROM(unit
, EL3ROM_ADDRCONFIG
, base
);
617 (config
& EL3REG_ADDRCONFIGF_XCVR
) >> EL3REG_ADDRCONFIGB_XCVR
;
618 autoselect
= (config
& EL3REG_ADDRCONFIGF_AUTOSELECT
) != 0;
623 /* Check if chosen medium is available */
625 new_ports
= ports
& port_masks
[transceiver
];
632 /* Auto-select media type */
636 /* Get transceivers with an active link */
638 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 4);
640 if(unit
->generation
< CYCLONE_GEN
)
644 (EL3REG_MEDIAOPTIONSF_10BASET
| EL3REG_MEDIAOPTIONSF_100BASETX
);
647 SelectMedium(unit
, EL3XCVR_10BASET
, base
);
648 media_status
= unit
->LEWordIn(unit
->card
, EL3REG_MEDIA
);
649 if((media_status
& EL3REG_MEDIAF_BEAT
) != 0)
654 if((ports
& EL3REG_MEDIAOPTIONSF_MII
) != 0
655 || unit
->generation
>= CYCLONE_GEN
)
657 for(i
= 0; i
< 32; i
++)
659 if(ReadMII(unit
, i
, MII_STATUS
, &status
, base
))
661 ReadMII(unit
, i
, MII_STATUS
, &status
, base
);
662 /* Yes, status reg must be read twice */
663 if((status
& MII_STATUSF_LINK
) != 0)
665 if(i
== 24) /* Built-in transceiver */
667 if(((status
& MII_STATUSF_AUTONEGDONE
) != 0)
668 && ((status
& MII_STATUSF_EXTREGSET
) != 0))
670 ReadMII(unit
, i
, MII_AUTONEGADVERT
, &advert
, base
);
671 ReadMII(unit
, i
, MII_AUTONEGABILITY
, &ability
,
673 modes
= advert
& ability
;
675 if((modes
& MII_AUTONEGF_100BASETX
) != 0)
676 links
|= EL3REG_MEDIAOPTIONSF_100BASETX
;
678 if((modes
& MII_AUTONEGF_100BASET4
) != 0)
679 links
|= EL3REG_MEDIAOPTIONSF_100BASET4
;
681 if((modes
& MII_AUTONEGF_10BASET
) != 0)
682 links
|= EL3REG_MEDIAOPTIONSF_10BASET
;
686 modes
= MII_AUTONEGF_10BASET
;
687 links
|= EL3REG_MEDIAOPTIONSF_10BASET
;
689 unit
->autoneg_modes
= modes
;
693 links
|= EL3REG_MEDIAOPTIONSF_MII
;
694 unit
->mii_phy_no
= i
;
702 if((ports
& EL3REG_MEDIAOPTIONSF_10BASE2
) != 0)
704 SelectMedium(unit
, EL3XCVR_10BASE2
, base
);
705 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_STARTCOAX
);
707 if(LoopbackTest(base
))
708 links
|= EL3REG_MEDIAOPTIONSF_10BASE2
;
710 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_STOPCOAX
);
714 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 0);
716 new_ports
= ports
& links
;
721 /* Prioritised choice from remaining transceivers */
723 for(i
= 0; i
< PORT_COUNT
; i
++)
725 transceiver
= port_choices
[i
];
726 if((ports
& port_masks
[transceiver
]) != 0)
728 unit
->transceiver
= transceiver
;
733 /* Find out whether to use full duplex */
735 if((transceiver
== EL3XCVR_10BASET
|| transceiver
== EL3XCVR_100BASETX
)
736 && unit
->generation
>= CYCLONE_GEN
)
738 modes
= unit
->autoneg_modes
;
741 (modes
& MII_AUTONEGF_100BASETXFD
) != 0
747 MII_AUTONEGF_100BASETX
749 MII_AUTONEGF_10BASETFD
753 MII_AUTONEGF_10BASETFD
755 unit
->flags
|= UNITF_FULLDUPLEX
;
765 /****i* etherlink3.device/ConfigureAdapter *********************************
768 * ConfigureAdapter -- .
771 * ConfigureAdapter(unit)
773 * VOID ConfigureAdapter(struct DevUnit *);
791 ****************************************************************************
795 VOID
ConfigureAdapter(struct DevUnit
*unit
, struct DevBase
*base
)
799 /* Set MAC address */
801 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 2);
803 for(i
= 0; i
< ETH_ADDRESSSIZE
; i
++)
804 unit
->ByteOut(unit
->card
, EL3REG_ADDRESS0
+ i
, unit
->address
[i
]);
806 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
808 for(i
= 0; i
< ETH_ADDRESSSIZE
; i
++)
809 unit
->ByteOut(unit
->card
, EL3REG_MASK0
+ i
, 0);
812 /* Enable wider statistics counters */
814 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 4);
815 if(unit
->generation
>= BOOMERANG_GEN
)
816 unit
->LEWordOut(unit
->card
, EL3REG_NETDIAG
,
817 EL3REG_NETDIAGF_WIDESTATS
);
819 /* Decide on promiscuous mode */
821 if((unit
->flags
& UNITF_PROM
) != 0)
822 unit
->rx_filter_cmd
|= EL3CMD_SETRXFILTERF_PROM
;
824 /* Select chosen transceiver */
826 SelectMedium(unit
, unit
->transceiver
, base
);
830 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
831 unit
->LELongOut(unit
->card
, EL3REG_UPLIST
, (ULONG
)unit
->upds
);
832 GoOnline(unit
, base
);
841 /****i* etherlink3.device/SelectMedium *************************************
847 * SelectMedium(unit, transceiver)
849 * VOID SelectMedium(struct DevUnit *, UWORD);
868 ****************************************************************************
872 VOID
SelectMedium(struct DevUnit
*unit
, UWORD transceiver
,
873 struct DevBase
*base
)
878 if((transceiver
== EL3XCVR_10BASET
|| transceiver
== EL3XCVR_100BASETX
)
879 && unit
->generation
>= CYCLONE_GEN
)
880 transceiver
= EL3XCVR_AUTONEG
;
882 /* Select transceiver */
885 unit
->LEWordIn(unit
->card
, EL3REG_STATUS
) >> EL3REG_STATUSB_WINDOW
;
886 if(unit
->bus
== PCI_BUS
)
888 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 3);
889 config
= unit
->LELongIn(unit
->card
, EL3REG_INTERNALCONFIG
);
890 config
&= ~EL3REG_INTERNALCONFIGF_XCVR
;
891 config
|= transceiver
<< EL3REG_INTERNALCONFIGB_XCVR
;
892 unit
->LELongOut(unit
->card
, EL3REG_INTERNALCONFIG
, config
);
896 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 0);
897 config
= unit
->LEWordIn(unit
->card
, EL3REG_ADDRCONFIG
);
898 config
&= ~EL3REG_ADDRCONFIGF_XCVR
;
899 config
|= transceiver
<< EL3REG_ADDRCONFIGB_XCVR
;
900 unit
->LEWordOut(unit
->card
, EL3REG_ADDRCONFIG
, config
);
902 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
903 EL3CMD_SELECTWINDOW
| old_window
);
910 /****i* etherlink3.device/GoOnline *****************************************
918 * VOID GoOnline(struct DevUnit *);
920 ****************************************************************************
924 VOID
GoOnline(struct DevUnit
*unit
, struct DevBase
*base
)
928 /* Choose interrupts */
930 unit
->flags
|= UNITF_ONLINE
;
931 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
932 EL3CMD_SETINTMASK
| unit
->int_mask
);
933 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
934 EL3CMD_SETZEROMASK
| unit
->int_mask
);
936 /* Enable the transceiver */
938 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
939 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_UPUNSTALL
);
941 transceiver
= unit
->transceiver
;
943 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 4);
944 if(transceiver
== EL3XCVR_100BASETX
)
946 unit
->LEWordOut(unit
->card
, EL3REG_MEDIA
, EL3REG_MEDIAF_BEATCHECK
);
948 else if(transceiver
== EL3XCVR_10BASET
)
950 unit
->LEWordOut(unit
->card
, EL3REG_MEDIA
,
951 EL3REG_MEDIAF_BEATCHECK
| EL3REG_MEDIAF_JABBERCHECK
);
953 else if(transceiver
== EL3XCVR_10BASE2
)
954 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_STARTCOAX
| 0);
956 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 3);
957 if((unit
->flags
& UNITF_FULLDUPLEX
) != 0)
958 unit
->LEWordOut(unit
->card
, EL3REG_MACCONTROL
,
959 EL3REG_MACCONTROLF_FULLDUPLEX
);
961 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, unit
->rx_filter_cmd
);
962 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_RXENABLE
);
963 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_TXENABLE
);
964 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 1);
966 /* Enable statistics collection */
968 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_STATSENABLE
);
970 /* Record start time and report Online event */
972 GetSysTime(&unit
->stats
.LastStart
);
973 ReportEvents(unit
, S2EVENT_ONLINE
, base
);
980 /****i* etherlink3.device/GoOffline ****************************************
988 * VOID GoOffline(struct DevUnit *);
990 ****************************************************************************
994 VOID
GoOffline(struct DevUnit
*unit
, struct DevBase
*base
)
996 unit
->flags
&= ~UNITF_ONLINE
;
998 if((unit
->flags
& UNITF_HAVEADAPTER
) != 0)
1000 /* Stop interrupts */
1002 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SETINTMASK
| 0);
1003 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1004 EL3CMD_ACKINT
| EL3INTF_ANY
);
1006 /* Stop transmission and reception */
1008 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_RXDISABLE
);
1009 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_TXDISABLE
);
1011 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
1013 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_UPSTALL
);
1014 while((unit
->LEWordIn(unit
->card
, EL3REG_STATUS
) &
1015 EL3REG_STATUSF_CMDINPROGRESS
) != 0);
1016 unit
->LELongOut(unit
->card
, EL3REG_UPLIST
, (ULONG
)NULL
);
1017 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_DOWNSTALL
);
1018 while((unit
->LEWordIn(unit
->card
, EL3REG_STATUS
)
1019 & EL3REG_STATUSF_CMDINPROGRESS
) != 0);
1020 unit
->LELongOut(unit
->card
, EL3REG_DOWNLIST
, (ULONG
)NULL
);
1023 /* Turn off media functions */
1025 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 4);
1026 unit
->LEWordOut(unit
->card
, EL3REG_MEDIA
, 0);
1027 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 1);
1029 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_STOPCOAX
| 0);
1032 /* Update then disable statistics */
1034 UpdateStats(unit
, base
);
1035 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_STATSDISABLE
);
1038 /* Flush pending read and write requests */
1040 FlushUnit(unit
, WRITE_QUEUE
, S2ERR_OUTOFSERVICE
, base
);
1042 /* Report Offline event and return */
1044 ReportEvents(unit
, S2EVENT_OFFLINE
, base
);
1050 /****i* etherlink3.device/AddMulticastRange ********************************
1053 * AddMulticastRange -- .
1056 * success = AddMulticastRange(unit, lower_bound, upper_bound)
1058 * BOOL AddMulticastRange(struct DevUnit *, UBYTE *, UBYTE *);
1060 ****************************************************************************
1064 BOOL
AddMulticastRange(struct DevUnit
*unit
, const UBYTE
*lower_bound
,
1065 const UBYTE
*upper_bound
, struct DevBase
*base
)
1067 struct AddressRange
*range
;
1068 ULONG lower_bound_left
, upper_bound_left
;
1069 UWORD lower_bound_right
, upper_bound_right
;
1071 lower_bound_left
= BELong(*((ULONG
*)lower_bound
));
1072 lower_bound_right
= BEWord(*((UWORD
*)(lower_bound
+ 4)));
1073 upper_bound_left
= BELong(*((ULONG
*)upper_bound
));
1074 upper_bound_right
= BEWord(*((UWORD
*)(upper_bound
+ 4)));
1076 range
= FindMulticastRange(unit
, lower_bound_left
, lower_bound_right
,
1077 upper_bound_left
, upper_bound_right
, base
);
1083 range
= AllocMem(sizeof(struct AddressRange
), MEMF_PUBLIC
);
1086 range
->lower_bound_left
= lower_bound_left
;
1087 range
->lower_bound_right
= lower_bound_right
;
1088 range
->upper_bound_left
= upper_bound_left
;
1089 range
->upper_bound_right
= upper_bound_right
;
1090 range
->add_count
= 1;
1093 AddTail((APTR
)&unit
->multicast_ranges
, (APTR
)range
);
1096 if(unit
->range_count
++ == 0)
1098 unit
->rx_filter_cmd
|= EL3CMD_SETRXFILTERF_MCAST
;
1099 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1100 unit
->rx_filter_cmd
);
1105 return range
!= NULL
;
1110 /****i* etherlink3.device/RemMulticastRange ********************************
1113 * RemMulticastRange -- .
1116 * found = RemMulticastRange(unit, lower_bound, upper_bound)
1118 * BOOL RemMulticastRange(struct DevUnit *, UBYTE *, UBYTE *);
1120 ****************************************************************************
1124 BOOL
RemMulticastRange(struct DevUnit
*unit
, const UBYTE
*lower_bound
,
1125 const UBYTE
*upper_bound
, struct DevBase
*base
)
1127 struct AddressRange
*range
;
1128 ULONG lower_bound_left
, upper_bound_left
;
1129 UWORD lower_bound_right
, upper_bound_right
;
1131 lower_bound_left
= BELong(*((ULONG
*)lower_bound
));
1132 lower_bound_right
= BEWord(*((UWORD
*)(lower_bound
+ 4)));
1133 upper_bound_left
= BELong(*((ULONG
*)upper_bound
));
1134 upper_bound_right
= BEWord(*((UWORD
*)(upper_bound
+ 4)));
1136 range
= FindMulticastRange(unit
, lower_bound_left
, lower_bound_right
,
1137 upper_bound_left
, upper_bound_right
, base
);
1141 if(--range
->add_count
== 0)
1144 Remove((APTR
)range
);
1146 FreeMem(range
, sizeof(struct AddressRange
));
1148 if(--unit
->range_count
== 0)
1150 unit
->rx_filter_cmd
&= ~EL3CMD_SETRXFILTERF_MCAST
;
1151 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1152 unit
->rx_filter_cmd
);
1157 return range
!= NULL
;
1162 /****i* etherlink3.device/FindMulticastRange *******************************
1165 * FindMulticastRange -- .
1168 * range = FindMulticastRange(unit, lower_bound_left,
1169 * lower_bound_right, upper_bound_left, upper_bound_right)
1171 * struct AddressRange *FindMulticastRange(struct DevUnit *, ULONG,
1172 * UWORD, ULONG, UWORD);
1174 ****************************************************************************
1178 static struct AddressRange
*FindMulticastRange(struct DevUnit
*unit
,
1179 ULONG lower_bound_left
, UWORD lower_bound_right
, ULONG upper_bound_left
,
1180 UWORD upper_bound_right
, struct DevBase
*base
)
1182 struct AddressRange
*range
, *tail
;
1185 range
= (APTR
)unit
->multicast_ranges
.mlh_Head
;
1186 tail
= (APTR
)&unit
->multicast_ranges
.mlh_Tail
;
1188 while((range
!= tail
) && !found
)
1190 if((lower_bound_left
== range
->lower_bound_left
) &&
1191 (lower_bound_right
== range
->lower_bound_right
) &&
1192 (upper_bound_left
== range
->upper_bound_left
) &&
1193 (upper_bound_right
== range
->upper_bound_right
))
1196 range
= (APTR
)range
->node
.mln_Succ
;
1207 /****i* etherlink3.device/FindTypeStats ************************************
1210 * FindTypeStats -- .
1213 * stats = FindTypeStats(unit, list,
1216 * struct TypeStats *FindTypeStats(struct DevUnit *, struct MinList *,
1219 ****************************************************************************
1223 struct TypeStats
*FindTypeStats(struct DevUnit
*unit
, struct MinList
*list
,
1224 ULONG packet_type
, struct DevBase
*base
)
1226 struct TypeStats
*stats
, *tail
;
1229 stats
= (APTR
)list
->mlh_Head
;
1230 tail
= (APTR
)&list
->mlh_Tail
;
1232 while(stats
!= tail
&& !found
)
1234 if(stats
->packet_type
== packet_type
)
1237 stats
= (APTR
)stats
->node
.mln_Succ
;
1248 /****i* etherlink3.device/FlushUnit ****************************************
1256 * VOID FlushUnit(struct DevUnit *);
1258 ****************************************************************************
1260 * Includes alternative implementations because of ambiguities in SANA-II
1265 VOID
FlushUnit(struct DevUnit
*unit
, UBYTE last_queue
, BYTE error
,
1266 struct DevBase
*base
)
1268 struct IORequest
*request
;
1270 struct Opener
*opener
, *tail
;
1272 /* Abort queued requests */
1274 for(i
= 0; i
<= last_queue
; i
++)
1276 while((request
= (APTR
)GetMsg(unit
->request_ports
[i
])) != NULL
)
1278 request
->io_Error
= IOERR_ABORTED
;
1279 ReplyMsg((APTR
)request
);
1284 opener
= (APTR
)unit
->openers
.mlh_Head
;
1285 tail
= (APTR
)&unit
->openers
.mlh_Tail
;
1287 /* Flush every opener's read queue */
1289 while(opener
!= tail
)
1291 while((request
= (APTR
)GetMsg(&opener
->read_port
)) != NULL
)
1293 request
->io_Error
= error
;
1294 ReplyMsg((APTR
)request
);
1296 opener
= (APTR
)opener
->node
.mln_Succ
;
1300 opener
= request
->ios2_BufferManagement
;
1301 while((request
= (APTR
)GetMsg(&opener
->read_port
)) != NULL
)
1303 request
->io_Error
= IOERR_ABORTED
;
1304 ReplyMsg((APTR
)request
);
1315 /****i* etherlink3.device/StatusInt ****************************************
1321 * finished = StatusInt(unit, int_code)
1323 * BOOL StatusInt(struct DevUnit *, APTR);
1325 ****************************************************************************
1327 * int_code is really in A5, but GCC 2.95.3 doesn't seem able to handle that.
1328 * Since we don't use this parameter, we can lie.
1332 BOOL
StatusInt(REG(a1
, struct DevUnit
*unit
), REG(a6
, APTR int_code
))
1334 struct DevBase
*base
;
1337 base
= unit
->device
;
1338 ints
= unit
->LEWordIn(unit
->card
, EL3REG_STATUS
);
1340 if((ints
& EL3INTF_ANY
) != 0)
1342 /* Handle interrupts */
1344 if((ints
& EL3INTF_UPDONE
) != 0)
1346 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1347 EL3CMD_ACKINT
| EL3INTF_UPDONE
);
1348 Cause(&unit
->rx_int
);
1350 if((ints
& EL3INTF_DOWNDONE
) != 0)
1352 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1353 EL3CMD_ACKINT
| EL3INTF_DOWNDONE
);
1354 Cause(&unit
->tx_end_int
);
1356 if((ints
& EL3INTF_UPDATESTATS
) != 0)
1357 UpdateStats(unit
, base
);
1358 if((ints
& EL3INTF_RXCOMPLETE
) != 0)
1361 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1362 EL3CMD_SETINTMASK
| (unit
->int_mask
& ~EL3INTF_RXCOMPLETE
));
1364 Cause(&unit
->rx_int
);
1366 if((ints
& EL3INTF_TXAVAIL
) != 0)
1368 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1369 EL3CMD_ACKINT
| EL3INTF_TXAVAIL
);
1370 Cause(&unit
->tx_int
);
1372 if((ints
& EL3INTF_TXCOMPLETE
) != 0)
1373 TxError(unit
, base
);
1375 /* Acknowledge interrupt request */
1377 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1378 EL3CMD_ACKINT
| EL3INTF_ANY
);
1386 /****i* etherlink3.device/RXInt ********************************************
1392 * RXInt(unit, int_code)
1394 * VOID RXInt(struct DevUnit *, APTR);
1396 ****************************************************************************
1400 static VOID
RXInt(REG(a1
, struct DevUnit
*unit
), REG(a5
, APTR int_code
))
1402 UWORD rx_status
, packet_size
;
1403 struct DevBase
*base
;
1404 BOOL is_orphan
, accepted
;
1407 struct IOSana2Req
*request
, *request_tail
;
1408 struct Opener
*opener
, *opener_tail
;
1409 struct TypeStats
*tracker
;
1411 base
= unit
->device
;
1412 buffer
= unit
->rx_buffer
;
1414 while(((rx_status
= unit
->LEWordIn(unit
->card
, EL3REG_RXSTATUS
))
1415 & EL3REG_RXSTATUSF_INCOMPLETE
) == 0)
1417 if((rx_status
& EL3REG_RXSTATUSF_ERROR
) == 0)
1419 /* Read packet header */
1422 packet_size
= rx_status
& EL3REG_RXSTATUS_SIZEMASK
;
1423 unit
->LongsIn(unit
->card
, EL3REG_DATA0
, (ULONG
*)buffer
,
1424 ETH_HEADERSIZE
+ 3 >> 2);
1426 if(AddressFilter(unit
, buffer
+ ETH_PACKET_DEST
, base
))
1428 packet_type
= BEWord(*((UWORD
*)(buffer
+ ETH_PACKET_TYPE
)));
1430 opener
= (APTR
)unit
->openers
.mlh_Head
;
1431 opener_tail
= (APTR
)&unit
->openers
.mlh_Tail
;
1433 /* Offer packet to every opener */
1435 while(opener
!= opener_tail
)
1437 request
= (APTR
)opener
->read_port
.mp_MsgList
.lh_Head
;
1438 request_tail
= (APTR
)&opener
->read_port
.mp_MsgList
.lh_Tail
;
1441 /* Offer packet to each request until it's accepted */
1443 while((request
!= request_tail
) && !accepted
)
1445 if(request
->ios2_PacketType
== packet_type
1446 || request
->ios2_PacketType
<= ETH_MTU
1447 && packet_type
<= ETH_MTU
)
1449 CopyPacket(unit
, request
, packet_size
, packet_type
,
1450 buffer
, !is_orphan
, base
);
1454 (APTR
)request
->ios2_Req
.io_Message
.mn_Node
.ln_Succ
;
1459 opener
= (APTR
)opener
->node
.mln_Succ
;
1462 /* If packet was unwanted, give it to S2_READORPHAN request */
1466 unit
->stats
.UnknownTypesReceived
++;
1467 if(!IsMsgPortEmpty(unit
->request_ports
[ADOPT_QUEUE
]))
1470 (APTR
)unit
->request_ports
[ADOPT_QUEUE
]->
1471 mp_MsgList
.lh_Head
, packet_size
, packet_type
, buffer
,
1476 /* Update remaining statistics */
1479 FindTypeStats(unit
, &unit
->type_trackers
, packet_type
, base
);
1482 tracker
->stats
.PacketsReceived
++;
1483 tracker
->stats
.BytesReceived
+= packet_size
;
1489 unit
->stats
.BadData
++;
1490 ReportEvents(unit
, S2EVENT_ERROR
| S2EVENT_HARDWARE
| S2EVENT_RX
,
1494 /* Discard packet */
1496 Disable(); /* Needed? */
1497 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_RXDISCARD
);
1498 while((unit
->LEWordIn(unit
->card
, EL3REG_STATUS
) &
1499 EL3REG_STATUSF_CMDINPROGRESS
) != 0);
1505 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1506 EL3CMD_SETINTMASK
| unit
->int_mask
);
1512 /****i* etherlink3.device/CopyPacket ***************************************
1518 * CopyPacket(unit, request, packet_size, packet_type,
1521 * VOID CopyPacket(struct DevUnit *, struct IOSana2Req *, UWORD, UWORD,
1524 ****************************************************************************
1528 static VOID
CopyPacket(struct DevUnit
*unit
, struct IOSana2Req
*request
,
1529 UWORD packet_size
, UWORD packet_type
, UBYTE
*buffer
, BOOL all_read
,
1530 struct DevBase
*base
)
1532 struct Opener
*opener
;
1533 BOOL filtered
= FALSE
;
1535 /* Set multicast and broadcast flags */
1537 request
->ios2_Req
.io_Flags
&= ~(SANA2IOF_BCAST
| SANA2IOF_MCAST
);
1538 if((*((ULONG
*)(buffer
+ ETH_PACKET_DEST
)) == 0xffffffff) &&
1539 (*((UWORD
*)(buffer
+ ETH_PACKET_DEST
+ 4)) == 0xffff))
1540 request
->ios2_Req
.io_Flags
|= SANA2IOF_BCAST
;
1541 else if((buffer
[ETH_PACKET_DEST
] & 0x1) != 0)
1542 request
->ios2_Req
.io_Flags
|= SANA2IOF_MCAST
;
1544 /* Set source and destination addresses and packet type */
1546 CopyMem(buffer
+ ETH_PACKET_SOURCE
, request
->ios2_SrcAddr
,
1548 CopyMem(buffer
+ ETH_PACKET_DEST
, request
->ios2_DstAddr
,
1550 request
->ios2_PacketType
= packet_type
;
1552 /* Read rest of packet (PIO mode only) */
1556 unit
->LongsIn(unit
->card
, EL3REG_DATA0
,
1557 (ULONG
*)(buffer
+ ((ETH_PACKET_DATA
+ 3) & ~0x3)),
1558 (packet_size
- ETH_PACKET_DATA
+ 1) >> 2);
1561 /* Adjust for cooked packet request */
1563 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
1565 packet_size
-= ETH_PACKET_DATA
;
1566 buffer
+= ETH_PACKET_DATA
;
1570 packet_size
+= 4; /* Needed for Shapeshifter & Fusion */
1572 request
->ios2_DataLength
= packet_size
;
1576 opener
= request
->ios2_BufferManagement
;
1577 if((request
->ios2_Req
.io_Command
== CMD_READ
) &&
1578 (opener
->filter_hook
!= NULL
))
1579 if(!CallHookPkt(opener
->filter_hook
, request
, buffer
))
1584 /* Copy packet into opener's buffer and reply packet */
1586 if(!opener
->rx_function(request
->ios2_Data
, buffer
, packet_size
))
1588 request
->ios2_Req
.io_Error
= S2ERR_NO_RESOURCES
;
1589 request
->ios2_WireError
= S2WERR_BUFF_ERROR
;
1591 S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
| S2EVENT_RX
,
1594 Remove((APTR
)request
);
1595 ReplyMsg((APTR
)request
);
1603 /****i* etherlink3.device/AddressFilter ************************************
1609 * accept = AddressFilter(unit, address)
1611 * BOOL AddressFilter(struct DevUnit *, UBYTE *);
1613 ****************************************************************************
1617 static BOOL
AddressFilter(struct DevUnit
*unit
, UBYTE
*address
,
1618 struct DevBase
*base
)
1620 struct AddressRange
*range
, *tail
;
1623 UWORD address_right
;
1625 /* Check whether address is unicast/broadcast or multicast */
1627 address_left
= BELong(*((ULONG
*)address
));
1628 address_right
= BEWord(*((UWORD
*)(address
+ 4)));
1630 if((address_left
& 0x01000000) != 0 &&
1631 !(address_left
== 0xffffffff && address_right
== 0xffff))
1633 /* Check if this multicast address is wanted */
1635 range
= (APTR
)unit
->multicast_ranges
.mlh_Head
;
1636 tail
= (APTR
)&unit
->multicast_ranges
.mlh_Tail
;
1639 while((range
!= tail
) && !accept
)
1641 if((address_left
> range
->lower_bound_left
||
1642 address_left
== range
->lower_bound_left
&&
1643 address_right
>= range
->lower_bound_right
) &&
1644 (address_left
< range
->upper_bound_left
||
1645 address_left
== range
->upper_bound_left
&&
1646 address_right
<= range
->upper_bound_right
))
1648 range
= (APTR
)range
->node
.mln_Succ
;
1652 unit
->special_stats
[S2SS_ETHERNET_BADMULTICAST
& 0xffff]++;
1660 /****i* etherlink3.device/TXInt ********************************************
1668 * VOID TXInt(struct DevUnit *);
1670 ****************************************************************************
1674 static VOID
TXInt(REG(a1
, struct DevUnit
*unit
), REG(a5
, APTR int_code
))
1676 UWORD packet_size
, data_size
, send_size
;
1677 struct DevBase
*base
;
1678 struct IOSana2Req
*request
;
1679 BOOL proceed
= TRUE
;
1680 struct Opener
*opener
;
1681 ULONG
*buffer
, wire_error
;
1682 UBYTE
*(*dma_tx_function
)(REG(a0
, APTR
));
1684 struct MsgPort
*port
;
1685 struct TypeStats
*tracker
;
1687 base
= unit
->device
;
1688 port
= unit
->request_ports
[WRITE_QUEUE
];
1690 while(proceed
&& (!IsMsgPortEmpty(port
)))
1694 request
= (APTR
)port
->mp_MsgList
.lh_Head
;
1695 data_size
= packet_size
= request
->ios2_DataLength
;
1697 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
1698 packet_size
+= ETH_PACKET_DATA
;
1700 if(unit
->LEWordIn(unit
->card
, EL3REG_TXSPACE
)
1701 > EL3_PREAMBLESIZE
+ packet_size
)
1703 /* Write packet preamble */
1705 unit
->LELongOut(unit
->card
, EL3REG_DATA0
, packet_size
);
1707 /* Write packet header */
1709 send_size
= (packet_size
+ 3) & ~0x3;
1710 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
1712 unit
->LongOut(unit
->card
, EL3REG_DATA0
,
1713 *((ULONG
*)request
->ios2_DstAddr
));
1714 unit
->WordOut(unit
->card
, EL3REG_DATA0
,
1715 *((UWORD
*)(request
->ios2_DstAddr
+ 4)));
1716 unit
->WordOut(unit
->card
, EL3REG_DATA0
,
1717 *((UWORD
*)unit
->address
));
1718 unit
->LongOut(unit
->card
, EL3REG_DATA0
,
1719 *((ULONG
*)(unit
->address
+ 2)));
1720 unit
->BEWordOut(unit
->card
, EL3REG_DATA0
,
1721 request
->ios2_PacketType
);
1722 send_size
-= ETH_HEADERSIZE
;
1725 /* Get packet data */
1727 opener
= (APTR
)request
->ios2_BufferManagement
;
1728 dma_tx_function
= opener
->dma_tx_function
;
1729 if(dma_tx_function
!= NULL
)
1730 buffer
= (ULONG
*)dma_tx_function(request
->ios2_Data
);
1736 buffer
= (ULONG
*)unit
->tx_buffer
;
1737 if(!opener
->tx_function(buffer
, request
->ios2_Data
, data_size
))
1739 error
= S2ERR_NO_RESOURCES
;
1740 wire_error
= S2WERR_BUFF_ERROR
;
1742 S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
1743 | S2EVENT_TX
, base
);
1747 /* Write packet data */
1751 unit
->LongsOut(unit
->card
, EL3REG_DATA0
, buffer
,
1753 buffer
+= (send_size
>> 2);
1754 if((send_size
& 0x3) != 0)
1755 unit
->WordOut(unit
->card
, EL3REG_DATA0
, *((UWORD
*)buffer
));
1760 request
->ios2_Req
.io_Error
= error
;
1761 request
->ios2_WireError
= wire_error
;
1762 Remove((APTR
)request
);
1763 ReplyMsg((APTR
)request
);
1765 /* Update statistics */
1769 tracker
= FindTypeStats(unit
, &unit
->type_trackers
,
1770 request
->ios2_PacketType
, base
);
1773 tracker
->stats
.PacketsSent
++;
1774 tracker
->stats
.BytesSent
+= packet_size
;
1783 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_SOFTINT
;
1786 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SETTXTHRESH
1787 | ((EL3_PREAMBLESIZE
+ packet_size
) >> unit
->size_shift
));
1788 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_IGNORE
;
1796 /****i* etherlink3.device/TxError ******************************************
1804 * VOID TxError(struct DevUnit *);
1806 ****************************************************************************
1810 static VOID
TxError(struct DevUnit
*unit
, struct DevBase
*base
)
1812 UPINT window1_offset
;
1813 UBYTE tx_status
, flags
= 0;
1815 window1_offset
= unit
->window1_offset
;
1817 /* Gather all errors */
1820 unit
->ByteIn(unit
->card
, window1_offset
+ EL3REG_TXSTATUS
))
1821 & EL3REG_TXSTATUSF_COMPLETE
) != 0)
1824 unit
->ByteOut(unit
->card
, window1_offset
+ EL3REG_TXSTATUS
, 0);
1827 /* Restart transmitter if necessary */
1829 if((flags
& EL3REG_TXSTATUSF_JABBER
) != 0)
1832 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_TXRESET
);
1833 while((unit
->LEWordIn(unit
->card
, EL3REG_STATUS
) &
1834 EL3REG_STATUSF_CMDINPROGRESS
) != 0);
1838 if((flags
& (EL3REG_TXSTATUSF_JABBER
| EL3REG_TXSTATUSF_OVERFLOW
1839 | EL3REG_TXSTATUSF_RECLAIMERROR
)) != 0)
1840 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_TXENABLE
);
1842 /* Report the error(s) */
1844 ReportEvents(unit
, S2EVENT_ERROR
| S2EVENT_HARDWARE
| S2EVENT_TX
, base
);
1851 /****i* etherlink3.device/UpdateStats **************************************
1859 * VOID UpdateStats(struct DevUnit *);
1861 ****************************************************************************
1865 VOID
UpdateStats(struct DevUnit
*unit
, struct DevBase
*base
)
1867 UBYTE frame_counts_upper
;
1868 UWORD generation
, old_window
;
1870 generation
= unit
->generation
;
1873 unit
->LEWordIn(unit
->card
, EL3REG_STATUS
) >> EL3REG_STATUSB_WINDOW
;
1874 if(generation
< VORTEX_GEN
)
1875 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_STATSDISABLE
);
1877 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 6);
1878 unit
->ByteIn(unit
->card
, EL3REG_CARRIERLOST
);
1879 unit
->ByteIn(unit
->card
, EL3REG_SQEERRORS
);
1880 unit
->ByteIn(unit
->card
, EL3REG_MULTIPLECOLLISIONS
);
1881 unit
->ByteIn(unit
->card
, EL3REG_SINGLECOLLISIONS
);
1882 unit
->ByteIn(unit
->card
, EL3REG_LATECOLLISIONS
);
1883 unit
->stats
.Overruns
+= unit
->ByteIn(unit
->card
, EL3REG_RXOVERRUNS
);
1884 unit
->stats
.PacketsSent
+= unit
->ByteIn(unit
->card
, EL3REG_TXFRAMESOK
);
1885 unit
->stats
.PacketsReceived
+=
1886 unit
->ByteIn(unit
->card
, EL3REG_RXFRAMESOK
);
1887 unit
->special_stats
[S2SS_ETHERNET_RETRIES
& 0xffff] +=
1888 unit
->ByteIn(unit
->card
, EL3REG_FRAMESDEFERRED
);
1889 unit
->LEWordIn(unit
->card
, EL3REG_RXBYTESOK
);
1890 unit
->LEWordIn(unit
->card
, EL3REG_TXBYTESOK
);
1891 if(generation
>= VORTEX_GEN
)
1893 frame_counts_upper
= unit
->ByteIn(unit
->card
, EL3REG_FRAMESOKUPPER
);
1894 unit
->stats
.PacketsReceived
+= (frame_counts_upper
& 0x3) << 8;
1895 unit
->stats
.PacketsSent
+= (frame_counts_upper
& 0x30) << 4;
1896 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 4);
1897 unit
->ByteIn(unit
->card
, EL3REG_BADSSD
);
1898 if(generation
>= BOOMERANG_GEN
)
1899 unit
->ByteIn(unit
->card
, EL3REG_BYTESOKUPPER
);
1902 if(generation
< VORTEX_GEN
)
1903 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_STATSENABLE
);
1904 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1905 EL3CMD_SELECTWINDOW
| old_window
);
1911 /****i* etherlink3.device/DMARXInt *****************************************
1917 * DMARXInt(unit, int_code)
1919 * VOID DMARXInt(struct DevUnit *, APTR);
1921 ****************************************************************************
1925 static VOID
DMARXInt(REG(a1
, struct DevUnit
*unit
),
1926 REG(a5
, APTR int_code
))
1929 struct DevBase
*base
;
1930 BOOL is_orphan
, accepted
;
1931 ULONG rx_status
, packet_type
, *upd
, *fragment
, dma_size
;
1933 struct IOSana2Req
*request
, *request_tail
;
1934 struct Opener
*opener
, *opener_tail
;
1935 struct TypeStats
*tracker
;
1937 base
= unit
->device
;
1938 upd
= unit
->next_upd
;
1940 dma_size
= UPD_SIZE
* RX_SLOT_COUNT
;
1941 CachePostDMA(unit
->upds
, &dma_size
, 0);
1943 while(((rx_status
= LELong(upd
[EL3UPD_STATUS
]))
1944 & EL3UPD_STATUSF_COMPLETE
) != 0)
1946 fragment
= upd
+ EL3UPD_FIRSTFRAG
;
1947 buffer
= (UBYTE
*)LELong(fragment
[EL3FRAG_ADDR
]);
1949 dma_size
= ETH_MAXPACKETSIZE
;
1950 CachePostDMA(buffer
, &dma_size
, 0);
1952 if((rx_status
& EL3UPD_STATUSF_ERROR
) == 0)
1955 packet_size
= rx_status
& EL3UPD_STATUSF_SIZE
;
1957 if(AddressFilter(unit
, buffer
+ ETH_PACKET_DEST
, base
))
1959 packet_type
= BEWord(*((UWORD
*)(buffer
+ ETH_PACKET_TYPE
)));
1961 opener
= (APTR
)unit
->openers
.mlh_Head
;
1962 opener_tail
= (APTR
)&unit
->openers
.mlh_Tail
;
1964 /* Offer packet to every opener */
1966 while(opener
!= opener_tail
)
1968 request
= (APTR
)opener
->read_port
.mp_MsgList
.lh_Head
;
1969 request_tail
= (APTR
)&opener
->read_port
.mp_MsgList
.lh_Tail
;
1972 /* Offer packet to each request until it's accepted */
1974 while((request
!= request_tail
) && !accepted
)
1976 if(request
->ios2_PacketType
== packet_type
1977 || request
->ios2_PacketType
<= ETH_MTU
1978 && packet_type
<= ETH_MTU
)
1980 CopyPacket(unit
, request
, packet_size
, packet_type
,
1981 buffer
, TRUE
, base
);
1985 (APTR
)request
->ios2_Req
.io_Message
.mn_Node
.ln_Succ
;
1990 opener
= (APTR
)opener
->node
.mln_Succ
;
1993 /* If packet was unwanted, give it to S2_READORPHAN request */
1997 unit
->stats
.UnknownTypesReceived
++;
1998 if(!IsMsgPortEmpty(unit
->request_ports
[ADOPT_QUEUE
]))
2001 (APTR
)unit
->request_ports
[ADOPT_QUEUE
]->
2002 mp_MsgList
.lh_Head
, packet_size
, packet_type
, buffer
,
2007 /* Update remaining statistics */
2010 FindTypeStats(unit
, &unit
->type_trackers
, packet_type
, base
);
2013 tracker
->stats
.PacketsReceived
++;
2014 tracker
->stats
.BytesReceived
+= packet_size
;
2020 unit
->stats
.BadData
++;
2021 ReportEvents(unit
, S2EVENT_ERROR
| S2EVENT_HARDWARE
| S2EVENT_RX
,
2025 upd
[EL3UPD_STATUS
] = 0;
2027 dma_size
= ETH_MAXPACKETSIZE
;
2028 CachePreDMA(buffer
, &dma_size
, 0);
2030 upd
= (ULONG
*)LELong(upd
[EL3UPD_NEXT
]);
2033 dma_size
= UPD_SIZE
* RX_SLOT_COUNT
;
2034 CachePreDMA(unit
->upds
, &dma_size
, 0);
2038 unit
->next_upd
= upd
;
2039 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_UPUNSTALL
);
2041 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
2042 EL3CMD_SETINTMASK
| unit
->int_mask
);
2049 /****i* etherlink3.device/DMATXInt *****************************************
2055 * DMATXInt(unit, int_code)
2057 * VOID DMATXInt(struct DevUnit *, APTR);
2059 ****************************************************************************
2063 static VOID
DMATXInt(REG(a1
, struct DevUnit
*unit
),
2064 REG(a5
, APTR int_code
))
2066 UWORD packet_size
, data_size
, slot
, new_slot
, *p
, *q
, i
;
2067 struct DevBase
*base
;
2068 struct IOSana2Req
*request
;
2069 BOOL proceed
= TRUE
;
2070 struct Opener
*opener
;
2071 ULONG wire_error
, *dpd
, *last_dpd
, *next_dpd
, *fragment
, dma_size
;
2072 UBYTE
*(*dma_tx_function
)(REG(a0
, APTR
));
2075 struct MsgPort
*port
;
2077 base
= unit
->device
;
2078 port
= unit
->request_ports
[WRITE_QUEUE
];
2080 while(proceed
&& (!IsMsgPortEmpty(port
)))
2082 slot
= unit
->tx_in_slot
;
2083 new_slot
= (slot
+ 1) % TX_SLOT_COUNT
;
2085 if(new_slot
!= unit
->tx_out_slot
2086 && (unit
->flags
& UNITF_TXBUFFERINUSE
) == 0)
2090 request
= (APTR
)port
->mp_MsgList
.lh_Head
;
2091 data_size
= packet_size
= request
->ios2_DataLength
;
2093 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
2094 packet_size
+= ETH_HEADERSIZE
;
2095 dpd
= unit
->dpds
+ ((DPD_SIZE
/ sizeof(ULONG
)) * slot
);
2097 /* Write packet preamble */
2099 Remove((APTR
)request
);
2100 unit
->tx_requests
[slot
] = request
;
2101 dpd
[EL3DPD_NEXT
] = (ULONG
)NULL
;
2102 dpd
[EL3DPD_HEADER
] =
2103 MakeLELong(EL3DPD_HEADERF_DLINT
| packet_size
);
2104 fragment
= dpd
+ EL3DPD_FIRSTFRAG
;
2106 /* Write packet header */
2108 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
2110 buffer
= unit
->headers
+ ETH_HEADERSIZE
* slot
;
2111 fragment
[EL3FRAG_ADDR
] = MakeLELong((ULONG
)buffer
);
2112 fragment
[EL3FRAG_LEN
] = MakeLELong(ETH_HEADERSIZE
);
2114 p
= (UWORD
*)buffer
;
2115 for(i
= 0, q
= (UWORD
*)request
->ios2_DstAddr
;
2116 i
< ETH_ADDRESSSIZE
/ 2; i
++)
2118 for(i
= 0, q
= (UWORD
*)unit
->address
;
2119 i
< ETH_ADDRESSSIZE
/ 2; i
++)
2121 *p
++ = MakeBEWord(request
->ios2_PacketType
);
2122 buffer
= (UBYTE
*)p
;
2124 dma_size
= ETH_HEADERSIZE
;
2125 CachePreDMA(buffer
, &dma_size
, DMA_ReadFromRAM
);
2126 fragment
+= EL3_FRAGLEN
;
2129 /* Get packet data */
2131 opener
= (APTR
)request
->ios2_BufferManagement
;
2132 dma_tx_function
= opener
->dma_tx_function
;
2133 if(dma_tx_function
!= NULL
)
2134 buffer
= dma_tx_function(request
->ios2_Data
);
2140 buffer
= unit
->tx_buffer
;
2141 if(opener
->tx_function(buffer
, request
->ios2_Data
, data_size
))
2142 unit
->flags
|= UNITF_TXBUFFERINUSE
;
2145 error
= S2ERR_NO_RESOURCES
;
2146 wire_error
= S2WERR_BUFF_ERROR
;
2148 S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
2149 | S2EVENT_TX
, base
);
2153 /* Write packet data */
2157 fragment
[EL3FRAG_ADDR
] = MakeLELong((ULONG
)buffer
);
2158 fragment
[EL3FRAG_LEN
] =
2159 MakeLELong(EL3FRAG_LENF_LAST
| data_size
);
2160 dma_size
= data_size
;
2161 CachePreDMA(buffer
, &dma_size
, DMA_ReadFromRAM
);
2163 /* Pass packet to adapter */
2165 last_dpd
= (ULONG
*)unit
->LELongIn(unit
->card
, EL3REG_DOWNLIST
);
2166 if(last_dpd
!= NULL
)
2168 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
2170 while((unit
->LEWordIn(unit
->card
, EL3REG_STATUS
)
2171 & EL3REG_STATUSF_CMDINPROGRESS
) != 0);
2172 while((next_dpd
= (ULONG
*)LELong(last_dpd
[EL3DPD_NEXT
]))
2174 last_dpd
= next_dpd
;
2175 last_dpd
[EL3DPD_NEXT
] = MakeLELong((ULONG
)dpd
);
2176 dma_size
= DPD_SIZE
* TX_SLOT_COUNT
;
2177 CachePreDMA(unit
->dpds
, &dma_size
, 0);
2178 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
2179 EL3CMD_DOWNUNSTALL
);
2183 dma_size
= DPD_SIZE
* TX_SLOT_COUNT
;
2184 CachePreDMA(unit
->dpds
, &dma_size
, 0);
2185 unit
->LELongOut(unit
->card
, EL3REG_DOWNLIST
, (ULONG
)dpd
);
2188 unit
->tx_in_slot
= new_slot
;
2194 request
->ios2_Req
.io_Error
= error
;
2195 request
->ios2_WireError
= wire_error
;
2196 ReplyMsg((APTR
)request
);
2204 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_SOFTINT
;
2206 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_IGNORE
;
2213 /****i* etherlink3.device/DMATXEndInt **************************************
2219 * TXInt(unit, int_code)
2221 * VOID TXInt(struct DevUnit *, APTR);
2224 * I think it's safe to assume that there will always be at least one
2225 * completed packet whenever this interrupt is called.
2227 ****************************************************************************
2231 static VOID
DMATXEndInt(REG(a1
, struct DevUnit
*unit
),
2232 REG(a5
, APTR int_code
))
2234 UWORD data_size
, packet_size
, new_out_slot
, i
;
2236 struct DevBase
*base
;
2237 struct IOSana2Req
*request
;
2238 ULONG
*dpd
, *fragment
, dma_size
;
2239 struct TypeStats
*tracker
;
2241 /* Find out which packets have completed */
2243 base
= unit
->device
;
2244 dpd
= (UPINT
*)unit
->LELongIn(unit
->card
, EL3REG_DOWNLIST
);
2246 new_out_slot
= (dpd
- unit
->dpds
) / (sizeof(ULONG
) * DPD_SIZE
);
2248 new_out_slot
= unit
->tx_in_slot
;
2250 /* Retire sent packets */
2252 for(i
= unit
->tx_out_slot
; i
!= new_out_slot
;
2253 i
= (i
+ 1) % TX_SLOT_COUNT
)
2255 /* Mark end of DMA */
2257 request
= unit
->tx_requests
[i
];
2258 data_size
= packet_size
= request
->ios2_DataLength
;
2259 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
2260 packet_size
+= ETH_HEADERSIZE
;
2262 dpd
= unit
->dpds
+ ((DPD_SIZE
/ sizeof(ULONG
)) * i
);
2263 fragment
= dpd
+ EL3DPD_FIRSTFRAG
;
2264 dma_size
= DPD_SIZE
* TX_SLOT_COUNT
;
2265 CachePostDMA(unit
->dpds
, &dma_size
, 0);
2267 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
2269 buffer
= (APTR
)LELong(fragment
[EL3FRAG_ADDR
]);
2270 dma_size
= ETH_HEADERSIZE
;
2271 CachePostDMA(buffer
, &dma_size
, DMA_ReadFromRAM
);
2272 fragment
+= EL3_FRAGLEN
;
2275 buffer
= (APTR
)LELong(fragment
[EL3FRAG_ADDR
]);
2276 dma_size
= data_size
;
2277 CachePostDMA(buffer
, &dma_size
, DMA_ReadFromRAM
);
2279 /* Check if unit's TX buffer is now free */
2281 if(buffer
== unit
->tx_buffer
)
2282 unit
->flags
&= ~UNITF_TXBUFFERINUSE
;
2284 /* Update statistics */
2286 tracker
= FindTypeStats(unit
, &unit
->type_trackers
,
2287 request
->ios2_PacketType
, base
);
2290 tracker
->stats
.PacketsSent
++;
2291 tracker
->stats
.BytesSent
+= packet_size
;
2296 request
->ios2_Req
.io_Error
= 0;
2297 ReplyMsg((APTR
)request
);
2300 unit
->tx_out_slot
= new_out_slot
;
2302 /* Restart downloads if they had stopped */
2304 if(unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
== PA_IGNORE
)
2305 Cause(&unit
->tx_int
);
2312 /****i* etherlink3.device/ReportEvents *************************************
2318 * ReportEvents(unit, events)
2320 * VOID ReportEvents(struct DevUnit *, ULONG);
2323 * unit - A unit of this device.
2324 * events - A mask of events to report.
2329 ****************************************************************************
2333 static VOID
ReportEvents(struct DevUnit
*unit
, ULONG events
,
2334 struct DevBase
*base
)
2336 struct IOSana2Req
*request
, *tail
, *next_request
;
2339 list
= &unit
->request_ports
[EVENT_QUEUE
]->mp_MsgList
;
2340 next_request
= (APTR
)list
->lh_Head
;
2341 tail
= (APTR
)&list
->lh_Tail
;
2344 while(next_request
!= tail
)
2346 request
= next_request
;
2347 next_request
= (APTR
)request
->ios2_Req
.io_Message
.mn_Node
.ln_Succ
;
2349 if((request
->ios2_WireError
& events
) != 0)
2351 request
->ios2_WireError
= events
;
2352 Remove((APTR
)request
);
2353 ReplyMsg((APTR
)request
);
2363 /****i* etherlink3.device/UnitTask *****************************************
2387 ****************************************************************************
2391 static VOID
UnitTask()
2394 struct IORequest
*request
;
2395 struct DevUnit
*unit
;
2396 struct DevBase
*base
;
2397 struct MsgPort
*general_port
;
2398 ULONG signals
, wait_signals
, card_removed_signal
, card_inserted_signal
,
2399 general_port_signal
;
2401 /* Get parameters */
2403 task
= AbsExecBase
->ThisTask
;
2404 unit
= task
->tc_UserData
;
2405 base
= unit
->device
;
2407 /* Activate general request port */
2409 general_port
= unit
->request_ports
[GENERAL_QUEUE
];
2410 general_port
->mp_SigTask
= task
;
2411 general_port
->mp_SigBit
= AllocSignal(-1);
2412 general_port_signal
= 1 << general_port
->mp_SigBit
;
2413 general_port
->mp_Flags
= PA_SIGNAL
;
2415 /* Allocate a signal for notification of card removal */
2417 card_removed_signal
= unit
->card_removed_signal
= 1 << AllocSignal(-1);
2418 card_inserted_signal
= unit
->card_inserted_signal
= 1 << AllocSignal(-1);
2419 wait_signals
= (1 << general_port
->mp_SigBit
) | card_removed_signal
2420 | card_inserted_signal
;
2422 /* Tell ourselves to check port for old messages */
2424 Signal(task
, general_port_signal
);
2426 /* Infinite loop to service requests and signals */
2430 signals
= Wait(wait_signals
);
2432 if((signals
& card_inserted_signal
) != 0)
2434 if(unit
->insertion_function(unit
->card
, base
))
2436 unit
->flags
|= UNITF_HAVEADAPTER
;
2437 if((unit
->flags
& UNITF_CONFIGURED
) != 0)
2438 ConfigureAdapter(unit
, base
);
2442 if((signals
& card_removed_signal
) != 0)
2444 unit
->removal_function(unit
->card
, base
);
2445 GoOffline(unit
, base
);
2448 if((signals
& general_port_signal
) != 0)
2450 while((request
= (APTR
)GetMsg(general_port
)) != NULL
)
2452 /* Service the request as soon as the unit is free */
2454 ObtainSemaphore(&unit
->access_lock
);
2455 ServiceRequest((APTR
)request
, base
);
2463 /****i* etherlink3.device/ReadEEPROM ***************************************
2466 * ReadEEPROM -- Read a location on card's EEPROM.
2469 * value = ReadEEPROM(unit, index)
2471 * UWORD ReadEEPROM(struct DevUnit *, UWORD);
2474 * unit - Device unit.
2475 * index - Offset within EEPROM.
2478 * value - Contents of specified EEPROM location.
2480 ****************************************************************************
2484 static UWORD
ReadEEPROM(struct DevUnit
*unit
, UWORD index
,
2485 struct DevBase
*base
)
2487 unit
->LEWordOut(unit
->card
, EL3REG_EEPROMCMD
, EL3ECMD_READ
| index
);
2488 while((unit
->LEWordIn(unit
->card
, EL3REG_EEPROMCMD
) &
2489 EL3REG_EEPROMCMDF_BUSY
) != 0);
2491 return unit
->LEWordIn(unit
->card
, EL3REG_EEPROMDATA
);
2496 /****i* etherlink3.device/ReadMII ******************************************
2499 * ReadMII -- Read a register on an MII PHY.
2502 * success = ReadMII(unit, phy_no, reg_no, value)
2504 * BOOL ReadMII(struct DevUnit *, UWORD, UWORD, UWORD *);
2507 * Reads a register on an MII PHY. Window 4 must be selected before
2508 * calling this function.
2511 * unit - Device unit.
2514 * value - Pointer to location to store value read from MII register.
2517 * success - Success indicator.
2519 ****************************************************************************
2523 static BOOL
ReadMII(struct DevUnit
*unit
, UWORD phy_no
, UWORD reg_no
,
2524 UWORD
*value
, struct DevBase
*base
)
2526 BOOL success
= TRUE
;
2528 WriteMIIBits(unit
, 0xffffffff, 32, base
);
2529 WriteMIIBits(unit
, 0x6, 4, base
);
2530 WriteMIIBits(unit
, phy_no
, 5, base
);
2531 WriteMIIBits(unit
, reg_no
, 5, base
);
2532 ReadMIIBit(unit
, base
);
2533 if(ReadMIIBit(unit
, base
))
2535 *value
= ReadMIIBits(unit
, 16, base
);
2536 ReadMIIBit(unit
, base
);
2543 /****i* etherlink3.device/WriteMII *****************************************
2546 * WriteMII -- Write to a register on an MII PHY.
2549 * WriteMII(unit, phy_no, reg_no, value)
2551 * VOID WriteMII(struct DevUnit *, UWORD, UWORD, UWORD);
2554 * unit - Device unit.
2557 * value - value to write to MII register.
2562 ****************************************************************************
2567 static VOID
WriteMII(struct DevUnit
*unit
, UWORD phy_no
, UWORD reg_no
,
2568 UWORD value
, struct DevBase
*base
)
2570 WriteMIIBits(unit
, 0xffffffff, 32, base
);
2571 WriteMIIBits(unit
, 0x5, 4, base
);
2572 WriteMIIBits(unit
, phy_no
, 5, base
);
2573 WriteMIIBits(unit
, reg_no
, 5, base
);
2574 WriteMIIBit(unit
, TRUE
, base
);
2575 WriteMIIBits(unit
, value
, 16, base
);
2576 DoMIIZCycle(unit
, base
);
2584 /****i* etherlink3.device/ReadMIIBits **************************************
2590 * value = ReadMIIBits(unit, count)
2592 * ULONG ReadMIIBits(struct DevUnit *, UBYTE);
2594 ****************************************************************************
2598 static ULONG
ReadMIIBits(struct DevUnit
*unit
, UBYTE count
,
2599 struct DevBase
*base
)
2604 /* LEWordOut(io_addr, LEWordIn(reg) & ~EL3REG_PHYMGMTF_WRITE);*/
2605 for(i
= 0; i
< count
; i
++)
2608 if(ReadMIIBit(unit
, base
))
2610 unit
->LEWordIn(unit
->card
, EL3REG_PHYMGMT
);
2612 /* ReadMIIBit(unit, base)? value |= 1;*/
2618 /****i* etherlink3.device/WriteMIIBits *************************************
2624 * WriteMIIBits(unit, value, count)
2626 * VOID WriteMIIBits(struct DevUnit *, ULONG, UBYTE);
2628 ****************************************************************************
2632 static VOID
WriteMIIBits(struct DevUnit
*unit
, ULONG value
, UBYTE count
,
2633 struct DevBase
*base
)
2637 for(mask
= 1 << (count
- 1); mask
!= 0; mask
>>= 1)
2638 WriteMIIBit(unit
, (value
& mask
) != 0, base
);
2645 /****i* etherlink3.device/ReadMIIBit ***************************************
2651 * is_one = ReadMIIBit(unit)
2653 * BOOL ReadMIIBit(struct DevUnit *);
2655 ****************************************************************************
2659 static BOOL
ReadMIIBit(struct DevUnit
*unit
, struct DevBase
*base
)
2663 unit
->LEWordOut(unit
->card
, EL3REG_PHYMGMT
, 0);
2664 BusyMicroDelay(1, base
);
2665 unit
->LEWordOut(unit
->card
, EL3REG_PHYMGMT
, EL3REG_PHYMGMTF_CLK
);
2666 BusyMicroDelay(1, base
);
2668 (unit
->LEWordIn(unit
->card
, EL3REG_PHYMGMT
) & EL3REG_PHYMGMTF_DATA
)
2670 BusyMicroDelay(1, base
);
2677 /****i* etherlink3.device/WriteMIIBit **************************************
2683 * WriteMIIBit(unit, is_one)
2685 * VOID WriteMIIBit(struct DevUnit *, BOOL);
2687 ****************************************************************************
2691 static VOID
WriteMIIBit(struct DevUnit
*unit
, BOOL is_one
,
2692 struct DevBase
*base
)
2694 unit
->LEWordOut(unit
->card
, EL3REG_PHYMGMT
, EL3REG_PHYMGMTF_WRITE
);
2695 BusyMicroDelay(1, base
);
2697 unit
->LEWordOut(unit
->card
, EL3REG_PHYMGMT
,
2698 EL3REG_PHYMGMTF_WRITE
| EL3REG_PHYMGMTF_CLK
|
2699 EL3REG_PHYMGMTF_DATA
);
2701 unit
->LEWordOut(unit
->card
, EL3REG_PHYMGMT
,
2702 EL3REG_PHYMGMTF_WRITE
| EL3REG_PHYMGMTF_CLK
);
2703 BusyMicroDelay(1, base
);
2710 /****i* etherlink3.device/DoMIIZCycle **************************************
2718 * VOID DoMIIZCycle(struct DevUnit *);
2720 ****************************************************************************
2725 static VOID
DoMIIZCycle(struct DevUnit
*unit
, struct DevBase
*base
)
2727 unit
->LEWordOut(unit
->card
, EL3REG_PHYMGMT
,
2728 unit
->LEWordIn(unit
->card
, EL3REG_PHYMGMT
) & ~EL3REG_PHYMGMTF_CLK
);
2729 BusyMicroDelay(1, base
);
2730 unit
->LEWordOut(unit
->card
, EL3REG_PHYMGMT
, EL3REG_PHYMGMTF_CLK
);
2731 BusyMicroDelay(1, base
);
2740 static VOID
BusyMicroDelay(ULONG micros
, struct DevBase
*base
)
2742 struct timeval time
, end_time
;
2744 GetSysTime(&end_time
);
2746 time
.tv_micro
= micros
;
2747 AddTime(&end_time
, &time
);
2749 while(CmpTime(&end_time
, &time
) < 0)
2757 static VOID
BusyMicroDelay(ULONG micros
, struct DevBase
*base
)
2759 struct EClockVal time
, end_time
;
2762 rate
= ReadEClock(&time
);
2763 end_time
.ev_hi
= time
.ev_hi
;
2764 end_time
.ev_lo
= time
.ev_lo
+ (micros
* rate
+ 1) / 1000000;
2765 if(end_time
.ev_lo
< time
.ev_lo
)
2768 while(time
.ev_lo
< end_time
.ev_lo
|| time
.ev_hi
< end_time
.ev_hi
)