3 Copyright (C) 2001-2017 Neil Cafferkey
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23 #include <exec/memory.h>
24 #include <exec/execbase.h>
25 #include <exec/errors.h>
26 #include <exec/tasks.h>
28 #include <proto/exec.h>
29 #include <proto/alib.h>
30 #include <proto/utility.h>
31 #include <proto/timer.h>
37 #include "unit_protos.h"
38 #include "request_protos.h"
39 #include "timer_protos.h"
42 #define TASK_PRIORITY 0
43 #define STACK_SIZE 4096
44 #define INT_MASK 0xffff
45 #define TX_DESC_SIZE (RH_DESCSIZE * 2 + ETH_HEADERSIZE + 2)
47 VOID
DeinitialiseAdapter(struct DevUnit
*unit
, struct DevBase
*base
);
48 static struct AddressRange
*FindMulticastRange(struct DevUnit
*unit
,
49 ULONG lower_bound_left
, UWORD lower_bound_right
, ULONG upper_bound_left
,
50 UWORD upper_bound_right
, struct DevBase
*base
);
51 static VOID
SetMulticast(struct DevUnit
*unit
, struct DevBase
*base
);
52 static BOOL
StatusInt(REG(a1
, struct DevUnit
*unit
), REG(a5
, APTR int_code
));
53 static VOID
RXInt(REG(a1
, struct DevUnit
*unit
), REG(a6
, APTR int_code
));
54 static VOID
DistributeRXPacket(struct DevUnit
*unit
, const UBYTE
*packet
,
55 UWORD packet_size
, struct DevBase
*base
);
56 static VOID
CopyPacket(struct DevUnit
*unit
, struct IOSana2Req
*request
,
57 UWORD packet_size
, UWORD packet_type
, const UBYTE
*buffer
,
58 struct DevBase
*base
);
59 static BOOL
AddressFilter(struct DevUnit
*unit
, UBYTE
*address
,
60 struct DevBase
*base
);
61 static VOID
TXInt(REG(a1
, struct DevUnit
*unit
), REG(a6
, APTR int_code
));
62 static VOID
TXEndInt(REG(a1
, struct DevUnit
*unit
), REG(a5
, APTR int_code
));
63 static VOID
RetireTXSlot(struct DevUnit
*unit
, UWORD slot
,
64 struct DevBase
*base
);
65 static VOID
ResetHandler(REG(a1
, struct DevUnit
*unit
),
66 REG(a6
, APTR int_code
));
67 static VOID
ReportEvents(struct DevUnit
*unit
, ULONG events
,
68 struct DevBase
*base
);
69 static VOID
UnitTask(struct DevUnit
*unit
);
70 UWORD
ReadMII(struct DevUnit
*unit
, UWORD phy_no
, UWORD reg_no
,
71 struct DevBase
*base
);
75 /****i* rhine.device/CreateUnit ********************************************
78 * CreateUnit -- Create a unit.
81 * unit = CreateUnit(index, io_base, id, card,
84 * struct DevUnit *CreateUnit(ULONG, APTR, UWORD, APTR,
85 * struct TagItem *, UWORD);
90 ****************************************************************************
94 struct DevUnit
*CreateUnit(ULONG index
, APTR card
,
95 const struct TagItem
*io_tags
, UWORD bus
, struct DevBase
*base
)
100 struct MsgPort
*port
;
102 ULONG
*desc
, desc_p
, buffer_p
, dma_size
;
105 unit
= AllocMem(sizeof(struct DevUnit
), MEMF_CLEAR
| MEMF_PUBLIC
);
111 /* Initialise lists etc. */
113 NewList((APTR
)&unit
->openers
);
114 NewList((APTR
)&unit
->type_trackers
);
115 NewList((APTR
)&unit
->multicast_ranges
);
122 /* Store I/O hooks */
125 (APTR
)GetTagData(IOTAG_ByteIn
, (UPINT
)NULL
, io_tags
);
127 (APTR
)GetTagData(IOTAG_ByteOut
, (UPINT
)NULL
, io_tags
);
129 (APTR
)GetTagData(IOTAG_LEWordIn
, (UPINT
)NULL
, io_tags
);
131 (APTR
)GetTagData(IOTAG_LELongIn
, (UPINT
)NULL
, io_tags
);
133 (APTR
)GetTagData(IOTAG_LEWordOut
, (UPINT
)NULL
, io_tags
);
135 (APTR
)GetTagData(IOTAG_LELongOut
, (UPINT
)NULL
, io_tags
);
137 (APTR
)GetTagData(IOTAG_AllocDMAMem
, (UPINT
)NULL
, io_tags
);
139 (APTR
)GetTagData(IOTAG_FreeDMAMem
, (UPINT
)NULL
, io_tags
);
140 if(unit
->ByteIn
== NULL
141 || unit
->ByteOut
== NULL
142 || unit
->LEWordIn
== NULL
143 || unit
->LELongIn
== NULL
144 || unit
->LEWordOut
== NULL
145 || unit
->LELongOut
== NULL
146 || unit
->AllocDMAMem
== NULL
147 || unit
->FreeDMAMem
== NULL
)
153 InitSemaphore(&unit
->access_lock
);
155 /* Create the message ports for queuing requests */
157 for(i
= 0; i
< REQUEST_QUEUE_COUNT
; i
++)
159 unit
->request_ports
[i
] = port
= AllocMem(sizeof(struct MsgPort
),
160 MEMF_PUBLIC
| MEMF_CLEAR
);
166 NewList(&port
->mp_MsgList
);
167 port
->mp_Flags
= PA_IGNORE
;
171 unit
->request_ports
[WRITE_QUEUE
]->mp_SigTask
= &unit
->tx_int
;
176 /* Allocate TX descriptors */
178 desc
= unit
->AllocDMAMem(unit
->card
, TX_DESC_SIZE
* TX_SLOT_COUNT
, 16);
185 /* Fill arrays of virtual and physical addresses of TX descriptors */
187 dma_size
= TX_DESC_SIZE
* TX_SLOT_COUNT
;
188 desc_p
= (ULONG
)(UPINT
)CachePreDMA(desc
, &dma_size
, 0);
189 if(dma_size
!= TX_DESC_SIZE
* TX_SLOT_COUNT
)
191 CachePostDMA(desc
, &dma_size
, 0);
193 for(i
= 0; i
< TX_SLOT_COUNT
; i
++)
195 unit
->tx_descs
[i
] = desc
;
196 desc
+= TX_DESC_SIZE
/ sizeof(ULONG
);
197 unit
->tx_descs_p
[i
] = desc_p
;
198 desc_p
+= TX_DESC_SIZE
;
204 /* Allocate RX descriptors */
206 desc
= unit
->AllocDMAMem(unit
->card
, RH_DESCSIZE
* RX_SLOT_COUNT
, 16);
213 /* Fill arrays of virtual and physical addresses of TX descriptors */
215 dma_size
= RH_DESCSIZE
* RX_SLOT_COUNT
;
216 desc_p
= (ULONG
)(UPINT
)CachePreDMA(desc
, &dma_size
, 0);
217 if(dma_size
!= RH_DESCSIZE
* RX_SLOT_COUNT
)
219 CachePostDMA(desc
, &dma_size
, 0);
221 for(i
= 0; i
< RX_SLOT_COUNT
; i
++)
223 unit
->rx_descs
[i
] = desc
;
224 desc
+= RH_DESCSIZE
/ sizeof(ULONG
);
225 unit
->rx_descs_p
[i
] = desc_p
;
226 desc_p
+= RH_DESCSIZE
;
229 /* Allocate packet buffers */
231 unit
->tx_buffer
= unit
->AllocDMAMem(unit
->card
, FRAME_BUFFER_SIZE
, 4);
232 if(unit
->tx_buffer
== NULL
)
235 for(i
= 0; i
< RX_SLOT_COUNT
; i
++)
237 unit
->rx_buffers
[i
] = unit
->AllocDMAMem(unit
->card
,
238 FRAME_BUFFER_SIZE
, 4);
239 if(unit
->rx_buffers
[i
] == NULL
)
243 unit
->tx_requests
= AllocVec(sizeof(APTR
) * TX_SLOT_COUNT
,
245 if(unit
->tx_requests
== NULL
)
251 /* Construct RX ring */
253 for(i
= 0; i
< RX_SLOT_COUNT
; i
++)
255 desc
= unit
->rx_descs
[i
];
256 desc
[RH_DESC_RXSTATUS
] = MakeLELong(RH_DESC_RXSTATUSF_INUSE
);
257 desc
[RH_DESC_RXCONTROL
] = MakeLELong(FRAME_BUFFER_SIZE
);
258 dma_size
= FRAME_BUFFER_SIZE
;
260 (ULONG
)(UPINT
)CachePreDMA(unit
->rx_buffers
[i
], &dma_size
, 0);
261 if(dma_size
!= FRAME_BUFFER_SIZE
)
263 desc
[RH_DESC_DATA
] = MakeLELong(buffer_p
);
265 MakeLELong(unit
->rx_descs_p
[(i
+ 1) % RX_SLOT_COUNT
]);
266 desc
+= RH_DESCSIZE
/ sizeof(ULONG
);
268 dma_size
= RH_DESCSIZE
* RX_SLOT_COUNT
;
269 CachePreDMA(unit
->rx_descs
, &dma_size
, 0);
274 /* Initialise network adapter hardware */
276 success
= InitialiseAdapter(unit
, FALSE
, base
);
277 unit
->flags
|= UNITF_HAVEADAPTER
;
282 /* Record maximum speed in BPS */
284 unit
->speed
= 100000000;
286 /* Initialise interrupts */
288 unit
->status_int
.is_Code
= (APTR
)StatusInt
;
289 unit
->status_int
.is_Data
= unit
;
291 unit
->rx_int
.is_Node
.ln_Name
=
292 base
->device
.dd_Library
.lib_Node
.ln_Name
;
293 unit
->rx_int
.is_Code
= (APTR
)RXInt
;
294 unit
->rx_int
.is_Data
= unit
;
296 unit
->tx_int
.is_Node
.ln_Name
=
297 base
->device
.dd_Library
.lib_Node
.ln_Name
;
298 unit
->tx_int
.is_Code
= (APTR
)TXInt
;
299 unit
->tx_int
.is_Data
= unit
;
301 unit
->tx_end_int
.is_Node
.ln_Name
=
302 base
->device
.dd_Library
.lib_Node
.ln_Name
;
303 unit
->tx_end_int
.is_Code
= (APTR
)TXEndInt
;
304 unit
->tx_end_int
.is_Data
= unit
;
306 unit
->reset_handler
.is_Node
.ln_Name
=
307 base
->device
.dd_Library
.lib_Node
.ln_Name
;
308 unit
->reset_handler
.is_Code
= (APTR
)ResetHandler
;
309 unit
->reset_handler
.is_Data
= unit
;
311 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_SOFTINT
;
313 /* Create a new task */
316 AllocMem(sizeof(struct Task
), MEMF_PUBLIC
| MEMF_CLEAR
);
323 stack
= AllocMem(STACK_SIZE
, MEMF_PUBLIC
);
330 /* Initialise and start task */
332 task
->tc_Node
.ln_Type
= NT_TASK
;
333 task
->tc_Node
.ln_Pri
= TASK_PRIORITY
;
334 task
->tc_Node
.ln_Name
= base
->device
.dd_Library
.lib_Node
.ln_Name
;
335 task
->tc_SPUpper
= stack
+ STACK_SIZE
;
336 task
->tc_SPLower
= stack
;
337 task
->tc_SPReg
= task
->tc_SPUpper
;
338 NewList(&task
->tc_MemEntry
);
340 if(AddUnitTask(task
, UnitTask
, unit
) != NULL
)
341 unit
->flags
|= UNITF_TASKADDED
;
348 DeleteUnit(unit
, base
);
357 /****i* rhine.device/DeleteUnit ********************************************
360 * DeleteUnit -- Delete a unit.
365 * VOID DeleteUnit(struct DevUnit *);
371 * unit - Device unit (may be NULL).
376 ****************************************************************************
380 VOID
DeleteUnit(struct DevUnit
*unit
, struct DevBase
*base
)
390 if((unit
->flags
& UNITF_TASKADDED
) != 0)
392 FreeMem(task
->tc_SPLower
, STACK_SIZE
);
393 FreeMem(task
, sizeof(struct Task
));
396 for(i
= 0; i
< REQUEST_QUEUE_COUNT
; i
++)
398 if(unit
->request_ports
[i
] != NULL
)
399 FreeMem(unit
->request_ports
[i
], sizeof(struct MsgPort
));
402 if((unit
->flags
& UNITF_ONLINE
) != 0) /* Needed! */
403 GoOffline(unit
, base
);
405 if((unit
->flags
& UNITF_HAVEADAPTER
) != 0)
406 DeinitialiseAdapter(unit
, base
);
408 for(i
= 0; i
< RX_SLOT_COUNT
; i
++)
409 unit
->FreeDMAMem(unit
->card
, unit
->rx_buffers
[i
]);
410 unit
->FreeDMAMem(unit
->card
, unit
->tx_buffer
);
411 unit
->FreeDMAMem(unit
->card
, unit
->rx_descs
[0]);
412 unit
->FreeDMAMem(unit
->card
, unit
->tx_descs
[0]);
414 FreeVec(unit
->tx_requests
);
416 FreeMem(unit
, sizeof(struct DevUnit
));
424 /****i* rhine.device/InitialiseAdapter *************************************
430 * success = InitialiseAdapter(unit, reinsertion)
432 * BOOL InitialiseAdapter(struct DevUnit *, BOOL);
441 * success - Success indicator.
443 ****************************************************************************
447 BOOL
InitialiseAdapter(struct DevUnit
*unit
, BOOL reinsertion
,
448 struct DevBase
*base
)
451 UBYTE
*p
, eeprom_reg
;
454 /* Reload data from EEPROM */
456 eeprom_reg
= unit
->ByteIn(unit
->card
, RH_REG_EEPROM
);
457 unit
->ByteOut(unit
->card
, RH_REG_EEPROM
,
458 eeprom_reg
| RH_REG_EEPROMF_LOAD
);
460 BusyMicroDelay(1, base
);
461 while((unit
->ByteIn(unit
->card
, RH_REG_EEPROM
) & RH_REG_EEPROMF_LOAD
)
464 /* Get default MAC address */
466 p
= unit
->default_address
;
467 for(i
= 0; i
< ETH_ADDRESSSIZE
; i
++)
468 *p
++ = unit
->ByteIn(unit
->card
, RH_REG_ADDRESS
+ i
);
470 /* Send reset command */
472 unit
->ByteOut(unit
->card
, RH_REG_CONTROL
+ 1, RH_REG_CONTROL1F_RESET
);
473 BusyMicroDelay(110, base
);
474 while((unit
->ByteIn(unit
->card
, RH_REG_CONTROL
+ 1)
475 & RH_REG_CONTROL1F_RESET
) != 0);
477 /* Disable interrupts */
479 unit
->LEWordOut(unit
->card
, RH_REG_INTSTATUS
, INT_MASK
);
480 unit
->LEWordOut(unit
->card
, RH_REG_INTMASK
, 0);
482 unit
->LEWordOut(unit
->card
, RH_REG_MIIINTMASK
, 0);
486 unit
->ByteOut(unit
->card
, RH_REG_MIICTRL
,
487 unit
->ByteIn(unit
->card
, RH_REG_MIICTRL
) | RH_REG_MIICTRLF_AUTOPOLL
);
490 unit
->mii_phy_no
= unit
->ByteIn(unit
->card
, RH_REG_MIICONFIG
)
491 & RH_REG_MIICONFIGF_PHYADDR
;
493 unit
->mii_phy_no
= 1;
502 /****i* rhine.device/DeinitialiseAdapter ***********************************
505 * DeinitialiseAdapter
508 * DeinitialiseAdapter(unit)
510 * VOID DeinitialiseAdapter(struct DevUnit *);
520 ****************************************************************************
524 VOID
DeinitialiseAdapter(struct DevUnit
*unit
, struct DevBase
*base
)
531 /****i* rhine.device/ConfigureAdapter **************************************
534 * ConfigureAdapter -- Set up card for transmission/reception.
537 * ConfigureAdapter(unit)
539 * VOID ConfigureAdapter(struct DevUnit *);
541 ****************************************************************************
545 VOID
ConfigureAdapter(struct DevUnit
*unit
, struct DevBase
*base
)
550 /* Set MAC address */
553 for(i
= 0; i
< ETH_ADDRESSSIZE
; i
++)
554 unit
->ByteOut(unit
->card
, RH_REG_ADDRESS
+ i
, *p
++);
558 unit
->LELongOut(unit
->card
, RH_REG_TXLIST
, unit
->tx_descs_p
[0]);
559 unit
->LELongOut(unit
->card
, RH_REG_RXLIST
, unit
->rx_descs_p
[0]);
561 /* Choose packet types to receive */
563 unit
->LEWordOut(unit
->card
, RH_REG_PCIBUSCONFIG
, 6);
564 unit
->ByteOut(unit
->card
, RH_REG_RXCONFIG
,
565 RH_REG_RXCONFIGF_BCAST
| RH_REG_RXCONFIGF_MCAST
);
574 /****i* rhine.device/GoOnline **********************************************
577 * GoOnline -- Enable transmission/reception.
582 * VOID GoOnline(struct DevUnit *);
584 ****************************************************************************
588 VOID
GoOnline(struct DevUnit
*unit
, struct DevBase
*base
)
590 /* Enable interrupts */
592 unit
->flags
|= UNITF_ONLINE
;
593 unit
->LEWordOut(unit
->card
, RH_REG_INTMASK
, INT_MASK
);
595 /* Enable frame transmission and reception */
597 unit
->LEWordOut(unit
->card
, RH_REG_CONTROL
, RH_REG_CONTROLF_TXENABLE
598 | RH_REG_CONTROLF_RXENABLE
| RH_REG_CONTROLF_START
);
600 /* Record start time and report Online event */
602 GetSysTime(&unit
->stats
.LastStart
);
603 ReportEvents(unit
, S2EVENT_ONLINE
, base
);
610 /****i* rhine.device/GoOffline *********************************************
613 * GoOffline -- Disable transmission/reception.
618 * VOID GoOffline(struct DevUnit *);
628 ****************************************************************************
632 VOID
GoOffline(struct DevUnit
*unit
, struct DevBase
*base
)
634 unit
->flags
&= ~UNITF_ONLINE
;
636 /* Flush pending read and write requests */
638 FlushUnit(unit
, MGMT_QUEUE
, S2ERR_OUTOFSERVICE
, base
);
640 /* Report Offline event and return */
642 ReportEvents(unit
, S2EVENT_OFFLINE
, base
);
648 /****i* rhine.device/AddMulticastRange *************************************
654 * success = AddMulticastRange(unit, lower_bound, upper_bound)
656 * BOOL AddMulticastRange(struct DevUnit *, UBYTE *, UBYTE *);
658 ****************************************************************************
662 BOOL
AddMulticastRange(struct DevUnit
*unit
, const UBYTE
*lower_bound
,
663 const UBYTE
*upper_bound
, struct DevBase
*base
)
665 struct AddressRange
*range
;
666 ULONG lower_bound_left
, upper_bound_left
;
667 UWORD lower_bound_right
, upper_bound_right
;
669 lower_bound_left
= BELong(*((ULONG
*)lower_bound
));
670 lower_bound_right
= BEWord(*((UWORD
*)(lower_bound
+ 4)));
671 upper_bound_left
= BELong(*((ULONG
*)upper_bound
));
672 upper_bound_right
= BEWord(*((UWORD
*)(upper_bound
+ 4)));
674 range
= FindMulticastRange(unit
, lower_bound_left
, lower_bound_right
,
675 upper_bound_left
, upper_bound_right
, base
);
681 range
= AllocMem(sizeof(struct AddressRange
), MEMF_PUBLIC
);
684 range
->lower_bound_left
= lower_bound_left
;
685 range
->lower_bound_right
= lower_bound_right
;
686 range
->upper_bound_left
= upper_bound_left
;
687 range
->upper_bound_right
= upper_bound_right
;
688 range
->add_count
= 1;
691 AddTail((APTR
)&unit
->multicast_ranges
, (APTR
)range
);
693 SetMulticast(unit
, base
);
698 return range
!= NULL
;
703 /****i* rhine.device/RemMulticastRange *************************************
709 * found = RemMulticastRange(unit, lower_bound, upper_bound)
711 * BOOL RemMulticastRange(struct DevUnit *, UBYTE *, UBYTE *);
713 ****************************************************************************
717 BOOL
RemMulticastRange(struct DevUnit
*unit
, const UBYTE
*lower_bound
,
718 const UBYTE
*upper_bound
, struct DevBase
*base
)
720 struct AddressRange
*range
;
721 ULONG lower_bound_left
, upper_bound_left
;
722 UWORD lower_bound_right
, upper_bound_right
;
724 lower_bound_left
= BELong(*((ULONG
*)lower_bound
));
725 lower_bound_right
= BEWord(*((UWORD
*)(lower_bound
+ 4)));
726 upper_bound_left
= BELong(*((ULONG
*)upper_bound
));
727 upper_bound_right
= BEWord(*((UWORD
*)(upper_bound
+ 4)));
729 range
= FindMulticastRange(unit
, lower_bound_left
, lower_bound_right
,
730 upper_bound_left
, upper_bound_right
, base
);
734 if(--range
->add_count
== 0)
739 SetMulticast(unit
, base
);
741 FreeMem(range
, sizeof(struct AddressRange
));
745 return range
!= NULL
;
750 /****i* rhine.device/FindMulticastRange ************************************
756 * range = FindMulticastRange(unit, lower_bound_left,
757 * lower_bound_right, upper_bound_left, upper_bound_right)
759 * struct AddressRange *FindMulticastRange(struct DevUnit *, ULONG,
760 * UWORD, ULONG, UWORD);
762 ****************************************************************************
766 static struct AddressRange
*FindMulticastRange(struct DevUnit
*unit
,
767 ULONG lower_bound_left
, UWORD lower_bound_right
, ULONG upper_bound_left
,
768 UWORD upper_bound_right
, struct DevBase
*base
)
770 struct AddressRange
*range
, *tail
;
773 range
= (APTR
)unit
->multicast_ranges
.mlh_Head
;
774 tail
= (APTR
)&unit
->multicast_ranges
.mlh_Tail
;
776 while(range
!= tail
&& !found
)
778 if(lower_bound_left
== range
->lower_bound_left
&&
779 lower_bound_right
== range
->lower_bound_right
&&
780 upper_bound_left
== range
->upper_bound_left
&&
781 upper_bound_right
== range
->upper_bound_right
)
784 range
= (APTR
)range
->node
.mln_Succ
;
795 /****i* rhine.device/SetMulticast ******************************************
803 * VOID SetMulticast(struct DevUnit *);
805 ****************************************************************************
809 static VOID
SetMulticast(struct DevUnit
*unit
, struct DevBase
*base
)
811 if(!IsListEmpty(&unit
->multicast_ranges
))
813 unit
->LELongOut(unit
->card
, RH_REG_MCASTFILTER
, 0xffffffff);
814 unit
->LELongOut(unit
->card
, RH_REG_MCASTFILTER
+ 4, 0xffffffff);
818 unit
->LELongOut(unit
->card
, RH_REG_MCASTFILTER
, 0);
819 unit
->LELongOut(unit
->card
, RH_REG_MCASTFILTER
+ 4, 0);
827 /****i* rhine.device/FindTypeStats *****************************************
833 * stats = FindTypeStats(unit, list,
836 * struct TypeStats *FindTypeStats(struct DevUnit *, struct MinList *,
839 ****************************************************************************
843 struct TypeStats
*FindTypeStats(struct DevUnit
*unit
, struct MinList
*list
,
844 ULONG packet_type
, struct DevBase
*base
)
846 struct TypeStats
*stats
, *tail
;
849 stats
= (APTR
)list
->mlh_Head
;
850 tail
= (APTR
)&list
->mlh_Tail
;
852 while(stats
!= tail
&& !found
)
854 if(stats
->packet_type
== packet_type
)
857 stats
= (APTR
)stats
->node
.mln_Succ
;
868 /****i* rhine.device/FlushUnit *********************************************
874 * FlushUnit(unit, last_queue, error)
876 * VOID FlushUnit(struct DevUnit *, UBYTE, BYTE);
878 ****************************************************************************
882 VOID
FlushUnit(struct DevUnit
*unit
, UBYTE last_queue
, BYTE error
,
883 struct DevBase
*base
)
885 struct IORequest
*request
;
887 struct Opener
*opener
, *tail
;
889 /* Abort queued requests */
891 for(i
= 0; i
<= last_queue
; i
++)
893 while((request
= (APTR
)GetMsg(unit
->request_ports
[i
])) != NULL
)
895 request
->io_Error
= IOERR_ABORTED
;
896 ReplyMsg((APTR
)request
);
901 opener
= (APTR
)unit
->openers
.mlh_Head
;
902 tail
= (APTR
)&unit
->openers
.mlh_Tail
;
904 /* Flush every opener's read queues */
906 while(opener
!= tail
)
908 while((request
= (APTR
)GetMsg(&opener
->read_port
)) != NULL
)
910 request
->io_Error
= error
;
911 ReplyMsg((APTR
)request
);
913 while((request
= (APTR
)GetMsg(&opener
->mgmt_port
)) != NULL
)
915 request
->io_Error
= error
;
916 ReplyMsg((APTR
)request
);
918 opener
= (APTR
)opener
->node
.mln_Succ
;
922 opener
= request
->ios2_BufferManagement
;
923 while((request
= (APTR
)GetMsg(&opener
->read_port
)) != NULL
)
925 request
->io_Error
= IOERR_ABORTED
;
926 ReplyMsg((APTR
)request
);
928 while((request
= (APTR
)GetMsg(&opener
->mgmt_port
)) != NULL
)
930 request
->io_Error
= IOERR_ABORTED
;
931 ReplyMsg((APTR
)request
);
942 /****i* rhine.device/StatusInt *********************************************
948 * finished = StatusInt(unit)
950 * BOOL StatusInt(struct DevUnit *);
953 * unit - A unit of this device.
956 * finished - Always FALSE.
958 ****************************************************************************
962 static BOOL
StatusInt(REG(a1
, struct DevUnit
*unit
), REG(a5
, APTR int_code
))
964 struct DevBase
*base
;
968 ints
= unit
->LEWordIn(unit
->card
, RH_REG_INTSTATUS
);
972 /* Acknowledge interrupts */
974 unit
->LEWordOut(unit
->card
, RH_REG_INTSTATUS
, ints
);
976 /* FIXME: Need IO-sync here for PPC etc.? */
978 /* Handle interrupts */
980 if((ints
& (RH_INTF_TXERR
| RH_INTF_TXOK
)) != 0)
981 Cause(&unit
->tx_end_int
);
982 if((ints
& (RH_INTF_RXERR
| RH_INTF_RXOK
)) != 0)
983 Cause(&unit
->rx_int
);
991 /****i* rhine.device/RXInt *************************************************
994 * RXInt -- Soft interrupt for packet reception.
999 * VOID RXInt(struct DevUnit *);
1004 * unit - A unit of this device.
1009 ****************************************************************************
1013 static VOID
RXInt(REG(a1
, struct DevUnit
*unit
), REG(a5
, APTR int_code
))
1015 UWORD slot
, packet_size
;
1016 struct DevBase
*base
;
1017 ULONG rx_status
, *desc
, dma_size
;
1020 base
= unit
->device
;
1021 slot
= unit
->rx_slot
;
1022 desc
= unit
->rx_descs
[slot
];
1024 dma_size
= TX_DESC_SIZE
;
1025 CachePostDMA(unit
->rx_descs
, &dma_size
, 0);
1026 while(((rx_status
= LELong(desc
[RH_DESC_RXSTATUS
]))
1027 & RH_DESC_RXSTATUSF_INUSE
) == 0)
1029 if((rx_status
& RH_DESC_RXSTATUSF_OK
) != 0)
1031 packet_size
= ((rx_status
& RH_DESC_RXSTATUSF_LENGTH
)
1032 >> RH_DESC_RXSTATUSB_LENGTH
) - ETH_CRCSIZE
;
1033 buffer
= unit
->rx_buffers
[slot
];
1035 if(AddressFilter(unit
, buffer
+ ETH_PACKET_DEST
, base
))
1037 unit
->stats
.PacketsReceived
++;
1038 DistributeRXPacket(unit
, buffer
, packet_size
, base
);
1043 unit
->stats
.BadData
++;
1044 ReportEvents(unit
, S2EVENT_ERROR
| S2EVENT_HARDWARE
| S2EVENT_RX
,
1048 /* Mark descriptor as free for next time */
1050 desc
[RH_DESC_RXSTATUS
] = MakeLELong(RH_DESC_RXSTATUSF_INUSE
);
1052 /* Get next descriptor */
1054 slot
= (slot
+ 1) % RX_SLOT_COUNT
;
1055 desc
= unit
->rx_descs
[slot
];
1060 unit
->rx_slot
= slot
;
1066 /****i* rhine.device/DistributeRXPacket ************************************
1069 * DistributeRXPacket -- Send a packet to all appropriate destinations.
1072 * DistributeRXPacket(unit, frame)
1074 * VOID DistributeRXPacket(struct DevUnit *, UBYTE *);
1076 ****************************************************************************
1080 static VOID
DistributeRXPacket(struct DevUnit
*unit
, const UBYTE
*packet
,
1081 UWORD packet_size
, struct DevBase
*base
)
1083 BOOL is_orphan
= TRUE
, accepted
;
1085 struct IOSana2Req
*request
, *request_tail
;
1086 struct Opener
*opener
, *opener_tail
;
1087 struct TypeStats
*tracker
;
1089 /* Offer packet to every opener */
1091 opener
= (APTR
)unit
->openers
.mlh_Head
;
1092 opener_tail
= (APTR
)&unit
->openers
.mlh_Tail
;
1093 packet_type
= BEWord(*((UWORD
*)(packet
+ ETH_PACKET_TYPE
)));
1095 while(opener
!= opener_tail
)
1097 request
= (APTR
)opener
->read_port
.mp_MsgList
.lh_Head
;
1098 request_tail
= (APTR
)&opener
->read_port
.mp_MsgList
.lh_Tail
;
1101 /* Offer packet to each request until it's accepted */
1103 while(request
!= request_tail
&& !accepted
)
1105 if(request
->ios2_PacketType
== packet_type
)
1107 CopyPacket(unit
, request
, packet_size
, packet_type
,
1112 (APTR
)request
->ios2_Req
.io_Message
.mn_Node
.ln_Succ
;
1117 opener
= (APTR
)opener
->node
.mln_Succ
;
1120 /* If packet was unwanted, give it to S2_READORPHAN request */
1124 unit
->stats
.UnknownTypesReceived
++;
1125 if(!IsMsgPortEmpty(unit
->request_ports
[ADOPT_QUEUE
]))
1128 (APTR
)unit
->request_ports
[ADOPT_QUEUE
]->mp_MsgList
.lh_Head
,
1129 packet_size
, packet_type
, packet
, base
);
1133 /* Update remaining statistics */
1135 if(packet_type
<= ETH_MTU
)
1136 packet_type
= ETH_MTU
;
1138 FindTypeStats(unit
, &unit
->type_trackers
, packet_type
, base
);
1141 tracker
->stats
.PacketsReceived
++;
1142 tracker
->stats
.BytesReceived
+= packet_size
;
1150 /****i* rhine.device/CopyPacket ********************************************
1153 * CopyPacket -- Copy packet to client's buffer.
1156 * CopyPacket(unit, request, packet_size, packet_type,
1159 * VOID CopyPacket(struct DevUnit *, struct IOSana2Req *, UWORD, UWORD,
1162 ****************************************************************************
1166 static VOID
CopyPacket(struct DevUnit
*unit
, struct IOSana2Req
*request
,
1167 UWORD packet_size
, UWORD packet_type
, const UBYTE
*buffer
,
1168 struct DevBase
*base
)
1170 struct Opener
*opener
;
1171 BOOL filtered
= FALSE
;
1173 /* Set multicast and broadcast flags */
1175 request
->ios2_Req
.io_Flags
&= ~(SANA2IOF_BCAST
| SANA2IOF_MCAST
);
1176 if((*((ULONG
*)(buffer
+ ETH_PACKET_DEST
)) == 0xffffffff) &&
1177 (*((UWORD
*)(buffer
+ ETH_PACKET_DEST
+ 4)) == 0xffff))
1178 request
->ios2_Req
.io_Flags
|= SANA2IOF_BCAST
;
1179 else if((buffer
[ETH_PACKET_DEST
] & 0x1) != 0)
1180 request
->ios2_Req
.io_Flags
|= SANA2IOF_MCAST
;
1182 /* Set source and destination addresses and packet type */
1184 CopyMem(buffer
+ ETH_PACKET_SOURCE
, request
->ios2_SrcAddr
,
1186 CopyMem(buffer
+ ETH_PACKET_DEST
, request
->ios2_DstAddr
,
1188 request
->ios2_PacketType
= packet_type
;
1190 /* Adjust for cooked packet request */
1192 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
1194 packet_size
-= ETH_PACKET_DATA
;
1195 buffer
+= ETH_PACKET_DATA
;
1199 packet_size
+= 4; /* Needed for Shapeshifter & Fusion */
1201 request
->ios2_DataLength
= packet_size
;
1205 opener
= request
->ios2_BufferManagement
;
1206 if(request
->ios2_Req
.io_Command
== CMD_READ
&&
1207 opener
->filter_hook
!= NULL
)
1208 if(!CallHookPkt(opener
->filter_hook
, request
, (APTR
)buffer
))
1213 /* Copy packet into opener's buffer and reply packet */
1215 if(!opener
->rx_function(request
->ios2_Data
, (APTR
)buffer
,
1218 request
->ios2_Req
.io_Error
= S2ERR_NO_RESOURCES
;
1219 request
->ios2_WireError
= S2WERR_BUFF_ERROR
;
1221 S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
| S2EVENT_RX
,
1224 Remove((APTR
)request
);
1225 ReplyMsg((APTR
)request
);
1233 /****i* rhine.device/AddressFilter *****************************************
1236 * AddressFilter -- Determine if an RX packet should be accepted.
1239 * accept = AddressFilter(unit, address)
1241 * BOOL AddressFilter(struct DevUnit *, UBYTE *);
1243 ****************************************************************************
1247 static BOOL
AddressFilter(struct DevUnit
*unit
, UBYTE
*address
,
1248 struct DevBase
*base
)
1250 struct AddressRange
*range
, *tail
;
1253 UWORD address_right
;
1255 /* Check whether address is unicast/broadcast or multicast */
1257 address_left
= BELong(*((ULONG
*)address
));
1258 address_right
= BEWord(*((UWORD
*)(address
+ 4)));
1260 if(((address_left
& 0x01000000) != 0) &&
1261 !((address_left
== 0xffffffff) && (address_right
== 0xffff)))
1263 /* Check if this multicast address is wanted */
1265 range
= (APTR
)unit
->multicast_ranges
.mlh_Head
;
1266 tail
= (APTR
)&unit
->multicast_ranges
.mlh_Tail
;
1269 while((range
!= tail
) && !accept
)
1271 if((address_left
> range
->lower_bound_left
||
1272 address_left
== range
->lower_bound_left
&&
1273 address_right
>= range
->lower_bound_right
) &&
1274 (address_left
< range
->upper_bound_left
||
1275 address_left
== range
->upper_bound_left
&&
1276 address_right
<= range
->upper_bound_right
))
1278 range
= (APTR
)range
->node
.mln_Succ
;
1282 unit
->special_stats
[S2SS_ETHERNET_BADMULTICAST
& 0xffff]++;
1290 /****i* rhine.device/TXInt *************************************************
1293 * TXInt -- Soft interrupt for packet transmission.
1298 * VOID TXInt(struct DevUnit *);
1303 * unit - A unit of this device.
1308 ****************************************************************************
1312 static VOID
TXInt(REG(a1
, struct DevUnit
*unit
), REG(a5
, APTR int_code
))
1314 struct DevBase
*base
;
1315 UWORD packet_size
, data_size
, slot
, new_slot
, *p
, *q
, i
;
1316 struct IOSana2Req
*request
;
1317 BOOL proceed
= TRUE
;
1318 struct Opener
*opener
;
1319 ULONG wire_error
, *desc
, dma_size
, desc_p
, buffer_p
, txcontrol_value
;
1320 UBYTE
*(*dma_tx_function
)(REG(a0
, APTR
));
1323 struct MsgPort
*port
;
1325 base
= unit
->device
;
1326 port
= unit
->request_ports
[WRITE_QUEUE
];
1328 while(proceed
&& !IsMsgPortEmpty(port
))
1330 slot
= unit
->tx_in_slot
;
1331 new_slot
= (slot
+ 1) % TX_SLOT_COUNT
;
1333 if(new_slot
!= unit
->tx_out_slot
1334 && (unit
->flags
& UNITF_TXBUFFERINUSE
) == 0)
1338 /* Get request and DMA frame descriptor */
1340 request
= (APTR
)port
->mp_MsgList
.lh_Head
;
1342 Remove((APTR
)request
);
1343 unit
->tx_requests
[slot
] = request
;
1344 desc
= unit
->tx_descs
[slot
];
1345 desc_p
= unit
->tx_descs_p
[slot
];
1347 data_size
= packet_size
= request
->ios2_DataLength
;
1348 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
1349 packet_size
+= ETH_HEADERSIZE
;
1350 if(packet_size
< ETH_MINSIZE
)
1351 packet_size
= ETH_MINSIZE
;
1353 /* Decide if one or two descriptors are needed, and generate
1354 Ethernet header if necessary */
1356 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
1358 /* Use first descriptor for Ethernet header */
1360 buffer
= (UBYTE
*)desc
+ 2 * RH_DESCSIZE
;
1361 buffer_p
= desc_p
+ 2 * RH_DESCSIZE
;
1363 desc
[RH_DESC_TXCONTROL
] =
1364 MakeLELong(RH_DESC_TXCONTROLF_FIRSTFRAG
1365 | RH_DESC_TXCONTROLF_CHAIN
| ETH_HEADERSIZE
);
1366 desc
[RH_DESC_DATA
] = MakeLELong(buffer_p
);
1367 desc
[RH_DESC_NEXT
] = MakeLELong(desc_p
+ RH_DESCSIZE
);
1369 /* Write Ethernet header */
1371 p
= (UWORD
*)buffer
;
1372 for(i
= 0, q
= (UWORD
*)request
->ios2_DstAddr
;
1373 i
< ETH_ADDRESSSIZE
/ 2; i
++)
1375 for(i
= 0, q
= (UWORD
*)unit
->address
;
1376 i
< ETH_ADDRESSSIZE
/ 2; i
++)
1378 *p
++ = MakeBEWord(request
->ios2_PacketType
);
1380 /* Use spare second descriptor for frame data */
1382 desc
+= RH_DESCSIZE
/ 4;
1383 desc_p
+= RH_DESCSIZE
;
1385 txcontrol_value
= RH_DESC_TXCONTROLF_INT
1386 | RH_DESC_TXCONTROLF_LASTFRAG
1387 | RH_DESC_TXCONTROLF_CHAIN
1388 | packet_size
- ETH_HEADERSIZE
;
1392 txcontrol_value
= RH_DESC_TXCONTROLF_INT
1393 | RH_DESC_TXCONTROLF_FIRSTFRAG
| RH_DESC_TXCONTROLF_LASTFRAG
1394 | RH_DESC_TXCONTROLF_CHAIN
1398 /* Get packet data */
1400 opener
= (APTR
)request
->ios2_BufferManagement
;
1401 dma_tx_function
= opener
->dma_tx_function
;
1402 if(dma_tx_function
!= NULL
)
1403 buffer
= dma_tx_function(request
->ios2_Data
);
1409 buffer
= unit
->tx_buffer
;
1410 if(opener
->tx_function(buffer
, request
->ios2_Data
,
1413 unit
->flags
|= UNITF_TXBUFFERINUSE
;
1417 error
= S2ERR_NO_RESOURCES
;
1418 wire_error
= S2WERR_BUFF_ERROR
;
1420 S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
1421 | S2EVENT_TX
, base
);
1424 unit
->tx_buffers
[slot
] = buffer
;
1426 /* Fill in descriptor for frame data */
1430 dma_size
= data_size
;
1431 buffer_p
= (ULONG
)(UPINT
)CachePreDMA(buffer
, &dma_size
,
1433 desc
[RH_DESC_TXCONTROL
] = MakeLELong(txcontrol_value
);
1434 desc
[RH_DESC_DATA
] = MakeLELong(buffer_p
);
1435 desc
[RH_DESC_NEXT
] = MakeLELong(unit
->tx_descs_p
[new_slot
]);
1437 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
1438 desc
-= RH_DESCSIZE
/ 4;
1440 desc
[RH_DESC_TXSTATUS
] = MakeLELong(RH_DESC_TXSTATUSF_INUSE
);
1445 /* Restart transmission if it had stopped */
1447 dma_size
= TX_DESC_SIZE
* TX_SLOT_COUNT
;
1448 CachePreDMA(unit
->tx_descs
, &dma_size
, 0);
1449 unit
->ByteOut(unit
->card
, RH_REG_CONTROL
,
1450 unit
->ByteIn(unit
->card
, RH_REG_CONTROL
)
1451 | RH_REG_CONTROLF_TXPOLL
);
1453 /* FIXME: Need IO-sync here for PPC etc.? */
1455 unit
->tx_in_slot
= new_slot
;
1459 /* Return failed request */
1461 request
->ios2_Req
.io_Error
= error
;
1462 request
->ios2_WireError
= wire_error
;
1463 ReplyMsg((APTR
)request
);
1471 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_SOFTINT
;
1473 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_IGNORE
;
1480 /****i* rhine.device/TXEndInt **********************************************
1483 * TXEndInt -- Clean up after a frame has been sent.
1486 * TXEndInt(unit, int_code)
1488 * VOID TXEndInt(struct DevUnit *, APTR);
1491 * unit - A unit of this device.
1492 * int_code - Unused.
1497 ****************************************************************************
1499 * It appears to be safe to assume that there will always be at least one
1500 * completed packet whenever this interrupt is called.
1504 static VOID
TXEndInt(REG(a1
, struct DevUnit
*unit
), REG(a5
, APTR int_code
))
1506 UWORD data_size
, i
= 0;
1508 struct DevBase
*base
;
1509 ULONG
*desc
, dma_size
;
1510 BOOL proceed
= TRUE
;
1512 /* Retire sent packets */
1514 base
= unit
->device
;
1515 dma_size
= TX_DESC_SIZE
* TX_SLOT_COUNT
;
1516 CachePostDMA(unit
->tx_descs
, &dma_size
, 0);
1518 i
= unit
->tx_out_slot
;
1521 /* Skip to "spare" descriptor if valid */
1523 desc
= unit
->tx_descs
[i
];
1524 if((desc
[RH_DESC_TXCONTROL
] & RH_DESC_TXCONTROLF_LASTFRAG
) == 0)
1527 /* Check that descriptor is not in use */
1529 if((desc
[RH_DESC_TXSTATUS
] & MakeLELong(RH_DESC_TXSTATUSF_INUSE
))
1530 == 0 && i
!= unit
->tx_in_slot
)
1532 buffer
= unit
->tx_buffers
[i
];
1533 dma_size
= data_size
;
1534 CachePostDMA(buffer
, &dma_size
, DMA_ReadFromRAM
);
1536 /* Check if unit's buffer is now free */
1538 if(buffer
== unit
->tx_buffer
)
1539 unit
->flags
&= ~UNITF_TXBUFFERINUSE
;
1541 RetireTXSlot(unit
, i
, base
);
1543 i
= (i
+ 1) % TX_SLOT_COUNT
;
1549 unit
->tx_out_slot
= i
;
1551 dma_size
= TX_DESC_SIZE
* TX_SLOT_COUNT
;
1552 CachePreDMA(unit
->tx_descs
, &dma_size
, 0);
1554 /* Restart downloads if they had stopped */
1556 if(unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
== PA_IGNORE
)
1557 Cause(&unit
->tx_int
);
1564 /****i* rhine.device/RetireTXSlot ******************************************
1567 * RetireTXSlot -- Reply finished TX request.
1570 * RetireTXSlot(unit, slot)
1572 * VOID RetireTXSlot(struct DevUnit *, UWORD);
1574 ****************************************************************************
1578 static VOID
RetireTXSlot(struct DevUnit
*unit
, UWORD slot
,
1579 struct DevBase
*base
)
1582 struct IOSana2Req
*request
;
1583 struct TypeStats
*tracker
;
1585 /* Update statistics */
1587 slot
= unit
->tx_out_slot
;
1588 request
= unit
->tx_requests
[slot
];
1589 frame_size
= request
->ios2_DataLength
;
1590 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
1591 frame_size
+= ETH_HEADERSIZE
;
1593 unit
->stats
.PacketsSent
++;
1595 tracker
= FindTypeStats(unit
, &unit
->type_trackers
,
1596 request
->ios2_PacketType
, base
);
1599 tracker
->stats
.PacketsSent
++;
1600 tracker
->stats
.BytesSent
+= frame_size
;
1605 request
->ios2_Req
.io_Error
= 0;
1606 ReplyMsg((APTR
)request
);
1613 /****i* rhine.device/ResetHandler ******************************************
1616 * ResetHandler -- Disable hardware before a reboot.
1619 * ResetHandler(unit, int_code)
1621 * VOID ResetHandler(struct DevUnit *, APTR);
1623 ****************************************************************************
1627 static VOID
ResetHandler(REG(a1
, struct DevUnit
*unit
),
1628 REG(a6
, APTR int_code
))
1630 if((unit
->flags
& UNITF_HAVEADAPTER
) != 0)
1632 /* Disable frame transmission and reception */
1634 unit
->LEWordOut(unit
->card
, RH_REG_CONTROL
, RH_REG_CONTROLF_STOP
);
1636 /* Stop interrupts */
1638 unit
->LEWordOut(unit
->card
, RH_REG_INTMASK
, 0);
1647 /****i* rhine.device/ReportEvents ******************************************
1653 * ReportEvents(unit, events)
1655 * VOID ReportEvents(struct DevUnit *, ULONG);
1660 * unit - A unit of this device.
1661 * events - A mask of events to report.
1666 ****************************************************************************
1670 static VOID
ReportEvents(struct DevUnit
*unit
, ULONG events
,
1671 struct DevBase
*base
)
1673 struct IOSana2Req
*request
, *tail
, *next_request
;
1676 list
= &unit
->request_ports
[EVENT_QUEUE
]->mp_MsgList
;
1677 next_request
= (APTR
)list
->lh_Head
;
1678 tail
= (APTR
)&list
->lh_Tail
;
1681 while(next_request
!= tail
)
1683 request
= next_request
;
1684 next_request
= (APTR
)request
->ios2_Req
.io_Message
.mn_Node
.ln_Succ
;
1686 if((request
->ios2_WireError
& events
) != 0)
1688 request
->ios2_WireError
= events
;
1689 Remove((APTR
)request
);
1690 ReplyMsg((APTR
)request
);
1700 /****i* rhine.device/UnitTask **********************************************
1708 * VOID UnitTask(struct DevUnit *);
1711 * Completes deferred requests, and handles card insertion and removal
1712 * in conjunction with the relevant interrupts.
1714 ****************************************************************************
1718 static VOID
UnitTask(struct DevUnit
*unit
)
1720 struct DevBase
*base
;
1721 struct IORequest
*request
;
1722 struct MsgPort
*general_port
;
1723 ULONG signals
= 0, wait_signals
, card_removed_signal
,
1724 card_inserted_signal
, general_port_signal
;
1726 base
= unit
->device
;
1728 /* Activate general request port */
1730 general_port
= unit
->request_ports
[GENERAL_QUEUE
];
1731 general_port
->mp_SigTask
= unit
->task
;
1732 general_port
->mp_SigBit
= AllocSignal(-1);
1733 general_port_signal
= 1 << general_port
->mp_SigBit
;
1734 general_port
->mp_Flags
= PA_SIGNAL
;
1736 /* Allocate signals for notification of card removal and insertion */
1738 card_removed_signal
= unit
->card_removed_signal
= 1 << AllocSignal(-1);
1739 card_inserted_signal
= unit
->card_inserted_signal
= 1 << AllocSignal(-1);
1740 wait_signals
= (1 << general_port
->mp_SigBit
) | card_removed_signal
1741 | card_inserted_signal
| SIGBREAKF_CTRL_C
;
1743 /* Tell ourselves to check port for old messages */
1745 Signal(unit
->task
, general_port_signal
);
1747 /* Infinite loop to service requests and signals */
1751 signals
= Wait(wait_signals
);
1753 if((signals
& card_inserted_signal
) != 0)
1755 if(unit
->insertion_function(unit
->card
, base
))
1757 unit
->flags
|= UNITF_HAVEADAPTER
;
1758 if((unit
->flags
& UNITF_CONFIGURED
) != 0)
1759 ConfigureAdapter(unit
, base
);
1760 if((unit
->flags
& UNITF_WASONLINE
) != 0)
1762 GoOnline(unit
, base
);
1763 unit
->flags
&= ~UNITF_WASONLINE
;
1768 if((signals
& card_removed_signal
) != 0)
1770 unit
->removal_function(unit
->card
, base
);
1771 if((unit
->flags
& UNITF_WASONLINE
) != 0)
1772 GoOffline(unit
, base
);
1775 if((signals
& general_port_signal
) != 0)
1777 while((request
= (APTR
)GetMsg(general_port
)) != NULL
)
1779 /* Service the request as soon as the unit is free */
1781 ObtainSemaphore(&unit
->access_lock
);
1782 ServiceRequest((APTR
)request
, base
);
1790 /****i* rhine.device/ReadMII ***********************************************
1793 * ReadMII -- Read a register in an MII PHY.
1796 * value = ReadMII(unit, phy_no, reg_no)
1798 * UWORD ReadMII(struct DevUnit *, UWORD, UWORD);
1801 * unit - A unit of this device.
1802 * phy_no - Index of PHY to use.
1803 * reg_no - MII register to read.
1806 * value - Value read from MII register.
1808 ****************************************************************************
1812 UWORD
ReadMII(struct DevUnit
*unit
, UWORD phy_no
, UWORD reg_no
,
1813 struct DevBase
*base
)
1815 while((unit
->ByteIn(unit
->card
, RH_REG_MIICTRL
)
1816 & (RH_REG_MIICTRLF_READ
| RH_REG_MIICTRLF_WRITE
)) != 0);
1818 unit
->ByteOut(unit
->card
, RH_REG_MIICTRL
, 0);
1819 unit
->ByteOut(unit
->card
, RH_REG_MIICONFIG
, phy_no
);
1820 unit
->ByteOut(unit
->card
, RH_REG_MIIREGNO
, reg_no
);
1821 unit
->ByteOut(unit
->card
, RH_REG_MIICTRL
, RH_REG_MIICTRLF_READ
);
1822 while((unit
->ByteIn(unit
->card
, RH_REG_MIICTRL
)
1823 & (RH_REG_MIICTRLF_READ
| RH_REG_MIICTRLF_WRITE
)) != 0);
1825 return unit
->LEWordIn(unit
->card
, RH_REG_MIIDATA
);