3 Copyright (C) 2001-2012 Neil Cafferkey
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston,
23 #include <exec/memory.h>
24 #include <exec/execbase.h>
25 #include <exec/errors.h>
27 #include <proto/exec.h>
28 #include <proto/alib.h>
29 #include <proto/utility.h>
30 #include <proto/timer.h>
35 #include "unit_protos.h"
36 #include "request_protos.h"
37 #include "timer_protos.h"
40 #define TASK_PRIORITY 0
41 #define STACK_SIZE 4096
42 #define INT_MASK 0xffff
43 #define TX_DESC_SIZE (RH_DESCSIZE * 2 + ETH_HEADERSIZE + 2)
46 #define AbsExecBase sys_base
49 VOID
DeinitialiseAdapter(struct DevUnit
*unit
, struct DevBase
*base
);
50 static struct AddressRange
*FindMulticastRange(struct DevUnit
*unit
,
51 ULONG lower_bound_left
, UWORD lower_bound_right
, ULONG upper_bound_left
,
52 UWORD upper_bound_right
, struct DevBase
*base
);
53 static VOID
SetMulticast(struct DevUnit
*unit
, struct DevBase
*base
);
54 static BOOL
StatusInt(REG(a1
, struct DevUnit
*unit
), REG(a5
, APTR int_code
));
55 static VOID
RXInt(REG(a1
, struct DevUnit
*unit
), REG(a6
, APTR int_code
));
56 static VOID
DistributeRXPacket(struct DevUnit
*unit
, const UBYTE
*packet
,
57 UWORD packet_size
, struct DevBase
*base
);
58 static VOID
CopyPacket(struct DevUnit
*unit
, struct IOSana2Req
*request
,
59 UWORD packet_size
, UWORD packet_type
, const UBYTE
*buffer
,
60 struct DevBase
*base
);
61 static BOOL
AddressFilter(struct DevUnit
*unit
, UBYTE
*address
,
62 struct DevBase
*base
);
63 static VOID
TXInt(REG(a1
, struct DevUnit
*unit
), REG(a6
, APTR int_code
));
64 static VOID
TXEndInt(REG(a1
, struct DevUnit
*unit
), REG(a5
, APTR int_code
));
65 static VOID
RetireTXSlot(struct DevUnit
*unit
, UWORD slot
,
66 struct DevBase
*base
);
67 static VOID
ResetHandler(REG(a1
, struct DevUnit
*unit
),
68 REG(a6
, APTR int_code
));
69 static VOID
ReportEvents(struct DevUnit
*unit
, ULONG events
,
70 struct DevBase
*base
);
71 static VOID
UnitTask(struct ExecBase
*sys_base
);
72 UWORD
ReadMII(struct DevUnit
*unit
, UWORD phy_no
, UWORD reg_no
,
73 struct DevBase
*base
);
75 #if !defined(__AROS__)
76 static const UBYTE broadcast_address
[] =
77 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
82 #define AddTask(task, initial_pc, final_pc) \
84 struct TagItem _task_tags[] = \
85 {{TASKTAG_ARG1, (IPTR)SysBase}, {TAG_END, 0}}; \
86 NewAddTask(task, initial_pc, final_pc, _task_tags); \
92 /****i* rhine.device/CreateUnit ********************************************
95 * CreateUnit -- Create a unit.
98 * unit = CreateUnit(index, io_base, id, card,
101 * struct DevUnit *CreateUnit(ULONG, APTR, UWORD, APTR,
102 * struct TagItem *, UWORD);
105 * Creates a new unit.
107 ****************************************************************************
111 struct DevUnit
*CreateUnit(ULONG index
, APTR card
,
112 struct TagItem
*io_tags
, UWORD bus
, struct DevBase
*base
)
115 struct DevUnit
*unit
;
117 struct MsgPort
*port
;
119 ULONG
*desc
, desc_p
, buffer_p
, dma_size
;
122 unit
= AllocMem(sizeof(struct DevUnit
), MEMF_CLEAR
| MEMF_PUBLIC
);
128 /* Initialise lists etc. */
130 NewList((APTR
)&unit
->openers
);
131 NewList((APTR
)&unit
->type_trackers
);
132 NewList((APTR
)&unit
->multicast_ranges
);
139 /* Store I/O hooks */
142 (APTR
)GetTagData(IOTAG_ByteIn
, (UPINT
)NULL
, io_tags
);
144 (APTR
)GetTagData(IOTAG_ByteOut
, (UPINT
)NULL
, io_tags
);
146 (APTR
)GetTagData(IOTAG_LEWordIn
, (UPINT
)NULL
, io_tags
);
148 (APTR
)GetTagData(IOTAG_LELongIn
, (UPINT
)NULL
, io_tags
);
150 (APTR
)GetTagData(IOTAG_LEWordOut
, (UPINT
)NULL
, io_tags
);
152 (APTR
)GetTagData(IOTAG_LELongOut
, (UPINT
)NULL
, io_tags
);
154 (APTR
)GetTagData(IOTAG_AllocDMAMem
, (UPINT
)NULL
, io_tags
);
156 (APTR
)GetTagData(IOTAG_FreeDMAMem
, (UPINT
)NULL
, io_tags
);
157 if(unit
->ByteIn
== NULL
158 || unit
->ByteOut
== NULL
159 || unit
->LEWordIn
== NULL
160 || unit
->LELongIn
== NULL
161 || unit
->LEWordOut
== NULL
162 || unit
->LELongOut
== NULL
163 || unit
->AllocDMAMem
== NULL
164 || unit
->FreeDMAMem
== NULL
)
170 InitSemaphore(&unit
->access_lock
);
172 /* Create the message ports for queuing requests */
174 for(i
= 0; i
< REQUEST_QUEUE_COUNT
; i
++)
176 unit
->request_ports
[i
] = port
= AllocMem(sizeof(struct MsgPort
),
177 MEMF_PUBLIC
| MEMF_CLEAR
);
183 NewList(&port
->mp_MsgList
);
184 port
->mp_Flags
= PA_IGNORE
;
188 unit
->request_ports
[WRITE_QUEUE
]->mp_SigTask
= &unit
->tx_int
;
193 /* Allocate TX descriptors */
195 desc
= unit
->AllocDMAMem(unit
->card
, TX_DESC_SIZE
* TX_SLOT_COUNT
, 16);
202 /* Fill arrays of virtual and physical addresses of TX descriptors */
204 dma_size
= TX_DESC_SIZE
* TX_SLOT_COUNT
;
205 desc_p
= (ULONG
)(UPINT
)CachePreDMA(desc
, &dma_size
, 0);
206 if(dma_size
!= TX_DESC_SIZE
* TX_SLOT_COUNT
)
208 CachePostDMA(desc
, &dma_size
, 0);
210 for(i
= 0; i
< TX_SLOT_COUNT
; i
++)
212 unit
->tx_descs
[i
] = desc
;
213 desc
+= TX_DESC_SIZE
/ sizeof(ULONG
);
214 unit
->tx_descs_p
[i
] = desc_p
;
215 desc_p
+= TX_DESC_SIZE
;
221 /* Allocate RX descriptors */
223 desc
= unit
->AllocDMAMem(unit
->card
, RH_DESCSIZE
* RX_SLOT_COUNT
, 16);
230 /* Fill arrays of virtual and physical addresses of TX descriptors */
232 dma_size
= RH_DESCSIZE
* RX_SLOT_COUNT
;
233 desc_p
= (ULONG
)(UPINT
)CachePreDMA(desc
, &dma_size
, 0);
234 if(dma_size
!= RH_DESCSIZE
* RX_SLOT_COUNT
)
236 CachePostDMA(desc
, &dma_size
, 0);
238 for(i
= 0; i
< RX_SLOT_COUNT
; i
++)
240 unit
->rx_descs
[i
] = desc
;
241 desc
+= RH_DESCSIZE
/ sizeof(ULONG
);
242 unit
->rx_descs_p
[i
] = desc_p
;
243 desc_p
+= RH_DESCSIZE
;
246 /* Allocate packet buffers */
248 unit
->tx_buffer
= unit
->AllocDMAMem(unit
->card
, FRAME_BUFFER_SIZE
, 4);
249 if(unit
->tx_buffer
== NULL
)
252 for(i
= 0; i
< RX_SLOT_COUNT
; i
++)
254 unit
->rx_buffers
[i
] = unit
->AllocDMAMem(unit
->card
,
255 FRAME_BUFFER_SIZE
, 4);
256 if(unit
->rx_buffers
[i
] == NULL
)
260 unit
->tx_requests
= AllocVec(sizeof(APTR
) * TX_SLOT_COUNT
,
262 if(unit
->tx_requests
== NULL
)
268 /* Construct RX ring */
270 for(i
= 0; i
< RX_SLOT_COUNT
; i
++)
272 desc
= unit
->rx_descs
[i
];
273 desc
[RH_DESC_RXSTATUS
] = MakeLELong(RH_DESC_RXSTATUSF_INUSE
);
274 desc
[RH_DESC_RXCONTROL
] = MakeLELong(FRAME_BUFFER_SIZE
);
275 dma_size
= FRAME_BUFFER_SIZE
;
277 (ULONG
)(UPINT
)CachePreDMA(unit
->rx_buffers
[i
], &dma_size
, 0);
278 if(dma_size
!= FRAME_BUFFER_SIZE
)
280 desc
[RH_DESC_DATA
] = MakeLELong(buffer_p
);
282 MakeLELong(unit
->rx_descs_p
[(i
+ 1) % RX_SLOT_COUNT
]);
283 desc
+= RH_DESCSIZE
/ sizeof(ULONG
);
285 dma_size
= RH_DESCSIZE
* RX_SLOT_COUNT
;
286 CachePreDMA(unit
->rx_descs
, &dma_size
, 0);
291 /* Initialise network adapter hardware */
293 success
= InitialiseAdapter(unit
, FALSE
, base
);
294 unit
->flags
|= UNITF_HAVEADAPTER
;
299 /* Record maximum speed in BPS */
301 unit
->speed
= 100000000;
303 /* Initialise interrupts */
305 unit
->status_int
.is_Code
= (APTR
)StatusInt
;
306 unit
->status_int
.is_Data
= unit
;
308 unit
->rx_int
.is_Node
.ln_Name
=
309 base
->device
.dd_Library
.lib_Node
.ln_Name
;
310 unit
->rx_int
.is_Code
= (APTR
)RXInt
;
311 unit
->rx_int
.is_Data
= unit
;
313 unit
->tx_int
.is_Node
.ln_Name
=
314 base
->device
.dd_Library
.lib_Node
.ln_Name
;
315 unit
->tx_int
.is_Code
= (APTR
)TXInt
;
316 unit
->tx_int
.is_Data
= unit
;
318 unit
->tx_end_int
.is_Node
.ln_Name
=
319 base
->device
.dd_Library
.lib_Node
.ln_Name
;
320 unit
->tx_end_int
.is_Code
= (APTR
)TXEndInt
;
321 unit
->tx_end_int
.is_Data
= unit
;
323 unit
->reset_handler
.is_Node
.ln_Name
=
324 base
->device
.dd_Library
.lib_Node
.ln_Name
;
325 unit
->reset_handler
.is_Code
= (APTR
)ResetHandler
;
326 unit
->reset_handler
.is_Data
= unit
;
328 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_SOFTINT
;
330 /* Create a new task */
333 AllocMem(sizeof(struct Task
), MEMF_PUBLIC
| MEMF_CLEAR
);
340 stack
= AllocMem(STACK_SIZE
, MEMF_PUBLIC
);
347 /* Initialise and start task */
349 task
->tc_Node
.ln_Type
= NT_TASK
;
350 task
->tc_Node
.ln_Pri
= TASK_PRIORITY
;
351 task
->tc_Node
.ln_Name
= base
->device
.dd_Library
.lib_Node
.ln_Name
;
352 task
->tc_SPUpper
= stack
+ STACK_SIZE
;
353 task
->tc_SPLower
= stack
;
354 task
->tc_SPReg
= stack
+ STACK_SIZE
;
355 NewList(&task
->tc_MemEntry
);
357 if(AddTask(task
, UnitTask
, NULL
) == NULL
)
363 /* Send the unit to the new task */
365 task
->tc_UserData
= unit
;
370 DeleteUnit(unit
, base
);
379 /****i* rhine.device/DeleteUnit ********************************************
382 * DeleteUnit -- Delete a unit.
387 * VOID DeleteUnit(struct DevUnit *);
393 * unit - Device unit (may be NULL).
398 ****************************************************************************
402 VOID
DeleteUnit(struct DevUnit
*unit
, struct DevBase
*base
)
412 if(task
->tc_UserData
!= NULL
)
415 FreeMem(task
->tc_SPLower
, STACK_SIZE
);
417 FreeMem(task
, sizeof(struct Task
));
420 for(i
= 0; i
< REQUEST_QUEUE_COUNT
; i
++)
422 if(unit
->request_ports
[i
] != NULL
)
423 FreeMem(unit
->request_ports
[i
], sizeof(struct MsgPort
));
426 if((unit
->flags
& UNITF_ONLINE
) != 0) /* Needed! */
427 GoOffline(unit
, base
);
429 if((unit
->flags
& UNITF_HAVEADAPTER
) != 0)
430 DeinitialiseAdapter(unit
, base
);
432 for(i
= 0; i
< RX_SLOT_COUNT
; i
++)
433 unit
->FreeDMAMem(unit
->card
, unit
->rx_buffers
[i
]);
434 unit
->FreeDMAMem(unit
->card
, unit
->tx_buffer
);
435 unit
->FreeDMAMem(unit
->card
, unit
->rx_descs
[0]);
436 unit
->FreeDMAMem(unit
->card
, unit
->tx_descs
[0]);
438 FreeVec(unit
->tx_requests
);
440 FreeMem(unit
, sizeof(struct DevUnit
));
448 /****i* rhine.device/InitialiseAdapter *************************************
454 * success = InitialiseAdapter(unit, reinsertion)
456 * BOOL InitialiseAdapter(struct DevUnit *, BOOL);
465 * success - Success indicator.
467 ****************************************************************************
471 BOOL
InitialiseAdapter(struct DevUnit
*unit
, BOOL reinsertion
,
472 struct DevBase
*base
)
475 UBYTE
*p
, eeprom_reg
;
478 /* Reload data from EEPROM */
480 eeprom_reg
= unit
->ByteIn(unit
->card
, RH_REG_EEPROM
);
481 unit
->ByteOut(unit
->card
, RH_REG_EEPROM
,
482 eeprom_reg
| RH_REG_EEPROMF_LOAD
);
484 BusyMicroDelay(1, base
);
485 while((unit
->ByteIn(unit
->card
, RH_REG_EEPROM
) & RH_REG_EEPROMF_LOAD
)
488 /* Get default MAC address */
490 p
= unit
->default_address
;
491 for(i
= 0; i
< ETH_ADDRESSSIZE
; i
++)
492 *p
++ = unit
->ByteIn(unit
->card
, RH_REG_ADDRESS
+ i
);
494 /* Send reset command */
496 unit
->ByteOut(unit
->card
, RH_REG_CONTROL
+ 1, RH_REG_CONTROL1F_RESET
);
497 BusyMicroDelay(110, base
);
498 while((unit
->ByteIn(unit
->card
, RH_REG_CONTROL
+ 1)
499 & RH_REG_CONTROL1F_RESET
) != 0);
501 /* Disable interrupts */
503 unit
->LEWordOut(unit
->card
, RH_REG_INTSTATUS
, INT_MASK
);
504 unit
->LEWordOut(unit
->card
, RH_REG_INTMASK
, 0);
506 unit
->LEWordOut(unit
->card
, RH_REG_MIIINTMASK
, 0);
510 unit
->ByteOut(unit
->card
, RH_REG_MIICTRL
,
511 unit
->ByteIn(unit
->card
, RH_REG_MIICTRL
) | RH_REG_MIICTRLF_AUTOPOLL
);
514 unit
->mii_phy_no
= unit
->ByteIn(unit
->card
, RH_REG_MIICONFIG
)
515 & RH_REG_MIICONFIGF_PHYADDR
;
517 unit
->mii_phy_no
= 1;
526 /****i* rhine.device/DeinitialiseAdapter ***********************************
529 * DeinitialiseAdapter
532 * DeinitialiseAdapter(unit)
534 * VOID DeinitialiseAdapter(struct DevUnit *);
544 ****************************************************************************
548 VOID
DeinitialiseAdapter(struct DevUnit
*unit
, struct DevBase
*base
)
555 /****i* rhine.device/ConfigureAdapter **************************************
558 * ConfigureAdapter -- Set up card for transmission/reception.
561 * ConfigureAdapter(unit)
563 * VOID ConfigureAdapter(struct DevUnit *);
565 ****************************************************************************
569 VOID
ConfigureAdapter(struct DevUnit
*unit
, struct DevBase
*base
)
574 /* Set MAC address */
577 for(i
= 0; i
< ETH_ADDRESSSIZE
; i
++)
578 unit
->ByteOut(unit
->card
, RH_REG_ADDRESS
+ i
, *p
++);
582 unit
->LELongOut(unit
->card
, RH_REG_TXLIST
, unit
->tx_descs_p
[0]);
583 unit
->LELongOut(unit
->card
, RH_REG_RXLIST
, unit
->rx_descs_p
[0]);
585 /* Choose packet types to receive */
587 unit
->LEWordOut(unit
->card
, RH_REG_PCIBUSCONFIG
, 6);
588 unit
->ByteOut(unit
->card
, RH_REG_RXCONFIG
,
589 RH_REG_RXCONFIGF_BCAST
| RH_REG_RXCONFIGF_MCAST
);
598 /****i* rhine.device/GoOnline **********************************************
601 * GoOnline -- Enable transmission/reception.
606 * VOID GoOnline(struct DevUnit *);
608 ****************************************************************************
612 VOID
GoOnline(struct DevUnit
*unit
, struct DevBase
*base
)
614 /* Enable interrupts */
616 unit
->flags
|= UNITF_ONLINE
;
617 unit
->LEWordOut(unit
->card
, RH_REG_INTMASK
, INT_MASK
);
619 /* Enable frame transmission and reception */
621 unit
->LEWordOut(unit
->card
, RH_REG_CONTROL
, RH_REG_CONTROLF_TXENABLE
622 | RH_REG_CONTROLF_RXENABLE
| RH_REG_CONTROLF_START
);
624 /* Record start time and report Online event */
626 GetSysTime(&unit
->stats
.LastStart
);
627 ReportEvents(unit
, S2EVENT_ONLINE
, base
);
634 /****i* rhine.device/GoOffline *********************************************
637 * GoOffline -- Disable transmission/reception.
642 * VOID GoOffline(struct DevUnit *);
652 ****************************************************************************
656 VOID
GoOffline(struct DevUnit
*unit
, struct DevBase
*base
)
658 unit
->flags
&= ~UNITF_ONLINE
;
660 /* Flush pending read and write requests */
662 FlushUnit(unit
, MGMT_QUEUE
, S2ERR_OUTOFSERVICE
, base
);
664 /* Report Offline event and return */
666 ReportEvents(unit
, S2EVENT_OFFLINE
, base
);
672 /****i* rhine.device/AddMulticastRange *************************************
678 * success = AddMulticastRange(unit, lower_bound, upper_bound)
680 * BOOL AddMulticastRange(struct DevUnit *, UBYTE *, UBYTE *);
682 ****************************************************************************
686 BOOL
AddMulticastRange(struct DevUnit
*unit
, const UBYTE
*lower_bound
,
687 const UBYTE
*upper_bound
, struct DevBase
*base
)
689 struct AddressRange
*range
;
690 ULONG lower_bound_left
, upper_bound_left
;
691 UWORD lower_bound_right
, upper_bound_right
;
693 lower_bound_left
= BELong(*((ULONG
*)lower_bound
));
694 lower_bound_right
= BEWord(*((UWORD
*)(lower_bound
+ 4)));
695 upper_bound_left
= BELong(*((ULONG
*)upper_bound
));
696 upper_bound_right
= BEWord(*((UWORD
*)(upper_bound
+ 4)));
698 range
= FindMulticastRange(unit
, lower_bound_left
, lower_bound_right
,
699 upper_bound_left
, upper_bound_right
, base
);
705 range
= AllocMem(sizeof(struct AddressRange
), MEMF_PUBLIC
);
708 range
->lower_bound_left
= lower_bound_left
;
709 range
->lower_bound_right
= lower_bound_right
;
710 range
->upper_bound_left
= upper_bound_left
;
711 range
->upper_bound_right
= upper_bound_right
;
712 range
->add_count
= 1;
715 AddTail((APTR
)&unit
->multicast_ranges
, (APTR
)range
);
717 SetMulticast(unit
, base
);
722 return range
!= NULL
;
727 /****i* rhine.device/RemMulticastRange *************************************
733 * found = RemMulticastRange(unit, lower_bound, upper_bound)
735 * BOOL RemMulticastRange(struct DevUnit *, UBYTE *, UBYTE *);
737 ****************************************************************************
741 BOOL
RemMulticastRange(struct DevUnit
*unit
, const UBYTE
*lower_bound
,
742 const UBYTE
*upper_bound
, struct DevBase
*base
)
744 struct AddressRange
*range
;
745 ULONG lower_bound_left
, upper_bound_left
;
746 UWORD lower_bound_right
, upper_bound_right
;
748 lower_bound_left
= BELong(*((ULONG
*)lower_bound
));
749 lower_bound_right
= BEWord(*((UWORD
*)(lower_bound
+ 4)));
750 upper_bound_left
= BELong(*((ULONG
*)upper_bound
));
751 upper_bound_right
= BEWord(*((UWORD
*)(upper_bound
+ 4)));
753 range
= FindMulticastRange(unit
, lower_bound_left
, lower_bound_right
,
754 upper_bound_left
, upper_bound_right
, base
);
758 if(--range
->add_count
== 0)
763 SetMulticast(unit
, base
);
765 FreeMem(range
, sizeof(struct AddressRange
));
769 return range
!= NULL
;
774 /****i* rhine.device/FindMulticastRange ************************************
780 * range = FindMulticastRange(unit, lower_bound_left,
781 * lower_bound_right, upper_bound_left, upper_bound_right)
783 * struct AddressRange *FindMulticastRange(struct DevUnit *, ULONG,
784 * UWORD, ULONG, UWORD);
786 ****************************************************************************
790 static struct AddressRange
*FindMulticastRange(struct DevUnit
*unit
,
791 ULONG lower_bound_left
, UWORD lower_bound_right
, ULONG upper_bound_left
,
792 UWORD upper_bound_right
, struct DevBase
*base
)
794 struct AddressRange
*range
, *tail
;
797 range
= (APTR
)unit
->multicast_ranges
.mlh_Head
;
798 tail
= (APTR
)&unit
->multicast_ranges
.mlh_Tail
;
800 while(range
!= tail
&& !found
)
802 if(lower_bound_left
== range
->lower_bound_left
&&
803 lower_bound_right
== range
->lower_bound_right
&&
804 upper_bound_left
== range
->upper_bound_left
&&
805 upper_bound_right
== range
->upper_bound_right
)
808 range
= (APTR
)range
->node
.mln_Succ
;
819 /****i* rhine.device/SetMulticast ******************************************
827 * VOID SetMulticast(struct DevUnit *);
829 ****************************************************************************
833 static VOID
SetMulticast(struct DevUnit
*unit
, struct DevBase
*base
)
835 if(!IsListEmpty(&unit
->multicast_ranges
))
837 unit
->LELongOut(unit
->card
, RH_REG_MCASTFILTER
, 0xffffffff);
838 unit
->LELongOut(unit
->card
, RH_REG_MCASTFILTER
+ 4, 0xffffffff);
842 unit
->LELongOut(unit
->card
, RH_REG_MCASTFILTER
, 0);
843 unit
->LELongOut(unit
->card
, RH_REG_MCASTFILTER
+ 4, 0);
851 /****i* rhine.device/FindTypeStats *****************************************
857 * stats = FindTypeStats(unit, list,
860 * struct TypeStats *FindTypeStats(struct DevUnit *, struct MinList *,
863 ****************************************************************************
867 struct TypeStats
*FindTypeStats(struct DevUnit
*unit
, struct MinList
*list
,
868 ULONG packet_type
, struct DevBase
*base
)
870 struct TypeStats
*stats
, *tail
;
873 stats
= (APTR
)list
->mlh_Head
;
874 tail
= (APTR
)&list
->mlh_Tail
;
876 while(stats
!= tail
&& !found
)
878 if(stats
->packet_type
== packet_type
)
881 stats
= (APTR
)stats
->node
.mln_Succ
;
892 /****i* rhine.device/FlushUnit *********************************************
898 * FlushUnit(unit, last_queue, error)
900 * VOID FlushUnit(struct DevUnit *, UBYTE, BYTE);
902 ****************************************************************************
906 VOID
FlushUnit(struct DevUnit
*unit
, UBYTE last_queue
, BYTE error
,
907 struct DevBase
*base
)
909 struct IORequest
*request
;
911 struct Opener
*opener
, *tail
;
913 /* Abort queued requests */
915 for(i
= 0; i
<= last_queue
; i
++)
917 while((request
= (APTR
)GetMsg(unit
->request_ports
[i
])) != NULL
)
919 request
->io_Error
= IOERR_ABORTED
;
920 ReplyMsg((APTR
)request
);
925 opener
= (APTR
)unit
->openers
.mlh_Head
;
926 tail
= (APTR
)&unit
->openers
.mlh_Tail
;
928 /* Flush every opener's read queues */
930 while(opener
!= tail
)
932 while((request
= (APTR
)GetMsg(&opener
->read_port
)) != NULL
)
934 request
->io_Error
= error
;
935 ReplyMsg((APTR
)request
);
937 while((request
= (APTR
)GetMsg(&opener
->mgmt_port
)) != NULL
)
939 request
->io_Error
= error
;
940 ReplyMsg((APTR
)request
);
942 opener
= (APTR
)opener
->node
.mln_Succ
;
946 opener
= request
->ios2_BufferManagement
;
947 while((request
= (APTR
)GetMsg(&opener
->read_port
)) != NULL
)
949 request
->io_Error
= IOERR_ABORTED
;
950 ReplyMsg((APTR
)request
);
952 while((request
= (APTR
)GetMsg(&opener
->mgmt_port
)) != NULL
)
954 request
->io_Error
= IOERR_ABORTED
;
955 ReplyMsg((APTR
)request
);
966 /****i* rhine.device/StatusInt *********************************************
972 * finished = StatusInt(unit)
974 * BOOL StatusInt(struct DevUnit *);
977 * unit - A unit of this device.
980 * finished - Always FALSE.
982 ****************************************************************************
986 static BOOL
StatusInt(REG(a1
, struct DevUnit
*unit
), REG(a5
, APTR int_code
))
988 struct DevBase
*base
;
992 ints
= unit
->LEWordIn(unit
->card
, RH_REG_INTSTATUS
);
996 /* Acknowledge interrupts */
998 unit
->LEWordOut(unit
->card
, RH_REG_INTSTATUS
, ints
);
1000 /* FIXME: Need IO-sync here for PPC etc.? */
1002 /* Handle interrupts */
1004 if((ints
& (RH_INTF_TXERR
| RH_INTF_TXOK
)) != 0)
1005 Cause(&unit
->tx_end_int
);
1006 if((ints
& (RH_INTF_RXERR
| RH_INTF_RXOK
)) != 0)
1007 Cause(&unit
->rx_int
);
1015 /****i* rhine.device/RXInt *************************************************
1018 * RXInt -- Soft interrupt for packet reception.
1023 * VOID RXInt(struct DevUnit *);
1028 * unit - A unit of this device.
1033 ****************************************************************************
1037 static VOID
RXInt(REG(a1
, struct DevUnit
*unit
), REG(a5
, APTR int_code
))
1039 UWORD slot
, packet_size
;
1040 struct DevBase
*base
;
1041 ULONG rx_status
, *desc
, dma_size
;
1044 base
= unit
->device
;
1045 slot
= unit
->rx_slot
;
1046 desc
= unit
->rx_descs
[slot
];
1048 dma_size
= TX_DESC_SIZE
;
1049 CachePostDMA(unit
->rx_descs
, &dma_size
, 0);
1050 while(((rx_status
= LELong(desc
[RH_DESC_RXSTATUS
]))
1051 & RH_DESC_RXSTATUSF_INUSE
) == 0)
1053 if((rx_status
& RH_DESC_RXSTATUSF_OK
) != 0)
1055 packet_size
= ((rx_status
& RH_DESC_RXSTATUSF_LENGTH
)
1056 >> RH_DESC_RXSTATUSB_LENGTH
) - ETH_CRCSIZE
;
1057 buffer
= unit
->rx_buffers
[slot
];
1059 if(AddressFilter(unit
, buffer
+ ETH_PACKET_DEST
, base
))
1061 unit
->stats
.PacketsReceived
++;
1062 DistributeRXPacket(unit
, buffer
, packet_size
, base
);
1067 unit
->stats
.BadData
++;
1068 ReportEvents(unit
, S2EVENT_ERROR
| S2EVENT_HARDWARE
| S2EVENT_RX
,
1072 /* Mark descriptor as free for next time */
1074 desc
[RH_DESC_RXSTATUS
] = MakeLELong(RH_DESC_RXSTATUSF_INUSE
);
1076 /* Get next descriptor */
1078 slot
= (slot
+ 1) % RX_SLOT_COUNT
;
1079 desc
= unit
->rx_descs
[slot
];
1084 unit
->rx_slot
= slot
;
1090 /****i* rhine.device/DistributeRXPacket ************************************
1093 * DistributeRXPacket -- Send a packet to all appropriate destinations.
1096 * DistributeRXPacket(unit, frame)
1098 * VOID DistributeRXPacket(struct DevUnit *, UBYTE *);
1100 ****************************************************************************
1104 static VOID
DistributeRXPacket(struct DevUnit
*unit
, const UBYTE
*packet
,
1105 UWORD packet_size
, struct DevBase
*base
)
1107 BOOL is_orphan
= TRUE
, accepted
;
1109 struct IOSana2Req
*request
, *request_tail
;
1110 struct Opener
*opener
, *opener_tail
;
1111 struct TypeStats
*tracker
;
1113 /* Offer packet to every opener */
1115 opener
= (APTR
)unit
->openers
.mlh_Head
;
1116 opener_tail
= (APTR
)&unit
->openers
.mlh_Tail
;
1117 packet_type
= BEWord(*((UWORD
*)(packet
+ ETH_PACKET_TYPE
)));
1119 while(opener
!= opener_tail
)
1121 request
= (APTR
)opener
->read_port
.mp_MsgList
.lh_Head
;
1122 request_tail
= (APTR
)&opener
->read_port
.mp_MsgList
.lh_Tail
;
1125 /* Offer packet to each request until it's accepted */
1127 while(request
!= request_tail
&& !accepted
)
1129 if(request
->ios2_PacketType
== packet_type
)
1131 CopyPacket(unit
, request
, packet_size
, packet_type
,
1136 (APTR
)request
->ios2_Req
.io_Message
.mn_Node
.ln_Succ
;
1141 opener
= (APTR
)opener
->node
.mln_Succ
;
1144 /* If packet was unwanted, give it to S2_READORPHAN request */
1148 unit
->stats
.UnknownTypesReceived
++;
1149 if(!IsMsgPortEmpty(unit
->request_ports
[ADOPT_QUEUE
]))
1152 (APTR
)unit
->request_ports
[ADOPT_QUEUE
]->mp_MsgList
.lh_Head
,
1153 packet_size
, packet_type
, packet
, base
);
1157 /* Update remaining statistics */
1159 if(packet_type
<= ETH_MTU
)
1160 packet_type
= ETH_MTU
;
1162 FindTypeStats(unit
, &unit
->type_trackers
, packet_type
, base
);
1165 tracker
->stats
.PacketsReceived
++;
1166 tracker
->stats
.BytesReceived
+= packet_size
;
1174 /****i* rhine.device/CopyPacket ********************************************
1177 * CopyPacket -- Copy packet to client's buffer.
1180 * CopyPacket(unit, request, packet_size, packet_type,
1183 * VOID CopyPacket(struct DevUnit *, struct IOSana2Req *, UWORD, UWORD,
1186 ****************************************************************************
1190 static VOID
CopyPacket(struct DevUnit
*unit
, struct IOSana2Req
*request
,
1191 UWORD packet_size
, UWORD packet_type
, const UBYTE
*buffer
,
1192 struct DevBase
*base
)
1194 struct Opener
*opener
;
1195 BOOL filtered
= FALSE
;
1197 /* Set multicast and broadcast flags */
1199 request
->ios2_Req
.io_Flags
&= ~(SANA2IOF_BCAST
| SANA2IOF_MCAST
);
1200 if((*((ULONG
*)(buffer
+ ETH_PACKET_DEST
)) == 0xffffffff) &&
1201 (*((UWORD
*)(buffer
+ ETH_PACKET_DEST
+ 4)) == 0xffff))
1202 request
->ios2_Req
.io_Flags
|= SANA2IOF_BCAST
;
1203 else if((buffer
[ETH_PACKET_DEST
] & 0x1) != 0)
1204 request
->ios2_Req
.io_Flags
|= SANA2IOF_MCAST
;
1206 /* Set source and destination addresses and packet type */
1208 CopyMem(buffer
+ ETH_PACKET_SOURCE
, request
->ios2_SrcAddr
,
1210 CopyMem(buffer
+ ETH_PACKET_DEST
, request
->ios2_DstAddr
,
1212 request
->ios2_PacketType
= packet_type
;
1214 /* Adjust for cooked packet request */
1216 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
1218 packet_size
-= ETH_PACKET_DATA
;
1219 buffer
+= ETH_PACKET_DATA
;
1223 packet_size
+= 4; /* Needed for Shapeshifter & Fusion */
1225 request
->ios2_DataLength
= packet_size
;
1229 opener
= request
->ios2_BufferManagement
;
1230 if(request
->ios2_Req
.io_Command
== CMD_READ
&&
1231 opener
->filter_hook
!= NULL
)
1232 if(!CallHookPkt(opener
->filter_hook
, request
, (APTR
)buffer
))
1237 /* Copy packet into opener's buffer and reply packet */
1239 if(!opener
->rx_function(request
->ios2_Data
, (APTR
)buffer
,
1242 request
->ios2_Req
.io_Error
= S2ERR_NO_RESOURCES
;
1243 request
->ios2_WireError
= S2WERR_BUFF_ERROR
;
1245 S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
| S2EVENT_RX
,
1248 Remove((APTR
)request
);
1249 ReplyMsg((APTR
)request
);
1257 /****i* rhine.device/AddressFilter *****************************************
1260 * AddressFilter -- Determine if an RX packet should be accepted.
1263 * accept = AddressFilter(unit, address)
1265 * BOOL AddressFilter(struct DevUnit *, UBYTE *);
1267 ****************************************************************************
1271 static BOOL
AddressFilter(struct DevUnit
*unit
, UBYTE
*address
,
1272 struct DevBase
*base
)
1274 struct AddressRange
*range
, *tail
;
1277 UWORD address_right
;
1279 /* Check whether address is unicast/broadcast or multicast */
1281 address_left
= BELong(*((ULONG
*)address
));
1282 address_right
= BEWord(*((UWORD
*)(address
+ 4)));
1284 if(((address_left
& 0x01000000) != 0) &&
1285 !((address_left
== 0xffffffff) && (address_right
== 0xffff)))
1287 /* Check if this multicast address is wanted */
1289 range
= (APTR
)unit
->multicast_ranges
.mlh_Head
;
1290 tail
= (APTR
)&unit
->multicast_ranges
.mlh_Tail
;
1293 while((range
!= tail
) && !accept
)
1295 if((address_left
> range
->lower_bound_left
||
1296 address_left
== range
->lower_bound_left
&&
1297 address_right
>= range
->lower_bound_right
) &&
1298 (address_left
< range
->upper_bound_left
||
1299 address_left
== range
->upper_bound_left
&&
1300 address_right
<= range
->upper_bound_right
))
1302 range
= (APTR
)range
->node
.mln_Succ
;
1306 unit
->special_stats
[S2SS_ETHERNET_BADMULTICAST
& 0xffff]++;
1314 /****i* rhine.device/TXInt *************************************************
1317 * TXInt -- Soft interrupt for packet transmission.
1322 * VOID TXInt(struct DevUnit *);
1327 * unit - A unit of this device.
1332 ****************************************************************************
1336 static VOID
TXInt(REG(a1
, struct DevUnit
*unit
), REG(a5
, APTR int_code
))
1338 struct DevBase
*base
;
1339 UWORD packet_size
, data_size
, slot
, new_slot
, *p
, *q
, i
;
1340 struct IOSana2Req
*request
;
1341 BOOL proceed
= TRUE
;
1342 struct Opener
*opener
;
1343 ULONG wire_error
, *desc
, dma_size
, desc_p
, buffer_p
, txcontrol_value
;
1344 UBYTE
*(*dma_tx_function
)(REG(a0
, APTR
));
1347 struct MsgPort
*port
;
1349 base
= unit
->device
;
1350 port
= unit
->request_ports
[WRITE_QUEUE
];
1352 while(proceed
&& !IsMsgPortEmpty(port
))
1354 slot
= unit
->tx_in_slot
;
1355 new_slot
= (slot
+ 1) % TX_SLOT_COUNT
;
1357 if(new_slot
!= unit
->tx_out_slot
1358 && (unit
->flags
& UNITF_TXBUFFERINUSE
) == 0)
1362 /* Get request and DMA frame descriptor */
1364 request
= (APTR
)port
->mp_MsgList
.lh_Head
;
1366 Remove((APTR
)request
);
1367 unit
->tx_requests
[slot
] = request
;
1368 desc
= unit
->tx_descs
[slot
];
1369 desc_p
= unit
->tx_descs_p
[slot
];
1371 data_size
= packet_size
= request
->ios2_DataLength
;
1372 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
1373 packet_size
+= ETH_HEADERSIZE
;
1374 if(packet_size
< ETH_MINSIZE
)
1375 packet_size
= ETH_MINSIZE
;
1377 /* Decide if one or two descriptors are needed, and generate
1378 Ethernet header if necessary */
1380 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
1382 /* Use first descriptor for Ethernet header */
1384 buffer
= (UBYTE
*)desc
+ 2 * RH_DESCSIZE
;
1385 buffer_p
= desc_p
+ 2 * RH_DESCSIZE
;
1387 desc
[RH_DESC_TXCONTROL
] =
1388 MakeLELong(RH_DESC_TXCONTROLF_FIRSTFRAG
1389 | RH_DESC_TXCONTROLF_CHAIN
| ETH_HEADERSIZE
);
1390 desc
[RH_DESC_DATA
] = MakeLELong(buffer_p
);
1391 desc
[RH_DESC_NEXT
] = MakeLELong(desc_p
+ RH_DESCSIZE
);
1393 /* Write Ethernet header */
1395 p
= (UWORD
*)buffer
;
1396 for(i
= 0, q
= (UWORD
*)request
->ios2_DstAddr
;
1397 i
< ETH_ADDRESSSIZE
/ 2; i
++)
1399 for(i
= 0, q
= (UWORD
*)unit
->address
;
1400 i
< ETH_ADDRESSSIZE
/ 2; i
++)
1402 *p
++ = MakeBEWord(request
->ios2_PacketType
);
1404 /* Use spare second descriptor for frame data */
1406 desc
+= RH_DESCSIZE
/ 4;
1407 desc_p
+= RH_DESCSIZE
;
1409 txcontrol_value
= RH_DESC_TXCONTROLF_INT
1410 | RH_DESC_TXCONTROLF_LASTFRAG
1411 | RH_DESC_TXCONTROLF_CHAIN
1412 | packet_size
- ETH_HEADERSIZE
;
1416 txcontrol_value
= RH_DESC_TXCONTROLF_INT
1417 | RH_DESC_TXCONTROLF_FIRSTFRAG
| RH_DESC_TXCONTROLF_LASTFRAG
1418 | RH_DESC_TXCONTROLF_CHAIN
1422 /* Get packet data */
1424 opener
= (APTR
)request
->ios2_BufferManagement
;
1425 dma_tx_function
= opener
->dma_tx_function
;
1426 if(dma_tx_function
!= NULL
)
1427 buffer
= dma_tx_function(request
->ios2_Data
);
1433 buffer
= unit
->tx_buffer
;
1434 if(opener
->tx_function(buffer
, request
->ios2_Data
,
1437 unit
->flags
|= UNITF_TXBUFFERINUSE
;
1441 error
= S2ERR_NO_RESOURCES
;
1442 wire_error
= S2WERR_BUFF_ERROR
;
1444 S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
1445 | S2EVENT_TX
, base
);
1448 unit
->tx_buffers
[slot
] = buffer
;
1450 /* Fill in descriptor for frame data */
1454 dma_size
= data_size
;
1455 buffer_p
= (ULONG
)(UPINT
)CachePreDMA(buffer
, &dma_size
,
1457 desc
[RH_DESC_TXCONTROL
] = MakeLELong(txcontrol_value
);
1458 desc
[RH_DESC_DATA
] = MakeLELong(buffer_p
);
1459 desc
[RH_DESC_NEXT
] = MakeLELong(unit
->tx_descs_p
[new_slot
]);
1461 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
1462 desc
-= RH_DESCSIZE
/ 4;
1464 desc
[RH_DESC_TXSTATUS
] = MakeLELong(RH_DESC_TXSTATUSF_INUSE
);
1469 /* Restart transmission if it had stopped */
1471 dma_size
= TX_DESC_SIZE
* TX_SLOT_COUNT
;
1472 CachePreDMA(unit
->tx_descs
, &dma_size
, 0);
1473 unit
->ByteOut(unit
->card
, RH_REG_CONTROL
,
1474 unit
->ByteIn(unit
->card
, RH_REG_CONTROL
)
1475 | RH_REG_CONTROLF_TXPOLL
);
1477 /* FIXME: Need IO-sync here for PPC etc.? */
1479 unit
->tx_in_slot
= new_slot
;
1483 /* Return failed request */
1485 request
->ios2_Req
.io_Error
= error
;
1486 request
->ios2_WireError
= wire_error
;
1487 ReplyMsg((APTR
)request
);
1495 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_SOFTINT
;
1497 unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_IGNORE
;
1504 /****i* rhine.device/TXEndInt **********************************************
1507 * TXEndInt -- Clean up after a frame has been sent.
1510 * TXEndInt(unit, int_code)
1512 * VOID TXEndInt(struct DevUnit *, APTR);
1515 * unit - A unit of this device.
1516 * int_code - Unused.
1521 ****************************************************************************
1523 * It appears to be safe to assume that there will always be at least one
1524 * completed packet whenever this interrupt is called.
1528 static VOID
TXEndInt(REG(a1
, struct DevUnit
*unit
), REG(a5
, APTR int_code
))
1530 UWORD data_size
, i
= 0;
1532 struct DevBase
*base
;
1533 ULONG
*desc
, dma_size
;
1534 BOOL proceed
= TRUE
;
1536 /* Retire sent packets */
1538 base
= unit
->device
;
1539 dma_size
= TX_DESC_SIZE
* TX_SLOT_COUNT
;
1540 CachePostDMA(unit
->tx_descs
, &dma_size
, 0);
1542 i
= unit
->tx_out_slot
;
1545 /* Skip to "spare" descriptor if valid */
1547 desc
= unit
->tx_descs
[i
];
1548 if((desc
[RH_DESC_TXCONTROL
] & RH_DESC_TXCONTROLF_LASTFRAG
) == 0)
1551 /* Check that descriptor is not in use */
1553 if((desc
[RH_DESC_TXSTATUS
] & MakeLELong(RH_DESC_TXSTATUSF_INUSE
))
1554 == 0 && i
!= unit
->tx_in_slot
)
1556 buffer
= unit
->tx_buffers
[i
];
1557 dma_size
= data_size
;
1558 CachePostDMA(buffer
, &dma_size
, DMA_ReadFromRAM
);
1560 /* Check if unit's buffer is now free */
1562 if(buffer
== unit
->tx_buffer
)
1563 unit
->flags
&= ~UNITF_TXBUFFERINUSE
;
1565 RetireTXSlot(unit
, i
, base
);
1567 i
= (i
+ 1) % TX_SLOT_COUNT
;
1573 unit
->tx_out_slot
= i
;
1575 dma_size
= TX_DESC_SIZE
* TX_SLOT_COUNT
;
1576 CachePreDMA(unit
->tx_descs
, &dma_size
, 0);
1578 /* Restart downloads if they had stopped */
1580 if(unit
->request_ports
[WRITE_QUEUE
]->mp_Flags
== PA_IGNORE
)
1581 Cause(&unit
->tx_int
);
1588 /****i* rhine.device/RetireTXSlot ******************************************
1591 * RetireTXSlot -- Reply finished TX request.
1594 * RetireTXSlot(unit, slot)
1596 * VOID RetireTXSlot(struct DevUnit *, UWORD);
1598 ****************************************************************************
1602 static VOID
RetireTXSlot(struct DevUnit
*unit
, UWORD slot
,
1603 struct DevBase
*base
)
1606 struct IOSana2Req
*request
;
1607 struct TypeStats
*tracker
;
1609 /* Update statistics */
1611 slot
= unit
->tx_out_slot
;
1612 request
= unit
->tx_requests
[slot
];
1613 frame_size
= request
->ios2_DataLength
;
1614 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
1615 frame_size
+= ETH_HEADERSIZE
;
1617 unit
->stats
.PacketsSent
++;
1619 tracker
= FindTypeStats(unit
, &unit
->type_trackers
,
1620 request
->ios2_PacketType
, base
);
1623 tracker
->stats
.PacketsSent
++;
1624 tracker
->stats
.BytesSent
+= frame_size
;
1629 request
->ios2_Req
.io_Error
= 0;
1630 ReplyMsg((APTR
)request
);
1637 /****i* rhine.device/ResetHandler ******************************************
1640 * ResetHandler -- Disable hardware before a reboot.
1643 * ResetHandler(unit, int_code)
1645 * VOID ResetHandler(struct DevUnit *, APTR);
1647 ****************************************************************************
1651 static VOID
ResetHandler(REG(a1
, struct DevUnit
*unit
),
1652 REG(a6
, APTR int_code
))
1654 if((unit
->flags
& UNITF_HAVEADAPTER
) != 0)
1656 /* Disable frame transmission and reception */
1658 unit
->LEWordOut(unit
->card
, RH_REG_CONTROL
, RH_REG_CONTROLF_STOP
);
1660 /* Stop interrupts */
1662 unit
->LEWordOut(unit
->card
, RH_REG_INTMASK
, 0);
1671 /****i* rhine.device/ReportEvents ******************************************
1677 * ReportEvents(unit, events)
1679 * VOID ReportEvents(struct DevUnit *, ULONG);
1684 * unit - A unit of this device.
1685 * events - A mask of events to report.
1690 ****************************************************************************
1694 static VOID
ReportEvents(struct DevUnit
*unit
, ULONG events
,
1695 struct DevBase
*base
)
1697 struct IOSana2Req
*request
, *tail
, *next_request
;
1700 list
= &unit
->request_ports
[EVENT_QUEUE
]->mp_MsgList
;
1701 next_request
= (APTR
)list
->lh_Head
;
1702 tail
= (APTR
)&list
->lh_Tail
;
1705 while(next_request
!= tail
)
1707 request
= next_request
;
1708 next_request
= (APTR
)request
->ios2_Req
.io_Message
.mn_Node
.ln_Succ
;
1710 if((request
->ios2_WireError
& events
) != 0)
1712 request
->ios2_WireError
= events
;
1713 Remove((APTR
)request
);
1714 ReplyMsg((APTR
)request
);
1724 /****i* rhine.device/UnitTask **********************************************
1735 * Completes deferred requests, and handles card insertion and removal
1736 * in conjunction with the relevant interrupts.
1738 ****************************************************************************
1742 static VOID
UnitTask(struct ExecBase
*sys_base
)
1745 struct IORequest
*request
;
1746 struct DevUnit
*unit
;
1747 struct DevBase
*base
;
1748 struct MsgPort
*general_port
;
1749 ULONG signals
= 0, wait_signals
, card_removed_signal
,
1750 card_inserted_signal
, general_port_signal
;
1752 /* Get parameters */
1754 task
= AbsExecBase
->ThisTask
;
1755 unit
= task
->tc_UserData
;
1756 base
= unit
->device
;
1758 /* Activate general request port */
1760 general_port
= unit
->request_ports
[GENERAL_QUEUE
];
1761 general_port
->mp_SigTask
= task
;
1762 general_port
->mp_SigBit
= AllocSignal(-1);
1763 general_port_signal
= 1 << general_port
->mp_SigBit
;
1764 general_port
->mp_Flags
= PA_SIGNAL
;
1766 /* Allocate signals for notification of card removal and insertion */
1768 card_removed_signal
= unit
->card_removed_signal
= 1 << AllocSignal(-1);
1769 card_inserted_signal
= unit
->card_inserted_signal
= 1 << AllocSignal(-1);
1770 wait_signals
= (1 << general_port
->mp_SigBit
) | card_removed_signal
1771 | card_inserted_signal
| SIGBREAKF_CTRL_C
;
1773 /* Tell ourselves to check port for old messages */
1775 Signal(task
, general_port_signal
);
1777 /* Infinite loop to service requests and signals */
1781 signals
= Wait(wait_signals
);
1783 if((signals
& card_inserted_signal
) != 0)
1785 if(unit
->insertion_function(unit
->card
, base
))
1787 unit
->flags
|= UNITF_HAVEADAPTER
;
1788 if((unit
->flags
& UNITF_CONFIGURED
) != 0)
1789 ConfigureAdapter(unit
, base
);
1790 if((unit
->flags
& UNITF_WASONLINE
) != 0)
1792 GoOnline(unit
, base
);
1793 unit
->flags
&= ~UNITF_WASONLINE
;
1798 if((signals
& card_removed_signal
) != 0)
1800 unit
->removal_function(unit
->card
, base
);
1801 if((unit
->flags
& UNITF_WASONLINE
) != 0)
1802 GoOffline(unit
, base
);
1805 if((signals
& general_port_signal
) != 0)
1807 while((request
= (APTR
)GetMsg(general_port
)) != NULL
)
1809 /* Service the request as soon as the unit is free */
1811 ObtainSemaphore(&unit
->access_lock
);
1812 ServiceRequest((APTR
)request
, base
);
1820 /****i* rhine.device/ReadMII ***********************************************
1823 * ReadMII -- Read a register in an MII PHY.
1826 * value = ReadMII(unit, phy_no, reg_no)
1828 * UWORD ReadMII(struct DevUnit *, UWORD, UWORD);
1831 * unit - A unit of this device.
1832 * phy_no - Index of PHY to use.
1833 * reg_no - MII register to read.
1836 * value - Value read from MII register.
1838 ****************************************************************************
1842 UWORD
ReadMII(struct DevUnit
*unit
, UWORD phy_no
, UWORD reg_no
,
1843 struct DevBase
*base
)
1845 while((unit
->ByteIn(unit
->card
, RH_REG_MIICTRL
)
1846 & (RH_REG_MIICTRLF_READ
| RH_REG_MIICTRLF_WRITE
)) != 0);
1848 unit
->ByteOut(unit
->card
, RH_REG_MIICTRL
, 0);
1849 unit
->ByteOut(unit
->card
, RH_REG_MIICONFIG
, phy_no
);
1850 unit
->ByteOut(unit
->card
, RH_REG_MIIREGNO
, reg_no
);
1851 unit
->ByteOut(unit
->card
, RH_REG_MIICTRL
, RH_REG_MIICTRLF_READ
);
1852 while((unit
->ByteIn(unit
->card
, RH_REG_MIICTRL
)
1853 & (RH_REG_MIICTRLF_READ
| RH_REG_MIICTRLF_WRITE
)) != 0);
1855 return unit
->LEWordIn(unit
->card
, RH_REG_MIIDATA
);