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,
21 #include <exec/types.h>
22 #include <exec/resident.h>
24 #include <exec/ports.h>
25 #include <exec/errors.h>
29 #include <devices/sana2.h>
30 #include <devices/sana2specialstats.h>
31 #include <devices/newstyle.h>
32 #include <devices/timer.h>
34 #include <utility/utility.h>
35 #include <utility/tagitem.h>
36 #include <utility/hooks.h>
38 #include <proto/exec.h>
39 #include <proto/dos.h>
40 #include <proto/battclock.h>
41 #include <proto/oop.h>
42 #include <proto/timer.h>
43 #include <proto/utility.h>
49 #include "e1000_api.h"
50 #include "e1000_defines.h"
52 #include LC_LIBDEFS_FILE
55 * Report incoming events to all hyphotetical event receivers
57 VOID
ReportEvents(struct e1000Base
*e1KBase
, struct e1000Unit
*unit
, ULONG events
)
59 struct IOSana2Req
*request
, *tail
, *next_request
;
62 list
= &unit
->e1ku_request_ports
[EVENT_QUEUE
]->mp_MsgList
;
63 next_request
= (APTR
)list
->lh_Head
;
64 tail
= (APTR
)&list
->lh_Tail
;
66 /* Go through list of event listeners. If send messages to receivers if event found */
68 while(next_request
!= tail
)
70 request
= next_request
;
71 next_request
= (APTR
)request
->ios2_Req
.io_Message
.mn_Node
.ln_Succ
;
73 if((request
->ios2_WireError
&events
) != 0)
75 request
->ios2_WireError
= events
;
76 Remove((APTR
)request
);
77 ReplyMsg((APTR
)request
);
85 struct TypeStats
*FindTypeStats(struct e1000Base
*e1KBase
, struct e1000Unit
*unit
,
86 struct MinList
*list
, ULONG packet_type
)
88 struct TypeStats
*stats
, *tail
;
91 stats
= (APTR
)list
->mlh_Head
;
92 tail
= (APTR
)&list
->mlh_Tail
;
94 while(stats
!= tail
&& !found
)
96 if(stats
->packet_type
== packet_type
)
99 stats
= (APTR
)stats
->node
.mln_Succ
;
108 void FlushUnit(LIBBASETYPEPTR LIBBASE
, struct e1000Unit
*unit
, UBYTE last_queue
, BYTE error
)
110 struct IORequest
*request
;
112 struct Opener
*opener
, *tail
;
114 D(bug("[%s] unit.FlushUnit\n", unit
->e1ku_name
));
116 /* Abort queued operations */
118 for (i
=0; i
<= last_queue
; i
++)
120 while ((request
= (APTR
)GetMsg(unit
->e1ku_request_ports
[i
])) != NULL
)
122 request
->io_Error
= IOERR_ABORTED
;
123 ReplyMsg((struct Message
*)request
);
127 opener
= (APTR
)unit
->e1ku_Openers
.mlh_Head
;
128 tail
= (APTR
)&unit
->e1ku_Openers
.mlh_Tail
;
130 /* Flush every opener's read queue */
132 while(opener
!= tail
)
134 while ((request
= (APTR
)GetMsg(&opener
->read_port
)) != NULL
)
136 request
->io_Error
= error
;
137 ReplyMsg((struct Message
*)request
);
139 opener
= (struct Opener
*)opener
->node
.mln_Succ
;
144 * Interrupt generated by Cause() to push new packets into the NIC interface
146 AROS_UFH3(void, e1000func_TX_Int
,
147 AROS_UFHA(struct e1000Unit
*, unit
, A1
),
148 AROS_UFHA(APTR
, dummy
, A5
),
149 AROS_UFHA(struct ExecBase
*,SysBase
, A6
))
153 struct e1000Base
*e1KBase
= unit
->e1ku_device
;
154 struct e1000_tx_ring
*tx_ring
= &unit
->e1ku_txRing
[0];
155 struct e1000_tx_desc
*tx_desc
= NULL
;
156 struct e1000_buffer
*buffer_info
;
157 struct eth_frame
*frame
;
158 struct IOSana2Req
*request
;
159 struct Opener
*opener
;
160 struct MsgPort
*port
;
161 struct TypeStats
*tracker
;
162 int tx_flags
= E1000_TX_FLAGS_IPV4
;
164 ULONG txd_upper
= 0, txd_lower
= E1000_TXD_CMD_IFCS
;
165 UWORD packet_size
, data_size
;
166 UBYTE
*buffer
, error
;
168 BOOL proceed
= FALSE
;
170 D(bug("[%s]: ## e1000func_TX_Int()\n", unit
->e1ku_name
));
172 if (tx_flags
& E1000_TX_FLAGS_TSO
) {
173 txd_lower
|= E1000_TXD_CMD_DEXT
| E1000_TXD_DTYP_D
|
175 txd_upper
|= E1000_TXD_POPTS_TXSM
<< 8;
177 if (tx_flags
& E1000_TX_FLAGS_IPV4
)
178 txd_upper
|= E1000_TXD_POPTS_IXSM
<< 8;
181 if (tx_flags
& E1000_TX_FLAGS_CSUM
) {
182 txd_lower
|= E1000_TXD_CMD_DEXT
| E1000_TXD_DTYP_D
;
183 txd_upper
|= E1000_TXD_POPTS_TXSM
<< 8;
186 if (tx_flags
& E1000_TX_FLAGS_VLAN
) {
187 txd_lower
|= E1000_TXD_CMD_VLE
;
188 txd_upper
|= (tx_flags
& E1000_TX_FLAGS_VLAN_MASK
);
191 i
= tx_ring
->next_to_use
;
193 proceed
= TRUE
; /* Success by default */
194 port
= unit
->e1ku_request_ports
[WRITE_QUEUE
];
196 D(bug("[%s]: ## e1000func_TX_Int: nxt to use = %d, write queue port @ %p\n", unit
->e1ku_name
, i
, port
));
198 while(proceed
&& (!IsMsgPortEmpty(port
)))
201 request
= (APTR
)port
->mp_MsgList
.lh_Head
;
202 data_size
= packet_size
= request
->ios2_DataLength
;
204 opener
= (APTR
)request
->ios2_BufferManagement
;
206 buffer_info
= &tx_ring
->buffer_info
[i
];
208 if ((buffer_info
->buffer
= AllocMem(ETH_MAXPACKETSIZE
, MEMF_PUBLIC
|MEMF_CLEAR
)) != NULL
)
210 frame
= buffer_info
->buffer
;
212 if ((buffer_info
->dma
= HIDD_PCIDriver_CPUtoPCI(unit
->e1ku_PCIDriver
, buffer_info
->buffer
)) == NULL
)
214 D(bug("[%s]: e1000func_TX_Int: Failed to Map Tx DMA buffer\n", unit
->e1ku_name
));
218 D(bug("[%s]: e1000func_TX_Int: Tx DMA buffer %d @ %p\n", unit
->e1ku_name
, i
, buffer_info
->dma
));
221 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
223 packet_size
+= ETH_PACKET_DATA
;
224 CopyMem(request
->ios2_DstAddr
, frame
->eth_packet_dest
, ETH_ADDRESSSIZE
);
225 CopyMem(unit
->e1ku_dev_addr
, frame
->eth_packet_source
, ETH_ADDRESSSIZE
);
226 frame
->eth_packet_type
= AROS_WORD2BE(request
->ios2_PacketType
);
228 buffer
= frame
->eth_packet_data
;
231 buffer
= (UBYTE
*)frame
;
233 if (!opener
->tx_function(buffer
, request
->ios2_Data
, data_size
))
235 error
= S2ERR_NO_RESOURCES
;
236 wire_error
= S2WERR_BUFF_ERROR
;
237 ReportEvents(LIBBASE
, unit
,
238 S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
242 /* Now the packet is already in TX buffer, update flags for NIC */
246 D(bug("[%s]: e1000func_TX_Int: packet %d [type = %d] queued for transmission.\n", unit
->e1ku_name
, i
, AROS_BE2WORD(frame
->eth_packet_type
)));
248 /* DEBUG? Dump frame if so */
252 D(bug("[%s]: Tx Buffer %d Packet Dump -:", unit
->e1ku_name
, i
));
253 for (j
=0; j
<64; j
++) {
255 D(bug("\n[%s]: %03x:", unit
->e1ku_name
, j
));
256 D(bug(" %02x", ((unsigned char*)frame
)[j
]));
263 /* Set the ring details for the packet .. */
264 buffer_info
->length
= packet_size
;
266 tx_desc
= E1000_TX_DESC(tx_ring
, i
);
267 tx_desc
->buffer_addr
= (UQUAD
)buffer_info
->dma
;
268 tx_desc
->lower
.data
= AROS_WORD2LE(txd_lower
| buffer_info
->length
);
269 tx_desc
->upper
.data
= AROS_WORD2LE(txd_upper
);
270 tx_desc
->lower
.data
|= AROS_WORD2LE(unit
->txd_cmd
);
271 MMIO_W32((APTR
)(((struct e1000_hw
*)unit
->e1ku_Private00
)->hw_addr
+ tx_ring
->tdt
), i
);
275 buffer_info
->next_to_watch
= i
;
277 if (++i
== tx_ring
->count
) i
= 0;
280 request
->ios2_Req
.io_Error
= error
;
281 request
->ios2_WireError
= wire_error
;
283 Remove((APTR
)request
);
285 ReplyMsg((APTR
)request
);
287 /* Update statistics */
290 tracker
= FindTypeStats(LIBBASE
, unit
, &unit
->e1ku_type_trackers
, request
->ios2_PacketType
);
294 tracker
->stats
.PacketsSent
++;
295 tracker
->stats
.BytesSent
+= packet_size
;
300 tx_ring
->next_to_use
= i
;
308 static void e1000func_WatchdogHandler(HIDDT_IRQ_Handler
*irq
, HIDDT_IRQ_HwInfo
*irq_hwi
)
310 struct e1000Unit
*unit
= (struct e1000Unit
*) irq
->h_Data
;
311 struct Device
*TimerBase
= unit
->e1ku_TimerSlowReq
->tr_node
.io_Device
;
315 //D(bug("[%s]: ## e1000func_WatchdogHandler()\n", unit->e1ku_name));
318 * If timeout timer is expected, and time elapsed - regenerate the
321 if (unit
->e1ku_toutNEED
&& (CmpTime(&time
, &unit
->e1ku_toutPOLL
) < 0))
323 unit
->e1ku_toutNEED
= FALSE
;
324 //Cause(&unit->e1ku_tx_end_int);
329 * The interrupt handler - schedules code execution to proper handlers depending
330 * on the message from e1000.
334 * Don't be surprised - this driver used to restart itself several times, in
335 * order to handle events which occur when the driver was handling previous
336 * events. It reduces the latency and amount of dropped packets. Additionally,
337 * this interrupt may put itself into deep sleep (or just quit) and restarts
338 * after certain amount of time (POLL_WAIT).
340 static void e1000func_IntHandler(HIDDT_IRQ_Handler
*irq
, HIDDT_IRQ_HwInfo
*irq_hwi
)
342 struct e1000Unit
*unit
= (struct e1000Unit
*) irq
->h_Data
;
343 struct Device
*TimerBase
= unit
->e1ku_TimerSlowReq
->tr_node
.io_Device
;
345 int rx_cleaned
, tx_cleaned
, i
, j
;
347 ULONG icr
= E1000_READ_REG((struct e1000_hw
*)unit
->e1ku_Private00
, E1000_ICR
);
349 D(bug("[%s]: e1000func_IntHandler(status %x): ", unit
->e1ku_name
, icr
));
353 D(bug("Skipping\n"));
354 return; /* Not our interrupt */
357 D(bug("Processing ..\n"));
359 if (((struct e1000_hw
*)unit
->e1ku_Private00
)->mac
.type
== e1000_82547
|| ((struct e1000_hw
*)unit
->e1ku_Private00
)->mac
.type
== e1000_82547_rev_2
)
360 E1000_WRITE_REG((struct e1000_hw
*)unit
->e1ku_Private00
, E1000_IMC
, ~0);
362 // adapter->total_tx_bytes = 0;
363 // adapter->total_rx_bytes = 0;
364 // adapter->total_tx_packets = 0;
365 // adapter->total_rx_packets = 0;
367 for (i
= 0; i
< E1000_MAX_INTR
; i
++) {
369 for (j
= 0; j
< unit
->e1ku_rxRing_QueueSize
; j
++)
370 rx_cleaned
|= e1000func_clean_rx_irq(unit
, &unit
->e1ku_rxRing
[j
]);
373 for (j
= 0 ; j
< unit
->e1ku_txRing_QueueSize
; j
++)
374 tx_cleaned
|= e1000func_clean_tx_irq(unit
, &unit
->e1ku_txRing
[j
]);
376 if (!rx_cleaned
&& !tx_cleaned
)
380 // if (adapter->itr_setting & 3)
381 // e1000_set_itr(adapter);
383 if (((struct e1000_hw
*)unit
->e1ku_Private00
)->mac
.type
== e1000_82547
|| ((struct e1000_hw
*)unit
->e1ku_Private00
)->mac
.type
== e1000_82547_rev_2
)
384 e1000func_irq_enable(unit
);
389 VOID
CopyPacket(struct e1000Base
*e1KBase
, struct e1000Unit
*unit
,
390 struct IOSana2Req
*request
, UWORD packet_size
, UWORD packet_type
,
391 struct eth_frame
*buffer
)
393 struct Opener
*opener
;
394 BOOL filtered
= FALSE
;
397 D(bug("[%s]: CopyPacket(packet @ %x, len = %d)\n", unit
->e1ku_name
, buffer
, packet_size
));
399 /* Set multicast and broadcast flags */
401 request
->ios2_Req
.io_Flags
&= ~(SANA2IOF_BCAST
| SANA2IOF_MCAST
);
402 if((*((ULONG
*)(buffer
->eth_packet_dest
)) == 0xffffffff) &&
403 (*((UWORD
*)(buffer
->eth_packet_dest
+ 4)) == 0xffff))
405 request
->ios2_Req
.io_Flags
|= SANA2IOF_BCAST
;
406 D(bug("[%s]: CopyPacket: BROADCAST Flag set\n", unit
->e1ku_name
));
408 else if((buffer
->eth_packet_dest
[0] & 0x1) != 0)
410 request
->ios2_Req
.io_Flags
|= SANA2IOF_MCAST
;
411 D(bug("[%s]: CopyPacket: MULTICAST Flag set\n", unit
->e1ku_name
));
414 /* Set source and destination addresses and packet type */
415 CopyMem(buffer
->eth_packet_source
, request
->ios2_SrcAddr
, ETH_ADDRESSSIZE
);
416 CopyMem(buffer
->eth_packet_dest
, request
->ios2_DstAddr
, ETH_ADDRESSSIZE
);
417 request
->ios2_PacketType
= packet_type
;
419 /* Adjust for cooked packet request */
421 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
423 packet_size
-= ETH_PACKET_DATA
;
424 ptr
= (UBYTE
*)&buffer
->eth_packet_data
[0];
428 ptr
= (UBYTE
*)buffer
;
431 request
->ios2_DataLength
= packet_size
;
433 D(bug("[%s]: CopyPacket: packet @ %x (%d bytes)\n", unit
->e1ku_name
, ptr
, packet_size
));
437 opener
= request
->ios2_BufferManagement
;
438 if((request
->ios2_Req
.io_Command
== CMD_READ
) &&
439 (opener
->filter_hook
!= NULL
))
440 if(!CallHookPkt(opener
->filter_hook
, request
, ptr
))
442 D(bug("[%s]: CopyPacket: packet filtered\n", unit
->e1ku_name
));
448 /* Copy packet into opener's buffer and reply packet */
449 D(bug("[%s]: CopyPacket: opener recieve packet .. ", unit
->e1ku_name
));
450 if(!opener
->rx_function(request
->ios2_Data
, ptr
, packet_size
))
452 D(bug("ERROR occured!!\n"));
453 request
->ios2_Req
.io_Error
= S2ERR_NO_RESOURCES
;
454 request
->ios2_WireError
= S2WERR_BUFF_ERROR
;
455 ReportEvents(LIBBASE
, unit
, S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
| S2EVENT_RX
);
459 D(bug("SUCCESS!!\n"));
462 Remove((APTR
)request
);
464 ReplyMsg((APTR
)request
);
465 D(bug("[%s]: CopyPacket: opener notified.\n", unit
->e1ku_name
));
469 BOOL
AddressFilter(struct e1000Base
*e1KBase
, struct e1000Unit
*unit
, UBYTE
*address
)
471 struct AddressRange
*range
, *tail
;
476 /* Check whether address is unicast/broadcast or multicast */
478 address_left
= AROS_BE2LONG(*((ULONG
*)address
));
479 address_right
= AROS_BE2WORD(*((UWORD
*)(address
+ 4)));
481 if((address_left
& 0x01000000) != 0 &&
482 !(address_left
== 0xffffffff && address_right
== 0xffff))
484 /* Check if this multicast address is wanted */
486 range
= (APTR
)unit
->e1ku_multicast_ranges
.mlh_Head
;
487 tail
= (APTR
)&unit
->e1ku_multicast_ranges
.mlh_Tail
;
490 while((range
!= tail
) && !accept
)
492 if((address_left
> range
->lower_bound_left
||
493 (address_left
== range
->lower_bound_left
&&
494 address_right
>= range
->lower_bound_right
)) &&
495 (address_left
< range
->upper_bound_left
||
496 (address_left
== range
->upper_bound_left
&&
497 address_right
<= range
->upper_bound_right
)))
499 range
= (APTR
)range
->node
.mln_Succ
;
503 unit
->e1ku_special_stats
[S2SS_ETHERNET_BADMULTICAST
& 0xffff]++;
511 AROS_UFH3(void, e1000func_Schedular
,
512 AROS_UFHA(STRPTR
, argPtr
, A0
),
513 AROS_UFHA(ULONG
, argSize
, D0
),
514 AROS_UFHA(struct ExecBase
*, SysBase
, A6
))
518 struct e1000Startup
*sm_UD
= FindTask(NULL
)->tc_UserData
;
519 struct e1000Unit
*unit
= sm_UD
->e1ksm_Unit
;
521 LIBBASETYPEPTR LIBBASE
= unit
->e1ku_device
;
523 struct MsgPort
*reply_port
, *input
;
525 D(bug("[%s] e1000func_Schedular()\n", unit
->e1ku_name
));
526 D(bug("[%s] e1000func_Schedular: Setting device up\n", unit
->e1ku_name
));
528 reply_port
= CreateMsgPort();
529 input
= CreateMsgPort();
531 unit
->e1ku_input_port
= input
;
533 /* Randomize the generator with current time */
534 BattClockBase
= OpenResource("battclock.resource");
535 srandom(ReadBattClock());
537 unit
->e1ku_TimerSlowPort
= CreateMsgPort();
539 if (unit
->e1ku_TimerSlowPort
)
541 unit
->e1ku_TimerSlowReq
= (struct timerequest
*)
542 CreateIORequest((struct MsgPort
*)unit
->e1ku_TimerSlowPort
, sizeof(struct timerequest
));
544 if (unit
->e1ku_TimerSlowReq
)
546 if (!OpenDevice("timer.device", UNIT_VBLANK
,
547 (struct IORequest
*)unit
->e1ku_TimerSlowReq
, 0))
549 struct Message
*msg
= AllocVec(sizeof(struct Message
), MEMF_PUBLIC
|MEMF_CLEAR
);
552 D(bug("[%s] e1000func_Schedular: Got VBLANK unit of timer.device\n", unit
->e1ku_name
));
554 e1000func_reset(unit
);
556 msg
->mn_ReplyPort
= reply_port
;
557 msg
->mn_Length
= sizeof(struct Message
);
559 D(bug("[%s] e1000func_Schedular: Setup complete. Sending handshake\n", unit
->e1ku_name
));
560 PutMsg(sm_UD
->e1ksm_SyncPort
, msg
);
561 WaitPort(reply_port
);
566 D(bug("[%s] e1000func_Schedular: entering forever loop ... \n", unit
->e1ku_name
));
568 unit
->e1ku_signal_0
= AllocSignal(-1);
569 unit
->e1ku_signal_1
= AllocSignal(-1);
570 unit
->e1ku_signal_2
= AllocSignal(-1);
571 unit
->e1ku_signal_3
= AllocSignal(-1);
573 sigset
= 1 << input
->mp_SigBit
|
574 1 << unit
->e1ku_signal_0
|
575 1 << unit
->e1ku_signal_1
|
576 1 << unit
->e1ku_signal_2
|
577 1 << unit
->e1ku_signal_3
;
580 ULONG recvd
= Wait(sigset
);
581 if (recvd
& unit
->e1ku_signal_0
)
584 * Shutdown process. Driver should close everything
585 * already and waits for our process to complete. Free
586 * memory allocared here and kindly return.
588 // unit->deinitialize(unit);
589 CloseDevice((struct IORequest
*)unit
->e1ku_TimerSlowReq
);
590 DeleteIORequest((struct IORequest
*)unit
->e1ku_TimerSlowReq
);
591 DeleteMsgPort(unit
->e1ku_TimerSlowPort
);
592 DeleteMsgPort(input
);
593 DeleteMsgPort(reply_port
);
595 D(bug("[%s] e1000func_Schedular: Process shutdown.\n", unit
->e1ku_name
));
598 else if (recvd
& (1 << input
->mp_SigBit
))
600 struct IOSana2Req
*io
;
602 /* Handle incoming transactions */
603 while ((io
= (struct IOSana2Req
*)GetMsg(input
))!= NULL
)
605 D(bug("[%s] e1000func_Schedular: Handle incomming transaction.\n", unit
->e1ku_name
));
606 ObtainSemaphore(&unit
->e1ku_unit_lock
);
607 handle_request(LIBBASE
, io
);
612 D(bug("[%s] e1000func_Schedular: Handle incomming signal.\n", unit
->e1ku_name
));
613 /* Handle incoming signals */
624 * Create new e1000 ethernet device unit
626 #warning "TODO: Handle cleanup on failure in CreateUnit more elegantly"
627 struct e1000Unit
*CreateUnit(struct e1000Base
*e1KBase
, OOP_Object
*pciDevice
)
629 struct e1000Unit
*unit
;
630 // UWORD eeprom_data = 0;
631 // UWORD eeprom_apme_mask = E1000_EEPROM_APME;
635 D(bug("[e1000] CreateUnit()\n"));
637 if ((unit
= AllocMem(sizeof(struct e1000Unit
), MEMF_PUBLIC
| MEMF_CLEAR
)) != NULL
)
645 Flash_Base
= (IPTR
)NULL
,
646 MMIO_Base
= (IPTR
)NULL
,
651 unit
->e1ku_UnitNum
= e1KBase
->e1kb_UnitCount
++;
653 unit
->e1ku_Sana2Info
.HardwareType
= S2WireType_Ethernet
;
654 unit
->e1ku_Sana2Info
.MTU
= ETH_MTU
;
655 unit
->e1ku_Sana2Info
.AddrFieldSize
= 8 * ETH_ADDRESSSIZE
;
657 if ((unit
->e1ku_Private00
= (IPTR
)AllocMem(sizeof(struct e1000_hw
), MEMF_PUBLIC
| MEMF_CLEAR
)) == (IPTR
)NULL
)
659 FreeMem(unit
, sizeof(struct e1000Unit
));
663 if ((unit
->e1ku_hw_stats
= (struct e1000_hw_stats
*)AllocMem(sizeof(struct e1000_hw_stats
), MEMF_PUBLIC
| MEMF_CLEAR
)) == (IPTR
)NULL
)
665 FreeMem(unit
->e1ku_Private00
, sizeof(struct e1000_hw
));
666 FreeMem(unit
, sizeof(struct e1000Unit
));
670 ((struct e1000_hw
*)unit
->e1ku_Private00
)->back
= unit
;
672 if ((unit
->e1ku_name
= AllocVec(6 + (unit
->e1ku_UnitNum
/10) + 2, MEMF_PUBLIC
| MEMF_CLEAR
)) == NULL
)
674 FreeMem(unit
->e1ku_hw_stats
, sizeof(struct e1000_hw_stats
));
675 FreeMem(unit
->e1ku_Private00
, sizeof(struct e1000_hw
));
676 FreeMem(unit
, sizeof(struct e1000Unit
));
680 sprintf((char *)unit
->e1ku_name
, "e1000.%d", unit
->e1ku_UnitNum
);
682 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_ProductID
, &DeviceID
);
683 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_RevisionID
, &RevisionID
);
684 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Driver
, (APTR
)&driver
);
686 unit
->e1ku_device
= e1KBase
;
687 ((struct e1000_hw
*)unit
->e1ku_Private00
)->device_id
= DeviceID
;
688 ((struct e1000_hw
*)unit
->e1ku_Private00
)->revision_id
= RevisionID
;
690 unit
->e1ku_mtu
= unit
->e1ku_Sana2Info
.MTU
;
691 unit
->rx_buffer_len
= MAXIMUM_ETHERNET_VLAN_SIZE
;
692 unit
->e1ku_frame_max
= unit
->e1ku_mtu
+ ETH_HEADERSIZE
+ ETH_CRCSIZE
;
693 unit
->e1ku_frame_min
= 60 + ETH_CRCSIZE
;
695 unit
->e1ku_PCIDevice
= pciDevice
;
696 unit
->e1ku_PCIDriver
= driver
;
698 InitSemaphore(&unit
->e1ku_unit_lock
);
699 NEWLIST(&unit
->e1ku_Openers
);
700 NEWLIST(&unit
->e1ku_multicast_ranges
);
701 NEWLIST(&unit
->e1ku_type_trackers
);
703 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_INTLine
, &unit
->e1ku_IRQ
);
704 D(bug("[%s] CreateUnit: Device IRQ : %d\n", unit
->e1ku_name
, unit
->e1ku_IRQ
));
706 for (i
= 1; i
<= 5; i
++)
708 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Base0
+ (i
* 3), &BaseAddr
);
709 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Type0
+ (i
* 3), &BaseType
);
710 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Size0
+ (i
* 3), &BaseLen
);
711 if ((BaseAddr
!= (IPTR
)NULL
) && (BaseLen
> 0))
713 if (BaseType
& ADDRF_IO
)
716 D(bug("[%s] CreateUnit: Device IO @ %p [%d bytes]\n", unit
->e1ku_name
, IOBase
, BaseLen
));
720 Flash_Base
= BaseAddr
;
721 Flash_Size
= BaseLen
;
722 D(bug("[%s] CreateUnit: Device Flash @ %p [%d bytes]\n", unit
->e1ku_name
, Flash_Base
, Flash_Size
));
727 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Base0
, &MMIO_Base
);
728 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Size0
, &MMIO_Size
);
729 D(bug("[%s] CreateUnit: Device MMIO @ %p\n", unit
->e1ku_name
, MMIO_Base
));
731 ((struct e1000_hw
*)unit
->e1ku_Private00
)->io_base
= (unsigned long)IOBase
;
732 ((struct e1000_hw
*)unit
->e1ku_Private00
)->hw_addr
= (UBYTE
*)HIDD_PCIDriver_MapPCI(driver
, (APTR
)MMIO_Base
, MMIO_Size
);
733 unit
->e1ku_MMIOSize
= MMIO_Size
;
735 D(bug("[%s] CreateUnit: Mapped MMIO @ %p [%d bytes]\n", unit
->e1ku_name
, ((struct e1000_hw
*)unit
->e1ku_Private00
)->hw_addr
, unit
->e1ku_MMIOSize
));
737 ((struct e1000_hw
*)unit
->e1ku_Private00
)->flash_address
= (UBYTE
*)HIDD_PCIDriver_MapPCI(driver
, (APTR
)Flash_Base
, Flash_Size
);
738 unit
->e1ku_FlashSize
= Flash_Size
;
740 D(bug("[%s] CreateUnit: Mapped Flash Memory @ %p [%d bytes]\n", unit
->e1ku_name
, ((struct e1000_hw
*)unit
->e1ku_Private00
)->flash_address
, unit
->e1ku_FlashSize
));
742 if ((((struct e1000_hw
*)unit
->e1ku_Private00
)->io_base
) && (((struct e1000_hw
*)unit
->e1ku_Private00
)->hw_addr
))
744 struct TagItem attrs
[] = {
745 { aHidd_PCIDevice_isIO
, TRUE
},
746 { aHidd_PCIDevice_isMEM
, TRUE
},
747 { aHidd_PCIDevice_isMaster
, TRUE
},
750 OOP_SetAttrs(pciDevice
, (struct TagItem
*)&attrs
);
752 unit
->e1ku_DelayPort
.mp_SigBit
= SIGB_SINGLE
;
753 unit
->e1ku_DelayPort
.mp_Flags
= PA_SIGNAL
;
754 unit
->e1ku_DelayPort
.mp_SigTask
= FindTask(NULL
);
755 unit
->e1ku_DelayPort
.mp_Node
.ln_Type
= NT_MSGPORT
;
756 NEWLIST(&unit
->e1ku_DelayPort
.mp_MsgList
);
758 unit
->e1ku_DelayReq
.tr_node
.io_Message
.mn_ReplyPort
= &unit
->e1ku_DelayPort
;
759 unit
->e1ku_DelayReq
.tr_node
.io_Message
.mn_Length
= sizeof(struct timerequest
);
761 OpenDevice((STRPTR
)"timer.device", UNIT_MICROHZ
, (struct IORequest
*)&unit
->e1ku_DelayReq
, 0);
763 /* Call e1000_api.c->e1000_setup_init_funcs */
764 if (e1000_setup_init_funcs((struct e1000_hw
*)unit
->e1ku_Private00
, FALSE
) != E1000_SUCCESS
)
766 /* Should never have loaded on this device */
767 D(bug("[%s] CreateUnit: Called on unsupported NIC type!!\n", unit
->e1ku_name
));
768 e1KBase
->e1kb_UnitCount
= unit
->e1ku_UnitNum
;
769 FreeVec(unit
->e1ku_name
);
770 FreeMem(unit
->e1ku_Private00
, sizeof(struct e1000_hw
));
771 FreeMem(unit
, sizeof(struct e1000Unit
));
775 D(bug("[%s] CreateUnit: Initialised Intel NIC functions..\n", unit
->e1ku_name
));
777 unit
->e1ku_txRing_QueueSize
= 1;
778 if ((unit
->e1ku_txRing
= AllocMem(sizeof(struct e1000_tx_ring
) * unit
->e1ku_txRing_QueueSize
, MEMF_PUBLIC
|MEMF_CLEAR
)) == NULL
)
780 #warning "TODO: Handle Tx Queue allocation failure more elegantly!"
781 D(bug("[%s] CreateUnit: Failed to Allocate Tx Ring Queue!!!\n", unit
->e1ku_name
));
784 D(bug("[%s] CreateUnit: Queue 0 TxRing @ %p\n", unit
->e1ku_name
, unit
->e1ku_txRing
));
786 unit
->e1ku_rxRing_QueueSize
= 1;
787 if ((unit
->e1ku_rxRing
= AllocMem(sizeof(struct e1000_rx_ring
) * unit
->e1ku_rxRing_QueueSize
, MEMF_PUBLIC
|MEMF_CLEAR
)) == NULL
)
789 #warning "TODO: Handle Rx Queue allocation failure more elegantly!"
790 D(bug("[%s] CreateUnit: Failed to Allocate Rx Ring Queue!!!\n", unit
->e1ku_name
));
793 D(bug("[%s] CreateUnit: Queue 0 RxRing @ %p\n", unit
->e1ku_name
, unit
->e1ku_rxRing
));
795 e1000func_irq_disable(unit
);
796 D(bug("[%s] CreateUnit: e1000 IRQ disabled\n", unit
->e1ku_name
));
798 if (e1000_init_mac_params((struct e1000_hw
*)unit
->e1ku_Private00
) != E1000_SUCCESS
)
800 D(bug("[%s] CreateUnit: Failed to init mac params\n", unit
->e1ku_name
));
802 D(bug("[%s] CreateUnit: MAC Params Initialised\n", unit
->e1ku_name
));
804 if (e1000_init_nvm_params((struct e1000_hw
*)unit
->e1ku_Private00
) != E1000_SUCCESS
)
806 D(bug("[%s] CreateUnit: Failed to init nvm params\n", unit
->e1ku_name
));
808 D(bug("[%s] CreateUnit: NVM Params Initialised\n", unit
->e1ku_name
));
810 if (e1000_init_phy_params((struct e1000_hw
*)unit
->e1ku_Private00
) != E1000_SUCCESS
)
812 D(bug("[%s] CreateUnit: Failed to init phy params\n", unit
->e1ku_name
));
814 D(bug("[%s] CreateUnit: PHY Params Initialised\n", unit
->e1ku_name
));
816 e1000_get_bus_info((struct e1000_hw
*)unit
->e1ku_Private00
);
818 D(bug("[%s] CreateUnit: Retrieved Bus information..\n", unit
->e1ku_name
));
820 e1000_init_script_state_82541((struct e1000_hw
*)unit
->e1ku_Private00
, TRUE
);
821 e1000_set_tbi_compatibility_82543((struct e1000_hw
*)unit
->e1ku_Private00
, TRUE
);
823 D(bug("[%s] CreateUnit: 82541/82543 Setup complete\n", unit
->e1ku_name
));
825 ((struct e1000_hw
*)unit
->e1ku_Private00
)->phy
.autoneg_wait_to_complete
= FALSE
;
826 ((struct e1000_hw
*)unit
->e1ku_Private00
)->mac
.adaptive_ifs
= TRUE
;
830 if (((struct e1000_hw
*)unit
->e1ku_Private00
)->phy
.media_type
== e1000_media_type_copper
)
832 ((struct e1000_hw
*)unit
->e1ku_Private00
)->phy
.mdix
= AUTO_ALL_MODES
;
833 ((struct e1000_hw
*)unit
->e1ku_Private00
)->phy
.disable_polarity_correction
= FALSE
;
834 ((struct e1000_hw
*)unit
->e1ku_Private00
)->phy
.ms_type
= E1000_MASTER_SLAVE
;
837 if (e1000_check_reset_block((struct e1000_hw
*)unit
->e1ku_Private00
))
839 D(bug("[%s] CreateUnit: PHY reset is blocked due to SOL/IDER session.\n", unit
->e1ku_name
));
842 /* Hardware features, flags and workarounds */
843 if (((struct e1000_hw
*)unit
->e1ku_Private00
)->mac
.type
>= e1000_82540
) {
844 unit
->e1ku_hwflags
|= E1000_FLAG_HAS_SMBUS
;
845 unit
->e1ku_hwflags
|= E1000_FLAG_HAS_INTR_MODERATION
;
848 if (((struct e1000_hw
*)unit
->e1ku_Private00
)->mac
.type
== e1000_82543
)
849 unit
->e1ku_hwflags
|= E1000_FLAG_BAD_TX_CARRIER_STATS_FD
;
851 e1000_reset_hw((struct e1000_hw
*)unit
->e1ku_Private00
);
852 D(bug("[%s] CreateUnit: e1000 hardware reset\n", unit
->e1ku_name
));
854 if (e1000_validate_nvm_checksum((struct e1000_hw
*)unit
->e1ku_Private00
) < 0) {
855 D(bug("[%s] CreateUnit: Warning: The NVM Checksum Is Not Valid!\n", unit
->e1ku_name
));
860 D(bug("[%s] CreateUnit: NVM Checksum validated succesfully\n", unit
->e1ku_name
));
863 /* copy the MAC address out of the NVM */
865 if (e1000_read_mac_addr((struct e1000_hw
*)unit
->e1ku_Private00
))
867 D(bug("[%s] CreateUnit: NVM Read Error\n", unit
->e1ku_name
));
871 D(bug("[%s] CreateUnit: MAC Address Read\n", unit
->e1ku_name
));
873 memcpy(unit
->e1ku_org_addr
, ((struct e1000_hw
*)unit
->e1ku_Private00
)->mac
.addr
, ETH_ADDRESSSIZE
);
874 memcpy(unit
->e1ku_dev_addr
, unit
->e1ku_org_addr
, ETH_ADDRESSSIZE
);
876 D(bug("[%s] CreateUnit: MAC Address %02x:%02x:%02x:%02x:%02x:%02x\n", unit
->e1ku_name
,
877 unit
->e1ku_dev_addr
[0], unit
->e1ku_dev_addr
[1], unit
->e1ku_dev_addr
[2],
878 unit
->e1ku_dev_addr
[3], unit
->e1ku_dev_addr
[4], unit
->e1ku_dev_addr
[5]));
881 D(bug("[%s] CreateUnit: (PCI%s:%s:%s)\n", unit
->e1ku_name
,
882 ((((struct e1000_hw
*)unit
->e1ku_Private00
)->bus
.type
== e1000_bus_type_pcix
) ? "-X" :
883 (((struct e1000_hw
*)unit
->e1ku_Private00
)->bus
.type
== e1000_bus_type_pci_express
? " Express":"")),
884 ((((struct e1000_hw
*)unit
->e1ku_Private00
)->bus
.speed
== e1000_bus_speed_2500
) ? "2.5Gb/s" :
885 (((struct e1000_hw
*)unit
->e1ku_Private00
)->bus
.speed
== e1000_bus_speed_133
) ? "133MHz" :
886 (((struct e1000_hw
*)unit
->e1ku_Private00
)->bus
.speed
== e1000_bus_speed_120
) ? "120MHz" :
887 (((struct e1000_hw
*)unit
->e1ku_Private00
)->bus
.speed
== e1000_bus_speed_100
) ? "100MHz" :
888 (((struct e1000_hw
*)unit
->e1ku_Private00
)->bus
.speed
== e1000_bus_speed_66
) ? "66MHz" : "33MHz"),
889 ((((struct e1000_hw
*)unit
->e1ku_Private00
)->bus
.width
== e1000_bus_width_64
) ? "64-bit" :
890 (((struct e1000_hw
*)unit
->e1ku_Private00
)->bus
.width
== e1000_bus_width_pcie_x4
) ? "Width x4" :
891 (((struct e1000_hw
*)unit
->e1ku_Private00
)->bus
.width
== e1000_bus_width_pcie_x1
) ? "Width x1" :
895 unit
->e1ku_irqhandler
= AllocMem(sizeof(HIDDT_IRQ_Handler
), MEMF_PUBLIC
|MEMF_CLEAR
);
896 unit
->e1ku_touthandler
= AllocMem(sizeof(HIDDT_IRQ_Handler
), MEMF_PUBLIC
|MEMF_CLEAR
);
898 if (unit
->e1ku_irqhandler
&& unit
->e1ku_touthandler
)
902 unit
->e1ku_irqhandler
->h_Node
.ln_Pri
= 100;
903 unit
->e1ku_irqhandler
->h_Node
.ln_Name
= LIBBASE
->e1kb_Device
.dd_Library
.lib_Node
.ln_Name
;
904 unit
->e1ku_irqhandler
->h_Code
= e1000func_IntHandler
;
905 unit
->e1ku_irqhandler
->h_Data
= unit
;
907 unit
->e1ku_touthandler
->h_Node
.ln_Pri
= 100;
908 unit
->e1ku_touthandler
->h_Node
.ln_Name
= LIBBASE
->e1kb_Device
.dd_Library
.lib_Node
.ln_Name
;
909 unit
->e1ku_touthandler
->h_Code
= e1000func_WatchdogHandler
;
910 unit
->e1ku_touthandler
->h_Data
= unit
;
912 unit
->e1ku_tx_int
.is_Node
.ln_Name
= unit
->e1ku_name
;
913 unit
->e1ku_tx_int
.is_Code
= e1000func_TX_Int
;
914 unit
->e1ku_tx_int
.is_Data
= unit
;
916 for (i
= 0; i
< REQUEST_QUEUE_COUNT
; i
++)
918 struct MsgPort
*port
;
920 if ((port
= AllocMem(sizeof(struct MsgPort
), MEMF_PUBLIC
| MEMF_CLEAR
)) == NULL
) success
= FALSE
;
924 unit
->e1ku_request_ports
[i
] = port
;
925 NEWLIST(&port
->mp_MsgList
);
926 port
->mp_Flags
= PA_IGNORE
;
927 port
->mp_SigTask
= &unit
->e1ku_tx_int
;
931 unit
->e1ku_request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_SOFTINT
;
935 struct e1000Startup
*sm_UD
;
938 if ((sm_UD
= AllocMem(sizeof(struct e1000Startup
), MEMF_PUBLIC
| MEMF_CLEAR
)) != NULL
)
940 sprintf((char *)tmpbuff
, e1000_TASK_NAME
, unit
->e1ku_name
);
942 sm_UD
->e1ksm_SyncPort
= CreateMsgPort();
943 sm_UD
->e1ksm_Unit
= unit
;
945 unit
->e1ku_Process
= CreateNewProcTags(
946 NP_Entry
, (IPTR
)e1000func_Schedular
,
948 NP_Synchronous
, FALSE
,
950 NP_UserData
, (IPTR
)sm_UD
,
951 NP_StackSize
, 140960,
954 WaitPort(sm_UD
->e1ksm_SyncPort
);
955 msg
= GetMsg(sm_UD
->e1ksm_SyncPort
);
957 DeleteMsgPort(sm_UD
->e1ksm_SyncPort
);
958 FreeMem(sm_UD
, sizeof(struct e1000Startup
));
960 D(bug("[%s] CreateUnit: Device Initialised. Unit %d @ %p\n", unit
->e1ku_name
, unit
->e1ku_UnitNum
, unit
));
968 if ((((struct e1000_hw
*)unit
->e1ku_Private00
)->io_base
) == (IPTR
)NULL
)
970 D(bug("[%s] CreateUnit: PANIC! Couldn't find IO area. Aborting\n", unit
->e1ku_name
));
973 if ((((struct e1000_hw
*)unit
->e1ku_Private00
)->hw_addr
) == (IPTR
)NULL
)
975 D(bug("[%s] CreateUnit: PANIC! Couldn't get MMIO area. Aborting\n", unit
->e1ku_name
));
979 DeleteUnit(e1KBase
, unit
);
984 * DeleteUnit - removes selected unit. Frees all resources and structures.
986 * The caller should be sure, that given unit is really ready to be freed.
989 void DeleteUnit(struct e1000Base
*e1KBase
, struct e1000Unit
*unit
)
994 if (unit
->e1ku_Process
)
996 Signal(&unit
->e1ku_Process
->pr_Task
, unit
->e1ku_signal_0
);
999 for (i
=0; i
< REQUEST_QUEUE_COUNT
; i
++)
1001 if (unit
->e1ku_request_ports
[i
] != NULL
)
1002 FreeMem(unit
->e1ku_request_ports
[i
], sizeof(struct MsgPort
));
1004 unit
->e1ku_request_ports
[i
] = NULL
;
1007 if (unit
->e1ku_irqhandler
)
1009 FreeMem(unit
->e1ku_irqhandler
, sizeof(HIDDT_IRQ_Handler
));
1012 if ((struct e1000_hw
*)unit
->e1ku_Private00
)
1014 if (((struct e1000_hw
*)unit
->e1ku_Private00
)->hw_addr
)
1016 HIDD_PCIDriver_UnmapPCI(unit
->e1ku_PCIDriver
,
1017 (APTR
)((struct e1000_hw
*)unit
->e1ku_Private00
)->hw_addr
,
1018 unit
->e1ku_MMIOSize
);
1020 FreeMem(unit
->e1ku_Private00
, sizeof(struct e1000_hw
));
1023 if (unit
->e1ku_name
)
1024 FreeVec(unit
->e1ku_name
);
1026 FreeMem(unit
, sizeof(struct e1000Unit
));
1030 static struct AddressRange
*FindMulticastRange(LIBBASETYPEPTR LIBBASE
, struct e1000Unit
*unit
,
1031 ULONG lower_bound_left
, UWORD lower_bound_right
, ULONG upper_bound_left
, UWORD upper_bound_right
)
1033 struct AddressRange
*range
, *tail
;
1036 range
= (APTR
)unit
->e1ku_multicast_ranges
.mlh_Head
;
1037 tail
= (APTR
)&unit
->e1ku_multicast_ranges
.mlh_Tail
;
1039 while((range
!= tail
) && !found
)
1041 if((lower_bound_left
== range
->lower_bound_left
) &&
1042 (lower_bound_right
== range
->lower_bound_right
) &&
1043 (upper_bound_left
== range
->upper_bound_left
) &&
1044 (upper_bound_right
== range
->upper_bound_right
))
1047 range
= (APTR
)range
->node
.mln_Succ
;
1056 BOOL
AddMulticastRange(LIBBASETYPEPTR LIBBASE
, struct e1000Unit
*unit
, const UBYTE
*lower_bound
,
1057 const UBYTE
*upper_bound
)
1059 struct AddressRange
*range
;
1060 ULONG lower_bound_left
, upper_bound_left
;
1061 UWORD lower_bound_right
, upper_bound_right
;
1063 lower_bound_left
= AROS_BE2LONG(*((ULONG
*)lower_bound
));
1064 lower_bound_right
= AROS_BE2WORD(*((UWORD
*)(lower_bound
+ 4)));
1065 upper_bound_left
= AROS_BE2LONG(*((ULONG
*)upper_bound
));
1066 upper_bound_right
= AROS_BE2WORD(*((UWORD
*)(upper_bound
+ 4)));
1068 range
= FindMulticastRange(LIBBASE
, unit
, lower_bound_left
, lower_bound_right
,
1069 upper_bound_left
, upper_bound_right
);
1075 range
= AllocMem(sizeof(struct AddressRange
), MEMF_PUBLIC
);
1078 range
->lower_bound_left
= lower_bound_left
;
1079 range
->lower_bound_right
= lower_bound_right
;
1080 range
->upper_bound_left
= upper_bound_left
;
1081 range
->upper_bound_right
= upper_bound_right
;
1082 range
->add_count
= 1;
1085 AddTail((APTR
)&unit
->e1ku_multicast_ranges
, (APTR
)range
);
1088 if (unit
->e1ku_range_count
++ == 0)
1090 unit
->e1ku_ifflags
|= IFF_ALLMULTI
;
1091 e1000func_set_multi(unit
);
1096 return range
!= NULL
;
1099 BOOL
RemMulticastRange(LIBBASETYPEPTR LIBBASE
, struct e1000Unit
*unit
, const UBYTE
*lower_bound
, const UBYTE
*upper_bound
)
1101 struct AddressRange
*range
;
1102 ULONG lower_bound_left
, upper_bound_left
;
1103 UWORD lower_bound_right
, upper_bound_right
;
1105 lower_bound_left
= AROS_BE2LONG(*((ULONG
*)lower_bound
));
1106 lower_bound_right
= AROS_BE2WORD(*((UWORD
*)(lower_bound
+ 4)));
1107 upper_bound_left
= AROS_BE2LONG(*((ULONG
*)upper_bound
));
1108 upper_bound_right
= AROS_BE2WORD(*((UWORD
*)(upper_bound
+ 4)));
1110 range
= FindMulticastRange(LIBBASE
, unit
, lower_bound_left
, lower_bound_right
,
1111 upper_bound_left
, upper_bound_right
);
1115 if(--range
->add_count
== 0)
1118 Remove((APTR
)range
);
1120 FreeMem(range
, sizeof(struct AddressRange
));
1122 if (--unit
->e1ku_range_count
== 0)
1124 unit
->e1ku_ifflags
&= ~IFF_ALLMULTI
;
1125 e1000func_set_multi(unit
);
1129 return range
!= NULL
;