3 Copyright (C) 2012-2017 The AROS Dev team
4 Copyright (C) 2001-2012 Neil Cafferkey
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25 #include <exec/memory.h>
26 #include <exec/execbase.h>
27 #include <exec/errors.h>
29 #include <proto/exec.h>
31 #include <proto/alib.h>
33 #include <clib/alib_protos.h>
35 #include <proto/utility.h>
36 #include <proto/timer.h>
39 #include "etherlink3.h"
42 #include "unit_protos.h"
43 #include "request_protos.h"
46 #define TASK_PRIORITY 0
47 #define STACK_SIZE 4096
49 (EL3INTF_UPDATESTATS | EL3INTF_RXCOMPLETE | EL3INTF_TXAVAIL \
51 #define DMA_INT_MASK \
52 (EL3INTF_UPDONE | EL3INTF_DOWNDONE | EL3INTF_UPDATESTATS \
58 #define AbsExecBase sys_base
62 #define AddTask(task, initial_pc, final_pc) \
63 IExec->AddTask(task, initial_pc, final_pc, NULL)
67 #define AddTask(task, initial_pc, final_pc) \
69 struct TagItem _task_tags[] = \
70 {{TASKTAG_ARG1, (IPTR)SysBase}, {TAG_END, 0}}; \
71 NewAddTask(task, initial_pc, final_pc, _task_tags); \
75 VOID
SelectMedium(struct DevUnit
*unit
, UWORD transceiver
,
76 struct DevBase
*base
);
77 static struct AddressRange
*FindMulticastRange(struct DevUnit
*unit
,
78 ULONG lower_bound_left
, UWORD lower_bound_right
, ULONG upper_bound_left
,
79 UWORD upper_bound_right
, struct DevBase
*base
);
80 static VOID
RXInt(REG(a1
, struct DevUnit
*unit
), REG(a5
, APTR int_code
));
81 static VOID
CopyPacket(struct DevUnit
*unit
, struct IOSana2Req
*request
,
82 UWORD packet_size
, UWORD packet_type
, UBYTE
*buffer
, BOOL all_read
,
83 struct DevBase
*base
);
84 static BOOL
AddressFilter(struct DevUnit
*unit
, UBYTE
*address
,
85 struct DevBase
*base
);
86 static VOID
TXInt(REG(a1
, struct DevUnit
*unit
), REG(a5
, APTR int_code
));
87 static VOID
TxError(struct DevUnit
*unit
, struct DevBase
*base
);
88 static VOID
DMARXInt(REG(a1
, struct DevUnit
*unit
),
89 REG(a5
, APTR int_code
));
90 static VOID
DMATXInt(REG(a1
, struct DevUnit
*unit
),
91 REG(a5
, APTR int_code
));
92 static VOID
DMATXEndInt(REG(a1
, struct DevUnit
*unit
),
93 REG(a5
, APTR int_code
));
94 static VOID
ReportEvents(struct DevUnit
*unit
, ULONG events
,
95 struct DevBase
*base
);
96 static VOID
UnitTask(struct ExecBase
*sys_base
);
97 static UWORD
ReadEEPROM(struct DevUnit
*unit
, UWORD index
,
98 struct DevBase
*base
);
99 static BOOL
ReadMII(struct DevUnit
*unit
, UWORD phy_no
, UWORD reg_no
,
100 UWORD
*value
, struct DevBase
*base
);
102 static VOID
WriteMII(struct DevUnit
*unit
, UWORD phy_no
, UWORD reg_no
,
103 UWORD value
, struct DevBase
*base
);
105 static ULONG
ReadMIIBits(struct DevUnit
*unit
, UBYTE count
,
106 struct DevBase
*base
);
107 static VOID
WriteMIIBits(struct DevUnit
*unit
, ULONG value
, UBYTE count
,
108 struct DevBase
*base
);
109 static BOOL
ReadMIIBit(struct DevUnit
*unit
, struct DevBase
*base
);
110 static VOID
WriteMIIBit(struct DevUnit
*unit
, BOOL is_one
,
111 struct DevBase
*base
);
113 static VOID
DoMIIZCycle(struct DevUnit
*unit
, struct DevBase
*base
);
115 static VOID
BusyMicroDelay(ULONG micros
, struct DevBase
*base
);
118 static const UBYTE port_choices
[] =
120 /* EL3XCVR_AUTONEG,*/
129 static const UBYTE port_masks
[] =
131 EL3REG_MEDIAOPTIONSF_10BASET
,
132 EL3REG_MEDIAOPTIONSF_AUI
,
134 EL3REG_MEDIAOPTIONSF_10BASE2
,
135 EL3REG_MEDIAOPTIONSF_100BASETX
,
136 EL3REG_MEDIAOPTIONSF_100BASEFX
,
137 EL3REG_MEDIAOPTIONSF_MII
,
139 EL3REG_MEDIAOPTIONSF_100BASETX
| EL3REG_MEDIAOPTIONSF_10BASET
143 /****i* etherlink3.device/CreateUnit ***************************************
146 * CreateUnit -- Create a unit.
149 * unit = CreateUnit(index, card, io_tags, generation,
152 * struct DevUnit *CreateUnit(ULONG, APTR, struct TagItem *, UWORD,
156 * Creates a new unit.
158 ****************************************************************************
162 struct DevUnit
*CreateUnit(ULONG index
, APTR card
,
163 const struct TagItem
*io_tags
, UWORD generation
, UWORD bus
,
164 struct DevBase
*base
)
167 struct DevUnit
*unit
;
169 struct MsgPort
*port
;
172 ULONG
*upd
, *next_upd
, *fragment
, dma_size
;
173 APTR rx_int_function
, tx_int_function
;
175 unit
= AllocMem(sizeof(struct DevUnit
), MEMF_CLEAR
| MEMF_PUBLIC
);
181 InitSemaphore(&unit
->access_lock
);
182 NewList((APTR
)&unit
->openers
);
183 NewList((APTR
)&unit
->type_trackers
);
184 NewList((APTR
)&unit
->multicast_ranges
);
189 unit
->generation
= generation
;
192 (APTR
)GetTagData(IOTAG_ByteIn
, (UPINT
)NULL
, io_tags
);
194 (APTR
)GetTagData(IOTAG_LongIn
, (UPINT
)NULL
, io_tags
);
196 (APTR
)GetTagData(IOTAG_ByteOut
, (UPINT
)NULL
, io_tags
);
198 (APTR
)GetTagData(IOTAG_WordOut
, (UPINT
)NULL
, io_tags
);
200 (APTR
)GetTagData(IOTAG_LongOut
, (UPINT
)NULL
, io_tags
);
202 (APTR
)GetTagData(IOTAG_LongsIn
, (UPINT
)NULL
, io_tags
);
204 (APTR
)GetTagData(IOTAG_LongsOut
, (UPINT
)NULL
, io_tags
);
206 (APTR
)GetTagData(IOTAG_BEWordOut
, (UPINT
)NULL
, io_tags
);
208 (APTR
)GetTagData(IOTAG_LEWordIn
, (UPINT
)NULL
, io_tags
);
210 (APTR
)GetTagData(IOTAG_LELongIn
, (UPINT
)NULL
, io_tags
);
212 (APTR
)GetTagData(IOTAG_LEWordOut
, (UPINT
)NULL
, io_tags
);
214 (APTR
)GetTagData(IOTAG_LELongOut
, (UPINT
)NULL
, io_tags
);
216 (APTR
)GetTagData(IOTAG_AllocDMAMem
, (UPINT
)NULL
, io_tags
);
218 (APTR
)GetTagData(IOTAG_FreeDMAMem
, (UPINT
)NULL
, io_tags
);
219 if(unit
->ByteIn
== NULL
|| unit
->LongIn
== NULL
220 || unit
->ByteOut
== NULL
221 || unit
->WordOut
== NULL
|| unit
->LongOut
== NULL
222 || unit
->LongsIn
== NULL
|| unit
->LongsOut
== NULL
223 || unit
->BEWordOut
== NULL
|| unit
->LEWordIn
== NULL
224 || unit
->LELongIn
== NULL
|| unit
->LEWordOut
== NULL
225 || unit
->LELongOut
== NULL
226 || generation
>= BOOMERANG_GEN
227 && (unit
->AllocDMAMem
== NULL
|| unit
->FreeDMAMem
== NULL
))
233 if(unit
->generation
>= VORTEX_GEN
)
234 unit
->size_shift
= 2;
236 InitialiseAdapter(unit
, FALSE
, base
);
237 unit
->flags
|= UNITF_HAVEADAPTER
;
239 /* Set up packet filter command */
241 unit
->rx_filter_cmd
= EL3CMD_SETRXFILTER
| EL3CMD_SETRXFILTERF_BCAST
242 | EL3CMD_SETRXFILTERF_UCAST
;
244 /* Set up interrupt mask */
246 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
247 unit
->int_mask
= DMA_INT_MASK
;
249 unit
->int_mask
= INT_MASK
;
251 /* Disable statistics interrupts for PCMCIA because they can't be
254 if(bus
== PCCARD_BUS
)
255 unit
->int_mask
&= ~EL3INTF_UPDATESTATS
;
257 /* Store location of registers that were originally in window 1 */
259 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
260 unit
->window1_offset
+= EL3_WINDOWSIZE
;
262 /* Create the message ports for queuing requests */
264 for(i
= 0; i
< REQUEST_QUEUE_COUNT
; i
++)
266 unit
->request_ports
[i
] = port
= AllocMem(sizeof(struct MsgPort
),
267 MEMF_PUBLIC
| MEMF_CLEAR
);
273 NewList(&port
->mp_MsgList
);
274 port
->mp_Flags
= PA_IGNORE
;
275 port
->mp_SigTask
= &unit
->tx_int
;
279 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
281 unit
->rx_buffer
= unit
->AllocDMAMem(unit
->card
,
282 ETH_MAXPACKETSIZE
* RX_SLOT_COUNT
, 1);
284 unit
->AllocDMAMem(unit
->card
, ETH_MAXPACKETSIZE
, 1);
289 AllocVec((ETH_MAXPACKETSIZE
+ 3) & ~3, MEMF_PUBLIC
);
290 unit
->tx_buffer
= AllocVec(ETH_MAXPACKETSIZE
, MEMF_PUBLIC
);
293 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
295 unit
->tx_requests
= AllocVec(sizeof(APTR
) * TX_SLOT_COUNT
,
297 unit
->headers
= unit
->AllocDMAMem(unit
->card
,
298 ETH_HEADERSIZE
* TX_SLOT_COUNT
, 1);
300 unit
->AllocDMAMem(unit
->card
, DPD_SIZE
* TX_SLOT_COUNT
, 8);
301 next_upd
= unit
->upds
=
302 unit
->AllocDMAMem(unit
->card
, UPD_SIZE
* RX_SLOT_COUNT
, 8);
303 if(unit
->tx_requests
== NULL
|| unit
->headers
== NULL
304 || unit
->dpds
== NULL
|| next_upd
== NULL
)
308 if(unit
->rx_buffer
== NULL
|| unit
->tx_buffer
== NULL
)
314 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
316 /* Construct RX ring */
318 buffer
= unit
->rx_buffer
;
319 for(i
= 0; i
< RX_SLOT_COUNT
; i
++)
322 next_upd
= upd
+ UPD_SIZE
/ sizeof(ULONG
);
323 upd
[EL3UPD_NEXT
] = MakeLELong((ULONG
)(UPINT
)next_upd
);
324 upd
[EL3UPD_STATUS
] = 0;
325 fragment
= upd
+ EL3UPD_FIRSTFRAG
;
326 fragment
[EL3FRAG_ADDR
] = MakeLELong((ULONG
)(UPINT
)buffer
);
327 fragment
[EL3FRAG_LEN
] =
328 MakeLELong(EL3FRAG_LENF_LAST
| ETH_MAXPACKETSIZE
);
329 buffer
+= ETH_MAXPACKETSIZE
;
331 upd
[EL3UPD_NEXT
] = MakeLELong((ULONG
)(UPINT
)unit
->upds
);
332 unit
->next_upd
= unit
->upds
;
334 dma_size
= UPD_SIZE
* RX_SLOT_COUNT
;
335 CachePreDMA(unit
->upds
, &dma_size
, 0);
336 dma_size
= ETH_MAXPACKETSIZE
* RX_SLOT_COUNT
;
337 CachePreDMA(unit
->rx_buffer
, &dma_size
, 0);
340 /* Record maximum speed in BPS */
342 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_100MBPS
) != 0)
343 unit
->speed
= 100000000;
345 unit
->speed
= 10000000;
347 /* Initialise status, transmit and receive interrupts */
349 unit
->status_int
.is_Node
.ln_Name
=
350 base
->device
.dd_Library
.lib_Node
.ln_Name
;
351 unit
->status_int
.is_Code
= (APTR
)StatusInt
;
352 unit
->status_int
.is_Data
= unit
;
354 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
355 rx_int_function
= DMARXInt
;
357 rx_int_function
= RXInt
;
358 unit
->rx_int
.is_Node
.ln_Name
=
359 base
->device
.dd_Library
.lib_Node
.ln_Name
;
360 unit
->rx_int
.is_Code
= rx_int_function
;
361 unit
->rx_int
.is_Data
= unit
;
363 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
364 tx_int_function
= DMATXInt
;
366 tx_int_function
= TXInt
;
367 unit
->tx_int
.is_Node
.ln_Name
=
368 base
->device
.dd_Library
.lib_Node
.ln_Name
;
369 unit
->tx_int
.is_Code
= tx_int_function
;
370 unit
->tx_int
.is_Data
= unit
;
372 unit
->tx_end_int
.is_Node
.ln_Name
=
373 base
->device
.dd_Library
.lib_Node
.ln_Name
;
374 unit
->tx_end_int
.is_Code
= DMATXEndInt
;
375 unit
->tx_end_int
.is_Data
= unit
;
377 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_SOFTINT
;
382 /* Create a new task */
385 AllocMem(sizeof(struct Task
), MEMF_PUBLIC
| MEMF_CLEAR
);
392 stack
= AllocMem(STACK_SIZE
, MEMF_PUBLIC
);
399 /* Initialise and start task */
401 task
->tc_Node
.ln_Type
= NT_TASK
;
402 task
->tc_Node
.ln_Pri
= TASK_PRIORITY
;
403 task
->tc_Node
.ln_Name
=
404 base
->device
.dd_Library
.lib_Node
.ln_Name
;
405 task
->tc_SPUpper
= stack
+ STACK_SIZE
;
406 task
->tc_SPLower
= stack
;
407 task
->tc_SPReg
= stack
+ STACK_SIZE
;
408 NewList(&task
->tc_MemEntry
);
410 if(AddTask(task
, UnitTask
, NULL
) == NULL
)
414 /* Send the unit to the new task */
417 task
->tc_UserData
= unit
;
421 DeleteUnit(unit
, base
);
430 /****i* etherlink3.device/DeleteUnit ***************************************
433 * DeleteUnit -- Delete a unit.
438 * VOID DeleteUnit(struct DevUnit *);
444 * unit - Device unit (can be NULL).
457 ****************************************************************************
461 VOID
DeleteUnit(struct DevUnit
*unit
, struct DevBase
*base
)
471 if(task
->tc_UserData
!= NULL
)
474 FreeMem(task
->tc_SPLower
, STACK_SIZE
);
476 FreeMem(task
, sizeof(struct Task
));
479 for(i
= 0; i
< REQUEST_QUEUE_COUNT
; i
++)
481 if(unit
->request_ports
[i
] != NULL
)
482 FreeMem(unit
->request_ports
[i
], sizeof(struct MsgPort
));
485 if((unit
->flags
& UNITF_HAVEADAPTER
) != 0) /* Needed! */
486 GoOffline(unit
, base
);
488 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
490 unit
->FreeDMAMem(unit
->card
, unit
->upds
);
491 unit
->FreeDMAMem(unit
->card
, unit
->dpds
);
492 unit
->FreeDMAMem(unit
->card
, unit
->headers
);
493 FreeVec(unit
->tx_requests
);
496 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
498 unit
->FreeDMAMem(unit
->card
, unit
->tx_buffer
);
499 unit
->FreeDMAMem(unit
->card
, unit
->rx_buffer
);
503 FreeVec(unit
->tx_buffer
);
504 FreeVec(unit
->rx_buffer
);
507 FreeMem(unit
, sizeof(struct DevUnit
));
515 /****i* etherlink3.device/InitialiseAdapter ********************************
518 * InitialiseAdapter -- .
521 * InitialiseAdapter(unit, reinsertion)
523 * BOOL InitialiseAdapter(struct DevUnit *, BOOL);
542 ****************************************************************************
546 BOOL
InitialiseAdapter(struct DevUnit
*unit
, BOOL reinsertion
,
547 struct DevBase
*base
)
550 UWORD address_part
, links
= 0, ports
, new_ports
, tp_ports
,
551 media_status
, transceiver
, status
, advert
, ability
, modes
;
555 /* Reset card. We avoid resetting the receive logic because it stops the
556 link status working in the MII Status register */
558 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
559 EL3CMD_RXRESET
| EL3CMD_RXRESETF_SKIPNETWORK
);
560 while((unit
->LEWordIn(unit
->card
, EL3REG_STATUS
) &
561 EL3REG_STATUSF_CMDINPROGRESS
) != 0);
562 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_TXRESET
);
563 while((unit
->LEWordIn(unit
->card
, EL3REG_STATUS
) &
564 EL3REG_STATUSF_CMDINPROGRESS
) != 0);
566 /* Select IO addresses and interrupt for PCCard */
568 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 0);
569 if(unit
->bus
== PCCARD_BUS
)
570 unit
->LEWordOut(unit
->card
, EL3REG_RESCONFIG
, 0x3f00);
571 if(unit
->bus
== ISA_BUS
)
572 unit
->LEWordOut(unit
->card
, EL3REG_RESCONFIG
, (10 << 12) | 0xf00);
574 /* Fully enable an ISA card */
576 if(unit
->bus
== ISA_BUS
)
577 unit
->LEWordOut(unit
->card
, EL3REG_CONFIG
, EL3REG_CONFIGF_ENABLE
);
579 /* Get card capabilities */
581 unit
->capabilities
= ReadEEPROM(unit
, EL3ROM_CAPABILITIES
, base
);
583 /* Get default MAC address */
585 p
= unit
->default_address
;
587 for(i
= 0; i
< ETH_ADDRESSSIZE
/ 2; i
++)
589 address_part
= ReadEEPROM(unit
, EL3ROM_ALTADDRESS0
+ i
, base
);
590 *p
++ = address_part
>> 8;
591 *p
++ = address_part
& 0xff;
594 /* Get available transceivers */
596 if(unit
->bus
== PCCARD_BUS
|| unit
->bus
== ISA_BUS
)
598 config
= unit
->LEWordIn(unit
->card
, EL3REG_CONFIG
);
599 ports
= (config
>> 8) &
600 (EL3REG_MEDIAOPTIONSF_AUI
| EL3REG_MEDIAOPTIONSF_10BASE2
);
601 if((config
& EL3REG_CONFIGF_10BASET
) != 0)
602 ports
|= EL3REG_MEDIAOPTIONSF_10BASET
;
606 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 3);
607 ports
= unit
->LEWordIn(unit
->card
, EL3REG_MEDIAOPTIONS
);
610 ports
= EL3REG_MEDIAOPTIONSF_MII
; /* fix for 3c916? */
614 /* Get transceiver choice from EEPROM */
616 if(unit
->bus
== PCI_BUS
)
618 config
= unit
->LELongIn(unit
->card
, EL3REG_INTERNALCONFIG
);
620 (config
& EL3REG_INTERNALCONFIGF_XCVR
)
621 >> EL3REG_INTERNALCONFIGB_XCVR
;
622 autoselect
= (config
& EL3REG_INTERNALCONFIGF_AUTOXCVR
) != 0;
626 config
= ReadEEPROM(unit
, EL3ROM_ADDRCONFIG
, base
);
628 (config
& EL3REG_ADDRCONFIGF_XCVR
) >> EL3REG_ADDRCONFIGB_XCVR
;
629 autoselect
= (config
& EL3REG_ADDRCONFIGF_AUTOSELECT
) != 0;
634 /* Check if chosen medium is available */
636 new_ports
= ports
& port_masks
[transceiver
];
643 /* Auto-select media type */
647 /* Get transceivers with an active link */
649 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 4);
651 if(unit
->generation
< CYCLONE_GEN
)
655 (EL3REG_MEDIAOPTIONSF_10BASET
| EL3REG_MEDIAOPTIONSF_100BASETX
);
658 SelectMedium(unit
, EL3XCVR_10BASET
, base
);
659 media_status
= unit
->LEWordIn(unit
->card
, EL3REG_MEDIA
);
660 if((media_status
& EL3REG_MEDIAF_BEAT
) != 0)
665 if((ports
& EL3REG_MEDIAOPTIONSF_MII
) != 0
666 || unit
->generation
>= CYCLONE_GEN
)
668 for(i
= 0; i
< 32; i
++)
670 if(ReadMII(unit
, i
, MII_STATUS
, &status
, base
))
672 ReadMII(unit
, i
, MII_STATUS
, &status
, base
);
673 /* Yes, status reg must be read twice */
674 if((status
& MII_STATUSF_LINK
) != 0)
676 if(i
== 24) /* Built-in transceiver */
678 if(((status
& MII_STATUSF_AUTONEGDONE
) != 0)
679 && ((status
& MII_STATUSF_EXTREGSET
) != 0))
681 ReadMII(unit
, i
, MII_AUTONEGADVERT
, &advert
, base
);
682 ReadMII(unit
, i
, MII_AUTONEGABILITY
, &ability
,
684 modes
= advert
& ability
;
686 if((modes
& MII_AUTONEGF_100BASETX
) != 0)
687 links
|= EL3REG_MEDIAOPTIONSF_100BASETX
;
689 if((modes
& MII_AUTONEGF_100BASET4
) != 0)
690 links
|= EL3REG_MEDIAOPTIONSF_100BASET4
;
692 if((modes
& MII_AUTONEGF_10BASET
) != 0)
693 links
|= EL3REG_MEDIAOPTIONSF_10BASET
;
697 modes
= MII_AUTONEGF_10BASET
;
698 links
|= EL3REG_MEDIAOPTIONSF_10BASET
;
700 unit
->autoneg_modes
= modes
;
704 links
|= EL3REG_MEDIAOPTIONSF_MII
;
705 unit
->mii_phy_no
= i
;
713 if((ports
& EL3REG_MEDIAOPTIONSF_10BASE2
) != 0)
715 SelectMedium(unit
, EL3XCVR_10BASE2
, base
);
716 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_STARTCOAX
);
718 if(LoopbackTest(base
))
719 links
|= EL3REG_MEDIAOPTIONSF_10BASE2
;
721 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_STOPCOAX
);
725 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 0);
727 new_ports
= ports
& links
;
732 /* Prioritised choice from remaining transceivers */
734 for(i
= 0; i
< PORT_COUNT
; i
++)
736 transceiver
= port_choices
[i
];
737 if((ports
& port_masks
[transceiver
]) != 0)
739 unit
->transceiver
= transceiver
;
744 /* Find out whether to use full duplex */
746 if((transceiver
== EL3XCVR_10BASET
|| transceiver
== EL3XCVR_100BASETX
)
747 && unit
->generation
>= CYCLONE_GEN
)
749 modes
= unit
->autoneg_modes
;
752 (modes
& MII_AUTONEGF_100BASETXFD
) != 0
758 MII_AUTONEGF_100BASETX
760 MII_AUTONEGF_10BASETFD
764 MII_AUTONEGF_10BASETFD
766 unit
->flags
|= UNITF_FULLDUPLEX
;
776 /****i* etherlink3.device/ConfigureAdapter *********************************
779 * ConfigureAdapter -- .
782 * ConfigureAdapter(unit)
784 * VOID ConfigureAdapter(struct DevUnit *);
802 ****************************************************************************
806 VOID
ConfigureAdapter(struct DevUnit
*unit
, struct DevBase
*base
)
810 /* Set MAC address */
812 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 2);
814 for(i
= 0; i
< ETH_ADDRESSSIZE
; i
++)
815 unit
->ByteOut(unit
->card
, EL3REG_ADDRESS0
+ i
, unit
->address
[i
]);
817 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
819 for(i
= 0; i
< ETH_ADDRESSSIZE
; i
++)
820 unit
->ByteOut(unit
->card
, EL3REG_MASK0
+ i
, 0);
823 /* Enable wider statistics counters */
825 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 4);
826 if(unit
->generation
>= BOOMERANG_GEN
)
827 unit
->LEWordOut(unit
->card
, EL3REG_NETDIAG
,
828 EL3REG_NETDIAGF_WIDESTATS
);
830 /* Decide on promiscuous mode */
832 if((unit
->flags
& UNITF_PROM
) != 0)
833 unit
->rx_filter_cmd
|= EL3CMD_SETRXFILTERF_PROM
;
835 /* Select chosen transceiver */
837 SelectMedium(unit
, unit
->transceiver
, base
);
841 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
842 unit
->LELongOut(unit
->card
, EL3REG_UPLIST
, (ULONG
)(UPINT
)unit
->upds
);
843 GoOnline(unit
, base
);
852 /****i* etherlink3.device/SelectMedium *************************************
858 * SelectMedium(unit, transceiver)
860 * VOID SelectMedium(struct DevUnit *, UWORD);
879 ****************************************************************************
883 VOID
SelectMedium(struct DevUnit
*unit
, UWORD transceiver
,
884 struct DevBase
*base
)
889 if((transceiver
== EL3XCVR_10BASET
|| transceiver
== EL3XCVR_100BASETX
)
890 && unit
->generation
>= CYCLONE_GEN
)
891 transceiver
= EL3XCVR_AUTONEG
;
893 /* Select transceiver */
896 unit
->LEWordIn(unit
->card
, EL3REG_STATUS
) >> EL3REG_STATUSB_WINDOW
;
897 if(unit
->bus
== PCI_BUS
)
899 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 3);
900 config
= unit
->LELongIn(unit
->card
, EL3REG_INTERNALCONFIG
);
901 config
&= ~EL3REG_INTERNALCONFIGF_XCVR
;
902 config
|= transceiver
<< EL3REG_INTERNALCONFIGB_XCVR
;
903 unit
->LELongOut(unit
->card
, EL3REG_INTERNALCONFIG
, config
);
907 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 0);
908 config
= unit
->LEWordIn(unit
->card
, EL3REG_ADDRCONFIG
);
909 config
&= ~EL3REG_ADDRCONFIGF_XCVR
;
910 config
|= transceiver
<< EL3REG_ADDRCONFIGB_XCVR
;
911 unit
->LEWordOut(unit
->card
, EL3REG_ADDRCONFIG
, config
);
913 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
914 EL3CMD_SELECTWINDOW
| old_window
);
921 /****i* etherlink3.device/GoOnline *****************************************
929 * VOID GoOnline(struct DevUnit *);
931 ****************************************************************************
935 VOID
GoOnline(struct DevUnit
*unit
, struct DevBase
*base
)
939 /* Choose interrupts */
941 unit
->flags
|= UNITF_ONLINE
;
942 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
943 EL3CMD_SETINTMASK
| unit
->int_mask
);
944 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
945 EL3CMD_SETZEROMASK
| unit
->int_mask
);
947 /* Enable the transceiver */
949 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
950 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_UPUNSTALL
);
952 transceiver
= unit
->transceiver
;
954 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 4);
955 if(transceiver
== EL3XCVR_100BASETX
)
957 unit
->LEWordOut(unit
->card
, EL3REG_MEDIA
, EL3REG_MEDIAF_BEATCHECK
);
959 else if(transceiver
== EL3XCVR_10BASET
)
961 unit
->LEWordOut(unit
->card
, EL3REG_MEDIA
,
962 EL3REG_MEDIAF_BEATCHECK
| EL3REG_MEDIAF_JABBERCHECK
);
964 else if(transceiver
== EL3XCVR_10BASE2
)
965 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_STARTCOAX
| 0);
967 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 3);
968 if((unit
->flags
& UNITF_FULLDUPLEX
) != 0)
969 unit
->LEWordOut(unit
->card
, EL3REG_MACCONTROL
,
970 EL3REG_MACCONTROLF_FULLDUPLEX
);
972 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, unit
->rx_filter_cmd
);
973 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_RXENABLE
);
974 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_TXENABLE
);
975 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 1);
977 /* Enable statistics collection */
979 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_STATSENABLE
);
981 /* Record start time and report Online event */
983 GetSysTime(&unit
->stats
.LastStart
);
984 ReportEvents(unit
, S2EVENT_ONLINE
, base
);
991 /****i* etherlink3.device/GoOffline ****************************************
999 * VOID GoOffline(struct DevUnit *);
1001 ****************************************************************************
1005 VOID
GoOffline(struct DevUnit
*unit
, struct DevBase
*base
)
1007 unit
->flags
&= ~UNITF_ONLINE
;
1009 if((unit
->flags
& UNITF_HAVEADAPTER
) != 0)
1011 /* Stop interrupts */
1013 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SETINTMASK
| 0);
1014 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1015 EL3CMD_ACKINT
| EL3INTF_ANY
);
1017 /* Stop transmission and reception */
1019 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_RXDISABLE
);
1020 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_TXDISABLE
);
1022 if((unit
->capabilities
& EL3ROM_CAPABILITIESF_FULLMASTER
) != 0)
1024 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_UPSTALL
);
1025 while((unit
->LEWordIn(unit
->card
, EL3REG_STATUS
) &
1026 EL3REG_STATUSF_CMDINPROGRESS
) != 0);
1027 unit
->LELongOut(unit
->card
, EL3REG_UPLIST
, (ULONG
)0);
1028 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_DOWNSTALL
);
1029 while((unit
->LEWordIn(unit
->card
, EL3REG_STATUS
)
1030 & EL3REG_STATUSF_CMDINPROGRESS
) != 0);
1031 unit
->LELongOut(unit
->card
, EL3REG_DOWNLIST
, (ULONG
)0);
1034 /* Turn off media functions */
1036 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 4);
1037 unit
->LEWordOut(unit
->card
, EL3REG_MEDIA
, 0);
1038 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 1);
1040 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_STOPCOAX
| 0);
1043 /* Update then disable statistics */
1045 UpdateStats(unit
, base
);
1046 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_STATSDISABLE
);
1049 /* Flush pending read and write requests */
1051 FlushUnit(unit
, WRITE_QUEUE
, S2ERR_OUTOFSERVICE
, base
);
1053 /* Report Offline event and return */
1055 ReportEvents(unit
, S2EVENT_OFFLINE
, base
);
1061 /****i* etherlink3.device/AddMulticastRange ********************************
1064 * AddMulticastRange -- .
1067 * success = AddMulticastRange(unit, lower_bound, upper_bound)
1069 * BOOL AddMulticastRange(struct DevUnit *, UBYTE *, UBYTE *);
1071 ****************************************************************************
1075 BOOL
AddMulticastRange(struct DevUnit
*unit
, const UBYTE
*lower_bound
,
1076 const UBYTE
*upper_bound
, struct DevBase
*base
)
1078 struct AddressRange
*range
;
1079 ULONG lower_bound_left
, upper_bound_left
;
1080 UWORD lower_bound_right
, upper_bound_right
;
1082 lower_bound_left
= BELong(*((ULONG
*)lower_bound
));
1083 lower_bound_right
= BEWord(*((UWORD
*)(lower_bound
+ 4)));
1084 upper_bound_left
= BELong(*((ULONG
*)upper_bound
));
1085 upper_bound_right
= BEWord(*((UWORD
*)(upper_bound
+ 4)));
1087 range
= FindMulticastRange(unit
, lower_bound_left
, lower_bound_right
,
1088 upper_bound_left
, upper_bound_right
, base
);
1094 range
= AllocMem(sizeof(struct AddressRange
), MEMF_PUBLIC
);
1097 range
->lower_bound_left
= lower_bound_left
;
1098 range
->lower_bound_right
= lower_bound_right
;
1099 range
->upper_bound_left
= upper_bound_left
;
1100 range
->upper_bound_right
= upper_bound_right
;
1101 range
->add_count
= 1;
1104 AddTail((APTR
)&unit
->multicast_ranges
, (APTR
)range
);
1107 if(unit
->range_count
++ == 0)
1109 unit
->rx_filter_cmd
|= EL3CMD_SETRXFILTERF_MCAST
;
1110 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1111 unit
->rx_filter_cmd
);
1116 return range
!= NULL
;
1121 /****i* etherlink3.device/RemMulticastRange ********************************
1124 * RemMulticastRange -- .
1127 * found = RemMulticastRange(unit, lower_bound, upper_bound)
1129 * BOOL RemMulticastRange(struct DevUnit *, UBYTE *, UBYTE *);
1131 ****************************************************************************
1135 BOOL
RemMulticastRange(struct DevUnit
*unit
, const UBYTE
*lower_bound
,
1136 const UBYTE
*upper_bound
, struct DevBase
*base
)
1138 struct AddressRange
*range
;
1139 ULONG lower_bound_left
, upper_bound_left
;
1140 UWORD lower_bound_right
, upper_bound_right
;
1142 lower_bound_left
= BELong(*((ULONG
*)lower_bound
));
1143 lower_bound_right
= BEWord(*((UWORD
*)(lower_bound
+ 4)));
1144 upper_bound_left
= BELong(*((ULONG
*)upper_bound
));
1145 upper_bound_right
= BEWord(*((UWORD
*)(upper_bound
+ 4)));
1147 range
= FindMulticastRange(unit
, lower_bound_left
, lower_bound_right
,
1148 upper_bound_left
, upper_bound_right
, base
);
1152 if(--range
->add_count
== 0)
1155 Remove((APTR
)range
);
1157 FreeMem(range
, sizeof(struct AddressRange
));
1159 if(--unit
->range_count
== 0)
1161 unit
->rx_filter_cmd
&= ~EL3CMD_SETRXFILTERF_MCAST
;
1162 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1163 unit
->rx_filter_cmd
);
1168 return range
!= NULL
;
1173 /****i* etherlink3.device/FindMulticastRange *******************************
1176 * FindMulticastRange -- .
1179 * range = FindMulticastRange(unit, lower_bound_left,
1180 * lower_bound_right, upper_bound_left, upper_bound_right)
1182 * struct AddressRange *FindMulticastRange(struct DevUnit *, ULONG,
1183 * UWORD, ULONG, UWORD);
1185 ****************************************************************************
1189 static struct AddressRange
*FindMulticastRange(struct DevUnit
*unit
,
1190 ULONG lower_bound_left
, UWORD lower_bound_right
, ULONG upper_bound_left
,
1191 UWORD upper_bound_right
, struct DevBase
*base
)
1193 struct AddressRange
*range
, *tail
;
1196 range
= (APTR
)unit
->multicast_ranges
.mlh_Head
;
1197 tail
= (APTR
)&unit
->multicast_ranges
.mlh_Tail
;
1199 while((range
!= tail
) && !found
)
1201 if((lower_bound_left
== range
->lower_bound_left
) &&
1202 (lower_bound_right
== range
->lower_bound_right
) &&
1203 (upper_bound_left
== range
->upper_bound_left
) &&
1204 (upper_bound_right
== range
->upper_bound_right
))
1207 range
= (APTR
)range
->node
.mln_Succ
;
1218 /****i* etherlink3.device/FindTypeStats ************************************
1221 * FindTypeStats -- .
1224 * stats = FindTypeStats(unit, list,
1227 * struct TypeStats *FindTypeStats(struct DevUnit *, struct MinList *,
1230 ****************************************************************************
1234 struct TypeStats
*FindTypeStats(struct DevUnit
*unit
, struct MinList
*list
,
1235 ULONG packet_type
, struct DevBase
*base
)
1237 struct TypeStats
*stats
, *tail
;
1240 stats
= (APTR
)list
->mlh_Head
;
1241 tail
= (APTR
)&list
->mlh_Tail
;
1243 while(stats
!= tail
&& !found
)
1245 if(stats
->packet_type
== packet_type
)
1248 stats
= (APTR
)stats
->node
.mln_Succ
;
1259 /****i* etherlink3.device/FlushUnit ****************************************
1265 * FlushUnit(unit, last_queue, error)
1267 * VOID FlushUnit(struct DevUnit *, UBYTE, BYTE);
1269 ****************************************************************************
1271 * Includes alternative implementations because of ambiguities in SANA-II
1276 VOID
FlushUnit(struct DevUnit
*unit
, UBYTE last_queue
, BYTE error
,
1277 struct DevBase
*base
)
1279 struct IORequest
*request
;
1281 struct Opener
*opener
, *tail
;
1283 /* Abort queued requests */
1285 for(i
= 0; i
<= last_queue
; i
++)
1287 while((request
= (APTR
)GetMsg(unit
->request_ports
[i
])) != NULL
)
1289 request
->io_Error
= IOERR_ABORTED
;
1290 ReplyMsg((APTR
)request
);
1295 opener
= (APTR
)unit
->openers
.mlh_Head
;
1296 tail
= (APTR
)&unit
->openers
.mlh_Tail
;
1298 /* Flush every opener's read queue */
1300 while(opener
!= tail
)
1302 while((request
= (APTR
)GetMsg(&opener
->read_port
)) != NULL
)
1304 request
->io_Error
= error
;
1305 ReplyMsg((APTR
)request
);
1307 opener
= (APTR
)opener
->node
.mln_Succ
;
1311 opener
= request
->ios2_BufferManagement
;
1312 while((request
= (APTR
)GetMsg(&opener
->read_port
)) != NULL
)
1314 request
->io_Error
= IOERR_ABORTED
;
1315 ReplyMsg((APTR
)request
);
1326 /****i* etherlink3.device/StatusInt ****************************************
1332 * finished = StatusInt(unit, int_code)
1334 * BOOL StatusInt(struct DevUnit *, APTR);
1336 ****************************************************************************
1338 * int_code is really in A5, but GCC 2.95.3 doesn't seem able to handle that.
1339 * Since we don't use this parameter, we can lie.
1343 BOOL
StatusInt(REG(a1
, struct DevUnit
*unit
), REG(a6
, APTR int_code
))
1345 struct DevBase
*base
;
1348 base
= unit
->device
;
1349 ints
= unit
->LEWordIn(unit
->card
, EL3REG_STATUS
);
1351 if((ints
& EL3INTF_ANY
) != 0)
1353 /* Handle interrupts */
1355 if((ints
& EL3INTF_UPDONE
) != 0)
1357 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1358 EL3CMD_ACKINT
| EL3INTF_UPDONE
);
1359 Cause(&unit
->rx_int
);
1361 if((ints
& EL3INTF_DOWNDONE
) != 0)
1363 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1364 EL3CMD_ACKINT
| EL3INTF_DOWNDONE
);
1365 Cause(&unit
->tx_end_int
);
1367 if((ints
& EL3INTF_UPDATESTATS
) != 0)
1368 UpdateStats(unit
, base
);
1369 if((ints
& EL3INTF_RXCOMPLETE
) != 0)
1372 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1373 EL3CMD_SETINTMASK
| (unit
->int_mask
& ~EL3INTF_RXCOMPLETE
));
1375 Cause(&unit
->rx_int
);
1377 if((ints
& EL3INTF_TXAVAIL
) != 0)
1379 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1380 EL3CMD_ACKINT
| EL3INTF_TXAVAIL
);
1381 Cause(&unit
->tx_int
);
1383 if((ints
& EL3INTF_TXCOMPLETE
) != 0)
1384 TxError(unit
, base
);
1386 /* Acknowledge interrupt request */
1388 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1389 EL3CMD_ACKINT
| EL3INTF_ANY
);
1397 /****i* etherlink3.device/RXInt ********************************************
1403 * RXInt(unit, int_code)
1405 * VOID RXInt(struct DevUnit *, APTR);
1407 ****************************************************************************
1411 static VOID
RXInt(REG(a1
, struct DevUnit
*unit
), REG(a5
, APTR int_code
))
1413 UWORD rx_status
, packet_size
;
1414 struct DevBase
*base
;
1415 BOOL is_orphan
, accepted
;
1418 struct IOSana2Req
*request
, *request_tail
;
1419 struct Opener
*opener
, *opener_tail
;
1420 struct TypeStats
*tracker
;
1422 base
= unit
->device
;
1423 buffer
= unit
->rx_buffer
;
1425 while(((rx_status
= unit
->LEWordIn(unit
->card
, EL3REG_RXSTATUS
))
1426 & EL3REG_RXSTATUSF_INCOMPLETE
) == 0)
1428 if((rx_status
& EL3REG_RXSTATUSF_ERROR
) == 0)
1430 /* Read packet header */
1433 packet_size
= rx_status
& EL3REG_RXSTATUS_SIZEMASK
;
1434 unit
->LongsIn(unit
->card
, EL3REG_DATA0
, (ULONG
*)buffer
,
1435 ETH_HEADERSIZE
+ 3 >> 2);
1437 if(AddressFilter(unit
, buffer
+ ETH_PACKET_DEST
, base
))
1439 packet_type
= BEWord(*((UWORD
*)(buffer
+ ETH_PACKET_TYPE
)));
1441 opener
= (APTR
)unit
->openers
.mlh_Head
;
1442 opener_tail
= (APTR
)&unit
->openers
.mlh_Tail
;
1444 /* Offer packet to every opener */
1446 while(opener
!= opener_tail
)
1448 request
= (APTR
)opener
->read_port
.mp_MsgList
.lh_Head
;
1449 request_tail
= (APTR
)&opener
->read_port
.mp_MsgList
.lh_Tail
;
1452 /* Offer packet to each request until it's accepted */
1454 while((request
!= request_tail
) && !accepted
)
1456 if(request
->ios2_PacketType
== packet_type
1457 || request
->ios2_PacketType
<= ETH_MTU
1458 && packet_type
<= ETH_MTU
)
1460 CopyPacket(unit
, request
, packet_size
, packet_type
,
1461 buffer
, !is_orphan
, base
);
1465 (APTR
)request
->ios2_Req
.io_Message
.mn_Node
.ln_Succ
;
1470 opener
= (APTR
)opener
->node
.mln_Succ
;
1473 /* If packet was unwanted, give it to S2_READORPHAN request */
1477 unit
->stats
.UnknownTypesReceived
++;
1478 if(!IsMsgPortEmpty(unit
->request_ports
[ADOPT_QUEUE
]))
1481 (APTR
)unit
->request_ports
[ADOPT_QUEUE
]->
1482 mp_MsgList
.lh_Head
, packet_size
, packet_type
, buffer
,
1487 /* Update remaining statistics */
1490 FindTypeStats(unit
, &unit
->type_trackers
, packet_type
, base
);
1493 tracker
->stats
.PacketsReceived
++;
1494 tracker
->stats
.BytesReceived
+= packet_size
;
1500 unit
->stats
.BadData
++;
1501 ReportEvents(unit
, S2EVENT_ERROR
| S2EVENT_HARDWARE
| S2EVENT_RX
,
1505 /* Discard packet */
1507 Disable(); /* Needed? */
1508 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_RXDISCARD
);
1509 while((unit
->LEWordIn(unit
->card
, EL3REG_STATUS
) &
1510 EL3REG_STATUSF_CMDINPROGRESS
) != 0);
1516 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1517 EL3CMD_SETINTMASK
| unit
->int_mask
);
1523 /****i* etherlink3.device/CopyPacket ***************************************
1529 * CopyPacket(unit, request, packet_size, packet_type,
1532 * VOID CopyPacket(struct DevUnit *, struct IOSana2Req *, UWORD, UWORD,
1535 ****************************************************************************
1539 static VOID
CopyPacket(struct DevUnit
*unit
, struct IOSana2Req
*request
,
1540 UWORD packet_size
, UWORD packet_type
, UBYTE
*buffer
, BOOL all_read
,
1541 struct DevBase
*base
)
1543 struct Opener
*opener
;
1544 BOOL filtered
= FALSE
;
1546 /* Set multicast and broadcast flags */
1548 request
->ios2_Req
.io_Flags
&= ~(SANA2IOF_BCAST
| SANA2IOF_MCAST
);
1549 if((*((ULONG
*)(buffer
+ ETH_PACKET_DEST
)) == 0xffffffff) &&
1550 (*((UWORD
*)(buffer
+ ETH_PACKET_DEST
+ 4)) == 0xffff))
1551 request
->ios2_Req
.io_Flags
|= SANA2IOF_BCAST
;
1552 else if((buffer
[ETH_PACKET_DEST
] & 0x1) != 0)
1553 request
->ios2_Req
.io_Flags
|= SANA2IOF_MCAST
;
1555 /* Set source and destination addresses and packet type */
1557 CopyMem(buffer
+ ETH_PACKET_SOURCE
, request
->ios2_SrcAddr
,
1559 CopyMem(buffer
+ ETH_PACKET_DEST
, request
->ios2_DstAddr
,
1561 request
->ios2_PacketType
= packet_type
;
1563 /* Read rest of packet (PIO mode only) */
1567 unit
->LongsIn(unit
->card
, EL3REG_DATA0
,
1568 (ULONG
*)(buffer
+ ((ETH_PACKET_DATA
+ 3) & ~0x3)),
1569 (packet_size
- ETH_PACKET_DATA
+ 1) >> 2);
1572 /* Adjust for cooked packet request */
1574 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
1576 packet_size
-= ETH_PACKET_DATA
;
1577 buffer
+= ETH_PACKET_DATA
;
1581 packet_size
+= 4; /* Needed for Shapeshifter & Fusion */
1583 request
->ios2_DataLength
= packet_size
;
1587 opener
= request
->ios2_BufferManagement
;
1588 if((request
->ios2_Req
.io_Command
== CMD_READ
) &&
1589 (opener
->filter_hook
!= NULL
))
1590 if(!CallHookPkt(opener
->filter_hook
, request
, buffer
))
1595 /* Copy packet into opener's buffer and reply packet */
1597 if(!opener
->rx_function(request
->ios2_Data
, buffer
, packet_size
))
1599 request
->ios2_Req
.io_Error
= S2ERR_NO_RESOURCES
;
1600 request
->ios2_WireError
= S2WERR_BUFF_ERROR
;
1602 S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
| S2EVENT_RX
,
1605 Remove((APTR
)request
);
1606 ReplyMsg((APTR
)request
);
1614 /****i* etherlink3.device/AddressFilter ************************************
1620 * accept = AddressFilter(unit, address)
1622 * BOOL AddressFilter(struct DevUnit *, UBYTE *);
1624 ****************************************************************************
1628 static BOOL
AddressFilter(struct DevUnit
*unit
, UBYTE
*address
,
1629 struct DevBase
*base
)
1631 struct AddressRange
*range
, *tail
;
1634 UWORD address_right
;
1636 /* Check whether address is unicast/broadcast or multicast */
1638 address_left
= BELong(*((ULONG
*)address
));
1639 address_right
= BEWord(*((UWORD
*)(address
+ 4)));
1641 if((address_left
& 0x01000000) != 0 &&
1642 !(address_left
== 0xffffffff && address_right
== 0xffff))
1644 /* Check if this multicast address is wanted */
1646 range
= (APTR
)unit
->multicast_ranges
.mlh_Head
;
1647 tail
= (APTR
)&unit
->multicast_ranges
.mlh_Tail
;
1650 while((range
!= tail
) && !accept
)
1652 if((address_left
> range
->lower_bound_left
||
1653 address_left
== range
->lower_bound_left
&&
1654 address_right
>= range
->lower_bound_right
) &&
1655 (address_left
< range
->upper_bound_left
||
1656 address_left
== range
->upper_bound_left
&&
1657 address_right
<= range
->upper_bound_right
))
1659 range
= (APTR
)range
->node
.mln_Succ
;
1663 unit
->special_stats
[S2SS_ETHERNET_BADMULTICAST
& 0xffff]++;
1671 /****i* etherlink3.device/TXInt ********************************************
1679 * VOID TXInt(struct DevUnit *);
1681 ****************************************************************************
1685 static VOID
TXInt(REG(a1
, struct DevUnit
*unit
), REG(a5
, APTR int_code
))
1687 UWORD packet_size
, data_size
, send_size
;
1688 struct DevBase
*base
;
1689 struct IOSana2Req
*request
;
1690 BOOL proceed
= TRUE
;
1691 struct Opener
*opener
;
1692 ULONG
*buffer
, wire_error
;
1693 UBYTE
*(*dma_tx_function
)(REG(a0
, APTR
));
1695 struct MsgPort
*port
;
1696 struct TypeStats
*tracker
;
1698 base
= unit
->device
;
1699 port
= unit
->request_ports
[WRITE_QUEUE
];
1701 while(proceed
&& (!IsMsgPortEmpty(port
)))
1705 request
= (APTR
)port
->mp_MsgList
.lh_Head
;
1706 data_size
= packet_size
= request
->ios2_DataLength
;
1708 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
1709 packet_size
+= ETH_PACKET_DATA
;
1711 if(unit
->LEWordIn(unit
->card
, EL3REG_TXSPACE
)
1712 > EL3_PREAMBLESIZE
+ packet_size
)
1714 /* Write packet preamble */
1716 unit
->LELongOut(unit
->card
, EL3REG_DATA0
, packet_size
);
1718 /* Write packet header */
1720 send_size
= (packet_size
+ 3) & ~0x3;
1721 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
1727 memcpy(&header
.bytes
[0], request
->ios2_DstAddr
, 6);
1728 memcpy(&header
.bytes
[6], unit
->address
, 6);
1729 unit
->LongOut(unit
->card
, EL3REG_DATA0
, header
.ulong
[0]);
1730 unit
->LongOut(unit
->card
, EL3REG_DATA0
, header
.ulong
[1]);
1731 unit
->LongOut(unit
->card
, EL3REG_DATA0
, header
.ulong
[2]);
1732 unit
->BEWordOut(unit
->card
, EL3REG_DATA0
,
1733 request
->ios2_PacketType
);
1734 send_size
-= ETH_HEADERSIZE
;
1737 /* Get packet data */
1739 opener
= (APTR
)request
->ios2_BufferManagement
;
1740 dma_tx_function
= opener
->dma_tx_function
;
1741 if(dma_tx_function
!= NULL
)
1742 buffer
= (ULONG
*)dma_tx_function(request
->ios2_Data
);
1748 buffer
= (ULONG
*)unit
->tx_buffer
;
1749 if(!opener
->tx_function(buffer
, request
->ios2_Data
, data_size
))
1751 error
= S2ERR_NO_RESOURCES
;
1752 wire_error
= S2WERR_BUFF_ERROR
;
1754 S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
1755 | S2EVENT_TX
, base
);
1759 /* Write packet data */
1763 unit
->LongsOut(unit
->card
, EL3REG_DATA0
, buffer
,
1765 buffer
+= (send_size
>> 2);
1766 if((send_size
& 0x3) != 0)
1767 unit
->WordOut(unit
->card
, EL3REG_DATA0
, *((UWORD
*)buffer
));
1772 request
->ios2_Req
.io_Error
= error
;
1773 request
->ios2_WireError
= wire_error
;
1774 Remove((APTR
)request
);
1775 ReplyMsg((APTR
)request
);
1777 /* Update statistics */
1781 tracker
= FindTypeStats(unit
, &unit
->type_trackers
,
1782 request
->ios2_PacketType
, base
);
1785 tracker
->stats
.PacketsSent
++;
1786 tracker
->stats
.BytesSent
+= packet_size
;
1795 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_SOFTINT
;
1798 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SETTXTHRESH
1799 | ((EL3_PREAMBLESIZE
+ packet_size
) >> unit
->size_shift
));
1800 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_IGNORE
;
1808 /****i* etherlink3.device/TxError ******************************************
1816 * VOID TxError(struct DevUnit *);
1818 ****************************************************************************
1822 static VOID
TxError(struct DevUnit
*unit
, struct DevBase
*base
)
1824 UPINT window1_offset
;
1825 UBYTE tx_status
, flags
= 0;
1827 window1_offset
= unit
->window1_offset
;
1829 /* Gather all errors */
1832 unit
->ByteIn(unit
->card
, window1_offset
+ EL3REG_TXSTATUS
))
1833 & EL3REG_TXSTATUSF_COMPLETE
) != 0)
1836 unit
->ByteOut(unit
->card
, window1_offset
+ EL3REG_TXSTATUS
, 0);
1839 /* Restart transmitter if necessary */
1841 if((flags
& EL3REG_TXSTATUSF_JABBER
) != 0)
1844 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_TXRESET
);
1845 while((unit
->LEWordIn(unit
->card
, EL3REG_STATUS
) &
1846 EL3REG_STATUSF_CMDINPROGRESS
) != 0);
1850 if((flags
& (EL3REG_TXSTATUSF_JABBER
| EL3REG_TXSTATUSF_OVERFLOW
1851 | EL3REG_TXSTATUSF_RECLAIMERROR
)) != 0)
1852 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_TXENABLE
);
1854 /* Report the error(s) */
1856 ReportEvents(unit
, S2EVENT_ERROR
| S2EVENT_HARDWARE
| S2EVENT_TX
, base
);
1863 /****i* etherlink3.device/UpdateStats **************************************
1871 * VOID UpdateStats(struct DevUnit *);
1873 ****************************************************************************
1877 VOID
UpdateStats(struct DevUnit
*unit
, struct DevBase
*base
)
1879 UBYTE frame_counts_upper
;
1880 UWORD generation
, old_window
;
1882 generation
= unit
->generation
;
1885 unit
->LEWordIn(unit
->card
, EL3REG_STATUS
) >> EL3REG_STATUSB_WINDOW
;
1886 if(generation
< VORTEX_GEN
)
1887 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_STATSDISABLE
);
1889 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 6);
1890 unit
->ByteIn(unit
->card
, EL3REG_CARRIERLOST
);
1891 unit
->ByteIn(unit
->card
, EL3REG_SQEERRORS
);
1892 unit
->ByteIn(unit
->card
, EL3REG_MULTIPLECOLLISIONS
);
1893 unit
->ByteIn(unit
->card
, EL3REG_SINGLECOLLISIONS
);
1894 unit
->ByteIn(unit
->card
, EL3REG_LATECOLLISIONS
);
1895 unit
->stats
.Overruns
+= unit
->ByteIn(unit
->card
, EL3REG_RXOVERRUNS
);
1896 unit
->stats
.PacketsSent
+= unit
->ByteIn(unit
->card
, EL3REG_TXFRAMESOK
);
1897 unit
->stats
.PacketsReceived
+=
1898 unit
->ByteIn(unit
->card
, EL3REG_RXFRAMESOK
);
1899 unit
->special_stats
[S2SS_ETHERNET_RETRIES
& 0xffff] +=
1900 unit
->ByteIn(unit
->card
, EL3REG_FRAMESDEFERRED
);
1901 unit
->LEWordIn(unit
->card
, EL3REG_RXBYTESOK
);
1902 unit
->LEWordIn(unit
->card
, EL3REG_TXBYTESOK
);
1903 if(generation
>= VORTEX_GEN
)
1905 frame_counts_upper
= unit
->ByteIn(unit
->card
, EL3REG_FRAMESOKUPPER
);
1906 unit
->stats
.PacketsReceived
+= (frame_counts_upper
& 0x3) << 8;
1907 unit
->stats
.PacketsSent
+= (frame_counts_upper
& 0x30) << 4;
1908 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_SELECTWINDOW
| 4);
1909 unit
->ByteIn(unit
->card
, EL3REG_BADSSD
);
1910 if(generation
>= BOOMERANG_GEN
)
1911 unit
->ByteIn(unit
->card
, EL3REG_BYTESOKUPPER
);
1914 if(generation
< VORTEX_GEN
)
1915 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_STATSENABLE
);
1916 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
1917 EL3CMD_SELECTWINDOW
| old_window
);
1923 /****i* etherlink3.device/DMARXInt *****************************************
1929 * DMARXInt(unit, int_code)
1931 * VOID DMARXInt(struct DevUnit *, APTR);
1933 ****************************************************************************
1937 static VOID
DMARXInt(REG(a1
, struct DevUnit
*unit
),
1938 REG(a5
, APTR int_code
))
1941 struct DevBase
*base
;
1942 BOOL is_orphan
, accepted
;
1943 ULONG rx_status
, packet_type
, *upd
, *fragment
, dma_size
;
1945 struct IOSana2Req
*request
, *request_tail
;
1946 struct Opener
*opener
, *opener_tail
;
1947 struct TypeStats
*tracker
;
1949 base
= unit
->device
;
1950 upd
= unit
->next_upd
;
1952 dma_size
= UPD_SIZE
* RX_SLOT_COUNT
;
1953 CachePostDMA(unit
->upds
, &dma_size
, 0);
1955 while(((rx_status
= LELong(upd
[EL3UPD_STATUS
]))
1956 & EL3UPD_STATUSF_COMPLETE
) != 0)
1958 fragment
= upd
+ EL3UPD_FIRSTFRAG
;
1959 buffer
= (UBYTE
*)(UPINT
)LELong(fragment
[EL3FRAG_ADDR
]);
1961 dma_size
= ETH_MAXPACKETSIZE
;
1962 CachePostDMA(buffer
, &dma_size
, 0);
1964 if((rx_status
& EL3UPD_STATUSF_ERROR
) == 0)
1967 packet_size
= rx_status
& EL3UPD_STATUSF_SIZE
;
1969 if(AddressFilter(unit
, buffer
+ ETH_PACKET_DEST
, base
))
1971 packet_type
= BEWord(*((UWORD
*)(buffer
+ ETH_PACKET_TYPE
)));
1973 opener
= (APTR
)unit
->openers
.mlh_Head
;
1974 opener_tail
= (APTR
)&unit
->openers
.mlh_Tail
;
1976 /* Offer packet to every opener */
1978 while(opener
!= opener_tail
)
1980 request
= (APTR
)opener
->read_port
.mp_MsgList
.lh_Head
;
1981 request_tail
= (APTR
)&opener
->read_port
.mp_MsgList
.lh_Tail
;
1984 /* Offer packet to each request until it's accepted */
1986 while((request
!= request_tail
) && !accepted
)
1988 if(request
->ios2_PacketType
== packet_type
1989 || request
->ios2_PacketType
<= ETH_MTU
1990 && packet_type
<= ETH_MTU
)
1992 CopyPacket(unit
, request
, packet_size
, packet_type
,
1993 buffer
, TRUE
, base
);
1997 (APTR
)request
->ios2_Req
.io_Message
.mn_Node
.ln_Succ
;
2002 opener
= (APTR
)opener
->node
.mln_Succ
;
2005 /* If packet was unwanted, give it to S2_READORPHAN request */
2009 unit
->stats
.UnknownTypesReceived
++;
2010 if(!IsMsgPortEmpty(unit
->request_ports
[ADOPT_QUEUE
]))
2013 (APTR
)unit
->request_ports
[ADOPT_QUEUE
]->
2014 mp_MsgList
.lh_Head
, packet_size
, packet_type
, buffer
,
2019 /* Update remaining statistics */
2022 FindTypeStats(unit
, &unit
->type_trackers
, packet_type
, base
);
2025 tracker
->stats
.PacketsReceived
++;
2026 tracker
->stats
.BytesReceived
+= packet_size
;
2032 unit
->stats
.BadData
++;
2033 ReportEvents(unit
, S2EVENT_ERROR
| S2EVENT_HARDWARE
| S2EVENT_RX
,
2037 upd
[EL3UPD_STATUS
] = 0;
2039 dma_size
= ETH_MAXPACKETSIZE
;
2040 CachePreDMA(buffer
, &dma_size
, 0);
2042 upd
= (ULONG
*)(UPINT
)LELong(upd
[EL3UPD_NEXT
]);
2045 dma_size
= UPD_SIZE
* RX_SLOT_COUNT
;
2046 CachePreDMA(unit
->upds
, &dma_size
, 0);
2050 unit
->next_upd
= upd
;
2051 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
, EL3CMD_UPUNSTALL
);
2053 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
2054 EL3CMD_SETINTMASK
| unit
->int_mask
);
2061 /****i* etherlink3.device/DMATXInt *****************************************
2067 * DMATXInt(unit, int_code)
2069 * VOID DMATXInt(struct DevUnit *, APTR);
2071 ****************************************************************************
2075 static VOID
DMATXInt(REG(a1
, struct DevUnit
*unit
),
2076 REG(a5
, APTR int_code
))
2078 UWORD packet_size
, data_size
, slot
, new_slot
, *p
, *q
, i
;
2079 struct DevBase
*base
;
2080 struct IOSana2Req
*request
;
2081 BOOL proceed
= TRUE
;
2082 struct Opener
*opener
;
2083 ULONG wire_error
, *dpd
, *last_dpd
, *next_dpd
, *fragment
, dma_size
;
2084 UBYTE
*(*dma_tx_function
)(REG(a0
, APTR
));
2087 struct MsgPort
*port
;
2089 base
= unit
->device
;
2090 port
= unit
->request_ports
[WRITE_QUEUE
];
2092 while(proceed
&& (!IsMsgPortEmpty(port
)))
2094 slot
= unit
->tx_in_slot
;
2095 new_slot
= (slot
+ 1) % TX_SLOT_COUNT
;
2097 if(new_slot
!= unit
->tx_out_slot
2098 && (unit
->flags
& UNITF_TXBUFFERINUSE
) == 0)
2102 request
= (APTR
)port
->mp_MsgList
.lh_Head
;
2103 data_size
= packet_size
= request
->ios2_DataLength
;
2105 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
2106 packet_size
+= ETH_HEADERSIZE
;
2107 dpd
= unit
->dpds
+ ((DPD_SIZE
/ sizeof(ULONG
)) * slot
);
2109 /* Write packet preamble */
2111 Remove((APTR
)request
);
2112 unit
->tx_requests
[slot
] = request
;
2113 dpd
[EL3DPD_NEXT
] = (ULONG
)0;
2114 dpd
[EL3DPD_HEADER
] =
2115 MakeLELong(EL3DPD_HEADERF_DLINT
| packet_size
);
2116 fragment
= dpd
+ EL3DPD_FIRSTFRAG
;
2118 /* Write packet header */
2120 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
2122 buffer
= unit
->headers
+ ETH_HEADERSIZE
* slot
;
2123 fragment
[EL3FRAG_ADDR
] = MakeLELong((ULONG
)(UPINT
)buffer
);
2124 fragment
[EL3FRAG_LEN
] = MakeLELong(ETH_HEADERSIZE
);
2126 p
= (UWORD
*)buffer
;
2127 for(i
= 0, q
= (UWORD
*)request
->ios2_DstAddr
;
2128 i
< ETH_ADDRESSSIZE
/ 2; i
++)
2130 for(i
= 0, q
= (UWORD
*)unit
->address
;
2131 i
< ETH_ADDRESSSIZE
/ 2; i
++)
2133 *p
++ = MakeBEWord(request
->ios2_PacketType
);
2134 buffer
= (UBYTE
*)p
;
2136 dma_size
= ETH_HEADERSIZE
;
2137 CachePreDMA(buffer
, &dma_size
, DMA_ReadFromRAM
);
2138 fragment
+= EL3_FRAGLEN
;
2141 /* Get packet data */
2143 opener
= (APTR
)request
->ios2_BufferManagement
;
2144 dma_tx_function
= opener
->dma_tx_function
;
2145 if(dma_tx_function
!= NULL
)
2146 buffer
= dma_tx_function(request
->ios2_Data
);
2152 buffer
= unit
->tx_buffer
;
2153 if(opener
->tx_function(buffer
, request
->ios2_Data
, data_size
))
2154 unit
->flags
|= UNITF_TXBUFFERINUSE
;
2157 error
= S2ERR_NO_RESOURCES
;
2158 wire_error
= S2WERR_BUFF_ERROR
;
2160 S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
2161 | S2EVENT_TX
, base
);
2165 /* Fill in rest of descriptor for packet transmission */
2169 fragment
[EL3FRAG_ADDR
] = MakeLELong((ULONG
)(UPINT
)buffer
);
2170 fragment
[EL3FRAG_LEN
] =
2171 MakeLELong(EL3FRAG_LENF_LAST
| data_size
);
2173 /* Pass packet to adapter */
2175 dma_size
= data_size
;
2176 CachePreDMA(buffer
, &dma_size
, DMA_ReadFromRAM
);
2178 last_dpd
= (ULONG
*)(UPINT
)
2179 unit
->LELongIn(unit
->card
, EL3REG_DOWNLIST
);
2180 if(last_dpd
!= NULL
)
2182 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
2184 while((unit
->LEWordIn(unit
->card
, EL3REG_STATUS
)
2185 & EL3REG_STATUSF_CMDINPROGRESS
) != 0);
2187 (ULONG
*)(UPINT
)LELong(last_dpd
[EL3DPD_NEXT
])) != NULL
)
2188 last_dpd
= next_dpd
;
2189 last_dpd
[EL3DPD_NEXT
] = MakeLELong((ULONG
)(UPINT
)dpd
);
2190 dma_size
= DPD_SIZE
* TX_SLOT_COUNT
;
2191 CachePreDMA(unit
->dpds
, &dma_size
, 0);
2192 unit
->LEWordOut(unit
->card
, EL3REG_COMMAND
,
2193 EL3CMD_DOWNUNSTALL
);
2197 dma_size
= DPD_SIZE
* TX_SLOT_COUNT
;
2198 CachePreDMA(unit
->dpds
, &dma_size
, 0);
2199 unit
->LELongOut(unit
->card
, EL3REG_DOWNLIST
,
2203 unit
->tx_in_slot
= new_slot
;
2207 /* Reply failed request */
2209 request
->ios2_Req
.io_Error
= error
;
2210 request
->ios2_WireError
= wire_error
;
2211 ReplyMsg((APTR
)request
);
2219 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_SOFTINT
;
2221 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_IGNORE
;
2228 /****i* etherlink3.device/DMATXEndInt **************************************
2234 * DMATXEndInt(unit, int_code)
2236 * VOID DMATXEndInt(struct DevUnit *, APTR);
2239 * I think it's safe to assume that there will always be at least one
2240 * completed packet whenever this interrupt is called.
2242 ****************************************************************************
2246 static VOID
DMATXEndInt(REG(a1
, struct DevUnit
*unit
),
2247 REG(a5
, APTR int_code
))
2249 UWORD data_size
, packet_size
, new_out_slot
, i
;
2251 struct DevBase
*base
;
2252 struct IOSana2Req
*request
;
2253 ULONG
*dpd
, *fragment
, dma_size
;
2254 struct TypeStats
*tracker
;
2256 /* Find out which packets have completed */
2258 base
= unit
->device
;
2259 dpd
= (ULONG
*)(UPINT
)unit
->LELongIn(unit
->card
, EL3REG_DOWNLIST
);
2261 new_out_slot
= (dpd
- unit
->dpds
) / (sizeof(ULONG
) * DPD_SIZE
);
2263 new_out_slot
= unit
->tx_in_slot
;
2265 /* Retire sent packets */
2267 for(i
= unit
->tx_out_slot
; i
!= new_out_slot
;
2268 i
= (i
+ 1) % TX_SLOT_COUNT
)
2270 /* Mark end of DMA */
2272 request
= unit
->tx_requests
[i
];
2273 data_size
= packet_size
= request
->ios2_DataLength
;
2274 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
2275 packet_size
+= ETH_HEADERSIZE
;
2277 dpd
= unit
->dpds
+ ((DPD_SIZE
/ sizeof(ULONG
)) * i
);
2278 fragment
= dpd
+ EL3DPD_FIRSTFRAG
;
2279 dma_size
= DPD_SIZE
* TX_SLOT_COUNT
;
2280 CachePostDMA(unit
->dpds
, &dma_size
, 0);
2282 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
2284 buffer
= (APTR
)(UPINT
)LELong(fragment
[EL3FRAG_ADDR
]);
2285 dma_size
= ETH_HEADERSIZE
;
2286 CachePostDMA(buffer
, &dma_size
, DMA_ReadFromRAM
);
2287 fragment
+= EL3_FRAGLEN
;
2290 buffer
= (APTR
)(UPINT
)LELong(fragment
[EL3FRAG_ADDR
]);
2291 dma_size
= data_size
;
2292 CachePostDMA(buffer
, &dma_size
, DMA_ReadFromRAM
);
2294 /* Check if unit's TX buffer is now free */
2296 if(buffer
== unit
->tx_buffer
)
2297 unit
->flags
&= ~UNITF_TXBUFFERINUSE
;
2299 /* Update statistics */
2301 tracker
= FindTypeStats(unit
, &unit
->type_trackers
,
2302 request
->ios2_PacketType
, base
);
2305 tracker
->stats
.PacketsSent
++;
2306 tracker
->stats
.BytesSent
+= packet_size
;
2311 request
->ios2_Req
.io_Error
= 0;
2312 ReplyMsg((APTR
)request
);
2315 unit
->tx_out_slot
= new_out_slot
;
2317 /* Restart downloads if they had stopped */
2319 if(unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
== PA_IGNORE
)
2320 Cause(&unit
->tx_int
);
2327 /****i* etherlink3.device/ReportEvents *************************************
2333 * ReportEvents(unit, events)
2335 * VOID ReportEvents(struct DevUnit *, ULONG);
2338 * unit - A unit of this device.
2339 * events - A mask of events to report.
2344 ****************************************************************************
2348 static VOID
ReportEvents(struct DevUnit
*unit
, ULONG events
,
2349 struct DevBase
*base
)
2351 struct IOSana2Req
*request
, *tail
, *next_request
;
2354 list
= &unit
->request_ports
[EVENT_QUEUE
]->mp_MsgList
;
2355 next_request
= (APTR
)list
->lh_Head
;
2356 tail
= (APTR
)&list
->lh_Tail
;
2359 while(next_request
!= tail
)
2361 request
= next_request
;
2362 next_request
= (APTR
)request
->ios2_Req
.io_Message
.mn_Node
.ln_Succ
;
2364 if((request
->ios2_WireError
& events
) != 0)
2366 request
->ios2_WireError
= events
;
2367 Remove((APTR
)request
);
2368 ReplyMsg((APTR
)request
);
2378 /****i* etherlink3.device/UnitTask *****************************************
2402 ****************************************************************************
2406 static VOID
UnitTask(struct ExecBase
*sys_base
)
2409 struct IORequest
*request
;
2410 struct DevUnit
*unit
;
2411 struct DevBase
*base
;
2412 struct MsgPort
*general_port
;
2413 ULONG signals
, wait_signals
, card_removed_signal
, card_inserted_signal
,
2414 general_port_signal
;
2416 /* Get parameters */
2418 task
= FindTask(NULL
);
2419 unit
= task
->tc_UserData
;
2420 base
= unit
->device
;
2422 /* Activate general request port */
2424 general_port
= unit
->request_ports
[GENERAL_QUEUE
];
2425 general_port
->mp_SigTask
= task
;
2426 general_port
->mp_SigBit
= AllocSignal(-1);
2427 general_port_signal
= 1 << general_port
->mp_SigBit
;
2428 general_port
->mp_Flags
= PA_SIGNAL
;
2430 /* Allocate a signal for notification of card removal */
2432 card_removed_signal
= unit
->card_removed_signal
= 1 << AllocSignal(-1);
2433 card_inserted_signal
= unit
->card_inserted_signal
= 1 << AllocSignal(-1);
2434 wait_signals
= (1 << general_port
->mp_SigBit
) | card_removed_signal
2435 | card_inserted_signal
;
2437 /* Tell ourselves to check port for old messages */
2439 Signal(task
, general_port_signal
);
2441 /* Infinite loop to service requests and signals */
2445 signals
= Wait(wait_signals
);
2447 if((signals
& card_inserted_signal
) != 0)
2449 if(unit
->insertion_function(unit
->card
, base
))
2451 unit
->flags
|= UNITF_HAVEADAPTER
;
2452 if((unit
->flags
& UNITF_CONFIGURED
) != 0)
2453 ConfigureAdapter(unit
, base
);
2457 if((signals
& card_removed_signal
) != 0)
2459 unit
->removal_function(unit
->card
, base
);
2460 GoOffline(unit
, base
);
2463 if((signals
& general_port_signal
) != 0)
2465 while((request
= (APTR
)GetMsg(general_port
)) != NULL
)
2467 /* Service the request as soon as the unit is free */
2469 ObtainSemaphore(&unit
->access_lock
);
2470 ServiceRequest((APTR
)request
, base
);
2478 /****i* etherlink3.device/ReadEEPROM ***************************************
2481 * ReadEEPROM -- Read a location on card's EEPROM.
2484 * value = ReadEEPROM(unit, index)
2486 * UWORD ReadEEPROM(struct DevUnit *, UWORD);
2489 * unit - Device unit.
2490 * index - Offset within EEPROM.
2493 * value - Contents of specified EEPROM location.
2495 ****************************************************************************
2499 static UWORD
ReadEEPROM(struct DevUnit
*unit
, UWORD index
,
2500 struct DevBase
*base
)
2502 unit
->LEWordOut(unit
->card
, EL3REG_EEPROMCMD
, EL3ECMD_READ
| index
);
2503 while((unit
->LEWordIn(unit
->card
, EL3REG_EEPROMCMD
) &
2504 EL3REG_EEPROMCMDF_BUSY
) != 0);
2506 return unit
->LEWordIn(unit
->card
, EL3REG_EEPROMDATA
);
2511 /****i* etherlink3.device/ReadMII ******************************************
2514 * ReadMII -- Read a register on an MII PHY.
2517 * success = ReadMII(unit, phy_no, reg_no, value)
2519 * BOOL ReadMII(struct DevUnit *, UWORD, UWORD, UWORD *);
2522 * Reads a register on an MII PHY. Window 4 must be selected before
2523 * calling this function.
2526 * unit - Device unit.
2529 * value - Pointer to location to store value read from MII register.
2532 * success - Success indicator.
2534 ****************************************************************************
2538 static BOOL
ReadMII(struct DevUnit
*unit
, UWORD phy_no
, UWORD reg_no
,
2539 UWORD
*value
, struct DevBase
*base
)
2541 BOOL success
= TRUE
;
2543 WriteMIIBits(unit
, 0xffffffff, 32, base
);
2544 WriteMIIBits(unit
, 0x6, 4, base
);
2545 WriteMIIBits(unit
, phy_no
, 5, base
);
2546 WriteMIIBits(unit
, reg_no
, 5, base
);
2547 ReadMIIBit(unit
, base
);
2548 if(ReadMIIBit(unit
, base
))
2550 *value
= ReadMIIBits(unit
, 16, base
);
2551 ReadMIIBit(unit
, base
);
2558 /****i* etherlink3.device/WriteMII *****************************************
2561 * WriteMII -- Write to a register on an MII PHY.
2564 * WriteMII(unit, phy_no, reg_no, value)
2566 * VOID WriteMII(struct DevUnit *, UWORD, UWORD, UWORD);
2569 * unit - Device unit.
2572 * value - value to write to MII register.
2577 ****************************************************************************
2582 static VOID
WriteMII(struct DevUnit
*unit
, UWORD phy_no
, UWORD reg_no
,
2583 UWORD value
, struct DevBase
*base
)
2585 WriteMIIBits(unit
, 0xffffffff, 32, base
);
2586 WriteMIIBits(unit
, 0x5, 4, base
);
2587 WriteMIIBits(unit
, phy_no
, 5, base
);
2588 WriteMIIBits(unit
, reg_no
, 5, base
);
2589 WriteMIIBit(unit
, TRUE
, base
);
2590 WriteMIIBits(unit
, value
, 16, base
);
2591 DoMIIZCycle(unit
, base
);
2599 /****i* etherlink3.device/ReadMIIBits **************************************
2605 * value = ReadMIIBits(unit, count)
2607 * ULONG ReadMIIBits(struct DevUnit *, UBYTE);
2609 ****************************************************************************
2613 static ULONG
ReadMIIBits(struct DevUnit
*unit
, UBYTE count
,
2614 struct DevBase
*base
)
2619 /* LEWordOut(io_addr, LEWordIn(reg) & ~EL3REG_PHYMGMTF_WRITE);*/
2620 for(i
= 0; i
< count
; i
++)
2623 if(ReadMIIBit(unit
, base
))
2625 unit
->LEWordIn(unit
->card
, EL3REG_PHYMGMT
);
2627 /* ReadMIIBit(unit, base)? value |= 1;*/
2633 /****i* etherlink3.device/WriteMIIBits *************************************
2639 * WriteMIIBits(unit, value, count)
2641 * VOID WriteMIIBits(struct DevUnit *, ULONG, UBYTE);
2643 ****************************************************************************
2647 static VOID
WriteMIIBits(struct DevUnit
*unit
, ULONG value
, UBYTE count
,
2648 struct DevBase
*base
)
2652 for(mask
= 1 << (count
- 1); mask
!= 0; mask
>>= 1)
2653 WriteMIIBit(unit
, (value
& mask
) != 0, base
);
2660 /****i* etherlink3.device/ReadMIIBit ***************************************
2666 * is_one = ReadMIIBit(unit)
2668 * BOOL ReadMIIBit(struct DevUnit *);
2670 ****************************************************************************
2674 static BOOL
ReadMIIBit(struct DevUnit
*unit
, struct DevBase
*base
)
2678 unit
->LEWordOut(unit
->card
, EL3REG_PHYMGMT
, 0);
2679 BusyMicroDelay(1, base
);
2680 unit
->LEWordOut(unit
->card
, EL3REG_PHYMGMT
, EL3REG_PHYMGMTF_CLK
);
2681 BusyMicroDelay(1, base
);
2683 (unit
->LEWordIn(unit
->card
, EL3REG_PHYMGMT
) & EL3REG_PHYMGMTF_DATA
)
2685 BusyMicroDelay(1, base
);
2692 /****i* etherlink3.device/WriteMIIBit **************************************
2698 * WriteMIIBit(unit, is_one)
2700 * VOID WriteMIIBit(struct DevUnit *, BOOL);
2702 ****************************************************************************
2706 static VOID
WriteMIIBit(struct DevUnit
*unit
, BOOL is_one
,
2707 struct DevBase
*base
)
2709 unit
->LEWordOut(unit
->card
, EL3REG_PHYMGMT
, EL3REG_PHYMGMTF_WRITE
);
2710 BusyMicroDelay(1, base
);
2712 unit
->LEWordOut(unit
->card
, EL3REG_PHYMGMT
,
2713 EL3REG_PHYMGMTF_WRITE
| EL3REG_PHYMGMTF_CLK
|
2714 EL3REG_PHYMGMTF_DATA
);
2716 unit
->LEWordOut(unit
->card
, EL3REG_PHYMGMT
,
2717 EL3REG_PHYMGMTF_WRITE
| EL3REG_PHYMGMTF_CLK
);
2718 BusyMicroDelay(1, base
);
2725 /****i* etherlink3.device/DoMIIZCycle **************************************
2733 * VOID DoMIIZCycle(struct DevUnit *);
2735 ****************************************************************************
2740 static VOID
DoMIIZCycle(struct DevUnit
*unit
, struct DevBase
*base
)
2742 unit
->LEWordOut(unit
->card
, EL3REG_PHYMGMT
,
2743 unit
->LEWordIn(unit
->card
, EL3REG_PHYMGMT
) & ~EL3REG_PHYMGMTF_CLK
);
2744 BusyMicroDelay(1, base
);
2745 unit
->LEWordOut(unit
->card
, EL3REG_PHYMGMT
, EL3REG_PHYMGMTF_CLK
);
2746 BusyMicroDelay(1, base
);
2755 static VOID
BusyMicroDelay(ULONG micros
, struct DevBase
*base
)
2757 struct timeval time
, end_time
;
2759 GetSysTime(&end_time
);
2761 time
.tv_micro
= micros
;
2762 AddTime(&end_time
, &time
);
2764 while(CmpTime(&end_time
, &time
) < 0)
2772 static VOID
BusyMicroDelay(ULONG micros
, struct DevBase
*base
)
2774 struct EClockVal time
, end_time
;
2777 rate
= ReadEClock(&time
);
2778 end_time
.ev_hi
= time
.ev_hi
;
2779 end_time
.ev_lo
= time
.ev_lo
+ (micros
* rate
+ 1) / 1000000;
2780 if(end_time
.ev_lo
< time
.ev_lo
)
2783 while(time
.ev_lo
< end_time
.ev_lo
|| time
.ev_hi
< end_time
.ev_hi
)