3 Copyright (C) 2001-2012 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,
24 #include <exec/memory.h>
25 #include <exec/execbase.h>
26 #include <exec/errors.h>
28 #include <proto/exec.h>
30 #include <proto/alib.h>
32 #include <clib/alib_protos.h>
34 #include <proto/utility.h>
35 #include <proto/timer.h>
38 #include "etherlink3.h"
41 #include "unit_protos.h"
42 #include "request_protos.h"
45 #define TASK_PRIORITY 0
46 #define STACK_SIZE 4096
48 (EL3INTF_UPDATESTATS | EL3INTF_RXCOMPLETE | EL3INTF_TXAVAIL \
50 #define DMA_INT_MASK \
51 (EL3INTF_UPDONE | EL3INTF_DOWNDONE | EL3INTF_UPDATESTATS \
57 #define AbsExecBase sys_base
61 #define AddTask(task, initial_pc, final_pc) \
62 IExec->AddTask(task, initial_pc, final_pc, NULL)
66 #define AddTask(task, initial_pc, final_pc) \
68 struct TagItem _task_tags[] = \
69 {{TASKTAG_ARG1, (IPTR)SysBase}, {TAG_END, 0}}; \
70 NewAddTask(task, initial_pc, final_pc, _task_tags); \
74 VOID
SelectMedium(struct DevUnit
*unit
, UWORD transceiver
,
75 struct DevBase
*base
);
76 static struct AddressRange
*FindMulticastRange(struct DevUnit
*unit
,
77 ULONG lower_bound_left
, UWORD lower_bound_right
, ULONG upper_bound_left
,
78 UWORD upper_bound_right
, struct DevBase
*base
);
79 static VOID
RXInt(REG(a1
, struct DevUnit
*unit
), REG(a5
, APTR int_code
));
80 static VOID
CopyPacket(struct DevUnit
*unit
, struct IOSana2Req
*request
,
81 UWORD packet_size
, UWORD packet_type
, UBYTE
*buffer
, BOOL all_read
,
82 struct DevBase
*base
);
83 static BOOL
AddressFilter(struct DevUnit
*unit
, UBYTE
*address
,
84 struct DevBase
*base
);
85 static VOID
TXInt(REG(a1
, struct DevUnit
*unit
), REG(a5
, APTR int_code
));
86 static VOID
TxError(struct DevUnit
*unit
, struct DevBase
*base
);
87 static VOID
DMARXInt(REG(a1
, struct DevUnit
*unit
),
88 REG(a5
, APTR int_code
));
89 static VOID
DMATXInt(REG(a1
, struct DevUnit
*unit
),
90 REG(a5
, APTR int_code
));
91 static VOID
DMATXEndInt(REG(a1
, struct DevUnit
*unit
),
92 REG(a5
, APTR int_code
));
93 static VOID
ReportEvents(struct DevUnit
*unit
, ULONG events
,
94 struct DevBase
*base
);
95 static VOID
UnitTask(struct ExecBase
*sys_base
);
96 static UWORD
ReadEEPROM(struct DevUnit
*unit
, UWORD index
,
97 struct DevBase
*base
);
98 static BOOL
ReadMII(struct DevUnit
*unit
, UWORD phy_no
, UWORD reg_no
,
99 UWORD
*value
, struct DevBase
*base
);
101 static VOID
WriteMII(struct DevUnit
*unit
, UWORD phy_no
, UWORD reg_no
,
102 UWORD value
, struct DevBase
*base
);
104 static ULONG
ReadMIIBits(struct DevUnit
*unit
, UBYTE count
,
105 struct DevBase
*base
);
106 static VOID
WriteMIIBits(struct DevUnit
*unit
, ULONG value
, UBYTE count
,
107 struct DevBase
*base
);
108 static BOOL
ReadMIIBit(struct DevUnit
*unit
, struct DevBase
*base
);
109 static VOID
WriteMIIBit(struct DevUnit
*unit
, BOOL is_one
,
110 struct DevBase
*base
);
112 static VOID
DoMIIZCycle(struct DevUnit
*unit
, struct DevBase
*base
);
114 static VOID
BusyMicroDelay(ULONG micros
, struct DevBase
*base
);
117 static const UBYTE port_choices
[] =
119 /* EL3XCVR_AUTONEG,*/
128 static const UBYTE port_masks
[] =
130 EL3REG_MEDIAOPTIONSF_10BASET
,
131 EL3REG_MEDIAOPTIONSF_AUI
,
133 EL3REG_MEDIAOPTIONSF_10BASE2
,
134 EL3REG_MEDIAOPTIONSF_100BASETX
,
135 EL3REG_MEDIAOPTIONSF_100BASEFX
,
136 EL3REG_MEDIAOPTIONSF_MII
,
138 EL3REG_MEDIAOPTIONSF_100BASETX
| EL3REG_MEDIAOPTIONSF_10BASET
142 /****i* etherlink3.device/CreateUnit ***************************************
145 * CreateUnit -- Create a unit.
148 * unit = CreateUnit(index, card, io_tags, generation,
151 * struct DevUnit *CreateUnit(ULONG, APTR, struct TagItem *, UWORD,
155 * Creates a new unit.
157 ****************************************************************************
161 struct DevUnit
*CreateUnit(ULONG index
, APTR card
,
162 struct TagItem
*io_tags
, UWORD generation
, UWORD bus
,
163 struct DevBase
*base
)
166 struct DevUnit
*unit
;
168 struct MsgPort
*port
;
171 ULONG
*upd
, *next_upd
, *fragment
, dma_size
;
172 APTR rx_int_function
, tx_int_function
;
174 unit
= AllocMem(sizeof(struct DevUnit
), MEMF_CLEAR
| MEMF_PUBLIC
);
180 InitSemaphore(&unit
->access_lock
);
181 NewList((APTR
)&unit
->openers
);
182 NewList((APTR
)&unit
->type_trackers
);
183 NewList((APTR
)&unit
->multicast_ranges
);
188 unit
->generation
= generation
;
191 (APTR
)GetTagData(IOTAG_ByteIn
, (UPINT
)NULL
, io_tags
);
193 (APTR
)GetTagData(IOTAG_LongIn
, (UPINT
)NULL
, io_tags
);
195 (APTR
)GetTagData(IOTAG_ByteOut
, (UPINT
)NULL
, io_tags
);
197 (APTR
)GetTagData(IOTAG_WordOut
, (UPINT
)NULL
, io_tags
);
199 (APTR
)GetTagData(IOTAG_LongOut
, (UPINT
)NULL
, io_tags
);
201 (APTR
)GetTagData(IOTAG_LongsIn
, (UPINT
)NULL
, io_tags
);
203 (APTR
)GetTagData(IOTAG_LongsOut
, (UPINT
)NULL
, io_tags
);
205 (APTR
)GetTagData(IOTAG_BEWordOut
, (UPINT
)NULL
, io_tags
);
207 (APTR
)GetTagData(IOTAG_LEWordIn
, (UPINT
)NULL
, io_tags
);
209 (APTR
)GetTagData(IOTAG_LELongIn
, (UPINT
)NULL
, io_tags
);
211 (APTR
)GetTagData(IOTAG_LEWordOut
, (UPINT
)NULL
, io_tags
);
213 (APTR
)GetTagData(IOTAG_LELongOut
, (UPINT
)NULL
, io_tags
);
215 (APTR
)GetTagData(IOTAG_AllocDMAMem
, (UPINT
)NULL
, io_tags
);
217 (APTR
)GetTagData(IOTAG_FreeDMAMem
, (UPINT
)NULL
, io_tags
);
218 if(unit
->ByteIn
== NULL
|| unit
->LongIn
== NULL
219 || unit
->ByteOut
== NULL
220 || unit
->WordOut
== NULL
|| unit
->LongOut
== NULL
221 || unit
->LongsIn
== NULL
|| unit
->LongsOut
== NULL
222 || unit
->BEWordOut
== NULL
|| unit
->LEWordIn
== NULL
223 || unit
->LELongIn
== NULL
|| unit
->LEWordOut
== NULL
224 || unit
->LELongOut
== NULL
225 || generation
>= BOOMERANG_GEN
226 && (unit
->AllocDMAMem
== NULL
|| unit
->FreeDMAMem
== NULL
))
232 if(unit
->generation
>= VORTEX_GEN
)
233 unit
->size_shift
= 2;
235 InitialiseAdapter(unit
, FALSE
, base
);
236 unit
->flags
|= UNITF_HAVEADAPTER
;
238 /* Set up packet filter command */
240 unit
->rx_filter_cmd
= EL3CMD_SETRXFILTER
| EL3CMD_SETRXFILTERF_BCAST
241 | EL3CMD_SETRXFILTERF_UCAST
;
243 /* Set up interrupt mask */
245 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
246 unit
->int_mask
= DMA_INT_MASK
;
248 unit
->int_mask
= INT_MASK
;
250 /* Disable statistics interrupts for PCMCIA because they can't be
253 if(bus
== PCCARD_BUS
)
254 unit
->int_mask
&= ~EL3INTF_UPDATESTATS
;
256 /* Store location of registers that were originally in window 1 */
258 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
259 unit
->window1_offset
+= EL3_WINDOWSIZE
;
261 /* Create the message ports for queuing requests */
263 for(i
= 0; i
< REQUEST_QUEUE_COUNT
; i
++)
265 unit
->request_ports
[i
] = port
= AllocMem(sizeof(struct MsgPort
),
266 MEMF_PUBLIC
| MEMF_CLEAR
);
272 NewList(&port
->mp_MsgList
);
273 port
->mp_Flags
= PA_IGNORE
;
274 port
->mp_SigTask
= &unit
->tx_int
;
278 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
280 unit
->rx_buffer
= unit
->AllocDMAMem(unit
->card
,
281 ETH_MAXPACKETSIZE
* RX_SLOT_COUNT
, 1);
283 unit
->AllocDMAMem(unit
->card
, ETH_MAXPACKETSIZE
, 1);
288 AllocVec((ETH_MAXPACKETSIZE
+ 3) & ~3, MEMF_PUBLIC
);
289 unit
->tx_buffer
= AllocVec(ETH_MAXPACKETSIZE
, MEMF_PUBLIC
);
292 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
294 unit
->tx_requests
= AllocVec(sizeof(APTR
) * TX_SLOT_COUNT
,
296 unit
->headers
= unit
->AllocDMAMem(unit
->card
,
297 ETH_HEADERSIZE
* TX_SLOT_COUNT
, 1);
299 unit
->AllocDMAMem(unit
->card
, DPD_SIZE
* TX_SLOT_COUNT
, 8);
300 next_upd
= unit
->upds
=
301 unit
->AllocDMAMem(unit
->card
, UPD_SIZE
* RX_SLOT_COUNT
, 8);
302 if(unit
->tx_requests
== NULL
|| unit
->headers
== NULL
303 || unit
->dpds
== NULL
|| next_upd
== NULL
)
307 if(unit
->rx_buffer
== NULL
|| unit
->tx_buffer
== NULL
)
313 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
315 /* Construct RX ring */
317 buffer
= unit
->rx_buffer
;
318 for(i
= 0; i
< RX_SLOT_COUNT
; i
++)
321 next_upd
= upd
+ UPD_SIZE
/ sizeof(ULONG
);
322 upd
[EL3UPD_NEXT
] = MakeLELong((ULONG
)(UPINT
)next_upd
);
323 upd
[EL3UPD_STATUS
] = 0;
324 fragment
= upd
+ EL3UPD_FIRSTFRAG
;
325 fragment
[EL3FRAG_ADDR
] = MakeLELong((ULONG
)(UPINT
)buffer
);
326 fragment
[EL3FRAG_LEN
] =
327 MakeLELong(EL3FRAG_LENF_LAST
| ETH_MAXPACKETSIZE
);
328 buffer
+= ETH_MAXPACKETSIZE
;
330 upd
[EL3UPD_NEXT
] = MakeLELong((ULONG
)(UPINT
)unit
->upds
);
331 unit
->next_upd
= unit
->upds
;
333 dma_size
= UPD_SIZE
* RX_SLOT_COUNT
;
334 CachePreDMA(unit
->upds
, &dma_size
, 0);
335 dma_size
= ETH_MAXPACKETSIZE
* RX_SLOT_COUNT
;
336 CachePreDMA(unit
->rx_buffer
, &dma_size
, 0);
339 /* Record maximum speed in BPS */
341 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_100MBPS
) != 0)
342 unit
->speed
= 100000000;
344 unit
->speed
= 10000000;
346 /* Initialise status, transmit and receive interrupts */
348 unit
->status_int
.is_Node
.ln_Name
=
349 base
->device
.dd_Library
.lib_Node
.ln_Name
;
350 unit
->status_int
.is_Code
= (APTR
)StatusInt
;
351 unit
->status_int
.is_Data
= unit
;
353 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
354 rx_int_function
= DMARXInt
;
356 rx_int_function
= RXInt
;
357 unit
->rx_int
.is_Node
.ln_Name
=
358 base
->device
.dd_Library
.lib_Node
.ln_Name
;
359 unit
->rx_int
.is_Code
= rx_int_function
;
360 unit
->rx_int
.is_Data
= unit
;
362 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
363 tx_int_function
= DMATXInt
;
365 tx_int_function
= TXInt
;
366 unit
->tx_int
.is_Node
.ln_Name
=
367 base
->device
.dd_Library
.lib_Node
.ln_Name
;
368 unit
->tx_int
.is_Code
= tx_int_function
;
369 unit
->tx_int
.is_Data
= unit
;
371 unit
->tx_end_int
.is_Node
.ln_Name
=
372 base
->device
.dd_Library
.lib_Node
.ln_Name
;
373 unit
->tx_end_int
.is_Code
= DMATXEndInt
;
374 unit
->tx_end_int
.is_Data
= unit
;
376 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_SOFTINT
;
381 /* Create a new task */
384 AllocMem(sizeof(struct Task
), MEMF_PUBLIC
| MEMF_CLEAR
);
391 stack
= AllocMem(STACK_SIZE
, MEMF_PUBLIC
);
398 /* Initialise and start task */
400 task
->tc_Node
.ln_Type
= NT_TASK
;
401 task
->tc_Node
.ln_Pri
= TASK_PRIORITY
;
402 task
->tc_Node
.ln_Name
=
403 base
->device
.dd_Library
.lib_Node
.ln_Name
;
404 task
->tc_SPUpper
= stack
+ STACK_SIZE
;
405 task
->tc_SPLower
= stack
;
406 task
->tc_SPReg
= stack
+ STACK_SIZE
;
407 NewList(&task
->tc_MemEntry
);
409 if(AddTask(task
, UnitTask
, NULL
) == NULL
)
413 /* Send the unit to the new task */
416 task
->tc_UserData
= unit
;
420 DeleteUnit(unit
, base
);
429 /****i* etherlink3.device/DeleteUnit ***************************************
432 * DeleteUnit -- Delete a unit.
437 * VOID DeleteUnit(struct DevUnit *);
443 * unit - Device unit (can be NULL).
456 ****************************************************************************
460 VOID
DeleteUnit(struct DevUnit
*unit
, struct DevBase
*base
)
470 if(task
->tc_UserData
!= NULL
)
473 FreeMem(task
->tc_SPLower
, STACK_SIZE
);
475 FreeMem(task
, sizeof(struct Task
));
478 for(i
= 0; i
< REQUEST_QUEUE_COUNT
; i
++)
480 if(unit
->request_ports
[i
] != NULL
)
481 FreeMem(unit
->request_ports
[i
], sizeof(struct MsgPort
));
484 if((unit
->flags
& UNITF_HAVEADAPTER
) != 0) /* Needed! */
485 GoOffline(unit
, base
);
487 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
489 unit
->FreeDMAMem(unit
->card
, unit
->upds
);
490 unit
->FreeDMAMem(unit
->card
, unit
->dpds
);
491 unit
->FreeDMAMem(unit
->card
, unit
->headers
);
492 FreeVec(unit
->tx_requests
);
495 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
497 unit
->FreeDMAMem(unit
->card
, unit
->tx_buffer
);
498 unit
->FreeDMAMem(unit
->card
, unit
->rx_buffer
);
502 FreeVec(unit
->tx_buffer
);
503 FreeVec(unit
->rx_buffer
);
506 FreeMem(unit
, sizeof(struct DevUnit
));
514 /****i* etherlink3.device/InitialiseAdapter ********************************
517 * InitialiseAdapter -- .
520 * InitialiseAdapter(unit, reinsertion)
522 * BOOL InitialiseAdapter(struct DevUnit *, BOOL);
541 ****************************************************************************
545 BOOL
InitialiseAdapter(struct DevUnit
*unit
, BOOL reinsertion
,
546 struct DevBase
*base
)
549 UWORD address_part
, links
= 0, ports
, new_ports
, tp_ports
,
550 media_status
, transceiver
, status
, advert
, ability
, modes
;
554 /* Reset card. We avoid resetting the receive logic because it stops the
555 link status working in the MII Status register */
557 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
558 EL3CMD_RXRESET
| EL3CMD_RXRESETF_SKIPNETWORK
);
559 while((unit
->LEWordIn(unit
->card
, EL3REG_STATUS
) &
560 EL3REG_STATUSF_CMDINPROGRESS
) != 0);
561 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_TXRESET
);
562 while((unit
->LEWordIn(unit
->card
, EL3REG_STATUS
) &
563 EL3REG_STATUSF_CMDINPROGRESS
) != 0);
565 /* Select IO addresses and interrupt for PCCard */
567 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 0);
568 if(unit
->bus
== PCCARD_BUS
)
569 unit
->LEWordOut(unit
->card
, EL3REG_RESCONFIG
, 0x3f00);
570 if(unit
->bus
== ISA_BUS
)
571 unit
->LEWordOut(unit
->card
, EL3REG_RESCONFIG
, (10 << 12) | 0xf00);
573 /* Fully enable an ISA card */
575 if(unit
->bus
== ISA_BUS
)
576 unit
->LEWordOut(unit
->card
, EL3REG_CONFIG
, EL3REG_CONFIGF_ENABLE
);
578 /* Get card capabilities */
580 unit
->capabilities
= ReadEEPROM(unit
, EL3ROM_CAPABILITIES
, base
);
582 /* Get default MAC address */
584 p
= unit
->default_address
;
586 for(i
= 0; i
< ETH_ADDRESSSIZE
/ 2; i
++)
588 address_part
= ReadEEPROM(unit
, EL3ROM_ALTADDRESS0
+ i
, base
);
589 *p
++ = address_part
>> 8;
590 *p
++ = address_part
& 0xff;
593 /* Get available transceivers */
595 if(unit
->bus
== PCCARD_BUS
|| unit
->bus
== ISA_BUS
)
597 config
= unit
->LEWordIn(unit
->card
, EL3REG_CONFIG
);
598 ports
= (config
>> 8) &
599 (EL3REG_MEDIAOPTIONSF_AUI
| EL3REG_MEDIAOPTIONSF_10BASE2
);
600 if((config
& EL3REG_CONFIGF_10BASET
) != 0)
601 ports
|= EL3REG_MEDIAOPTIONSF_10BASET
;
605 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 3);
606 ports
= unit
->LEWordIn(unit
->card
, EL3REG_MEDIAOPTIONS
);
609 ports
= EL3REG_MEDIAOPTIONSF_MII
; /* fix for 3c916? */
613 /* Get transceiver choice from EEPROM */
615 if(unit
->bus
== PCI_BUS
)
617 config
= unit
->LELongIn(unit
->card
, EL3REG_INTERNALCONFIG
);
619 (config
& EL3REG_INTERNALCONFIGF_XCVR
)
620 >> EL3REG_INTERNALCONFIGB_XCVR
;
621 autoselect
= (config
& EL3REG_INTERNALCONFIGF_AUTOXCVR
) != 0;
625 config
= ReadEEPROM(unit
, EL3ROM_ADDRCONFIG
, base
);
627 (config
& EL3REG_ADDRCONFIGF_XCVR
) >> EL3REG_ADDRCONFIGB_XCVR
;
628 autoselect
= (config
& EL3REG_ADDRCONFIGF_AUTOSELECT
) != 0;
633 /* Check if chosen medium is available */
635 new_ports
= ports
& port_masks
[transceiver
];
642 /* Auto-select media type */
646 /* Get transceivers with an active link */
648 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 4);
650 if(unit
->generation
< CYCLONE_GEN
)
654 (EL3REG_MEDIAOPTIONSF_10BASET
| EL3REG_MEDIAOPTIONSF_100BASETX
);
657 SelectMedium(unit
, EL3XCVR_10BASET
, base
);
658 media_status
= unit
->LEWordIn(unit
->card
, EL3REG_MEDIA
);
659 if((media_status
& EL3REG_MEDIAF_BEAT
) != 0)
664 if((ports
& EL3REG_MEDIAOPTIONSF_MII
) != 0
665 || unit
->generation
>= CYCLONE_GEN
)
667 for(i
= 0; i
< 32; i
++)
669 if(ReadMII(unit
, i
, MII_STATUS
, &status
, base
))
671 ReadMII(unit
, i
, MII_STATUS
, &status
, base
);
672 /* Yes, status reg must be read twice */
673 if((status
& MII_STATUSF_LINK
) != 0)
675 if(i
== 24) /* Built-in transceiver */
677 if(((status
& MII_STATUSF_AUTONEGDONE
) != 0)
678 && ((status
& MII_STATUSF_EXTREGSET
) != 0))
680 ReadMII(unit
, i
, MII_AUTONEGADVERT
, &advert
, base
);
681 ReadMII(unit
, i
, MII_AUTONEGABILITY
, &ability
,
683 modes
= advert
& ability
;
685 if((modes
& MII_AUTONEGF_100BASETX
) != 0)
686 links
|= EL3REG_MEDIAOPTIONSF_100BASETX
;
688 if((modes
& MII_AUTONEGF_100BASET4
) != 0)
689 links
|= EL3REG_MEDIAOPTIONSF_100BASET4
;
691 if((modes
& MII_AUTONEGF_10BASET
) != 0)
692 links
|= EL3REG_MEDIAOPTIONSF_10BASET
;
696 modes
= MII_AUTONEGF_10BASET
;
697 links
|= EL3REG_MEDIAOPTIONSF_10BASET
;
699 unit
->autoneg_modes
= modes
;
703 links
|= EL3REG_MEDIAOPTIONSF_MII
;
704 unit
->mii_phy_no
= i
;
712 if((ports
& EL3REG_MEDIAOPTIONSF_10BASE2
) != 0)
714 SelectMedium(unit
, EL3XCVR_10BASE2
, base
);
715 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_STARTCOAX
);
717 if(LoopbackTest(base
))
718 links
|= EL3REG_MEDIAOPTIONSF_10BASE2
;
720 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_STOPCOAX
);
724 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 0);
726 new_ports
= ports
& links
;
731 /* Prioritised choice from remaining transceivers */
733 for(i
= 0; i
< PORT_COUNT
; i
++)
735 transceiver
= port_choices
[i
];
736 if((ports
& port_masks
[transceiver
]) != 0)
738 unit
->transceiver
= transceiver
;
743 /* Find out whether to use full duplex */
745 if((transceiver
== EL3XCVR_10BASET
|| transceiver
== EL3XCVR_100BASETX
)
746 && unit
->generation
>= CYCLONE_GEN
)
748 modes
= unit
->autoneg_modes
;
751 (modes
& MII_AUTONEGF_100BASETXFD
) != 0
757 MII_AUTONEGF_100BASETX
759 MII_AUTONEGF_10BASETFD
763 MII_AUTONEGF_10BASETFD
765 unit
->flags
|= UNITF_FULLDUPLEX
;
775 /****i* etherlink3.device/ConfigureAdapter *********************************
778 * ConfigureAdapter -- .
781 * ConfigureAdapter(unit)
783 * VOID ConfigureAdapter(struct DevUnit *);
801 ****************************************************************************
805 VOID
ConfigureAdapter(struct DevUnit
*unit
, struct DevBase
*base
)
809 /* Set MAC address */
811 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 2);
813 for(i
= 0; i
< ETH_ADDRESSSIZE
; i
++)
814 unit
->ByteOut(unit
->card
, EL3REG_ADDRESS0
+ i
, unit
->address
[i
]);
816 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
818 for(i
= 0; i
< ETH_ADDRESSSIZE
; i
++)
819 unit
->ByteOut(unit
->card
, EL3REG_MASK0
+ i
, 0);
822 /* Enable wider statistics counters */
824 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 4);
825 if(unit
->generation
>= BOOMERANG_GEN
)
826 unit
->LEWordOut(unit
->card
, EL3REG_NETDIAG
,
827 EL3REG_NETDIAGF_WIDESTATS
);
829 /* Decide on promiscuous mode */
831 if((unit
->flags
& UNITF_PROM
) != 0)
832 unit
->rx_filter_cmd
|= EL3CMD_SETRXFILTERF_PROM
;
834 /* Select chosen transceiver */
836 SelectMedium(unit
, unit
->transceiver
, base
);
840 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
841 unit
->LELongOut(unit
->card
, EL3REG_UPLIST
, (ULONG
)(UPINT
)unit
->upds
);
842 GoOnline(unit
, base
);
851 /****i* etherlink3.device/SelectMedium *************************************
857 * SelectMedium(unit, transceiver)
859 * VOID SelectMedium(struct DevUnit *, UWORD);
878 ****************************************************************************
882 VOID
SelectMedium(struct DevUnit
*unit
, UWORD transceiver
,
883 struct DevBase
*base
)
888 if((transceiver
== EL3XCVR_10BASET
|| transceiver
== EL3XCVR_100BASETX
)
889 && unit
->generation
>= CYCLONE_GEN
)
890 transceiver
= EL3XCVR_AUTONEG
;
892 /* Select transceiver */
895 unit
->LEWordIn(unit
->card
, EL3REG_STATUS
) >> EL3REG_STATUSB_WINDOW
;
896 if(unit
->bus
== PCI_BUS
)
898 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 3);
899 config
= unit
->LELongIn(unit
->card
, EL3REG_INTERNALCONFIG
);
900 config
&= ~EL3REG_INTERNALCONFIGF_XCVR
;
901 config
|= transceiver
<< EL3REG_INTERNALCONFIGB_XCVR
;
902 unit
->LELongOut(unit
->card
, EL3REG_INTERNALCONFIG
, config
);
906 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 0);
907 config
= unit
->LEWordIn(unit
->card
, EL3REG_ADDRCONFIG
);
908 config
&= ~EL3REG_ADDRCONFIGF_XCVR
;
909 config
|= transceiver
<< EL3REG_ADDRCONFIGB_XCVR
;
910 unit
->LEWordOut(unit
->card
, EL3REG_ADDRCONFIG
, config
);
912 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
913 EL3CMD_SELECTWINDOW
| old_window
);
920 /****i* etherlink3.device/GoOnline *****************************************
928 * VOID GoOnline(struct DevUnit *);
930 ****************************************************************************
934 VOID
GoOnline(struct DevUnit
*unit
, struct DevBase
*base
)
938 /* Choose interrupts */
940 unit
->flags
|= UNITF_ONLINE
;
941 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
942 EL3CMD_SETINTMASK
| unit
->int_mask
);
943 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
944 EL3CMD_SETZEROMASK
| unit
->int_mask
);
946 /* Enable the transceiver */
948 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
949 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_UPUNSTALL
);
951 transceiver
= unit
->transceiver
;
953 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 4);
954 if(transceiver
== EL3XCVR_100BASETX
)
956 unit
->LEWordOut(unit
->card
, EL3REG_MEDIA
, EL3REG_MEDIAF_BEATCHECK
);
958 else if(transceiver
== EL3XCVR_10BASET
)
960 unit
->LEWordOut(unit
->card
, EL3REG_MEDIA
,
961 EL3REG_MEDIAF_BEATCHECK
| EL3REG_MEDIAF_JABBERCHECK
);
963 else if(transceiver
== EL3XCVR_10BASE2
)
964 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_STARTCOAX
| 0);
966 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 3);
967 if((unit
->flags
& UNITF_FULLDUPLEX
) != 0)
968 unit
->LEWordOut(unit
->card
, EL3REG_MACCONTROL
,
969 EL3REG_MACCONTROLF_FULLDUPLEX
);
971 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, unit
->rx_filter_cmd
);
972 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_RXENABLE
);
973 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_TXENABLE
);
974 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 1);
976 /* Enable statistics collection */
978 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_STATSENABLE
);
980 /* Record start time and report Online event */
982 GetSysTime(&unit
->stats
.LastStart
);
983 ReportEvents(unit
, S2EVENT_ONLINE
, base
);
990 /****i* etherlink3.device/GoOffline ****************************************
998 * VOID GoOffline(struct DevUnit *);
1000 ****************************************************************************
1004 VOID
GoOffline(struct DevUnit
*unit
, struct DevBase
*base
)
1006 unit
->flags
&= ~UNITF_ONLINE
;
1008 if((unit
->flags
& UNITF_HAVEADAPTER
) != 0)
1010 /* Stop interrupts */
1012 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SETINTMASK
| 0);
1013 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1014 EL3CMD_ACKINT
| EL3INTF_ANY
);
1016 /* Stop transmission and reception */
1018 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_RXDISABLE
);
1019 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_TXDISABLE
);
1021 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
1023 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_UPSTALL
);
1024 while((unit
->LEWordIn(unit
->card
, EL3REG_STATUS
) &
1025 EL3REG_STATUSF_CMDINPROGRESS
) != 0);
1026 unit
->LELongOut(unit
->card
, EL3REG_UPLIST
, (ULONG
)0);
1027 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_DOWNSTALL
);
1028 while((unit
->LEWordIn(unit
->card
, EL3REG_STATUS
)
1029 & EL3REG_STATUSF_CMDINPROGRESS
) != 0);
1030 unit
->LELongOut(unit
->card
, EL3REG_DOWNLIST
, (ULONG
)0);
1033 /* Turn off media functions */
1035 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 4);
1036 unit
->LEWordOut(unit
->card
, EL3REG_MEDIA
, 0);
1037 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 1);
1039 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_STOPCOAX
| 0);
1042 /* Update then disable statistics */
1044 UpdateStats(unit
, base
);
1045 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_STATSDISABLE
);
1048 /* Flush pending read and write requests */
1050 FlushUnit(unit
, WRITE_QUEUE
, S2ERR_OUTOFSERVICE
, base
);
1052 /* Report Offline event and return */
1054 ReportEvents(unit
, S2EVENT_OFFLINE
, base
);
1060 /****i* etherlink3.device/AddMulticastRange ********************************
1063 * AddMulticastRange -- .
1066 * success = AddMulticastRange(unit, lower_bound, upper_bound)
1068 * BOOL AddMulticastRange(struct DevUnit *, UBYTE *, UBYTE *);
1070 ****************************************************************************
1074 BOOL
AddMulticastRange(struct DevUnit
*unit
, const UBYTE
*lower_bound
,
1075 const UBYTE
*upper_bound
, struct DevBase
*base
)
1077 struct AddressRange
*range
;
1078 ULONG lower_bound_left
, upper_bound_left
;
1079 UWORD lower_bound_right
, upper_bound_right
;
1081 lower_bound_left
= BELong(*((ULONG
*)lower_bound
));
1082 lower_bound_right
= BEWord(*((UWORD
*)(lower_bound
+ 4)));
1083 upper_bound_left
= BELong(*((ULONG
*)upper_bound
));
1084 upper_bound_right
= BEWord(*((UWORD
*)(upper_bound
+ 4)));
1086 range
= FindMulticastRange(unit
, lower_bound_left
, lower_bound_right
,
1087 upper_bound_left
, upper_bound_right
, base
);
1093 range
= AllocMem(sizeof(struct AddressRange
), MEMF_PUBLIC
);
1096 range
->lower_bound_left
= lower_bound_left
;
1097 range
->lower_bound_right
= lower_bound_right
;
1098 range
->upper_bound_left
= upper_bound_left
;
1099 range
->upper_bound_right
= upper_bound_right
;
1100 range
->add_count
= 1;
1103 AddTail((APTR
)&unit
->multicast_ranges
, (APTR
)range
);
1106 if(unit
->range_count
++ == 0)
1108 unit
->rx_filter_cmd
|= EL3CMD_SETRXFILTERF_MCAST
;
1109 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1110 unit
->rx_filter_cmd
);
1115 return range
!= NULL
;
1120 /****i* etherlink3.device/RemMulticastRange ********************************
1123 * RemMulticastRange -- .
1126 * found = RemMulticastRange(unit, lower_bound, upper_bound)
1128 * BOOL RemMulticastRange(struct DevUnit *, UBYTE *, UBYTE *);
1130 ****************************************************************************
1134 BOOL
RemMulticastRange(struct DevUnit
*unit
, const UBYTE
*lower_bound
,
1135 const UBYTE
*upper_bound
, struct DevBase
*base
)
1137 struct AddressRange
*range
;
1138 ULONG lower_bound_left
, upper_bound_left
;
1139 UWORD lower_bound_right
, upper_bound_right
;
1141 lower_bound_left
= BELong(*((ULONG
*)lower_bound
));
1142 lower_bound_right
= BEWord(*((UWORD
*)(lower_bound
+ 4)));
1143 upper_bound_left
= BELong(*((ULONG
*)upper_bound
));
1144 upper_bound_right
= BEWord(*((UWORD
*)(upper_bound
+ 4)));
1146 range
= FindMulticastRange(unit
, lower_bound_left
, lower_bound_right
,
1147 upper_bound_left
, upper_bound_right
, base
);
1151 if(--range
->add_count
== 0)
1154 Remove((APTR
)range
);
1156 FreeMem(range
, sizeof(struct AddressRange
));
1158 if(--unit
->range_count
== 0)
1160 unit
->rx_filter_cmd
&= ~EL3CMD_SETRXFILTERF_MCAST
;
1161 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1162 unit
->rx_filter_cmd
);
1167 return range
!= NULL
;
1172 /****i* etherlink3.device/FindMulticastRange *******************************
1175 * FindMulticastRange -- .
1178 * range = FindMulticastRange(unit, lower_bound_left,
1179 * lower_bound_right, upper_bound_left, upper_bound_right)
1181 * struct AddressRange *FindMulticastRange(struct DevUnit *, ULONG,
1182 * UWORD, ULONG, UWORD);
1184 ****************************************************************************
1188 static struct AddressRange
*FindMulticastRange(struct DevUnit
*unit
,
1189 ULONG lower_bound_left
, UWORD lower_bound_right
, ULONG upper_bound_left
,
1190 UWORD upper_bound_right
, struct DevBase
*base
)
1192 struct AddressRange
*range
, *tail
;
1195 range
= (APTR
)unit
->multicast_ranges
.mlh_Head
;
1196 tail
= (APTR
)&unit
->multicast_ranges
.mlh_Tail
;
1198 while((range
!= tail
) && !found
)
1200 if((lower_bound_left
== range
->lower_bound_left
) &&
1201 (lower_bound_right
== range
->lower_bound_right
) &&
1202 (upper_bound_left
== range
->upper_bound_left
) &&
1203 (upper_bound_right
== range
->upper_bound_right
))
1206 range
= (APTR
)range
->node
.mln_Succ
;
1217 /****i* etherlink3.device/FindTypeStats ************************************
1220 * FindTypeStats -- .
1223 * stats = FindTypeStats(unit, list,
1226 * struct TypeStats *FindTypeStats(struct DevUnit *, struct MinList *,
1229 ****************************************************************************
1233 struct TypeStats
*FindTypeStats(struct DevUnit
*unit
, struct MinList
*list
,
1234 ULONG packet_type
, struct DevBase
*base
)
1236 struct TypeStats
*stats
, *tail
;
1239 stats
= (APTR
)list
->mlh_Head
;
1240 tail
= (APTR
)&list
->mlh_Tail
;
1242 while(stats
!= tail
&& !found
)
1244 if(stats
->packet_type
== packet_type
)
1247 stats
= (APTR
)stats
->node
.mln_Succ
;
1258 /****i* etherlink3.device/FlushUnit ****************************************
1264 * FlushUnit(unit, last_queue, error)
1266 * VOID FlushUnit(struct DevUnit *, UBYTE, BYTE);
1268 ****************************************************************************
1270 * Includes alternative implementations because of ambiguities in SANA-II
1275 VOID
FlushUnit(struct DevUnit
*unit
, UBYTE last_queue
, BYTE error
,
1276 struct DevBase
*base
)
1278 struct IORequest
*request
;
1280 struct Opener
*opener
, *tail
;
1282 /* Abort queued requests */
1284 for(i
= 0; i
<= last_queue
; i
++)
1286 while((request
= (APTR
)GetMsg(unit
->request_ports
[i
])) != NULL
)
1288 request
->io_Error
= IOERR_ABORTED
;
1289 ReplyMsg((APTR
)request
);
1294 opener
= (APTR
)unit
->openers
.mlh_Head
;
1295 tail
= (APTR
)&unit
->openers
.mlh_Tail
;
1297 /* Flush every opener's read queue */
1299 while(opener
!= tail
)
1301 while((request
= (APTR
)GetMsg(&opener
->read_port
)) != NULL
)
1303 request
->io_Error
= error
;
1304 ReplyMsg((APTR
)request
);
1306 opener
= (APTR
)opener
->node
.mln_Succ
;
1310 opener
= request
->ios2_BufferManagement
;
1311 while((request
= (APTR
)GetMsg(&opener
->read_port
)) != NULL
)
1313 request
->io_Error
= IOERR_ABORTED
;
1314 ReplyMsg((APTR
)request
);
1325 /****i* etherlink3.device/StatusInt ****************************************
1331 * finished = StatusInt(unit, int_code)
1333 * BOOL StatusInt(struct DevUnit *, APTR);
1335 ****************************************************************************
1337 * int_code is really in A5, but GCC 2.95.3 doesn't seem able to handle that.
1338 * Since we don't use this parameter, we can lie.
1342 BOOL
StatusInt(REG(a1
, struct DevUnit
*unit
), REG(a6
, APTR int_code
))
1344 struct DevBase
*base
;
1347 base
= unit
->device
;
1348 ints
= unit
->LEWordIn(unit
->card
, EL3REG_STATUS
);
1350 if((ints
& EL3INTF_ANY
) != 0)
1352 /* Handle interrupts */
1354 if((ints
& EL3INTF_UPDONE
) != 0)
1356 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1357 EL3CMD_ACKINT
| EL3INTF_UPDONE
);
1358 Cause(&unit
->rx_int
);
1360 if((ints
& EL3INTF_DOWNDONE
) != 0)
1362 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1363 EL3CMD_ACKINT
| EL3INTF_DOWNDONE
);
1364 Cause(&unit
->tx_end_int
);
1366 if((ints
& EL3INTF_UPDATESTATS
) != 0)
1367 UpdateStats(unit
, base
);
1368 if((ints
& EL3INTF_RXCOMPLETE
) != 0)
1371 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1372 EL3CMD_SETINTMASK
| (unit
->int_mask
& ~EL3INTF_RXCOMPLETE
));
1374 Cause(&unit
->rx_int
);
1376 if((ints
& EL3INTF_TXAVAIL
) != 0)
1378 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1379 EL3CMD_ACKINT
| EL3INTF_TXAVAIL
);
1380 Cause(&unit
->tx_int
);
1382 if((ints
& EL3INTF_TXCOMPLETE
) != 0)
1383 TxError(unit
, base
);
1385 /* Acknowledge interrupt request */
1387 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1388 EL3CMD_ACKINT
| EL3INTF_ANY
);
1396 /****i* etherlink3.device/RXInt ********************************************
1402 * RXInt(unit, int_code)
1404 * VOID RXInt(struct DevUnit *, APTR);
1406 ****************************************************************************
1410 static VOID
RXInt(REG(a1
, struct DevUnit
*unit
), REG(a5
, APTR int_code
))
1412 UWORD rx_status
, packet_size
;
1413 struct DevBase
*base
;
1414 BOOL is_orphan
, accepted
;
1417 struct IOSana2Req
*request
, *request_tail
;
1418 struct Opener
*opener
, *opener_tail
;
1419 struct TypeStats
*tracker
;
1421 base
= unit
->device
;
1422 buffer
= unit
->rx_buffer
;
1424 while(((rx_status
= unit
->LEWordIn(unit
->card
, EL3REG_RXSTATUS
))
1425 & EL3REG_RXSTATUSF_INCOMPLETE
) == 0)
1427 if((rx_status
& EL3REG_RXSTATUSF_ERROR
) == 0)
1429 /* Read packet header */
1432 packet_size
= rx_status
& EL3REG_RXSTATUS_SIZEMASK
;
1433 unit
->LongsIn(unit
->card
, EL3REG_DATA0
, (ULONG
*)buffer
,
1434 ETH_HEADERSIZE
+ 3 >> 2);
1436 if(AddressFilter(unit
, buffer
+ ETH_PACKET_DEST
, base
))
1438 packet_type
= BEWord(*((UWORD
*)(buffer
+ ETH_PACKET_TYPE
)));
1440 opener
= (APTR
)unit
->openers
.mlh_Head
;
1441 opener_tail
= (APTR
)&unit
->openers
.mlh_Tail
;
1443 /* Offer packet to every opener */
1445 while(opener
!= opener_tail
)
1447 request
= (APTR
)opener
->read_port
.mp_MsgList
.lh_Head
;
1448 request_tail
= (APTR
)&opener
->read_port
.mp_MsgList
.lh_Tail
;
1451 /* Offer packet to each request until it's accepted */
1453 while((request
!= request_tail
) && !accepted
)
1455 if(request
->ios2_PacketType
== packet_type
1456 || request
->ios2_PacketType
<= ETH_MTU
1457 && packet_type
<= ETH_MTU
)
1459 CopyPacket(unit
, request
, packet_size
, packet_type
,
1460 buffer
, !is_orphan
, base
);
1464 (APTR
)request
->ios2_Req
.io_Message
.mn_Node
.ln_Succ
;
1469 opener
= (APTR
)opener
->node
.mln_Succ
;
1472 /* If packet was unwanted, give it to S2_READORPHAN request */
1476 unit
->stats
.UnknownTypesReceived
++;
1477 if(!IsMsgPortEmpty(unit
->request_ports
[ADOPT_QUEUE
]))
1480 (APTR
)unit
->request_ports
[ADOPT_QUEUE
]->
1481 mp_MsgList
.lh_Head
, packet_size
, packet_type
, buffer
,
1486 /* Update remaining statistics */
1489 FindTypeStats(unit
, &unit
->type_trackers
, packet_type
, base
);
1492 tracker
->stats
.PacketsReceived
++;
1493 tracker
->stats
.BytesReceived
+= packet_size
;
1499 unit
->stats
.BadData
++;
1500 ReportEvents(unit
, S2EVENT_ERROR
| S2EVENT_HARDWARE
| S2EVENT_RX
,
1504 /* Discard packet */
1506 Disable(); /* Needed? */
1507 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_RXDISCARD
);
1508 while((unit
->LEWordIn(unit
->card
, EL3REG_STATUS
) &
1509 EL3REG_STATUSF_CMDINPROGRESS
) != 0);
1515 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1516 EL3CMD_SETINTMASK
| unit
->int_mask
);
1522 /****i* etherlink3.device/CopyPacket ***************************************
1528 * CopyPacket(unit, request, packet_size, packet_type,
1531 * VOID CopyPacket(struct DevUnit *, struct IOSana2Req *, UWORD, UWORD,
1534 ****************************************************************************
1538 static VOID
CopyPacket(struct DevUnit
*unit
, struct IOSana2Req
*request
,
1539 UWORD packet_size
, UWORD packet_type
, UBYTE
*buffer
, BOOL all_read
,
1540 struct DevBase
*base
)
1542 struct Opener
*opener
;
1543 BOOL filtered
= FALSE
;
1545 /* Set multicast and broadcast flags */
1547 request
->ios2_Req
.io_Flags
&= ~(SANA2IOF_BCAST
| SANA2IOF_MCAST
);
1548 if((*((ULONG
*)(buffer
+ ETH_PACKET_DEST
)) == 0xffffffff) &&
1549 (*((UWORD
*)(buffer
+ ETH_PACKET_DEST
+ 4)) == 0xffff))
1550 request
->ios2_Req
.io_Flags
|= SANA2IOF_BCAST
;
1551 else if((buffer
[ETH_PACKET_DEST
] & 0x1) != 0)
1552 request
->ios2_Req
.io_Flags
|= SANA2IOF_MCAST
;
1554 /* Set source and destination addresses and packet type */
1556 CopyMem(buffer
+ ETH_PACKET_SOURCE
, request
->ios2_SrcAddr
,
1558 CopyMem(buffer
+ ETH_PACKET_DEST
, request
->ios2_DstAddr
,
1560 request
->ios2_PacketType
= packet_type
;
1562 /* Read rest of packet (PIO mode only) */
1566 unit
->LongsIn(unit
->card
, EL3REG_DATA0
,
1567 (ULONG
*)(buffer
+ ((ETH_PACKET_DATA
+ 3) & ~0x3)),
1568 (packet_size
- ETH_PACKET_DATA
+ 1) >> 2);
1571 /* Adjust for cooked packet request */
1573 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
1575 packet_size
-= ETH_PACKET_DATA
;
1576 buffer
+= ETH_PACKET_DATA
;
1580 packet_size
+= 4; /* Needed for Shapeshifter & Fusion */
1582 request
->ios2_DataLength
= packet_size
;
1586 opener
= request
->ios2_BufferManagement
;
1587 if((request
->ios2_Req
.io_Command
== CMD_READ
) &&
1588 (opener
->filter_hook
!= NULL
))
1589 if(!CallHookPkt(opener
->filter_hook
, request
, buffer
))
1594 /* Copy packet into opener's buffer and reply packet */
1596 if(!opener
->rx_function(request
->ios2_Data
, buffer
, packet_size
))
1598 request
->ios2_Req
.io_Error
= S2ERR_NO_RESOURCES
;
1599 request
->ios2_WireError
= S2WERR_BUFF_ERROR
;
1601 S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
| S2EVENT_RX
,
1604 Remove((APTR
)request
);
1605 ReplyMsg((APTR
)request
);
1613 /****i* etherlink3.device/AddressFilter ************************************
1619 * accept = AddressFilter(unit, address)
1621 * BOOL AddressFilter(struct DevUnit *, UBYTE *);
1623 ****************************************************************************
1627 static BOOL
AddressFilter(struct DevUnit
*unit
, UBYTE
*address
,
1628 struct DevBase
*base
)
1630 struct AddressRange
*range
, *tail
;
1633 UWORD address_right
;
1635 /* Check whether address is unicast/broadcast or multicast */
1637 address_left
= BELong(*((ULONG
*)address
));
1638 address_right
= BEWord(*((UWORD
*)(address
+ 4)));
1640 if((address_left
& 0x01000000) != 0 &&
1641 !(address_left
== 0xffffffff && address_right
== 0xffff))
1643 /* Check if this multicast address is wanted */
1645 range
= (APTR
)unit
->multicast_ranges
.mlh_Head
;
1646 tail
= (APTR
)&unit
->multicast_ranges
.mlh_Tail
;
1649 while((range
!= tail
) && !accept
)
1651 if((address_left
> range
->lower_bound_left
||
1652 address_left
== range
->lower_bound_left
&&
1653 address_right
>= range
->lower_bound_right
) &&
1654 (address_left
< range
->upper_bound_left
||
1655 address_left
== range
->upper_bound_left
&&
1656 address_right
<= range
->upper_bound_right
))
1658 range
= (APTR
)range
->node
.mln_Succ
;
1662 unit
->special_stats
[S2SS_ETHERNET_BADMULTICAST
& 0xffff]++;
1670 /****i* etherlink3.device/TXInt ********************************************
1678 * VOID TXInt(struct DevUnit *);
1680 ****************************************************************************
1684 static VOID
TXInt(REG(a1
, struct DevUnit
*unit
), REG(a5
, APTR int_code
))
1686 UWORD packet_size
, data_size
, send_size
;
1687 struct DevBase
*base
;
1688 struct IOSana2Req
*request
;
1689 BOOL proceed
= TRUE
;
1690 struct Opener
*opener
;
1691 ULONG
*buffer
, wire_error
;
1692 UBYTE
*(*dma_tx_function
)(REG(a0
, APTR
));
1694 struct MsgPort
*port
;
1695 struct TypeStats
*tracker
;
1697 base
= unit
->device
;
1698 port
= unit
->request_ports
[WRITE_QUEUE
];
1700 while(proceed
&& (!IsMsgPortEmpty(port
)))
1704 request
= (APTR
)port
->mp_MsgList
.lh_Head
;
1705 data_size
= packet_size
= request
->ios2_DataLength
;
1707 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
1708 packet_size
+= ETH_PACKET_DATA
;
1710 if(unit
->LEWordIn(unit
->card
, EL3REG_TXSPACE
)
1711 > EL3_PREAMBLESIZE
+ packet_size
)
1713 /* Write packet preamble */
1715 unit
->LELongOut(unit
->card
, EL3REG_DATA0
, packet_size
);
1717 /* Write packet header */
1719 send_size
= (packet_size
+ 3) & ~0x3;
1720 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
1726 memcpy(&header
.bytes
[0], request
->ios2_DstAddr
, 6);
1727 memcpy(&header
.bytes
[6], unit
->address
, 6);
1728 unit
->LongOut(unit
->card
, EL3REG_DATA0
, header
.ulong
[0]);
1729 unit
->LongOut(unit
->card
, EL3REG_DATA0
, header
.ulong
[1]);
1730 unit
->LongOut(unit
->card
, EL3REG_DATA0
, header
.ulong
[2]);
1731 unit
->BEWordOut(unit
->card
, EL3REG_DATA0
,
1732 request
->ios2_PacketType
);
1733 send_size
-= ETH_HEADERSIZE
;
1736 /* Get packet data */
1738 opener
= (APTR
)request
->ios2_BufferManagement
;
1739 dma_tx_function
= opener
->dma_tx_function
;
1740 if(dma_tx_function
!= NULL
)
1741 buffer
= (ULONG
*)dma_tx_function(request
->ios2_Data
);
1747 buffer
= (ULONG
*)unit
->tx_buffer
;
1748 if(!opener
->tx_function(buffer
, request
->ios2_Data
, data_size
))
1750 error
= S2ERR_NO_RESOURCES
;
1751 wire_error
= S2WERR_BUFF_ERROR
;
1753 S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
1754 | S2EVENT_TX
, base
);
1758 /* Write packet data */
1762 unit
->LongsOut(unit
->card
, EL3REG_DATA0
, buffer
,
1764 buffer
+= (send_size
>> 2);
1765 if((send_size
& 0x3) != 0)
1766 unit
->WordOut(unit
->card
, EL3REG_DATA0
, *((UWORD
*)buffer
));
1771 request
->ios2_Req
.io_Error
= error
;
1772 request
->ios2_WireError
= wire_error
;
1773 Remove((APTR
)request
);
1774 ReplyMsg((APTR
)request
);
1776 /* Update statistics */
1780 tracker
= FindTypeStats(unit
, &unit
->type_trackers
,
1781 request
->ios2_PacketType
, base
);
1784 tracker
->stats
.PacketsSent
++;
1785 tracker
->stats
.BytesSent
+= packet_size
;
1794 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_SOFTINT
;
1797 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SETTXTHRESH
1798 | ((EL3_PREAMBLESIZE
+ packet_size
) >> unit
->size_shift
));
1799 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_IGNORE
;
1807 /****i* etherlink3.device/TxError ******************************************
1815 * VOID TxError(struct DevUnit *);
1817 ****************************************************************************
1821 static VOID
TxError(struct DevUnit
*unit
, struct DevBase
*base
)
1823 UPINT window1_offset
;
1824 UBYTE tx_status
, flags
= 0;
1826 window1_offset
= unit
->window1_offset
;
1828 /* Gather all errors */
1831 unit
->ByteIn(unit
->card
, window1_offset
+ EL3REG_TXSTATUS
))
1832 & EL3REG_TXSTATUSF_COMPLETE
) != 0)
1835 unit
->ByteOut(unit
->card
, window1_offset
+ EL3REG_TXSTATUS
, 0);
1838 /* Restart transmitter if necessary */
1840 if((flags
& EL3REG_TXSTATUSF_JABBER
) != 0)
1843 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_TXRESET
);
1844 while((unit
->LEWordIn(unit
->card
, EL3REG_STATUS
) &
1845 EL3REG_STATUSF_CMDINPROGRESS
) != 0);
1849 if((flags
& (EL3REG_TXSTATUSF_JABBER
| EL3REG_TXSTATUSF_OVERFLOW
1850 | EL3REG_TXSTATUSF_RECLAIMERROR
)) != 0)
1851 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_TXENABLE
);
1853 /* Report the error(s) */
1855 ReportEvents(unit
, S2EVENT_ERROR
| S2EVENT_HARDWARE
| S2EVENT_TX
, base
);
1862 /****i* etherlink3.device/UpdateStats **************************************
1870 * VOID UpdateStats(struct DevUnit *);
1872 ****************************************************************************
1876 VOID
UpdateStats(struct DevUnit
*unit
, struct DevBase
*base
)
1878 UBYTE frame_counts_upper
;
1879 UWORD generation
, old_window
;
1881 generation
= unit
->generation
;
1884 unit
->LEWordIn(unit
->card
, EL3REG_STATUS
) >> EL3REG_STATUSB_WINDOW
;
1885 if(generation
< VORTEX_GEN
)
1886 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_STATSDISABLE
);
1888 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 6);
1889 unit
->ByteIn(unit
->card
, EL3REG_CARRIERLOST
);
1890 unit
->ByteIn(unit
->card
, EL3REG_SQEERRORS
);
1891 unit
->ByteIn(unit
->card
, EL3REG_MULTIPLECOLLISIONS
);
1892 unit
->ByteIn(unit
->card
, EL3REG_SINGLECOLLISIONS
);
1893 unit
->ByteIn(unit
->card
, EL3REG_LATECOLLISIONS
);
1894 unit
->stats
.Overruns
+= unit
->ByteIn(unit
->card
, EL3REG_RXOVERRUNS
);
1895 unit
->stats
.PacketsSent
+= unit
->ByteIn(unit
->card
, EL3REG_TXFRAMESOK
);
1896 unit
->stats
.PacketsReceived
+=
1897 unit
->ByteIn(unit
->card
, EL3REG_RXFRAMESOK
);
1898 unit
->special_stats
[S2SS_ETHERNET_RETRIES
& 0xffff] +=
1899 unit
->ByteIn(unit
->card
, EL3REG_FRAMESDEFERRED
);
1900 unit
->LEWordIn(unit
->card
, EL3REG_RXBYTESOK
);
1901 unit
->LEWordIn(unit
->card
, EL3REG_TXBYTESOK
);
1902 if(generation
>= VORTEX_GEN
)
1904 frame_counts_upper
= unit
->ByteIn(unit
->card
, EL3REG_FRAMESOKUPPER
);
1905 unit
->stats
.PacketsReceived
+= (frame_counts_upper
& 0x3) << 8;
1906 unit
->stats
.PacketsSent
+= (frame_counts_upper
& 0x30) << 4;
1907 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 4);
1908 unit
->ByteIn(unit
->card
, EL3REG_BADSSD
);
1909 if(generation
>= BOOMERANG_GEN
)
1910 unit
->ByteIn(unit
->card
, EL3REG_BYTESOKUPPER
);
1913 if(generation
< VORTEX_GEN
)
1914 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_STATSENABLE
);
1915 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1916 EL3CMD_SELECTWINDOW
| old_window
);
1922 /****i* etherlink3.device/DMARXInt *****************************************
1928 * DMARXInt(unit, int_code)
1930 * VOID DMARXInt(struct DevUnit *, APTR);
1932 ****************************************************************************
1936 static VOID
DMARXInt(REG(a1
, struct DevUnit
*unit
),
1937 REG(a5
, APTR int_code
))
1940 struct DevBase
*base
;
1941 BOOL is_orphan
, accepted
;
1942 ULONG rx_status
, packet_type
, *upd
, *fragment
, dma_size
;
1944 struct IOSana2Req
*request
, *request_tail
;
1945 struct Opener
*opener
, *opener_tail
;
1946 struct TypeStats
*tracker
;
1948 base
= unit
->device
;
1949 upd
= unit
->next_upd
;
1951 dma_size
= UPD_SIZE
* RX_SLOT_COUNT
;
1952 CachePostDMA(unit
->upds
, &dma_size
, 0);
1954 while(((rx_status
= LELong(upd
[EL3UPD_STATUS
]))
1955 & EL3UPD_STATUSF_COMPLETE
) != 0)
1957 fragment
= upd
+ EL3UPD_FIRSTFRAG
;
1958 buffer
= (UBYTE
*)(UPINT
)LELong(fragment
[EL3FRAG_ADDR
]);
1960 dma_size
= ETH_MAXPACKETSIZE
;
1961 CachePostDMA(buffer
, &dma_size
, 0);
1963 if((rx_status
& EL3UPD_STATUSF_ERROR
) == 0)
1966 packet_size
= rx_status
& EL3UPD_STATUSF_SIZE
;
1968 if(AddressFilter(unit
, buffer
+ ETH_PACKET_DEST
, base
))
1970 packet_type
= BEWord(*((UWORD
*)(buffer
+ ETH_PACKET_TYPE
)));
1972 opener
= (APTR
)unit
->openers
.mlh_Head
;
1973 opener_tail
= (APTR
)&unit
->openers
.mlh_Tail
;
1975 /* Offer packet to every opener */
1977 while(opener
!= opener_tail
)
1979 request
= (APTR
)opener
->read_port
.mp_MsgList
.lh_Head
;
1980 request_tail
= (APTR
)&opener
->read_port
.mp_MsgList
.lh_Tail
;
1983 /* Offer packet to each request until it's accepted */
1985 while((request
!= request_tail
) && !accepted
)
1987 if(request
->ios2_PacketType
== packet_type
1988 || request
->ios2_PacketType
<= ETH_MTU
1989 && packet_type
<= ETH_MTU
)
1991 CopyPacket(unit
, request
, packet_size
, packet_type
,
1992 buffer
, TRUE
, base
);
1996 (APTR
)request
->ios2_Req
.io_Message
.mn_Node
.ln_Succ
;
2001 opener
= (APTR
)opener
->node
.mln_Succ
;
2004 /* If packet was unwanted, give it to S2_READORPHAN request */
2008 unit
->stats
.UnknownTypesReceived
++;
2009 if(!IsMsgPortEmpty(unit
->request_ports
[ADOPT_QUEUE
]))
2012 (APTR
)unit
->request_ports
[ADOPT_QUEUE
]->
2013 mp_MsgList
.lh_Head
, packet_size
, packet_type
, buffer
,
2018 /* Update remaining statistics */
2021 FindTypeStats(unit
, &unit
->type_trackers
, packet_type
, base
);
2024 tracker
->stats
.PacketsReceived
++;
2025 tracker
->stats
.BytesReceived
+= packet_size
;
2031 unit
->stats
.BadData
++;
2032 ReportEvents(unit
, S2EVENT_ERROR
| S2EVENT_HARDWARE
| S2EVENT_RX
,
2036 upd
[EL3UPD_STATUS
] = 0;
2038 dma_size
= ETH_MAXPACKETSIZE
;
2039 CachePreDMA(buffer
, &dma_size
, 0);
2041 upd
= (ULONG
*)(UPINT
)LELong(upd
[EL3UPD_NEXT
]);
2044 dma_size
= UPD_SIZE
* RX_SLOT_COUNT
;
2045 CachePreDMA(unit
->upds
, &dma_size
, 0);
2049 unit
->next_upd
= upd
;
2050 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_UPUNSTALL
);
2052 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
2053 EL3CMD_SETINTMASK
| unit
->int_mask
);
2060 /****i* etherlink3.device/DMATXInt *****************************************
2066 * DMATXInt(unit, int_code)
2068 * VOID DMATXInt(struct DevUnit *, APTR);
2070 ****************************************************************************
2074 static VOID
DMATXInt(REG(a1
, struct DevUnit
*unit
),
2075 REG(a5
, APTR int_code
))
2077 UWORD packet_size
, data_size
, slot
, new_slot
, *p
, *q
, i
;
2078 struct DevBase
*base
;
2079 struct IOSana2Req
*request
;
2080 BOOL proceed
= TRUE
;
2081 struct Opener
*opener
;
2082 ULONG wire_error
, *dpd
, *last_dpd
, *next_dpd
, *fragment
, dma_size
;
2083 UBYTE
*(*dma_tx_function
)(REG(a0
, APTR
));
2086 struct MsgPort
*port
;
2088 base
= unit
->device
;
2089 port
= unit
->request_ports
[WRITE_QUEUE
];
2091 while(proceed
&& (!IsMsgPortEmpty(port
)))
2093 slot
= unit
->tx_in_slot
;
2094 new_slot
= (slot
+ 1) % TX_SLOT_COUNT
;
2096 if(new_slot
!= unit
->tx_out_slot
2097 && (unit
->flags
& UNITF_TXBUFFERINUSE
) == 0)
2101 request
= (APTR
)port
->mp_MsgList
.lh_Head
;
2102 data_size
= packet_size
= request
->ios2_DataLength
;
2104 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
2105 packet_size
+= ETH_HEADERSIZE
;
2106 dpd
= unit
->dpds
+ ((DPD_SIZE
/ sizeof(ULONG
)) * slot
);
2108 /* Write packet preamble */
2110 Remove((APTR
)request
);
2111 unit
->tx_requests
[slot
] = request
;
2112 dpd
[EL3DPD_NEXT
] = (ULONG
)0;
2113 dpd
[EL3DPD_HEADER
] =
2114 MakeLELong(EL3DPD_HEADERF_DLINT
| packet_size
);
2115 fragment
= dpd
+ EL3DPD_FIRSTFRAG
;
2117 /* Write packet header */
2119 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
2121 buffer
= unit
->headers
+ ETH_HEADERSIZE
* slot
;
2122 fragment
[EL3FRAG_ADDR
] = MakeLELong((ULONG
)(UPINT
)buffer
);
2123 fragment
[EL3FRAG_LEN
] = MakeLELong(ETH_HEADERSIZE
);
2125 p
= (UWORD
*)buffer
;
2126 for(i
= 0, q
= (UWORD
*)request
->ios2_DstAddr
;
2127 i
< ETH_ADDRESSSIZE
/ 2; i
++)
2129 for(i
= 0, q
= (UWORD
*)unit
->address
;
2130 i
< ETH_ADDRESSSIZE
/ 2; i
++)
2132 *p
++ = MakeBEWord(request
->ios2_PacketType
);
2133 buffer
= (UBYTE
*)p
;
2135 dma_size
= ETH_HEADERSIZE
;
2136 CachePreDMA(buffer
, &dma_size
, DMA_ReadFromRAM
);
2137 fragment
+= EL3_FRAGLEN
;
2140 /* Get packet data */
2142 opener
= (APTR
)request
->ios2_BufferManagement
;
2143 dma_tx_function
= opener
->dma_tx_function
;
2144 if(dma_tx_function
!= NULL
)
2145 buffer
= dma_tx_function(request
->ios2_Data
);
2151 buffer
= unit
->tx_buffer
;
2152 if(opener
->tx_function(buffer
, request
->ios2_Data
, data_size
))
2153 unit
->flags
|= UNITF_TXBUFFERINUSE
;
2156 error
= S2ERR_NO_RESOURCES
;
2157 wire_error
= S2WERR_BUFF_ERROR
;
2159 S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
2160 | S2EVENT_TX
, base
);
2164 /* Fill in rest of descriptor for packet transmission */
2168 fragment
[EL3FRAG_ADDR
] = MakeLELong((ULONG
)(UPINT
)buffer
);
2169 fragment
[EL3FRAG_LEN
] =
2170 MakeLELong(EL3FRAG_LENF_LAST
| data_size
);
2172 /* Pass packet to adapter */
2174 dma_size
= data_size
;
2175 CachePreDMA(buffer
, &dma_size
, DMA_ReadFromRAM
);
2177 last_dpd
= (ULONG
*)(UPINT
)
2178 unit
->LELongIn(unit
->card
, EL3REG_DOWNLIST
);
2179 if(last_dpd
!= NULL
)
2181 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
2183 while((unit
->LEWordIn(unit
->card
, EL3REG_STATUS
)
2184 & EL3REG_STATUSF_CMDINPROGRESS
) != 0);
2186 (ULONG
*)(UPINT
)LELong(last_dpd
[EL3DPD_NEXT
])) != NULL
)
2187 last_dpd
= next_dpd
;
2188 last_dpd
[EL3DPD_NEXT
] = MakeLELong((ULONG
)(UPINT
)dpd
);
2189 dma_size
= DPD_SIZE
* TX_SLOT_COUNT
;
2190 CachePreDMA(unit
->dpds
, &dma_size
, 0);
2191 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
2192 EL3CMD_DOWNUNSTALL
);
2196 dma_size
= DPD_SIZE
* TX_SLOT_COUNT
;
2197 CachePreDMA(unit
->dpds
, &dma_size
, 0);
2198 unit
->LELongOut(unit
->card
, EL3REG_DOWNLIST
,
2202 unit
->tx_in_slot
= new_slot
;
2206 /* Reply failed request */
2208 request
->ios2_Req
.io_Error
= error
;
2209 request
->ios2_WireError
= wire_error
;
2210 ReplyMsg((APTR
)request
);
2218 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_SOFTINT
;
2220 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_IGNORE
;
2227 /****i* etherlink3.device/DMATXEndInt **************************************
2233 * DMATXEndInt(unit, int_code)
2235 * VOID DMATXEndInt(struct DevUnit *, APTR);
2238 * I think it's safe to assume that there will always be at least one
2239 * completed packet whenever this interrupt is called.
2241 ****************************************************************************
2245 static VOID
DMATXEndInt(REG(a1
, struct DevUnit
*unit
),
2246 REG(a5
, APTR int_code
))
2248 UWORD data_size
, packet_size
, new_out_slot
, i
;
2250 struct DevBase
*base
;
2251 struct IOSana2Req
*request
;
2252 ULONG
*dpd
, *fragment
, dma_size
;
2253 struct TypeStats
*tracker
;
2255 /* Find out which packets have completed */
2257 base
= unit
->device
;
2258 dpd
= (ULONG
*)(UPINT
)unit
->LELongIn(unit
->card
, EL3REG_DOWNLIST
);
2260 new_out_slot
= (dpd
- unit
->dpds
) / (sizeof(ULONG
) * DPD_SIZE
);
2262 new_out_slot
= unit
->tx_in_slot
;
2264 /* Retire sent packets */
2266 for(i
= unit
->tx_out_slot
; i
!= new_out_slot
;
2267 i
= (i
+ 1) % TX_SLOT_COUNT
)
2269 /* Mark end of DMA */
2271 request
= unit
->tx_requests
[i
];
2272 data_size
= packet_size
= request
->ios2_DataLength
;
2273 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
2274 packet_size
+= ETH_HEADERSIZE
;
2276 dpd
= unit
->dpds
+ ((DPD_SIZE
/ sizeof(ULONG
)) * i
);
2277 fragment
= dpd
+ EL3DPD_FIRSTFRAG
;
2278 dma_size
= DPD_SIZE
* TX_SLOT_COUNT
;
2279 CachePostDMA(unit
->dpds
, &dma_size
, 0);
2281 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
2283 buffer
= (APTR
)(UPINT
)LELong(fragment
[EL3FRAG_ADDR
]);
2284 dma_size
= ETH_HEADERSIZE
;
2285 CachePostDMA(buffer
, &dma_size
, DMA_ReadFromRAM
);
2286 fragment
+= EL3_FRAGLEN
;
2289 buffer
= (APTR
)(UPINT
)LELong(fragment
[EL3FRAG_ADDR
]);
2290 dma_size
= data_size
;
2291 CachePostDMA(buffer
, &dma_size
, DMA_ReadFromRAM
);
2293 /* Check if unit's TX buffer is now free */
2295 if(buffer
== unit
->tx_buffer
)
2296 unit
->flags
&= ~UNITF_TXBUFFERINUSE
;
2298 /* Update statistics */
2300 tracker
= FindTypeStats(unit
, &unit
->type_trackers
,
2301 request
->ios2_PacketType
, base
);
2304 tracker
->stats
.PacketsSent
++;
2305 tracker
->stats
.BytesSent
+= packet_size
;
2310 request
->ios2_Req
.io_Error
= 0;
2311 ReplyMsg((APTR
)request
);
2314 unit
->tx_out_slot
= new_out_slot
;
2316 /* Restart downloads if they had stopped */
2318 if(unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
== PA_IGNORE
)
2319 Cause(&unit
->tx_int
);
2326 /****i* etherlink3.device/ReportEvents *************************************
2332 * ReportEvents(unit, events)
2334 * VOID ReportEvents(struct DevUnit *, ULONG);
2337 * unit - A unit of this device.
2338 * events - A mask of events to report.
2343 ****************************************************************************
2347 static VOID
ReportEvents(struct DevUnit
*unit
, ULONG events
,
2348 struct DevBase
*base
)
2350 struct IOSana2Req
*request
, *tail
, *next_request
;
2353 list
= &unit
->request_ports
[EVENT_QUEUE
]->mp_MsgList
;
2354 next_request
= (APTR
)list
->lh_Head
;
2355 tail
= (APTR
)&list
->lh_Tail
;
2358 while(next_request
!= tail
)
2360 request
= next_request
;
2361 next_request
= (APTR
)request
->ios2_Req
.io_Message
.mn_Node
.ln_Succ
;
2363 if((request
->ios2_WireError
& events
) != 0)
2365 request
->ios2_WireError
= events
;
2366 Remove((APTR
)request
);
2367 ReplyMsg((APTR
)request
);
2377 /****i* etherlink3.device/UnitTask *****************************************
2401 ****************************************************************************
2405 static VOID
UnitTask(struct ExecBase
*sys_base
)
2408 struct IORequest
*request
;
2409 struct DevUnit
*unit
;
2410 struct DevBase
*base
;
2411 struct MsgPort
*general_port
;
2412 ULONG signals
, wait_signals
, card_removed_signal
, card_inserted_signal
,
2413 general_port_signal
;
2415 /* Get parameters */
2417 task
= AbsExecBase
->ThisTask
;
2418 unit
= task
->tc_UserData
;
2419 base
= unit
->device
;
2421 /* Activate general request port */
2423 general_port
= unit
->request_ports
[GENERAL_QUEUE
];
2424 general_port
->mp_SigTask
= task
;
2425 general_port
->mp_SigBit
= AllocSignal(-1);
2426 general_port_signal
= 1 << general_port
->mp_SigBit
;
2427 general_port
->mp_Flags
= PA_SIGNAL
;
2429 /* Allocate a signal for notification of card removal */
2431 card_removed_signal
= unit
->card_removed_signal
= 1 << AllocSignal(-1);
2432 card_inserted_signal
= unit
->card_inserted_signal
= 1 << AllocSignal(-1);
2433 wait_signals
= (1 << general_port
->mp_SigBit
) | card_removed_signal
2434 | card_inserted_signal
;
2436 /* Tell ourselves to check port for old messages */
2438 Signal(task
, general_port_signal
);
2440 /* Infinite loop to service requests and signals */
2444 signals
= Wait(wait_signals
);
2446 if((signals
& card_inserted_signal
) != 0)
2448 if(unit
->insertion_function(unit
->card
, base
))
2450 unit
->flags
|= UNITF_HAVEADAPTER
;
2451 if((unit
->flags
& UNITF_CONFIGURED
) != 0)
2452 ConfigureAdapter(unit
, base
);
2456 if((signals
& card_removed_signal
) != 0)
2458 unit
->removal_function(unit
->card
, base
);
2459 GoOffline(unit
, base
);
2462 if((signals
& general_port_signal
) != 0)
2464 while((request
= (APTR
)GetMsg(general_port
)) != NULL
)
2466 /* Service the request as soon as the unit is free */
2468 ObtainSemaphore(&unit
->access_lock
);
2469 ServiceRequest((APTR
)request
, base
);
2477 /****i* etherlink3.device/ReadEEPROM ***************************************
2480 * ReadEEPROM -- Read a location on card's EEPROM.
2483 * value = ReadEEPROM(unit, index)
2485 * UWORD ReadEEPROM(struct DevUnit *, UWORD);
2488 * unit - Device unit.
2489 * index - Offset within EEPROM.
2492 * value - Contents of specified EEPROM location.
2494 ****************************************************************************
2498 static UWORD
ReadEEPROM(struct DevUnit
*unit
, UWORD index
,
2499 struct DevBase
*base
)
2501 unit
->LEWordOut(unit
->card
, EL3REG_EEPROMCMD
, EL3ECMD_READ
| index
);
2502 while((unit
->LEWordIn(unit
->card
, EL3REG_EEPROMCMD
) &
2503 EL3REG_EEPROMCMDF_BUSY
) != 0);
2505 return unit
->LEWordIn(unit
->card
, EL3REG_EEPROMDATA
);
2510 /****i* etherlink3.device/ReadMII ******************************************
2513 * ReadMII -- Read a register on an MII PHY.
2516 * success = ReadMII(unit, phy_no, reg_no, value)
2518 * BOOL ReadMII(struct DevUnit *, UWORD, UWORD, UWORD *);
2521 * Reads a register on an MII PHY. Window 4 must be selected before
2522 * calling this function.
2525 * unit - Device unit.
2528 * value - Pointer to location to store value read from MII register.
2531 * success - Success indicator.
2533 ****************************************************************************
2537 static BOOL
ReadMII(struct DevUnit
*unit
, UWORD phy_no
, UWORD reg_no
,
2538 UWORD
*value
, struct DevBase
*base
)
2540 BOOL success
= TRUE
;
2542 WriteMIIBits(unit
, 0xffffffff, 32, base
);
2543 WriteMIIBits(unit
, 0x6, 4, base
);
2544 WriteMIIBits(unit
, phy_no
, 5, base
);
2545 WriteMIIBits(unit
, reg_no
, 5, base
);
2546 ReadMIIBit(unit
, base
);
2547 if(ReadMIIBit(unit
, base
))
2549 *value
= ReadMIIBits(unit
, 16, base
);
2550 ReadMIIBit(unit
, base
);
2557 /****i* etherlink3.device/WriteMII *****************************************
2560 * WriteMII -- Write to a register on an MII PHY.
2563 * WriteMII(unit, phy_no, reg_no, value)
2565 * VOID WriteMII(struct DevUnit *, UWORD, UWORD, UWORD);
2568 * unit - Device unit.
2571 * value - value to write to MII register.
2576 ****************************************************************************
2581 static VOID
WriteMII(struct DevUnit
*unit
, UWORD phy_no
, UWORD reg_no
,
2582 UWORD value
, struct DevBase
*base
)
2584 WriteMIIBits(unit
, 0xffffffff, 32, base
);
2585 WriteMIIBits(unit
, 0x5, 4, base
);
2586 WriteMIIBits(unit
, phy_no
, 5, base
);
2587 WriteMIIBits(unit
, reg_no
, 5, base
);
2588 WriteMIIBit(unit
, TRUE
, base
);
2589 WriteMIIBits(unit
, value
, 16, base
);
2590 DoMIIZCycle(unit
, base
);
2598 /****i* etherlink3.device/ReadMIIBits **************************************
2604 * value = ReadMIIBits(unit, count)
2606 * ULONG ReadMIIBits(struct DevUnit *, UBYTE);
2608 ****************************************************************************
2612 static ULONG
ReadMIIBits(struct DevUnit
*unit
, UBYTE count
,
2613 struct DevBase
*base
)
2618 /* LEWordOut(io_addr, LEWordIn(reg) & ~EL3REG_PHYMGMTF_WRITE);*/
2619 for(i
= 0; i
< count
; i
++)
2622 if(ReadMIIBit(unit
, base
))
2624 unit
->LEWordIn(unit
->card
, EL3REG_PHYMGMT
);
2626 /* ReadMIIBit(unit, base)? value |= 1;*/
2632 /****i* etherlink3.device/WriteMIIBits *************************************
2638 * WriteMIIBits(unit, value, count)
2640 * VOID WriteMIIBits(struct DevUnit *, ULONG, UBYTE);
2642 ****************************************************************************
2646 static VOID
WriteMIIBits(struct DevUnit
*unit
, ULONG value
, UBYTE count
,
2647 struct DevBase
*base
)
2651 for(mask
= 1 << (count
- 1); mask
!= 0; mask
>>= 1)
2652 WriteMIIBit(unit
, (value
& mask
) != 0, base
);
2659 /****i* etherlink3.device/ReadMIIBit ***************************************
2665 * is_one = ReadMIIBit(unit)
2667 * BOOL ReadMIIBit(struct DevUnit *);
2669 ****************************************************************************
2673 static BOOL
ReadMIIBit(struct DevUnit
*unit
, struct DevBase
*base
)
2677 unit
->LEWordOut(unit
->card
, EL3REG_PHYMGMT
, 0);
2678 BusyMicroDelay(1, base
);
2679 unit
->LEWordOut(unit
->card
, EL3REG_PHYMGMT
, EL3REG_PHYMGMTF_CLK
);
2680 BusyMicroDelay(1, base
);
2682 (unit
->LEWordIn(unit
->card
, EL3REG_PHYMGMT
) & EL3REG_PHYMGMTF_DATA
)
2684 BusyMicroDelay(1, base
);
2691 /****i* etherlink3.device/WriteMIIBit **************************************
2697 * WriteMIIBit(unit, is_one)
2699 * VOID WriteMIIBit(struct DevUnit *, BOOL);
2701 ****************************************************************************
2705 static VOID
WriteMIIBit(struct DevUnit
*unit
, BOOL is_one
,
2706 struct DevBase
*base
)
2708 unit
->LEWordOut(unit
->card
, EL3REG_PHYMGMT
, EL3REG_PHYMGMTF_WRITE
);
2709 BusyMicroDelay(1, base
);
2711 unit
->LEWordOut(unit
->card
, EL3REG_PHYMGMT
,
2712 EL3REG_PHYMGMTF_WRITE
| EL3REG_PHYMGMTF_CLK
|
2713 EL3REG_PHYMGMTF_DATA
);
2715 unit
->LEWordOut(unit
->card
, EL3REG_PHYMGMT
,
2716 EL3REG_PHYMGMTF_WRITE
| EL3REG_PHYMGMTF_CLK
);
2717 BusyMicroDelay(1, base
);
2724 /****i* etherlink3.device/DoMIIZCycle **************************************
2732 * VOID DoMIIZCycle(struct DevUnit *);
2734 ****************************************************************************
2739 static VOID
DoMIIZCycle(struct DevUnit
*unit
, struct DevBase
*base
)
2741 unit
->LEWordOut(unit
->card
, EL3REG_PHYMGMT
,
2742 unit
->LEWordIn(unit
->card
, EL3REG_PHYMGMT
) & ~EL3REG_PHYMGMTF_CLK
);
2743 BusyMicroDelay(1, base
);
2744 unit
->LEWordOut(unit
->card
, EL3REG_PHYMGMT
, EL3REG_PHYMGMTF_CLK
);
2745 BusyMicroDelay(1, base
);
2754 static VOID
BusyMicroDelay(ULONG micros
, struct DevBase
*base
)
2756 struct timeval time
, end_time
;
2758 GetSysTime(&end_time
);
2760 time
.tv_micro
= micros
;
2761 AddTime(&end_time
, &time
);
2763 while(CmpTime(&end_time
, &time
) < 0)
2771 static VOID
BusyMicroDelay(ULONG micros
, struct DevBase
*base
)
2773 struct EClockVal time
, end_time
;
2776 rate
= ReadEClock(&time
);
2777 end_time
.ev_hi
= time
.ev_hi
;
2778 end_time
.ev_lo
= time
.ev_lo
+ (micros
* rate
+ 1) / 1000000;
2779 if(end_time
.ev_lo
< time
.ev_lo
)
2782 while(time
.ev_lo
< end_time
.ev_lo
|| time
.ev_hi
< end_time
.ev_hi
)