Reverted removal of 'const' from TagItem arrays/pointers in r50146
[AROS.git] / workbench / devs / networks / rhine / unit.c
blob4ef0a4b0eada3b87f8a48ef768d893c0b8822d52
1 /*
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,
19 MA 02111-1307, USA.
24 #include <exec/memory.h>
25 #include <exec/execbase.h>
26 #include <exec/errors.h>
28 #include <proto/exec.h>
29 #include <proto/alib.h>
30 #include <proto/utility.h>
31 #include <proto/timer.h>
33 #include "device.h"
34 #include "rhine.h"
36 #include "unit_protos.h"
37 #include "request_protos.h"
38 #include "timer_protos.h"
41 #define TASK_PRIORITY 0
42 #define STACK_SIZE 4096
43 #define INT_MASK 0xffff
44 #define TX_DESC_SIZE (RH_DESCSIZE * 2 + ETH_HEADERSIZE + 2)
46 #ifndef AbsExecBase
47 #define AbsExecBase sys_base
48 #endif
50 VOID DeinitialiseAdapter(struct DevUnit *unit, struct DevBase *base);
51 static struct AddressRange *FindMulticastRange(struct DevUnit *unit,
52 ULONG lower_bound_left, UWORD lower_bound_right, ULONG upper_bound_left,
53 UWORD upper_bound_right, struct DevBase *base);
54 static VOID SetMulticast(struct DevUnit *unit, struct DevBase *base);
55 static BOOL StatusInt(REG(a1, struct DevUnit *unit), REG(a5, APTR int_code));
56 static VOID RXInt(REG(a1, struct DevUnit *unit), REG(a6, APTR int_code));
57 static VOID DistributeRXPacket(struct DevUnit *unit, const UBYTE *packet,
58 UWORD packet_size, struct DevBase *base);
59 static VOID CopyPacket(struct DevUnit *unit, struct IOSana2Req *request,
60 UWORD packet_size, UWORD packet_type, const UBYTE *buffer,
61 struct DevBase *base);
62 static BOOL AddressFilter(struct DevUnit *unit, UBYTE *address,
63 struct DevBase *base);
64 static VOID TXInt(REG(a1, struct DevUnit *unit), REG(a6, APTR int_code));
65 static VOID TXEndInt(REG(a1, struct DevUnit *unit), REG(a5, APTR int_code));
66 static VOID RetireTXSlot(struct DevUnit *unit, UWORD slot,
67 struct DevBase *base);
68 static VOID ResetHandler(REG(a1, struct DevUnit *unit),
69 REG(a6, APTR int_code));
70 static VOID ReportEvents(struct DevUnit *unit, ULONG events,
71 struct DevBase *base);
72 static VOID UnitTask(struct ExecBase *sys_base);
73 UWORD ReadMII(struct DevUnit *unit, UWORD phy_no, UWORD reg_no,
74 struct DevBase *base);
76 #if !defined(__AROS__)
77 static const UBYTE broadcast_address[] =
78 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
79 #endif
81 #ifdef __AROS__
82 #undef AddTask
83 #define AddTask(task, initial_pc, final_pc) \
84 ({ \
85 struct TagItem _task_tags[] = \
86 {{TASKTAG_ARG1, (IPTR)SysBase}, {TAG_END, 0}}; \
87 NewAddTask(task, initial_pc, final_pc, _task_tags); \
89 #endif
93 /****i* rhine.device/CreateUnit ********************************************
95 * NAME
96 * CreateUnit -- Create a unit.
98 * SYNOPSIS
99 * unit = CreateUnit(index, io_base, id, card,
100 * io_tags, bus)
102 * struct DevUnit *CreateUnit(ULONG, APTR, UWORD, APTR,
103 * struct TagItem *, UWORD);
105 * FUNCTION
106 * Creates a new unit.
108 ****************************************************************************
112 struct DevUnit *CreateUnit(ULONG index, APTR card,
113 const struct TagItem *io_tags, UWORD bus, struct DevBase *base)
115 BOOL success = TRUE;
116 struct DevUnit *unit;
117 struct Task *task;
118 struct MsgPort *port;
119 UWORD i;
120 ULONG *desc, desc_p, buffer_p, dma_size;
121 APTR stack;
123 unit = AllocMem(sizeof(struct DevUnit), MEMF_CLEAR | MEMF_PUBLIC);
124 if(unit == NULL)
125 success = FALSE;
127 if(success)
129 /* Initialise lists etc. */
131 NewList((APTR)&unit->openers);
132 NewList((APTR)&unit->type_trackers);
133 NewList((APTR)&unit->multicast_ranges);
135 unit->index = index;
136 unit->device = base;
137 unit->card = card;
138 unit->bus = bus;
140 /* Store I/O hooks */
142 unit->ByteIn =
143 (APTR)GetTagData(IOTAG_ByteIn, (UPINT)NULL, io_tags);
144 unit->ByteOut =
145 (APTR)GetTagData(IOTAG_ByteOut, (UPINT)NULL, io_tags);
146 unit->LEWordIn =
147 (APTR)GetTagData(IOTAG_LEWordIn, (UPINT)NULL, io_tags);
148 unit->LELongIn =
149 (APTR)GetTagData(IOTAG_LELongIn, (UPINT)NULL, io_tags);
150 unit->LEWordOut =
151 (APTR)GetTagData(IOTAG_LEWordOut, (UPINT)NULL, io_tags);
152 unit->LELongOut =
153 (APTR)GetTagData(IOTAG_LELongOut, (UPINT)NULL, io_tags);
154 unit->AllocDMAMem =
155 (APTR)GetTagData(IOTAG_AllocDMAMem, (UPINT)NULL, io_tags);
156 unit->FreeDMAMem =
157 (APTR)GetTagData(IOTAG_FreeDMAMem, (UPINT)NULL, io_tags);
158 if(unit->ByteIn == NULL
159 || unit->ByteOut == NULL
160 || unit->LEWordIn == NULL
161 || unit->LELongIn == NULL
162 || unit->LEWordOut == NULL
163 || unit->LELongOut == NULL
164 || unit->AllocDMAMem == NULL
165 || unit->FreeDMAMem == NULL)
166 success = FALSE;
169 if(success)
171 InitSemaphore(&unit->access_lock);
173 /* Create the message ports for queuing requests */
175 for(i = 0; i < REQUEST_QUEUE_COUNT; i++)
177 unit->request_ports[i] = port = AllocMem(sizeof(struct MsgPort),
178 MEMF_PUBLIC | MEMF_CLEAR);
179 if(port == NULL)
180 success = FALSE;
182 if(success)
184 NewList(&port->mp_MsgList);
185 port->mp_Flags = PA_IGNORE;
188 if(success)
189 unit->request_ports[WRITE_QUEUE]->mp_SigTask = &unit->tx_int;
192 if(success)
194 /* Allocate TX descriptors */
196 desc = unit->AllocDMAMem(unit->card, TX_DESC_SIZE * TX_SLOT_COUNT, 16);
197 if(desc == NULL)
198 success = FALSE;
201 if(success)
203 /* Fill arrays of virtual and physical addresses of TX descriptors */
205 dma_size = TX_DESC_SIZE * TX_SLOT_COUNT;
206 desc_p = (ULONG)(UPINT)CachePreDMA(desc, &dma_size, 0);
207 if(dma_size != TX_DESC_SIZE * TX_SLOT_COUNT)
208 success = FALSE;
209 CachePostDMA(desc, &dma_size, 0);
211 for(i = 0; i < TX_SLOT_COUNT; i++)
213 unit->tx_descs[i] = desc;
214 desc += TX_DESC_SIZE / sizeof(ULONG);
215 unit->tx_descs_p[i] = desc_p;
216 desc_p += TX_DESC_SIZE;
220 if(success)
222 /* Allocate RX descriptors */
224 desc = unit->AllocDMAMem(unit->card, RH_DESCSIZE * RX_SLOT_COUNT, 16);
225 if(desc == NULL)
226 success = FALSE;
229 if(success)
231 /* Fill arrays of virtual and physical addresses of TX descriptors */
233 dma_size = RH_DESCSIZE * RX_SLOT_COUNT;
234 desc_p = (ULONG)(UPINT)CachePreDMA(desc, &dma_size, 0);
235 if(dma_size != RH_DESCSIZE * RX_SLOT_COUNT)
236 success = FALSE;
237 CachePostDMA(desc, &dma_size, 0);
239 for(i = 0; i < RX_SLOT_COUNT; i++)
241 unit->rx_descs[i] = desc;
242 desc += RH_DESCSIZE / sizeof(ULONG);
243 unit->rx_descs_p[i] = desc_p;
244 desc_p += RH_DESCSIZE;
247 /* Allocate packet buffers */
249 unit->tx_buffer = unit->AllocDMAMem(unit->card, FRAME_BUFFER_SIZE, 4);
250 if(unit->tx_buffer == NULL)
251 success = FALSE;
253 for(i = 0; i < RX_SLOT_COUNT; i++)
255 unit->rx_buffers[i] = unit->AllocDMAMem(unit->card,
256 FRAME_BUFFER_SIZE, 4);
257 if(unit->rx_buffers[i] == NULL)
258 success = FALSE;
261 unit->tx_requests = AllocVec(sizeof(APTR) * TX_SLOT_COUNT,
262 MEMF_PUBLIC);
263 if(unit->tx_requests == NULL)
264 success = FALSE;
267 if(success)
269 /* Construct RX ring */
271 for(i = 0; i < RX_SLOT_COUNT; i++)
273 desc = unit->rx_descs[i];
274 desc[RH_DESC_RXSTATUS] = MakeLELong(RH_DESC_RXSTATUSF_INUSE);
275 desc[RH_DESC_RXCONTROL] = MakeLELong(FRAME_BUFFER_SIZE);
276 dma_size = FRAME_BUFFER_SIZE;
277 buffer_p =
278 (ULONG)(UPINT)CachePreDMA(unit->rx_buffers[i], &dma_size, 0);
279 if(dma_size != FRAME_BUFFER_SIZE)
280 success = FALSE;
281 desc[RH_DESC_DATA] = MakeLELong(buffer_p);
282 desc[RH_DESC_NEXT] =
283 MakeLELong(unit->rx_descs_p[(i + 1) % RX_SLOT_COUNT]);
284 desc += RH_DESCSIZE / sizeof(ULONG);
286 dma_size = RH_DESCSIZE * RX_SLOT_COUNT;
287 CachePreDMA(unit->rx_descs, &dma_size, 0);
290 if(success)
292 /* Initialise network adapter hardware */
294 success = InitialiseAdapter(unit, FALSE, base);
295 unit->flags |= UNITF_HAVEADAPTER;
298 if(success)
300 /* Record maximum speed in BPS */
302 unit->speed = 100000000;
304 /* Initialise interrupts */
306 unit->status_int.is_Code = (APTR)StatusInt;
307 unit->status_int.is_Data = unit;
309 unit->rx_int.is_Node.ln_Name =
310 base->device.dd_Library.lib_Node.ln_Name;
311 unit->rx_int.is_Code = (APTR)RXInt;
312 unit->rx_int.is_Data = unit;
314 unit->tx_int.is_Node.ln_Name =
315 base->device.dd_Library.lib_Node.ln_Name;
316 unit->tx_int.is_Code = (APTR)TXInt;
317 unit->tx_int.is_Data = unit;
319 unit->tx_end_int.is_Node.ln_Name =
320 base->device.dd_Library.lib_Node.ln_Name;
321 unit->tx_end_int.is_Code = (APTR)TXEndInt;
322 unit->tx_end_int.is_Data = unit;
324 unit->reset_handler.is_Node.ln_Name =
325 base->device.dd_Library.lib_Node.ln_Name;
326 unit->reset_handler.is_Code = (APTR)ResetHandler;
327 unit->reset_handler.is_Data = unit;
329 unit->request_ports[WRITE_QUEUE]->mp_Flags = PA_SOFTINT;
331 /* Create a new task */
333 unit->task = task =
334 AllocMem(sizeof(struct Task), MEMF_PUBLIC | MEMF_CLEAR);
335 if(task == NULL)
336 success = FALSE;
339 if(success)
341 stack = AllocMem(STACK_SIZE, MEMF_PUBLIC);
342 if(stack == NULL)
343 success = FALSE;
346 if(success)
348 /* Initialise and start task */
350 task->tc_Node.ln_Type = NT_TASK;
351 task->tc_Node.ln_Pri = TASK_PRIORITY;
352 task->tc_Node.ln_Name = base->device.dd_Library.lib_Node.ln_Name;
353 task->tc_SPUpper = stack + STACK_SIZE;
354 task->tc_SPLower = stack;
355 task->tc_SPReg = stack + STACK_SIZE;
356 NewList(&task->tc_MemEntry);
358 if(AddTask(task, UnitTask, NULL) == NULL)
359 success = FALSE;
362 if(success)
364 /* Send the unit to the new task */
366 task->tc_UserData = unit;
369 if(!success)
371 DeleteUnit(unit, base);
372 unit = NULL;
375 return unit;
380 /****i* rhine.device/DeleteUnit ********************************************
382 * NAME
383 * DeleteUnit -- Delete a unit.
385 * SYNOPSIS
386 * DeleteUnit(unit)
388 * VOID DeleteUnit(struct DevUnit *);
390 * FUNCTION
391 * Deletes a unit.
393 * INPUTS
394 * unit - Device unit (may be NULL).
396 * RESULT
397 * None.
399 ****************************************************************************
403 VOID DeleteUnit(struct DevUnit *unit, struct DevBase *base)
405 UBYTE i;
406 struct Task *task;
408 if(unit != NULL)
410 task = unit->task;
411 if(task != NULL)
413 if(task->tc_UserData != NULL)
415 RemTask(task);
416 FreeMem(task->tc_SPLower, STACK_SIZE);
418 FreeMem(task, sizeof(struct Task));
421 for(i = 0; i < REQUEST_QUEUE_COUNT; i++)
423 if(unit->request_ports[i] != NULL)
424 FreeMem(unit->request_ports[i], sizeof(struct MsgPort));
427 if((unit->flags & UNITF_ONLINE) != 0) /* Needed! */
428 GoOffline(unit, base);
430 if((unit->flags & UNITF_HAVEADAPTER) != 0)
431 DeinitialiseAdapter(unit, base);
433 for(i = 0; i < RX_SLOT_COUNT; i++)
434 unit->FreeDMAMem(unit->card, unit->rx_buffers[i]);
435 unit->FreeDMAMem(unit->card, unit->tx_buffer);
436 unit->FreeDMAMem(unit->card, unit->rx_descs[0]);
437 unit->FreeDMAMem(unit->card, unit->tx_descs[0]);
439 FreeVec(unit->tx_requests);
441 FreeMem(unit, sizeof(struct DevUnit));
444 return;
449 /****i* rhine.device/InitialiseAdapter *************************************
451 * NAME
452 * InitialiseAdapter
454 * SYNOPSIS
455 * success = InitialiseAdapter(unit, reinsertion)
457 * BOOL InitialiseAdapter(struct DevUnit *, BOOL);
459 * FUNCTION
461 * INPUTS
462 * unit
463 * reinsertion
465 * RESULT
466 * success - Success indicator.
468 ****************************************************************************
472 BOOL InitialiseAdapter(struct DevUnit *unit, BOOL reinsertion,
473 struct DevBase *base)
475 BOOL success = TRUE;
476 UBYTE *p, eeprom_reg;
477 UWORD i;
479 /* Reload data from EEPROM */
481 eeprom_reg = unit->ByteIn(unit->card, RH_REG_EEPROM);
482 unit->ByteOut(unit->card, RH_REG_EEPROM,
483 eeprom_reg | RH_REG_EEPROMF_LOAD);
485 BusyMicroDelay(1, base);
486 while((unit->ByteIn(unit->card, RH_REG_EEPROM) & RH_REG_EEPROMF_LOAD)
487 != 0);
489 /* Get default MAC address */
491 p = unit->default_address;
492 for(i = 0; i < ETH_ADDRESSSIZE; i++)
493 *p++ = unit->ByteIn(unit->card, RH_REG_ADDRESS + i);
495 /* Send reset command */
497 unit->ByteOut(unit->card, RH_REG_CONTROL + 1, RH_REG_CONTROL1F_RESET);
498 BusyMicroDelay(110, base);
499 while((unit->ByteIn(unit->card, RH_REG_CONTROL + 1)
500 & RH_REG_CONTROL1F_RESET) != 0);
502 /* Disable interrupts */
504 unit->LEWordOut(unit->card, RH_REG_INTSTATUS, INT_MASK);
505 unit->LEWordOut(unit->card, RH_REG_INTMASK, 0);
506 if(TRUE)
507 unit->LEWordOut(unit->card, RH_REG_MIIINTMASK, 0);
509 /* Configure MII */
511 unit->ByteOut(unit->card, RH_REG_MIICTRL,
512 unit->ByteIn(unit->card, RH_REG_MIICTRL) | RH_REG_MIICTRLF_AUTOPOLL);
514 if(TRUE)
515 unit->mii_phy_no = unit->ByteIn(unit->card, RH_REG_MIICONFIG)
516 & RH_REG_MIICONFIGF_PHYADDR;
517 else
518 unit->mii_phy_no = 1;
520 /* Return */
522 return success;
527 /****i* rhine.device/DeinitialiseAdapter ***********************************
529 * NAME
530 * DeinitialiseAdapter
532 * SYNOPSIS
533 * DeinitialiseAdapter(unit)
535 * VOID DeinitialiseAdapter(struct DevUnit *);
537 * FUNCTION
539 * INPUTS
540 * unit
542 * RESULT
543 * None.
545 ****************************************************************************
549 VOID DeinitialiseAdapter(struct DevUnit *unit, struct DevBase *base)
551 return;
556 /****i* rhine.device/ConfigureAdapter **************************************
558 * NAME
559 * ConfigureAdapter -- Set up card for transmission/reception.
561 * SYNOPSIS
562 * ConfigureAdapter(unit)
564 * VOID ConfigureAdapter(struct DevUnit *);
566 ****************************************************************************
570 VOID ConfigureAdapter(struct DevUnit *unit, struct DevBase *base)
572 const UBYTE *p;
573 UWORD i;
575 /* Set MAC address */
577 p = unit->address;
578 for(i = 0; i < ETH_ADDRESSSIZE; i++)
579 unit->ByteOut(unit->card, RH_REG_ADDRESS + i, *p++);
581 /* Set DMA rings */
583 unit->LELongOut(unit->card, RH_REG_TXLIST, unit->tx_descs_p[0]);
584 unit->LELongOut(unit->card, RH_REG_RXLIST, unit->rx_descs_p[0]);
586 /* Choose packet types to receive */
588 unit->LEWordOut(unit->card, RH_REG_PCIBUSCONFIG, 6);
589 unit->ByteOut(unit->card, RH_REG_RXCONFIG,
590 RH_REG_RXCONFIGF_BCAST | RH_REG_RXCONFIGF_MCAST);
592 /* Return */
594 return;
599 /****i* rhine.device/GoOnline **********************************************
601 * NAME
602 * GoOnline -- Enable transmission/reception.
604 * SYNOPSIS
605 * GoOnline(unit)
607 * VOID GoOnline(struct DevUnit *);
609 ****************************************************************************
613 VOID GoOnline(struct DevUnit *unit, struct DevBase *base)
615 /* Enable interrupts */
617 unit->flags |= UNITF_ONLINE;
618 unit->LEWordOut(unit->card, RH_REG_INTMASK, INT_MASK);
620 /* Enable frame transmission and reception */
622 unit->LEWordOut(unit->card, RH_REG_CONTROL, RH_REG_CONTROLF_TXENABLE
623 | RH_REG_CONTROLF_RXENABLE | RH_REG_CONTROLF_START);
625 /* Record start time and report Online event */
627 GetSysTime(&unit->stats.LastStart);
628 ReportEvents(unit, S2EVENT_ONLINE, base);
630 return;
635 /****i* rhine.device/GoOffline *********************************************
637 * NAME
638 * GoOffline -- Disable transmission/reception.
640 * SYNOPSIS
641 * GoOffline(unit)
643 * VOID GoOffline(struct DevUnit *);
645 * FUNCTION
647 * INPUTS
648 * unit
650 * RESULT
651 * None.
653 ****************************************************************************
657 VOID GoOffline(struct DevUnit *unit, struct DevBase *base)
659 unit->flags &= ~UNITF_ONLINE;
661 /* Flush pending read and write requests */
663 FlushUnit(unit, MGMT_QUEUE, S2ERR_OUTOFSERVICE, base);
665 /* Report Offline event and return */
667 ReportEvents(unit, S2EVENT_OFFLINE, base);
668 return;
673 /****i* rhine.device/AddMulticastRange *************************************
675 * NAME
676 * AddMulticastRange
678 * SYNOPSIS
679 * success = AddMulticastRange(unit, lower_bound, upper_bound)
681 * BOOL AddMulticastRange(struct DevUnit *, UBYTE *, UBYTE *);
683 ****************************************************************************
687 BOOL AddMulticastRange(struct DevUnit *unit, const UBYTE *lower_bound,
688 const UBYTE *upper_bound, struct DevBase *base)
690 struct AddressRange *range;
691 ULONG lower_bound_left, upper_bound_left;
692 UWORD lower_bound_right, upper_bound_right;
694 lower_bound_left = BELong(*((ULONG *)lower_bound));
695 lower_bound_right = BEWord(*((UWORD *)(lower_bound + 4)));
696 upper_bound_left = BELong(*((ULONG *)upper_bound));
697 upper_bound_right = BEWord(*((UWORD *)(upper_bound + 4)));
699 range = FindMulticastRange(unit, lower_bound_left, lower_bound_right,
700 upper_bound_left, upper_bound_right, base);
702 if(range != NULL)
703 range->add_count++;
704 else
706 range = AllocMem(sizeof(struct AddressRange), MEMF_PUBLIC);
707 if(range != NULL)
709 range->lower_bound_left = lower_bound_left;
710 range->lower_bound_right = lower_bound_right;
711 range->upper_bound_left = upper_bound_left;
712 range->upper_bound_right = upper_bound_right;
713 range->add_count = 1;
715 Disable();
716 AddTail((APTR)&unit->multicast_ranges, (APTR)range);
717 unit->range_count++;
718 SetMulticast(unit, base);
719 Enable();
723 return range != NULL;
728 /****i* rhine.device/RemMulticastRange *************************************
730 * NAME
731 * RemMulticastRange
733 * SYNOPSIS
734 * found = RemMulticastRange(unit, lower_bound, upper_bound)
736 * BOOL RemMulticastRange(struct DevUnit *, UBYTE *, UBYTE *);
738 ****************************************************************************
742 BOOL RemMulticastRange(struct DevUnit *unit, const UBYTE *lower_bound,
743 const UBYTE *upper_bound, struct DevBase *base)
745 struct AddressRange *range;
746 ULONG lower_bound_left, upper_bound_left;
747 UWORD lower_bound_right, upper_bound_right;
749 lower_bound_left = BELong(*((ULONG *)lower_bound));
750 lower_bound_right = BEWord(*((UWORD *)(lower_bound + 4)));
751 upper_bound_left = BELong(*((ULONG *)upper_bound));
752 upper_bound_right = BEWord(*((UWORD *)(upper_bound + 4)));
754 range = FindMulticastRange(unit, lower_bound_left, lower_bound_right,
755 upper_bound_left, upper_bound_right, base);
757 if(range != NULL)
759 if(--range->add_count == 0)
761 Disable();
762 Remove((APTR)range);
763 unit->range_count--;
764 SetMulticast(unit, base);
765 Enable();
766 FreeMem(range, sizeof(struct AddressRange));
770 return range != NULL;
775 /****i* rhine.device/FindMulticastRange ************************************
777 * NAME
778 * FindMulticastRange
780 * SYNOPSIS
781 * range = FindMulticastRange(unit, lower_bound_left,
782 * lower_bound_right, upper_bound_left, upper_bound_right)
784 * struct AddressRange *FindMulticastRange(struct DevUnit *, ULONG,
785 * UWORD, ULONG, UWORD);
787 ****************************************************************************
791 static struct AddressRange *FindMulticastRange(struct DevUnit *unit,
792 ULONG lower_bound_left, UWORD lower_bound_right, ULONG upper_bound_left,
793 UWORD upper_bound_right, struct DevBase *base)
795 struct AddressRange *range, *tail;
796 BOOL found = FALSE;
798 range = (APTR)unit->multicast_ranges.mlh_Head;
799 tail = (APTR)&unit->multicast_ranges.mlh_Tail;
801 while(range != tail && !found)
803 if(lower_bound_left == range->lower_bound_left &&
804 lower_bound_right == range->lower_bound_right &&
805 upper_bound_left == range->upper_bound_left &&
806 upper_bound_right == range->upper_bound_right)
807 found = TRUE;
808 else
809 range = (APTR)range->node.mln_Succ;
812 if(!found)
813 range = NULL;
815 return range;
820 /****i* rhine.device/SetMulticast ******************************************
822 * NAME
823 * SetMulticast
825 * SYNOPSIS
826 * SetMulticast(unit)
828 * VOID SetMulticast(struct DevUnit *);
830 ****************************************************************************
834 static VOID SetMulticast(struct DevUnit *unit, struct DevBase *base)
836 if(!IsListEmpty(&unit->multicast_ranges))
838 unit->LELongOut(unit->card, RH_REG_MCASTFILTER, 0xffffffff);
839 unit->LELongOut(unit->card, RH_REG_MCASTFILTER + 4, 0xffffffff);
841 else
843 unit->LELongOut(unit->card, RH_REG_MCASTFILTER, 0);
844 unit->LELongOut(unit->card, RH_REG_MCASTFILTER + 4, 0);
847 return;
852 /****i* rhine.device/FindTypeStats *****************************************
854 * NAME
855 * FindTypeStats
857 * SYNOPSIS
858 * stats = FindTypeStats(unit, list,
859 * packet_type)
861 * struct TypeStats *FindTypeStats(struct DevUnit *, struct MinList *,
862 * ULONG);
864 ****************************************************************************
868 struct TypeStats *FindTypeStats(struct DevUnit *unit, struct MinList *list,
869 ULONG packet_type, struct DevBase *base)
871 struct TypeStats *stats, *tail;
872 BOOL found = FALSE;
874 stats = (APTR)list->mlh_Head;
875 tail = (APTR)&list->mlh_Tail;
877 while(stats != tail && !found)
879 if(stats->packet_type == packet_type)
880 found = TRUE;
881 else
882 stats = (APTR)stats->node.mln_Succ;
885 if(!found)
886 stats = NULL;
888 return stats;
893 /****i* rhine.device/FlushUnit *********************************************
895 * NAME
896 * FlushUnit
898 * SYNOPSIS
899 * FlushUnit(unit, last_queue, error)
901 * VOID FlushUnit(struct DevUnit *, UBYTE, BYTE);
903 ****************************************************************************
907 VOID FlushUnit(struct DevUnit *unit, UBYTE last_queue, BYTE error,
908 struct DevBase *base)
910 struct IORequest *request;
911 UBYTE i;
912 struct Opener *opener, *tail;
914 /* Abort queued requests */
916 for(i = 0; i <= last_queue; i++)
918 while((request = (APTR)GetMsg(unit->request_ports[i])) != NULL)
920 request->io_Error = IOERR_ABORTED;
921 ReplyMsg((APTR)request);
925 #if 1
926 opener = (APTR)unit->openers.mlh_Head;
927 tail = (APTR)&unit->openers.mlh_Tail;
929 /* Flush every opener's read queues */
931 while(opener != tail)
933 while((request = (APTR)GetMsg(&opener->read_port)) != NULL)
935 request->io_Error = error;
936 ReplyMsg((APTR)request);
938 while((request = (APTR)GetMsg(&opener->mgmt_port)) != NULL)
940 request->io_Error = error;
941 ReplyMsg((APTR)request);
943 opener = (APTR)opener->node.mln_Succ;
946 #else
947 opener = request->ios2_BufferManagement;
948 while((request = (APTR)GetMsg(&opener->read_port)) != NULL)
950 request->io_Error = IOERR_ABORTED;
951 ReplyMsg((APTR)request);
953 while((request = (APTR)GetMsg(&opener->mgmt_port)) != NULL)
955 request->io_Error = IOERR_ABORTED;
956 ReplyMsg((APTR)request);
958 #endif
960 /* Return */
962 return;
967 /****i* rhine.device/StatusInt *********************************************
969 * NAME
970 * StatusInt
972 * SYNOPSIS
973 * finished = StatusInt(unit)
975 * BOOL StatusInt(struct DevUnit *);
977 * INPUTS
978 * unit - A unit of this device.
980 * RESULT
981 * finished - Always FALSE.
983 ****************************************************************************
987 static BOOL StatusInt(REG(a1, struct DevUnit *unit), REG(a5, APTR int_code))
989 struct DevBase *base;
990 UWORD ints;
992 base = unit->device;
993 ints = unit->LEWordIn(unit->card, RH_REG_INTSTATUS);
995 if(ints != 0)
997 /* Acknowledge interrupts */
999 unit->LEWordOut(unit->card, RH_REG_INTSTATUS, ints);
1001 /* FIXME: Need IO-sync here for PPC etc.? */
1003 /* Handle interrupts */
1005 if((ints & (RH_INTF_TXERR | RH_INTF_TXOK)) != 0)
1006 Cause(&unit->tx_end_int);
1007 if((ints & (RH_INTF_RXERR | RH_INTF_RXOK)) != 0)
1008 Cause(&unit->rx_int);
1011 return FALSE;
1016 /****i* rhine.device/RXInt *************************************************
1018 * NAME
1019 * RXInt -- Soft interrupt for packet reception.
1021 * SYNOPSIS
1022 * RXInt(unit)
1024 * VOID RXInt(struct DevUnit *);
1026 * FUNCTION
1028 * INPUTS
1029 * unit - A unit of this device.
1031 * RESULT
1032 * None.
1034 ****************************************************************************
1038 static VOID RXInt(REG(a1, struct DevUnit *unit), REG(a5, APTR int_code))
1040 UWORD slot, packet_size;
1041 struct DevBase *base;
1042 ULONG rx_status, *desc, dma_size;
1043 UBYTE *buffer;
1045 base = unit->device;
1046 slot = unit->rx_slot;
1047 desc = unit->rx_descs[slot];
1049 dma_size = TX_DESC_SIZE;
1050 CachePostDMA(unit->rx_descs, &dma_size, 0);
1051 while(((rx_status = LELong(desc[RH_DESC_RXSTATUS]))
1052 & RH_DESC_RXSTATUSF_INUSE) == 0)
1054 if((rx_status & RH_DESC_RXSTATUSF_OK) != 0)
1056 packet_size = ((rx_status & RH_DESC_RXSTATUSF_LENGTH)
1057 >> RH_DESC_RXSTATUSB_LENGTH) - ETH_CRCSIZE;
1058 buffer = unit->rx_buffers[slot];
1060 if(AddressFilter(unit, buffer + ETH_PACKET_DEST, base))
1062 unit->stats.PacketsReceived++;
1063 DistributeRXPacket(unit, buffer, packet_size, base);
1066 else
1068 unit->stats.BadData++;
1069 ReportEvents(unit, S2EVENT_ERROR | S2EVENT_HARDWARE | S2EVENT_RX,
1070 base);
1073 /* Mark descriptor as free for next time */
1075 desc[RH_DESC_RXSTATUS] = MakeLELong(RH_DESC_RXSTATUSF_INUSE);
1077 /* Get next descriptor */
1079 slot = (slot + 1) % RX_SLOT_COUNT;
1080 desc = unit->rx_descs[slot];
1083 /* Return */
1085 unit->rx_slot = slot;
1086 return;
1091 /****i* rhine.device/DistributeRXPacket ************************************
1093 * NAME
1094 * DistributeRXPacket -- Send a packet to all appropriate destinations.
1096 * SYNOPSIS
1097 * DistributeRXPacket(unit, frame)
1099 * VOID DistributeRXPacket(struct DevUnit *, UBYTE *);
1101 ****************************************************************************
1105 static VOID DistributeRXPacket(struct DevUnit *unit, const UBYTE *packet,
1106 UWORD packet_size, struct DevBase *base)
1108 BOOL is_orphan = TRUE, accepted;
1109 ULONG packet_type;
1110 struct IOSana2Req *request, *request_tail;
1111 struct Opener *opener, *opener_tail;
1112 struct TypeStats *tracker;
1114 /* Offer packet to every opener */
1116 opener = (APTR)unit->openers.mlh_Head;
1117 opener_tail = (APTR)&unit->openers.mlh_Tail;
1118 packet_type = BEWord(*((UWORD *)(packet + ETH_PACKET_TYPE)));
1120 while(opener != opener_tail)
1122 request = (APTR)opener->read_port.mp_MsgList.lh_Head;
1123 request_tail = (APTR)&opener->read_port.mp_MsgList.lh_Tail;
1124 accepted = FALSE;
1126 /* Offer packet to each request until it's accepted */
1128 while(request != request_tail && !accepted)
1130 if(request->ios2_PacketType == packet_type)
1132 CopyPacket(unit, request, packet_size, packet_type,
1133 packet, base);
1134 accepted = TRUE;
1136 request =
1137 (APTR)request->ios2_Req.io_Message.mn_Node.ln_Succ;
1140 if(accepted)
1141 is_orphan = FALSE;
1142 opener = (APTR)opener->node.mln_Succ;
1145 /* If packet was unwanted, give it to S2_READORPHAN request */
1147 if(is_orphan)
1149 unit->stats.UnknownTypesReceived++;
1150 if(!IsMsgPortEmpty(unit->request_ports[ADOPT_QUEUE]))
1152 CopyPacket(unit,
1153 (APTR)unit->request_ports[ADOPT_QUEUE]->mp_MsgList.lh_Head,
1154 packet_size, packet_type, packet, base);
1158 /* Update remaining statistics */
1160 if(packet_type <= ETH_MTU)
1161 packet_type = ETH_MTU;
1162 tracker =
1163 FindTypeStats(unit, &unit->type_trackers, packet_type, base);
1164 if(tracker != NULL)
1166 tracker->stats.PacketsReceived++;
1167 tracker->stats.BytesReceived += packet_size;
1170 return;
1175 /****i* rhine.device/CopyPacket ********************************************
1177 * NAME
1178 * CopyPacket -- Copy packet to client's buffer.
1180 * SYNOPSIS
1181 * CopyPacket(unit, request, packet_size, packet_type,
1182 * buffer)
1184 * VOID CopyPacket(struct DevUnit *, struct IOSana2Req *, UWORD, UWORD,
1185 * UBYTE *);
1187 ****************************************************************************
1191 static VOID CopyPacket(struct DevUnit *unit, struct IOSana2Req *request,
1192 UWORD packet_size, UWORD packet_type, const UBYTE *buffer,
1193 struct DevBase *base)
1195 struct Opener *opener;
1196 BOOL filtered = FALSE;
1198 /* Set multicast and broadcast flags */
1200 request->ios2_Req.io_Flags &= ~(SANA2IOF_BCAST | SANA2IOF_MCAST);
1201 if((*((ULONG *)(buffer + ETH_PACKET_DEST)) == 0xffffffff) &&
1202 (*((UWORD *)(buffer + ETH_PACKET_DEST + 4)) == 0xffff))
1203 request->ios2_Req.io_Flags |= SANA2IOF_BCAST;
1204 else if((buffer[ETH_PACKET_DEST] & 0x1) != 0)
1205 request->ios2_Req.io_Flags |= SANA2IOF_MCAST;
1207 /* Set source and destination addresses and packet type */
1209 CopyMem(buffer + ETH_PACKET_SOURCE, request->ios2_SrcAddr,
1210 ETH_ADDRESSSIZE);
1211 CopyMem(buffer + ETH_PACKET_DEST, request->ios2_DstAddr,
1212 ETH_ADDRESSSIZE);
1213 request->ios2_PacketType = packet_type;
1215 /* Adjust for cooked packet request */
1217 if((request->ios2_Req.io_Flags & SANA2IOF_RAW) == 0)
1219 packet_size -= ETH_PACKET_DATA;
1220 buffer += ETH_PACKET_DATA;
1222 #ifdef USE_HACKS
1223 else
1224 packet_size += 4; /* Needed for Shapeshifter & Fusion */
1225 #endif
1226 request->ios2_DataLength = packet_size;
1228 /* Filter packet */
1230 opener = request->ios2_BufferManagement;
1231 if(request->ios2_Req.io_Command == CMD_READ &&
1232 opener->filter_hook != NULL)
1233 if(!CallHookPkt(opener->filter_hook, request, (APTR)buffer))
1234 filtered = TRUE;
1236 if(!filtered)
1238 /* Copy packet into opener's buffer and reply packet */
1240 if(!opener->rx_function(request->ios2_Data, (APTR)buffer,
1241 packet_size))
1243 request->ios2_Req.io_Error = S2ERR_NO_RESOURCES;
1244 request->ios2_WireError = S2WERR_BUFF_ERROR;
1245 ReportEvents(unit,
1246 S2EVENT_ERROR | S2EVENT_SOFTWARE | S2EVENT_BUFF | S2EVENT_RX,
1247 base);
1249 Remove((APTR)request);
1250 ReplyMsg((APTR)request);
1253 return;
1258 /****i* rhine.device/AddressFilter *****************************************
1260 * NAME
1261 * AddressFilter -- Determine if an RX packet should be accepted.
1263 * SYNOPSIS
1264 * accept = AddressFilter(unit, address)
1266 * BOOL AddressFilter(struct DevUnit *, UBYTE *);
1268 ****************************************************************************
1272 static BOOL AddressFilter(struct DevUnit *unit, UBYTE *address,
1273 struct DevBase *base)
1275 struct AddressRange *range, *tail;
1276 BOOL accept = TRUE;
1277 ULONG address_left;
1278 UWORD address_right;
1280 /* Check whether address is unicast/broadcast or multicast */
1282 address_left = BELong(*((ULONG *)address));
1283 address_right = BEWord(*((UWORD *)(address + 4)));
1285 if(((address_left & 0x01000000) != 0) &&
1286 !((address_left == 0xffffffff) && (address_right == 0xffff)))
1288 /* Check if this multicast address is wanted */
1290 range = (APTR)unit->multicast_ranges.mlh_Head;
1291 tail = (APTR)&unit->multicast_ranges.mlh_Tail;
1292 accept = FALSE;
1294 while((range != tail) && !accept)
1296 if((address_left > range->lower_bound_left ||
1297 address_left == range->lower_bound_left &&
1298 address_right >= range->lower_bound_right) &&
1299 (address_left < range->upper_bound_left ||
1300 address_left == range->upper_bound_left &&
1301 address_right <= range->upper_bound_right))
1302 accept = TRUE;
1303 range = (APTR)range->node.mln_Succ;
1306 if(!accept)
1307 unit->special_stats[S2SS_ETHERNET_BADMULTICAST & 0xffff]++;
1310 return accept;
1315 /****i* rhine.device/TXInt *************************************************
1317 * NAME
1318 * TXInt -- Soft interrupt for packet transmission.
1320 * SYNOPSIS
1321 * TXInt(unit)
1323 * VOID TXInt(struct DevUnit *);
1325 * FUNCTION
1327 * INPUTS
1328 * unit - A unit of this device.
1330 * RESULT
1331 * None.
1333 ****************************************************************************
1337 static VOID TXInt(REG(a1, struct DevUnit *unit), REG(a5, APTR int_code))
1339 struct DevBase *base;
1340 UWORD packet_size, data_size, slot, new_slot, *p, *q, i;
1341 struct IOSana2Req *request;
1342 BOOL proceed = TRUE;
1343 struct Opener *opener;
1344 ULONG wire_error, *desc, dma_size, desc_p, buffer_p, txcontrol_value;
1345 UBYTE *(*dma_tx_function)(REG(a0, APTR));
1346 BYTE error;
1347 UBYTE *buffer;
1348 struct MsgPort *port;
1350 base = unit->device;
1351 port = unit->request_ports[WRITE_QUEUE];
1353 while(proceed && !IsMsgPortEmpty(port))
1355 slot = unit->tx_in_slot;
1356 new_slot = (slot + 1) % TX_SLOT_COUNT;
1358 if(new_slot != unit->tx_out_slot
1359 && (unit->flags & UNITF_TXBUFFERINUSE) == 0)
1361 error = 0;
1363 /* Get request and DMA frame descriptor */
1365 request = (APTR)port->mp_MsgList.lh_Head;
1367 Remove((APTR)request);
1368 unit->tx_requests[slot] = request;
1369 desc = unit->tx_descs[slot];
1370 desc_p = unit->tx_descs_p[slot];
1372 data_size = packet_size = request->ios2_DataLength;
1373 if((request->ios2_Req.io_Flags & SANA2IOF_RAW) == 0)
1374 packet_size += ETH_HEADERSIZE;
1375 if(packet_size < ETH_MINSIZE)
1376 packet_size = ETH_MINSIZE;
1378 /* Decide if one or two descriptors are needed, and generate
1379 Ethernet header if necessary */
1381 if((request->ios2_Req.io_Flags & SANA2IOF_RAW) == 0)
1383 /* Use first descriptor for Ethernet header */
1385 buffer = (UBYTE *)desc + 2 * RH_DESCSIZE;
1386 buffer_p = desc_p + 2 * RH_DESCSIZE;
1388 desc[RH_DESC_TXCONTROL] =
1389 MakeLELong(RH_DESC_TXCONTROLF_FIRSTFRAG
1390 | RH_DESC_TXCONTROLF_CHAIN | ETH_HEADERSIZE);
1391 desc[RH_DESC_DATA] = MakeLELong(buffer_p);
1392 desc[RH_DESC_NEXT] = MakeLELong(desc_p + RH_DESCSIZE);
1394 /* Write Ethernet header */
1396 p = (UWORD *)buffer;
1397 for(i = 0, q = (UWORD *)request->ios2_DstAddr;
1398 i < ETH_ADDRESSSIZE / 2; i++)
1399 *p++ = *q++;
1400 for(i = 0, q = (UWORD *)unit->address;
1401 i < ETH_ADDRESSSIZE / 2; i++)
1402 *p++ = *q++;
1403 *p++ = MakeBEWord(request->ios2_PacketType);
1405 /* Use spare second descriptor for frame data */
1407 desc += RH_DESCSIZE / 4;
1408 desc_p += RH_DESCSIZE;
1410 txcontrol_value = RH_DESC_TXCONTROLF_INT
1411 | RH_DESC_TXCONTROLF_LASTFRAG
1412 | RH_DESC_TXCONTROLF_CHAIN
1413 | packet_size - ETH_HEADERSIZE;
1415 else
1417 txcontrol_value = RH_DESC_TXCONTROLF_INT
1418 | RH_DESC_TXCONTROLF_FIRSTFRAG | RH_DESC_TXCONTROLF_LASTFRAG
1419 | RH_DESC_TXCONTROLF_CHAIN
1420 | packet_size;
1423 /* Get packet data */
1425 opener = (APTR)request->ios2_BufferManagement;
1426 dma_tx_function = opener->dma_tx_function;
1427 if(dma_tx_function != NULL)
1428 buffer = dma_tx_function(request->ios2_Data);
1429 else
1430 buffer = NULL;
1432 if(buffer == NULL)
1434 buffer = unit->tx_buffer;
1435 if(opener->tx_function(buffer, request->ios2_Data,
1436 data_size))
1438 unit->flags |= UNITF_TXBUFFERINUSE;
1440 else
1442 error = S2ERR_NO_RESOURCES;
1443 wire_error = S2WERR_BUFF_ERROR;
1444 ReportEvents(unit,
1445 S2EVENT_ERROR | S2EVENT_SOFTWARE | S2EVENT_BUFF
1446 | S2EVENT_TX, base);
1449 unit->tx_buffers[slot] = buffer;
1451 /* Fill in descriptor for frame data */
1453 if(error == 0)
1455 dma_size = data_size;
1456 buffer_p = (ULONG)(UPINT)CachePreDMA(buffer, &dma_size,
1457 DMA_ReadFromRAM);
1458 desc[RH_DESC_TXCONTROL] = MakeLELong(txcontrol_value);
1459 desc[RH_DESC_DATA] = MakeLELong(buffer_p);
1460 desc[RH_DESC_NEXT] = MakeLELong(unit->tx_descs_p[new_slot]);
1462 if((request->ios2_Req.io_Flags & SANA2IOF_RAW) == 0)
1463 desc -= RH_DESCSIZE / 4;
1465 desc[RH_DESC_TXSTATUS] = MakeLELong(RH_DESC_TXSTATUSF_INUSE);
1468 if(error == 0)
1470 /* Restart transmission if it had stopped */
1472 dma_size = TX_DESC_SIZE * TX_SLOT_COUNT;
1473 CachePreDMA(unit->tx_descs, &dma_size, 0);
1474 unit->ByteOut(unit->card, RH_REG_CONTROL,
1475 unit->ByteIn(unit->card, RH_REG_CONTROL)
1476 | RH_REG_CONTROLF_TXPOLL);
1478 /* FIXME: Need IO-sync here for PPC etc.? */
1480 unit->tx_in_slot = new_slot;
1482 else
1484 /* Return failed request */
1486 request->ios2_Req.io_Error = error;
1487 request->ios2_WireError = wire_error;
1488 ReplyMsg((APTR)request);
1491 else
1492 proceed = FALSE;
1495 if(proceed)
1496 unit->request_ports[WRITE_QUEUE]->mp_Flags = PA_SOFTINT;
1497 else
1498 unit->request_ports[WRITE_QUEUE]->mp_Flags = PA_IGNORE;
1500 return;
1505 /****i* rhine.device/TXEndInt **********************************************
1507 * NAME
1508 * TXEndInt -- Clean up after a frame has been sent.
1510 * SYNOPSIS
1511 * TXEndInt(unit, int_code)
1513 * VOID TXEndInt(struct DevUnit *, APTR);
1515 * INPUTS
1516 * unit - A unit of this device.
1517 * int_code - Unused.
1519 * RESULT
1520 * None.
1522 ****************************************************************************
1524 * It appears to be safe to assume that there will always be at least one
1525 * completed packet whenever this interrupt is called.
1529 static VOID TXEndInt(REG(a1, struct DevUnit *unit), REG(a5, APTR int_code))
1531 UWORD data_size, i = 0;
1532 UBYTE *buffer;
1533 struct DevBase *base;
1534 ULONG *desc, dma_size;
1535 BOOL proceed = TRUE;
1537 /* Retire sent packets */
1539 base = unit->device;
1540 dma_size = TX_DESC_SIZE * TX_SLOT_COUNT;
1541 CachePostDMA(unit->tx_descs, &dma_size, 0);
1543 i = unit->tx_out_slot;
1544 while(proceed)
1546 /* Skip to "spare" descriptor if valid */
1548 desc = unit->tx_descs[i];
1549 if((desc[RH_DESC_TXCONTROL] & RH_DESC_TXCONTROLF_LASTFRAG) == 0)
1550 desc += 4;
1552 /* Check that descriptor is not in use */
1554 if((desc[RH_DESC_TXSTATUS] & MakeLELong(RH_DESC_TXSTATUSF_INUSE))
1555 == 0 && i != unit->tx_in_slot)
1557 buffer = unit->tx_buffers[i];
1558 dma_size = data_size;
1559 CachePostDMA(buffer, &dma_size, DMA_ReadFromRAM);
1561 /* Check if unit's buffer is now free */
1563 if(buffer == unit->tx_buffer)
1564 unit->flags &= ~UNITF_TXBUFFERINUSE;
1566 RetireTXSlot(unit, i, base);
1568 i = (i + 1) % TX_SLOT_COUNT;
1570 else
1571 proceed = FALSE;
1574 unit->tx_out_slot = i;
1576 dma_size = TX_DESC_SIZE * TX_SLOT_COUNT;
1577 CachePreDMA(unit->tx_descs, &dma_size, 0);
1579 /* Restart downloads if they had stopped */
1581 if(unit->request_ports[WRITE_QUEUE]->mp_Flags == PA_IGNORE)
1582 Cause(&unit->tx_int);
1584 return;
1589 /****i* rhine.device/RetireTXSlot ******************************************
1591 * NAME
1592 * RetireTXSlot -- Reply finished TX request.
1594 * SYNOPSIS
1595 * RetireTXSlot(unit, slot)
1597 * VOID RetireTXSlot(struct DevUnit *, UWORD);
1599 ****************************************************************************
1603 static VOID RetireTXSlot(struct DevUnit *unit, UWORD slot,
1604 struct DevBase *base)
1606 UWORD frame_size;
1607 struct IOSana2Req *request;
1608 struct TypeStats *tracker;
1610 /* Update statistics */
1612 slot = unit->tx_out_slot;
1613 request = unit->tx_requests[slot];
1614 frame_size = request->ios2_DataLength;
1615 if((request->ios2_Req.io_Flags & SANA2IOF_RAW) == 0)
1616 frame_size += ETH_HEADERSIZE;
1618 unit->stats.PacketsSent++;
1620 tracker = FindTypeStats(unit, &unit->type_trackers,
1621 request->ios2_PacketType, base);
1622 if(tracker != NULL)
1624 tracker->stats.PacketsSent++;
1625 tracker->stats.BytesSent += frame_size;
1628 /* Reply request */
1630 request->ios2_Req.io_Error = 0;
1631 ReplyMsg((APTR)request);
1633 return;
1638 /****i* rhine.device/ResetHandler ******************************************
1640 * NAME
1641 * ResetHandler -- Disable hardware before a reboot.
1643 * SYNOPSIS
1644 * ResetHandler(unit, int_code)
1646 * VOID ResetHandler(struct DevUnit *, APTR);
1648 ****************************************************************************
1652 static VOID ResetHandler(REG(a1, struct DevUnit *unit),
1653 REG(a6, APTR int_code))
1655 if((unit->flags & UNITF_HAVEADAPTER) != 0)
1657 /* Disable frame transmission and reception */
1659 unit->LEWordOut(unit->card, RH_REG_CONTROL, RH_REG_CONTROLF_STOP);
1661 /* Stop interrupts */
1663 unit->LEWordOut(unit->card, RH_REG_INTMASK, 0);
1667 return;
1672 /****i* rhine.device/ReportEvents ******************************************
1674 * NAME
1675 * ReportEvents
1677 * SYNOPSIS
1678 * ReportEvents(unit, events)
1680 * VOID ReportEvents(struct DevUnit *, ULONG);
1682 * FUNCTION
1684 * INPUTS
1685 * unit - A unit of this device.
1686 * events - A mask of events to report.
1688 * RESULT
1689 * None.
1691 ****************************************************************************
1695 static VOID ReportEvents(struct DevUnit *unit, ULONG events,
1696 struct DevBase *base)
1698 struct IOSana2Req *request, *tail, *next_request;
1699 struct List *list;
1701 list = &unit->request_ports[EVENT_QUEUE]->mp_MsgList;
1702 next_request = (APTR)list->lh_Head;
1703 tail = (APTR)&list->lh_Tail;
1705 Disable();
1706 while(next_request != tail)
1708 request = next_request;
1709 next_request = (APTR)request->ios2_Req.io_Message.mn_Node.ln_Succ;
1711 if((request->ios2_WireError & events) != 0)
1713 request->ios2_WireError = events;
1714 Remove((APTR)request);
1715 ReplyMsg((APTR)request);
1718 Enable();
1720 return;
1725 /****i* rhine.device/UnitTask **********************************************
1727 * NAME
1728 * UnitTask
1730 * SYNOPSIS
1731 * UnitTask()
1733 * VOID UnitTask();
1735 * FUNCTION
1736 * Completes deferred requests, and handles card insertion and removal
1737 * in conjunction with the relevant interrupts.
1739 ****************************************************************************
1743 static VOID UnitTask(struct ExecBase *sys_base)
1745 struct Task *task;
1746 struct IORequest *request;
1747 struct DevUnit *unit;
1748 struct DevBase *base;
1749 struct MsgPort *general_port;
1750 ULONG signals = 0, wait_signals, card_removed_signal,
1751 card_inserted_signal, general_port_signal;
1753 /* Get parameters */
1755 task = FindTask(NULL);
1756 unit = task->tc_UserData;
1757 base = unit->device;
1759 /* Activate general request port */
1761 general_port = unit->request_ports[GENERAL_QUEUE];
1762 general_port->mp_SigTask = task;
1763 general_port->mp_SigBit = AllocSignal(-1);
1764 general_port_signal = 1 << general_port->mp_SigBit;
1765 general_port->mp_Flags = PA_SIGNAL;
1767 /* Allocate signals for notification of card removal and insertion */
1769 card_removed_signal = unit->card_removed_signal = 1 << AllocSignal(-1);
1770 card_inserted_signal = unit->card_inserted_signal = 1 << AllocSignal(-1);
1771 wait_signals = (1 << general_port->mp_SigBit) | card_removed_signal
1772 | card_inserted_signal | SIGBREAKF_CTRL_C;
1774 /* Tell ourselves to check port for old messages */
1776 Signal(task, general_port_signal);
1778 /* Infinite loop to service requests and signals */
1780 while(TRUE)
1782 signals = Wait(wait_signals);
1784 if((signals & card_inserted_signal) != 0)
1786 if(unit->insertion_function(unit->card, base))
1788 unit->flags |= UNITF_HAVEADAPTER;
1789 if((unit->flags & UNITF_CONFIGURED) != 0)
1790 ConfigureAdapter(unit, base);
1791 if((unit->flags & UNITF_WASONLINE) != 0)
1793 GoOnline(unit, base);
1794 unit->flags &= ~UNITF_WASONLINE;
1799 if((signals & card_removed_signal) != 0)
1801 unit->removal_function(unit->card, base);
1802 if((unit->flags & UNITF_WASONLINE) != 0)
1803 GoOffline(unit, base);
1806 if((signals & general_port_signal) != 0)
1808 while((request = (APTR)GetMsg(general_port)) != NULL)
1810 /* Service the request as soon as the unit is free */
1812 ObtainSemaphore(&unit->access_lock);
1813 ServiceRequest((APTR)request, base);
1821 /****i* rhine.device/ReadMII ***********************************************
1823 * NAME
1824 * ReadMII -- Read a register in an MII PHY.
1826 * SYNOPSIS
1827 * value = ReadMII(unit, phy_no, reg_no)
1829 * UWORD ReadMII(struct DevUnit *, UWORD, UWORD);
1831 * INPUTS
1832 * unit - A unit of this device.
1833 * phy_no - Index of PHY to use.
1834 * reg_no - MII register to read.
1836 * RESULT
1837 * value - Value read from MII register.
1839 ****************************************************************************
1843 UWORD ReadMII(struct DevUnit *unit, UWORD phy_no, UWORD reg_no,
1844 struct DevBase *base)
1846 while((unit->ByteIn(unit->card, RH_REG_MIICTRL)
1847 & (RH_REG_MIICTRLF_READ | RH_REG_MIICTRLF_WRITE)) != 0);
1849 unit->ByteOut(unit->card, RH_REG_MIICTRL, 0);
1850 unit->ByteOut(unit->card, RH_REG_MIICONFIG, phy_no);
1851 unit->ByteOut(unit->card, RH_REG_MIIREGNO, reg_no);
1852 unit->ByteOut(unit->card, RH_REG_MIICTRL, RH_REG_MIICTRLF_READ);
1853 while((unit->ByteIn(unit->card, RH_REG_MIICTRL)
1854 & (RH_REG_MIICTRLF_READ | RH_REG_MIICTRLF_WRITE)) != 0);
1856 return unit->LEWordIn(unit->card, RH_REG_MIIDATA);