2 * $Id: unit.c 29318 2008-08-29 20:52:01Z NicJA $
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,
22 #include <exec/types.h>
23 #include <exec/resident.h>
25 #include <exec/ports.h>
26 #include <exec/errors.h>
30 #include <devices/sana2.h>
31 #include <devices/sana2specialstats.h>
32 #include <devices/newstyle.h>
33 #include <devices/timer.h>
35 #include <utility/utility.h>
36 #include <utility/tagitem.h>
37 #include <utility/hooks.h>
39 #include <proto/exec.h>
40 #include <proto/dos.h>
41 #include <proto/battclock.h>
42 #include <proto/oop.h>
43 #include <proto/timer.h>
44 #include <proto/utility.h>
51 #include LC_LIBDEFS_FILE
54 extern UBYTE
MMIO_R8(UBYTE
*);
55 extern UWORD
MMIO_R16(UWORD
*);
56 extern ULONG
MMIO_R32(ULONG
*);
57 extern void MMIO_W8(UBYTE
*, UBYTE
);
58 extern void MMIO_W16(UWORD
*, UWORD
);
59 extern void MMIO_W32(ULONG
*, ULONG
);
61 extern void rtl8168_CheckLinkStatus(struct net_device
*);
64 * Report incoming events to all hyphotetical event receivers
66 VOID
ReportEvents(struct RTL8168Base
*RTL8168DeviceBase
, struct RTL8168Unit
*unit
, ULONG events
)
68 struct IOSana2Req
*request
, *tail
, *next_request
;
71 list
= &unit
->rtl8168u_request_ports
[EVENT_QUEUE
]->mp_MsgList
;
72 next_request
= (APTR
)list
->lh_Head
;
73 tail
= (APTR
)&list
->lh_Tail
;
75 /* Go through list of event listeners. If send messages to receivers if event found */
77 while(next_request
!= tail
)
79 request
= next_request
;
80 next_request
= (APTR
)request
->ios2_Req
.io_Message
.mn_Node
.ln_Succ
;
82 if((request
->ios2_WireError
&events
) != 0)
84 request
->ios2_WireError
= events
;
85 Remove((APTR
)request
);
86 ReplyMsg((APTR
)request
);
94 struct TypeStats
*FindTypeStats(struct RTL8168Base
*RTL8168DeviceBase
, struct RTL8168Unit
*unit
,
95 struct MinList
*list
, ULONG packet_type
)
97 struct TypeStats
*stats
, *tail
;
100 stats
= (APTR
)list
->mlh_Head
;
101 tail
= (APTR
)&list
->mlh_Tail
;
103 while(stats
!= tail
&& !found
)
105 if(stats
->packet_type
== packet_type
)
108 stats
= (APTR
)stats
->node
.mln_Succ
;
117 void FlushUnit(LIBBASETYPEPTR LIBBASE
, struct RTL8168Unit
*unit
, UBYTE last_queue
, BYTE error
)
119 struct IORequest
*request
;
121 struct Opener
*opener
, *tail
;
123 RTLD(bug("[%s] unit.FlushUnit\n", unit
->rtl8168u_name
))
125 /* Abort queued operations */
126 for (i
=0; i
<= last_queue
; i
++)
128 while ((request
= (APTR
)GetMsg(unit
->rtl8168u_request_ports
[i
])) != NULL
)
130 request
->io_Error
= IOERR_ABORTED
;
131 ReplyMsg((struct Message
*)request
);
135 opener
= (APTR
)unit
->rtl8168u_Openers
.mlh_Head
;
136 tail
= (APTR
)unit
->rtl8168u_Openers
.mlh_Tail
;
138 /* Flush every opener's read queue */
139 while(opener
!= tail
)
141 while ((request
= (APTR
)GetMsg(&opener
->read_port
)) != NULL
)
143 request
->io_Error
= error
;
144 ReplyMsg((struct Message
*)request
);
146 opener
= (struct Opener
*)opener
->node
.mln_Succ
;
150 static inline void rtl8168_MarkToASIC(struct RxDesc
*desc
, ULONG rx_buf_sz
)
152 ULONG eor
= AROS_LE2LONG(desc
->opts1
) & RingEnd
;
154 desc
->opts1
= AROS_LONG2LE(DescOwn
| eor
| rx_buf_sz
);
157 /* Interrupt Rx Support Function ..
158 * It's duty is to iterate throgh RX queue searching for new packets.
160 void RTL8168_Rx_Process(struct RTL8168Unit
*unit
)
162 struct RTL8168Base
*RTL8168DeviceBase
= unit
->rtl8168u_device
;
163 struct rtl8168_priv
*np
= unit
->rtl8168u_priv
;
164 APTR base
= unit
->rtl8168u_BaseMem
;
166 struct TypeStats
*tracker
;
168 struct Opener
*opener
, *opener_tail
;
169 struct IOSana2Req
*request
, *request_tail
;
170 BOOL accepted
, is_orphan
;
172 RTLD(bug("[%s] RTL8168_Rx_Process() !!!!\n", unit
->rtl8168u_name
))
174 struct eth_frame
*frame
;
176 unsigned short cur_rx
, rx_left
;
178 rx_left
= NUM_RX_DESC
- np
->dirty_rx
;
180 RTLD(bug("[%s] RTL8168_Rx_Process: cur_rx = %d, rx_left = %d, dirty = %d\n", unit
->rtl8168u_name
, cur_rx
, rx_left
, np
->dirty_rx
))
182 for (; rx_left
> 0; rx_left
--, cur_rx
++) {
183 unsigned int entry
= cur_rx
% NUM_RX_DESC
;
184 struct RxDesc
*desc
= np
->RxDescArray
+ entry
;
187 status
= AROS_LE2LONG(desc
->opts1
);
189 if (status
& DescOwn
)
192 RTLD(bug("[%s] RTL8168_Rx_Process: Packet %d\n", unit
->rtl8168u_name
, entry
))
194 if (status
& RxRES
) {
195 RTLD(bug("[%s] RTL8168_Rx_Process: Rx ERROR, status = %08x\n",
196 unit
->rtl8168u_name
, status
))
198 #warning "TODO: record rx errors .."
199 /* RTLDEV->stats.rx_errors++;
201 if (status & (RxRWT | RxRUNT))
202 RTLDEV->stats.rx_length_errors++;
204 RTLDEV->stats.rx_crc_errors++;
206 rtl8168_MarkToASIC(desc
, np
->rx_buf_sz
);
210 int pkt_size
= (status
& 0x00003FFF) - ETH_CRCSIZE
;
212 frame
= (UBYTE
*)(desc
->addr
);
213 RTLD(bug("[%s] RTL8168_Rx_Process: frame @ %p, pkt_size=%d\n", unit
->rtl8168u_name
, frame
, pkt_size
))
215 /* got a valid packet - forward it to the network core */
220 for (j
= 0; j
< pkt_size
; j
++) {
227 bug("[%s] RTL8168_Rx_Process: %03x:", unit
->rtl8168u_name
, j
);
229 bug(" %02x", ((unsigned char*)frame
)[j
]);
234 /* Check for address validity */
235 if(AddressFilter(LIBBASE
, unit
, frame
->eth_packet_dest
))
237 /* Packet is addressed to this driver */
238 packet_type
= AROS_BE2WORD(frame
->eth_packet_type
);
239 RTLD(bug("[%s] RTL8168_Rx_Process: Packet IP accepted with type = %d\n", unit
->rtl8168u_name
, packet_type
))
241 opener
= (APTR
)unit
->rtl8168u_Openers
.mlh_Head
;
242 opener_tail
= (APTR
)&unit
->rtl8168u_Openers
.mlh_Tail
;
244 /* Offer packet to every opener */
245 while(opener
!= opener_tail
)
247 request
= (APTR
)opener
->read_port
.mp_MsgList
.lh_Head
;
248 request_tail
= (APTR
)&opener
->read_port
.mp_MsgList
.lh_Tail
;
251 /* Offer packet to each request until it's accepted */
252 while((request
!= request_tail
) && !accepted
)
254 if((request
->ios2_PacketType
== packet_type
)
255 || ((request
->ios2_PacketType
<= ETH_MTU
)
256 && (packet_type
<= ETH_MTU
)))
258 RTLD(bug("[%s] RTL8168_Rx_Process: copy packet for opener ..\n", unit
->rtl8168u_name
))
259 CopyPacket(LIBBASE
, unit
, request
, pkt_size
, packet_type
, frame
);
262 request
= (struct IOSana2Req
*)request
->ios2_Req
.io_Message
.mn_Node
.ln_Succ
;
268 opener
= (APTR
)opener
->node
.mln_Succ
;
271 /* If packet was unwanted, give it to S2_READORPHAN request */
274 unit
->rtl8168u_stats
.UnknownTypesReceived
++;
276 if(!IsMsgPortEmpty(unit
->rtl8168u_request_ports
[ADOPT_QUEUE
]))
278 CopyPacket(LIBBASE
, unit
,
279 (APTR
)unit
->rtl8168u_request_ports
[ADOPT_QUEUE
]->
280 mp_MsgList
.lh_Head
, pkt_size
, packet_type
, frame
);
281 RTLD(bug("[%s] RTL8168_Rx_Process: packet copied to orphan queue\n", unit
->rtl8168u_name
))
285 rtl8168_MarkToASIC(desc
, (ULONG
)np
->rx_buf_sz
);
287 /* Update remaining statistics */
288 tracker
= FindTypeStats(LIBBASE
, unit
, &unit
->rtl8168u_type_trackers
, packet_type
);
292 tracker
->stats
.PacketsReceived
++;
293 tracker
->stats
.BytesReceived
+= pkt_size
;
296 unit
->rtl8168u_stats
.PacketsReceived
++;
300 RTLD(bug("[%s] RTL8168_Rx_Process: Rx Packet Processing complete\n", unit
->rtl8168u_name
))
304 * Interrupt generated by Cause() to push new packets into the NIC interface
306 AROS_UFH3(void, RTL8168_TX_IntF
,
307 AROS_UFHA(struct RTL8168Unit
*, unit
, A1
),
308 AROS_UFHA(APTR
, dummy
, A5
),
309 AROS_UFHA(struct ExecBase
*,SysBase
, A6
))
313 struct rtl8168_priv
*np
= unit
->rtl8168u_priv
;
314 struct RTL8168Base
*RTL8168DeviceBase
= unit
->rtl8168u_device
;
315 APTR base
= unit
->rtl8168u_BaseMem
;
318 BOOL proceed
= FALSE
; /* Fails by default */
320 RTLD(bug("[%s] RTL8168_TX_IntF()\n", unit
->rtl8168u_name
))
322 /* send packet only if there is free space on tx queue. Otherwise do nothing */
323 if (!netif_queue_stopped(unit
))
325 UWORD packet_size
, data_size
;
326 struct IOSana2Req
*request
;
327 struct Opener
*opener
;
331 struct MsgPort
*port
;
333 proceed
= TRUE
; /* Success by default */
334 port
= unit
->rtl8168u_request_ports
[WRITE_QUEUE
];
336 /* Still no error and there are packets to be sent? */
337 while(proceed
&& (!IsMsgPortEmpty(port
)))
339 nr
= np
->cur_tx
% NUM_TX_DESC
;
342 request
= (APTR
)port
->mp_MsgList
.lh_Head
;
343 data_size
= packet_size
= request
->ios2_DataLength
;
345 opener
= (APTR
)request
->ios2_BufferManagement
;
347 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
349 packet_size
+= ETH_PACKET_DATA
;
352 if ((!(AROS_LE2LONG(np
->TxDescArray
[nr
].opts1
) & DescOwn
)) &&
353 ((np
->TxDescArray
[nr
].addr
= AllocMem(packet_size
, MEMF_CLEAR
| MEMF_PUBLIC
)) != NULL
))
355 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
357 CopyMem(request
->ios2_DstAddr
, &((struct eth_frame
*)np
->TxDescArray
[nr
].addr
)->eth_packet_dest
, ETH_ADDRESSSIZE
);
358 CopyMem(unit
->rtl8168u_dev_addr
, &((struct eth_frame
*)np
->TxDescArray
[nr
].addr
)->eth_packet_source
, ETH_ADDRESSSIZE
);
359 ((struct eth_frame
*)np
->TxDescArray
[nr
].addr
)->eth_packet_type
= AROS_WORD2BE(request
->ios2_PacketType
);
361 buffer
= &((struct eth_frame
*)np
->TxDescArray
[nr
].addr
)->eth_packet_data
;
364 buffer
= np
->TxDescArray
[nr
].addr
;
366 if (!opener
->tx_function(buffer
, request
->ios2_Data
, data_size
))
368 error
= S2ERR_NO_RESOURCES
;
369 wire_error
= S2WERR_BUFF_ERROR
;
370 ReportEvents(LIBBASE
, unit
,
371 S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
375 // Now the packet is already in TX buffer, update flags for NIC
379 APTR packet
= np
->TxDescArray
[nr
].addr
;
380 bug("[%s] RTL8168_TX_IntF: packet %d @ %p [type = %d] queued for transmission.\n", unit
->rtl8168u_name
, nr
, np
->TxDescArray
[nr
].addr
, AROS_BE2WORD(((struct eth_frame
*)packet
)->eth_packet_type
))
385 for (j
= 0; j
< packet_size
; j
++) {
392 bug("[%s] RTL8168_TX_IntF: %03x:", unit
->rtl8168u_name
, j
);
394 bug(" %02x", ((unsigned char*)np
->TxDescArray
[nr
].addr
)[j
]);
399 // Set the ring details for the packet ..
400 np
->TxDescArray
[nr
].opts1
= AROS_LONG2LE(DescOwn
| FirstFrag
| LastFrag
| packet_size
| (RingEnd
* !((nr
+ 1) % NUM_TX_DESC
)));
401 np
->TxDescArray
[nr
].opts2
= AROS_LONG2LE(0);
403 #warning "TODO: Perhaps set the Tx Poll bit after we leave the while loop .."
404 RTL_W8(base
+ (TxPoll
), NPQ
); /* set polling bit */
408 request
->ios2_Req
.io_Error
= error
;
409 request
->ios2_WireError
= wire_error
;
411 Remove((APTR
)request
);
413 ReplyMsg((APTR
)request
);
420 // If we've just run out of free space on the TX queue, stop
421 // it and give up pushing further frames
422 if ( (try_count
+ 1) >= NUM_TX_DESC
)
424 RTLD(bug("[%s] output queue full!. Stopping [count = %d, NUM_TX_DESC = %d\n", unit
->rtl8168u_name
, try_count
, NUM_TX_DESC
))
425 netif_stop_queue(unit
);
431 /* Was there success? Enable incomming of new packets */
433 unit
->rtl8168u_request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_SOFTINT
;
435 unit
->rtl8168u_request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_IGNORE
;
441 * Handle timeouts and other strange cases
443 static void RTL8168_TimeoutHandlerF(HIDDT_IRQ_Handler
*irq
, HIDDT_IRQ_HwInfo
*hw
)
445 struct RTL8168Unit
*unit
= (struct RTL8168Unit
*) irq
->h_Data
;
447 struct Device
*TimerBase
= unit
->rtl8168u_TimerSlowReq
->tr_node
.io_Device
;
450 //RTLD(bug("[%s] RTL8168_TimeoutHandlerF()\n", unit->rtl8168u_name))
453 * If timeout timer is expected, and time elapsed - regenerate the
456 if (unit
->rtl8168u_toutNEED
&& (CmpTime(&time
, &unit
->rtl8168u_toutPOLL
) < 0))
458 unit
->rtl8168u_toutNEED
= FALSE
;
459 //Cause(&unit->rtl8168u_tx_end_int);
463 static void RTL8168_Tx_Cleanup(struct net_device
*unit
)
465 struct rtl8168_priv
*np
= unit
->rtl8168u_priv
;
466 unsigned int dirty_tx
, tx_left
;
467 struct TypeStats
*tracker
;
469 dirty_tx
= np
->dirty_tx
;
470 tx_left
= np
->cur_tx
- dirty_tx
;
472 while (tx_left
> 0) {
473 unsigned int entry
= dirty_tx
% NUM_TX_DESC
;
474 ULONG packet_size
, status
;
476 status
= AROS_LE2LONG(np
->TxDescArray
[entry
].opts1
);
478 if (status
& DescOwn
)
481 packet_size
= status
& 0x3FFF;
482 tracker
= FindTypeStats(unit
->rtl8168u_device
, unit
, &unit
->rtl8168u_type_trackers
, ((struct eth_frame
*)np
->TxDescArray
[entry
].addr
)->eth_packet_type
);
485 tracker
->stats
.PacketsSent
++;
486 tracker
->stats
.BytesSent
+= packet_size
;
489 if (status
& LastFrag
) {
490 RTLD(bug("[%s] RTL8168_Tx_Cleanup: Released buffer %d (%d bytes)\n", unit
->rtl8168u_name
, entry
, packet_size
))
491 np
->TxDescArray
[entry
].opts1
= AROS_LONG2LE(RingEnd
);
492 np
->TxDescArray
[entry
].addr
= NULL
;
497 if (np
->dirty_tx
!= dirty_tx
) {
498 np
->dirty_tx
= dirty_tx
;
500 if (netif_queue_stopped(dev) &&
501 (TX_BUFFS_AVAIL(np) >= MAX_SKB_FRAGS)) {
502 netif_wake_queue(dev);
509 * Interrupt handler called whenever RTL8168 NIC interface generates interrupt.
511 static void RTL8168_IntHandlerF(HIDDT_IRQ_Handler
*irq
, HIDDT_IRQ_HwInfo
*hw
)
513 struct RTL8168Unit
*unit
= (struct RTL8168Unit
*) irq
->h_Data
;
514 struct rtl8168_priv
*np
= unit
->rtl8168u_priv
;
515 APTR base
= unit
->rtl8168u_BaseMem
;
519 int boguscnt
= unit
->rtl8168u_device
->rtl8168b_MaxIntWork
;
521 UWORD intr_clean_mask
= SYSErr
| PCSTimeout
| SWInt
|
522 LinkChg
| RxDescUnavail
|
523 TxErr
| TxOK
| RxErr
| RxOK
;
525 RTL_W16(base
+ (IntrMask
), 0x0000);
527 RTLD(bug("[%s] RTL8168_IntHandlerF()!!!!!!!\n", unit
->rtl8168u_name
))
530 status
= RTL_R16(base
+ (IntrStatus
));
532 /* hotplug/major error/no more work/shared irq */
533 if ((status
== 0xFFFF) || !status
)
538 // if (!netif_running(unit)) {
539 // rtl8168_asic_down(unit);
543 status
&= (np
->intr_mask
| TxDescUnavail
);
544 RTL_W16(base
+ (IntrStatus
), intr_clean_mask
);
546 if (!(status
& unit
->rtl8168u_intr_mask
))
549 //Work around for rx fifo overflow
550 if (status
& RxFIFOOver
)
552 RTLD(bug("[%s] RTL8168_IntHandlerF: Rx FIFO overflow occured!\n", unit
->rtl8168u_name
))
553 if (np
->mcfg
== CFG_METHOD_1
) {
554 /*np->rx_fifo_overflow = 1;
555 netif_stop_queue(unit);
557 rtl8168_rx_clear(np);
558 rtl8168_init_ring(unit);
559 rtl8168_hw_start(unit);*/
560 RTL_W16(base
+ (IntrStatus
), RxFIFOOver
);
561 /*netif_wake_queue(unit);
562 np->rx_fifo_overflow = 0;*/
566 if (status
& SYSErr
) {
567 RTLD(bug("[%s] RTL8168_IntHandlerF: PCI error occured!\n", unit
->rtl8168u_name
))
568 // rtl8168_pcierr_interrupt(unit);
572 if (status
& LinkChg
)
574 RTLD(bug("[%s] RTL8168_IntHandlerF: Link Change!\n", unit
->rtl8168u_name
))
575 rtl8168_CheckLinkStatus(unit
);
578 if ((status
& TxOK
) && (status
& TxDescUnavail
))
580 RTL_W8(base
+ (TxPoll
), NPQ
); /* set polling bit */
581 RTL_W16(base
+ (IntrStatus
), TxDescUnavail
);
584 if (status
& (RxOK
| RxDescUnavail
| RxFIFOOver
))
586 RTLD(bug("[%s] RTL8168_IntHandlerF: Packet Reception detected!\n", unit
->rtl8168u_name
))
587 RTL8168_Rx_Process(unit
);
588 // rtl8168_rx_interrupt(unit, np, np->mmio_addr, ~(u32)0);
591 if (status
& (TxOK
| TxErr
))
593 RTLD(bug("[%s] RTL8168_IntHandlerF: Packet Transmission detected!\n", unit
->rtl8168u_name
))
594 RTL8168_Tx_Cleanup(unit
);
597 } while (boguscnt
> 0);
600 RTLD(bug("[%s] RTL8168_IntHandlerF: Too much work at interrupt!\n", unit
->rtl8168u_name
))
601 /* Clear all interrupt sources. */
602 RTL_W16(base
+ (IntrStatus
), 0xffff);
606 RTL_W16(base
+ (IntrMask
), np
->intr_mask
);
611 VOID
CopyPacket(struct RTL8168Base
*RTL8168DeviceBase
, struct RTL8168Unit
*unit
,
612 struct IOSana2Req
*request
, UWORD packet_size
, UWORD packet_type
,
613 struct eth_frame
*buffer
)
615 struct Opener
*opener
;
616 BOOL filtered
= FALSE
;
619 RTLD(bug("[%s] CopyPacket(packet @ %x, len = %d)\n", unit
->rtl8168u_name
, buffer
, packet_size
))
621 /* Set multicast and broadcast flags */
623 request
->ios2_Req
.io_Flags
&= ~(SANA2IOF_BCAST
| SANA2IOF_MCAST
);
624 if((*((ULONG
*)(buffer
->eth_packet_dest
)) == 0xffffffff) &&
625 (*((UWORD
*)(buffer
->eth_packet_dest
+ 4)) == 0xffff))
627 request
->ios2_Req
.io_Flags
|= SANA2IOF_BCAST
;
628 RTLD(bug("[%s] CopyPacket: BROADCAST Flag set\n", unit
->rtl8168u_name
))
630 else if((buffer
->eth_packet_dest
[0] & 0x1) != 0)
632 request
->ios2_Req
.io_Flags
|= SANA2IOF_MCAST
;
633 RTLD(bug("[%s] CopyPacket: MULTICAST Flag set\n", unit
->rtl8168u_name
))
636 /* Set source and destination addresses and packet type */
637 CopyMem(buffer
->eth_packet_source
, request
->ios2_SrcAddr
, ETH_ADDRESSSIZE
);
638 CopyMem(buffer
->eth_packet_dest
, request
->ios2_DstAddr
, ETH_ADDRESSSIZE
);
639 request
->ios2_PacketType
= packet_type
;
641 /* Adjust for cooked packet request */
643 if((request
->ios2_Req
.io_Flags
& SANA2IOF_RAW
) == 0)
645 packet_size
-= ETH_PACKET_DATA
;
646 ptr
= (UBYTE
*)&buffer
->eth_packet_data
[0];
650 ptr
= (UBYTE
*)buffer
;
653 request
->ios2_DataLength
= packet_size
;
655 RTLD(bug("[%s] CopyPacket: packet @ %x (%d bytes)\n", unit
->rtl8168u_name
, ptr
, packet_size
))
659 opener
= request
->ios2_BufferManagement
;
660 if((request
->ios2_Req
.io_Command
== CMD_READ
) &&
661 (opener
->filter_hook
!= NULL
))
662 if(!CallHookPkt(opener
->filter_hook
, request
, ptr
))
664 RTLD(bug("[%s] CopyPacket: packet filtered\n", unit
->rtl8168u_name
))
670 /* Copy packet into opener's buffer and reply packet */
671 RTLD(bug("[%s] CopyPacket: opener recieve packet .. ", unit
->rtl8168u_name
))
672 if(!opener
->rx_function(request
->ios2_Data
, ptr
, packet_size
))
674 RTLD(bug("ERROR occured!!\n"))
675 request
->ios2_Req
.io_Error
= S2ERR_NO_RESOURCES
;
676 request
->ios2_WireError
= S2WERR_BUFF_ERROR
;
677 ReportEvents(LIBBASE
, unit
, S2EVENT_ERROR
| S2EVENT_SOFTWARE
| S2EVENT_BUFF
| S2EVENT_RX
);
681 RTLD(bug("SUCCESS!!\n"))
684 Remove((APTR
)request
);
686 ReplyMsg((APTR
)request
);
687 RTLD(bug("[%s] CopyPacket: opener notified.\n", unit
->rtl8168u_name
))
691 BOOL
AddressFilter(struct RTL8168Base
*RTL8168DeviceBase
, struct RTL8168Unit
*unit
, UBYTE
*address
)
693 struct AddressRange
*range
, *tail
;
698 /* Check whether address is unicast/broadcast or multicast */
700 address_left
= AROS_BE2LONG(*((ULONG
*)address
));
701 address_right
= AROS_BE2WORD(*((UWORD
*)(address
+ 4)));
703 if((address_left
& 0x01000000) != 0 &&
704 !(address_left
== 0xffffffff && address_right
== 0xffff))
706 /* Check if this multicast address is wanted */
708 range
= (APTR
)unit
->rtl8168u_multicast_ranges
.mlh_Head
;
709 tail
= (APTR
)&unit
->rtl8168u_multicast_ranges
.mlh_Tail
;
712 while((range
!= tail
) && !accept
)
714 if((address_left
> range
->lower_bound_left
||
715 (address_left
== range
->lower_bound_left
&&
716 address_right
>= range
->lower_bound_right
)) &&
717 (address_left
< range
->upper_bound_left
||
718 (address_left
== range
->upper_bound_left
&&
719 address_right
<= range
->upper_bound_right
)))
721 range
= (APTR
)range
->node
.mln_Succ
;
725 unit
->rtl8168u_special_stats
[S2SS_ETHERNET_BADMULTICAST
& 0xffff]++;
733 AROS_UFH3(void, RTL8168_Schedular
,
734 AROS_UFHA(STRPTR
, argPtr
, A0
),
735 AROS_UFHA(ULONG
, argSize
, D0
),
736 AROS_UFHA(struct ExecBase
*, SysBase
, A6
))
740 struct Task
*taskSelf
= FindTask(NULL
);
741 struct RTL8168Startup
*sm_UD
= taskSelf
->tc_UserData
;
742 struct RTL8168Unit
*unit
= sm_UD
->rtl8168sm_Unit
;
744 LIBBASETYPEPTR LIBBASE
= unit
->rtl8168u_device
;
745 struct MsgPort
*reply_port
, *input
;
748 RTLD(bug("[%s] RTL8168_Schedular()\n", taskSelf
->tc_Node
.ln_Name
))
749 RTLD(bug("[%s] RTL8168_Schedular: Setting up device '%s'\n", taskSelf
->tc_Node
.ln_Name
, unit
->rtl8168u_name
))
751 if ((reply_port
= CreateMsgPort()) == NULL
)
753 RTLD(bug("[%s] RTL8168_Schedular: Failed to create Reply message port\n", taskSelf
->tc_Node
.ln_Name
))
756 if ((input
= CreateMsgPort()) == NULL
)
758 RTLD(bug("[%s] RTL8168_Schedular: Failed to create Input message port\n", taskSelf
->tc_Node
.ln_Name
))
761 unit
->rtl8168u_input_port
= input
;
763 /* Randomize the generator with current time */
764 if ((BattClockBase
= OpenResource("battclock.resource")) != NULL
)
766 srandom(ReadBattClock());
769 if ((unit
->rtl8168u_TimerSlowPort
= CreateMsgPort()) != NULL
)
771 unit
->rtl8168u_TimerSlowReq
= (struct timerequest
*)
772 CreateIORequest((struct MsgPort
*)unit
->rtl8168u_TimerSlowPort
, sizeof(struct timerequest
));
774 if (unit
->rtl8168u_TimerSlowReq
)
776 if (!OpenDevice("timer.device", UNIT_MICROHZ
,
777 (struct IORequest
*)unit
->rtl8168u_TimerSlowReq
, 0))
779 struct Message
*msg
= AllocVec(sizeof(struct Message
), MEMF_PUBLIC
|MEMF_CLEAR
);
782 RTLD(bug("[%s] RTL8168_Schedular: Got MICROHZ unit of timer.device\n", taskSelf
->tc_Node
.ln_Name
))
784 unit
->initialize(unit
);
786 msg
->mn_ReplyPort
= reply_port
;
787 msg
->mn_Length
= sizeof(struct Message
);
789 RTLD(bug("[%s] RTL8168_Schedular: Setup complete. Sending handshake\n", taskSelf
->tc_Node
.ln_Name
))
790 PutMsg(sm_UD
->rtl8168sm_SyncPort
, msg
);
791 WaitPort(reply_port
);
796 RTLD(bug("[%s] RTL8168_Schedular: entering forever loop ... \n", taskSelf
->tc_Node
.ln_Name
))
798 unit
->rtl8168u_signal_0
= AllocSignal(-1);
799 unit
->rtl8168u_signal_1
= AllocSignal(-1);
800 unit
->rtl8168u_signal_2
= AllocSignal(-1);
801 unit
->rtl8168u_signal_3
= AllocSignal(-1);
803 sigset
= 1 << input
->mp_SigBit
|
804 1 << unit
->rtl8168u_signal_0
|
805 1 << unit
->rtl8168u_signal_1
|
806 1 << unit
->rtl8168u_signal_2
|
807 1 << unit
->rtl8168u_signal_3
;
810 ULONG recvd
= Wait(sigset
);
811 if (recvd
& unit
->rtl8168u_signal_0
)
814 * Shutdown process. Driver should close everything
815 * already and waits for our process to complete. Free
816 * memory allocared here and kindly return.
818 unit
->deinitialize(unit
);
819 CloseDevice((struct IORequest
*)unit
->rtl8168u_TimerSlowReq
);
820 DeleteIORequest((struct IORequest
*)unit
->rtl8168u_TimerSlowReq
);
821 DeleteMsgPort(unit
->rtl8168u_TimerSlowPort
);
822 DeleteMsgPort(input
);
823 DeleteMsgPort(reply_port
);
825 RTLD(bug("[%s] RTL8168_Schedular: Process shutdown.\n", taskSelf
->tc_Node
.ln_Name
))
828 else if (recvd
& (1 << input
->mp_SigBit
))
830 struct IOSana2Req
*io
;
832 /* Handle incoming transactions */
833 while ((io
= (struct IOSana2Req
*)GetMsg(input
)) != NULL
)
835 RTLD(bug("[%s] RTL8168_Schedular: Handle incomming transaction.\n", taskSelf
->tc_Node
.ln_Name
))
836 ObtainSemaphore(&unit
->rtl8168u_unit_lock
);
837 handle_request(LIBBASE
, io
);
842 RTLD(bug("[%s] RTL8168_Schedular: Handle incomming signal.\n", taskSelf
->tc_Node
.ln_Name
))
843 /* Handle incoming signals */
853 static struct AddressRange
*FindMulticastRange(LIBBASETYPEPTR LIBBASE
, struct RTL8168Unit
*unit
,
854 ULONG lower_bound_left
, UWORD lower_bound_right
, ULONG upper_bound_left
, UWORD upper_bound_right
)
856 struct AddressRange
*range
, *tail
;
859 range
= (APTR
)unit
->rtl8168u_multicast_ranges
.mlh_Head
;
860 tail
= (APTR
)&unit
->rtl8168u_multicast_ranges
.mlh_Tail
;
862 while((range
!= tail
) && !found
)
864 if((lower_bound_left
== range
->lower_bound_left
) &&
865 (lower_bound_right
== range
->lower_bound_right
) &&
866 (upper_bound_left
== range
->upper_bound_left
) &&
867 (upper_bound_right
== range
->upper_bound_right
))
870 range
= (APTR
)range
->node
.mln_Succ
;
879 BOOL
AddMulticastRange(LIBBASETYPEPTR LIBBASE
, struct RTL8168Unit
*unit
, const UBYTE
*lower_bound
,
880 const UBYTE
*upper_bound
)
882 struct AddressRange
*range
;
883 ULONG lower_bound_left
, upper_bound_left
;
884 UWORD lower_bound_right
, upper_bound_right
;
886 lower_bound_left
= AROS_BE2LONG(*((ULONG
*)lower_bound
));
887 lower_bound_right
= AROS_BE2WORD(*((UWORD
*)(lower_bound
+ 4)));
888 upper_bound_left
= AROS_BE2LONG(*((ULONG
*)upper_bound
));
889 upper_bound_right
= AROS_BE2WORD(*((UWORD
*)(upper_bound
+ 4)));
891 range
= FindMulticastRange(LIBBASE
, unit
, lower_bound_left
, lower_bound_right
,
892 upper_bound_left
, upper_bound_right
);
898 range
= AllocMem(sizeof(struct AddressRange
), MEMF_PUBLIC
);
901 range
->lower_bound_left
= lower_bound_left
;
902 range
->lower_bound_right
= lower_bound_right
;
903 range
->upper_bound_left
= upper_bound_left
;
904 range
->upper_bound_right
= upper_bound_right
;
905 range
->add_count
= 1;
908 AddTail((APTR
)&unit
->rtl8168u_multicast_ranges
, (APTR
)range
);
911 if (unit
->rtl8168u_range_count
++ == 0)
913 unit
->rtl8168u_flags
|= IFF_ALLMULTI
;
914 unit
->set_multicast(unit
);
919 return range
!= NULL
;
922 BOOL
RemMulticastRange(LIBBASETYPEPTR LIBBASE
, struct RTL8168Unit
*unit
, const UBYTE
*lower_bound
, const UBYTE
*upper_bound
)
924 struct AddressRange
*range
;
925 ULONG lower_bound_left
, upper_bound_left
;
926 UWORD lower_bound_right
, upper_bound_right
;
928 lower_bound_left
= AROS_BE2LONG(*((ULONG
*)lower_bound
));
929 lower_bound_right
= AROS_BE2WORD(*((UWORD
*)(lower_bound
+ 4)));
930 upper_bound_left
= AROS_BE2LONG(*((ULONG
*)upper_bound
));
931 upper_bound_right
= AROS_BE2WORD(*((UWORD
*)(upper_bound
+ 4)));
933 range
= FindMulticastRange(LIBBASE
, unit
, lower_bound_left
, lower_bound_right
,
934 upper_bound_left
, upper_bound_right
);
938 if(--range
->add_count
== 0)
943 FreeMem(range
, sizeof(struct AddressRange
));
945 if (--unit
->rtl8168u_range_count
== 0)
947 unit
->rtl8168u_flags
&= ~IFF_ALLMULTI
;
948 unit
->set_multicast(unit
);
952 return range
!= NULL
;
956 * Create new RTL8168 ethernet device unit
958 struct RTL8168Unit
*CreateUnit(struct RTL8168Base
*RTL8168DeviceBase
, OOP_Object
*pciDevice
, IPTR CardRevision
)
960 struct RTL8168Unit
*unit
;
964 #if defined(RTL_DEBUG)
967 #warning "TODO: Get option to debug from somewhere .."
968 BOOL doDebug
= FALSE
;
973 bug("[rtl8168] CreateUnit()\n");
976 if ((unit
= AllocMem(sizeof(struct RTL8168Unit
), MEMF_PUBLIC
| MEMF_CLEAR
)) != NULL
)
978 IPTR DeviceID
, mmiobase
, mmiolen
, type
;
980 BOOL mmioerror
= FALSE
;
983 unit
->rtl8168u_flags
|= IFF_DEBUG
;
985 unit
->rtl8168u_UnitNum
= RTL8168DeviceBase
->rtl8168b_UnitCount
++;
987 unit
->rtl8168u_Sana2Info
.HardwareType
= S2WireType_Ethernet
;
988 unit
->rtl8168u_Sana2Info
.MTU
= ETH_MTU
;
989 unit
->rtl8168u_Sana2Info
.AddrFieldSize
= 8 * ETH_ADDRESSSIZE
;
991 unit
->rtl8168u_intr_mask
= SYSErr
| LinkChg
| RxDescUnavail
| TxErr
| TxOK
| RxErr
| RxOK
;
993 if ((unit
->rtl8168u_name
= AllocVec(8 + (unit
->rtl8168u_UnitNum
/10) + 2, MEMF_CLEAR
|MEMF_PUBLIC
)) == NULL
)
995 FreeMem(unit
, sizeof(struct RTL8168Unit
));
998 sprintf((char *)unit
->rtl8168u_name
, "rtl8168.%d", unit
->rtl8168u_UnitNum
);
1000 RTLD(bug("[rtl8168] CreateUnit: Unit allocated @ 0x%p\n", unit
))
1002 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Driver
, (APTR
)&driver
);
1004 unit
->rtl8168u_device
= RTL8168DeviceBase
;
1005 unit
->rtl8168u_PCIDevice
= pciDevice
;
1006 unit
->rtl8168u_PCIDriver
= driver
;
1008 unit
->rtl8168u_mtu
= unit
->rtl8168u_Sana2Info
.MTU
;
1010 InitSemaphore(&unit
->rtl8168u_unit_lock
);
1011 NEWLIST(&unit
->rtl8168u_Openers
);
1012 NEWLIST(&unit
->rtl8168u_multicast_ranges
);
1013 NEWLIST(&unit
->rtl8168u_type_trackers
);
1015 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_INTLine
, &unit
->rtl8168u_IRQ
);
1016 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Base0
, &unit
->rtl8168u_BaseIO
);
1017 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Base2
, &mmiobase
);
1018 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Size2
, &mmiolen
);
1019 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_Type2
, &type
);
1021 RTLD(bug("[%s] CreateUnit: INT:%d, base0:0x%p, base2:0x%p, size2:%d\n", unit
->rtl8168u_name
,
1022 unit
->rtl8168u_IRQ
, unit
->rtl8168u_BaseIO
,
1025 if (type
& ADDRF_IO
)
1027 RTLD(bug("[%s] CreateUnit: MMIO Region of wrong type!\n", unit
->rtl8168u_name
))
1031 if (mmiolen
< R8168_REGS_SIZE
)
1033 RTLD(bug("[%s] CreateUnit: Invalid MMIO Reg size (%d, expected %d)\n", unit
->rtl8168u_name
,
1041 FreeMem(unit
->rtl8168u_name
, 8 + (unit
->rtl8168u_UnitNum
/10) + 2);
1042 FreeMem(unit
, sizeof(struct RTL8168Unit
));
1046 #warning "TODO: how do we set memory write invalidate for PCI devices on AROS?"
1048 unit
->rtl8168u_SizeMem
= R8168_REGS_SIZE
;
1049 unit
->rtl8168u_BaseMem
= (IPTR
)HIDD_PCIDriver_MapPCI(driver
, (APTR
)mmiobase
, unit
->rtl8168u_SizeMem
);
1051 if (unit
->rtl8168u_BaseMem
!= NULL
)
1053 struct TagItem attrs
[] = {
1054 { aHidd_PCIDevice_isIO
, TRUE
},
1055 { aHidd_PCIDevice_isMEM
, TRUE
},
1056 { aHidd_PCIDevice_isMaster
, TRUE
},
1059 OOP_SetAttrs(pciDevice
, (struct TagItem
*)&attrs
);
1061 RTLD(bug("[%s] CreateUnit: PCI_BaseMem @ 0x%p\n", unit
->rtl8168u_name
, unit
->rtl8168u_BaseMem
))
1063 unit
->rtl8168u_DelayPort
.mp_SigBit
= SIGB_SINGLE
;
1064 unit
->rtl8168u_DelayPort
.mp_Flags
= PA_SIGNAL
;
1065 unit
->rtl8168u_DelayPort
.mp_SigTask
= FindTask(NULL
);
1066 unit
->rtl8168u_DelayPort
.mp_Node
.ln_Type
= NT_MSGPORT
;
1067 NEWLIST(&unit
->rtl8168u_DelayPort
.mp_MsgList
);
1069 unit
->rtl8168u_DelayReq
.tr_node
.io_Message
.mn_ReplyPort
= &unit
->rtl8168u_DelayPort
;
1070 unit
->rtl8168u_DelayReq
.tr_node
.io_Message
.mn_Length
= sizeof(struct timerequest
);
1072 OpenDevice((STRPTR
)"timer.device", UNIT_MICROHZ
, (struct IORequest
*)&unit
->rtl8168u_DelayReq
, 0);
1074 if ((unit
->rtl8168u_priv
= AllocMem(sizeof(struct rtl8168_priv
), MEMF_PUBLIC
|MEMF_CLEAR
)) != NULL
)
1076 unit
->rtl8168u_priv
->pci_dev
= unit
;
1077 InitSemaphore(&unit
->rtl8168u_priv
->lock
);
1079 unit
->rtl8168u_irqhandler
= AllocMem(sizeof(HIDDT_IRQ_Handler
), MEMF_PUBLIC
|MEMF_CLEAR
);
1080 unit
->rtl8168u_touthandler
= AllocMem(sizeof(HIDDT_IRQ_Handler
), MEMF_PUBLIC
|MEMF_CLEAR
);
1082 if ((unit
->rtl8168u_irqhandler
!= NULL
)
1083 && (unit
->rtl8168u_touthandler
!= NULL
))
1085 struct Message
*msg
;
1087 unit
->rtl8168u_irqhandler
->h_Node
.ln_Pri
= 100;
1088 unit
->rtl8168u_irqhandler
->h_Node
.ln_Name
= LIBBASE
->rtl8168b_Device
.dd_Library
.lib_Node
.ln_Name
;
1089 unit
->rtl8168u_irqhandler
->h_Code
= RTL8168_IntHandlerF
;
1090 unit
->rtl8168u_irqhandler
->h_Data
= unit
;
1092 unit
->rtl8168u_touthandler
->h_Node
.ln_Pri
= 100;
1093 unit
->rtl8168u_touthandler
->h_Node
.ln_Name
= LIBBASE
->rtl8168b_Device
.dd_Library
.lib_Node
.ln_Name
;
1094 unit
->rtl8168u_touthandler
->h_Code
= RTL8168_TimeoutHandlerF
;
1095 unit
->rtl8168u_touthandler
->h_Data
= unit
;
1097 unit
->rtl8168u_rx_int
.is_Node
.ln_Name
= unit
->rtl8168u_name
;
1098 //unit->rtl8168u_rx_int.is_Code = RTL8168_RX_IntF;
1099 unit
->rtl8168u_rx_int
.is_Data
= unit
;
1101 unit
->rtl8168u_tx_int
.is_Node
.ln_Name
= unit
->rtl8168u_name
;
1102 unit
->rtl8168u_tx_int
.is_Code
= RTL8168_TX_IntF
;
1103 unit
->rtl8168u_tx_int
.is_Data
= unit
;
1105 for (i
=0; i
< REQUEST_QUEUE_COUNT
; i
++)
1107 struct MsgPort
*port
= AllocMem(sizeof(struct MsgPort
), MEMF_PUBLIC
| MEMF_CLEAR
);
1108 unit
->rtl8168u_request_ports
[i
] = port
;
1110 if (port
== NULL
) success
= FALSE
;
1114 NEWLIST(&port
->mp_MsgList
);
1115 port
->mp_Flags
= PA_IGNORE
;
1116 port
->mp_SigTask
= &unit
->rtl8168u_tx_int
;
1120 unit
->rtl8168u_request_ports
[WRITE_QUEUE
]->mp_Flags
= PA_SOFTINT
;
1124 struct RTL8168Startup
*sm_UD
;
1127 if ((sm_UD
= AllocMem(sizeof(struct RTL8168Startup
), MEMF_PUBLIC
| MEMF_CLEAR
)) != NULL
)
1129 sprintf((char *)tmpbuff
, RTL8168_TASK_NAME
, unit
->rtl8168u_name
);
1131 sm_UD
->rtl8168sm_SyncPort
= CreateMsgPort();
1132 sm_UD
->rtl8168sm_Unit
= unit
;
1134 rtl8168nic_get_functions(unit
);
1136 unit
->rtl8168u_Process
= CreateNewProcTags(
1137 NP_Entry
, (IPTR
)RTL8168_Schedular
,
1139 NP_Synchronous
, FALSE
,
1141 NP_UserData
, (IPTR
)sm_UD
,
1142 NP_StackSize
, 140960,
1145 WaitPort(sm_UD
->rtl8168sm_SyncPort
);
1146 msg
= GetMsg(sm_UD
->rtl8168sm_SyncPort
);
1148 DeleteMsgPort(sm_UD
->rtl8168sm_SyncPort
);
1149 FreeMem(sm_UD
, sizeof(struct RTL8168Startup
));
1151 RTLD(bug("[%s] CreateUnit: Device Initialised. Unit %d @ %p\n", unit
->rtl8168u_name
, unit
->rtl8168u_UnitNum
, unit
))
1157 RTLD(bug("[%s] ERRORS occured during Device setup - ABORTING\n", unit
->rtl8168u_name
))
1164 RTLD(bug("[rtl8168] PANIC! Couldn't get MMIO area. Aborting\n"))
1169 bug("[rtl8168] CreateUnit: Failed to Allocate Unit storage!\n");
1172 DeleteUnit(RTL8168DeviceBase
, unit
);
1177 * DeleteUnit - removes selected unit. Frees all resources and structures.
1179 * The caller should be sure, that given unit is really ready to be freed.
1182 void DeleteUnit(struct RTL8168Base
*RTL8168DeviceBase
, struct RTL8168Unit
*Unit
)
1187 if (Unit
->rtl8168u_Process
)
1189 Signal(&Unit
->rtl8168u_Process
->pr_Task
, Unit
->rtl8168u_signal_0
);
1192 for (i
=0; i
< REQUEST_QUEUE_COUNT
; i
++)
1194 if (Unit
->rtl8168u_request_ports
[i
] != NULL
)
1195 FreeMem(Unit
->rtl8168u_request_ports
[i
], sizeof(struct MsgPort
));
1197 Unit
->rtl8168u_request_ports
[i
] = NULL
;
1200 if (Unit
->rtl8168u_irqhandler
)
1202 FreeMem(Unit
->rtl8168u_irqhandler
, sizeof(HIDDT_IRQ_Handler
));
1205 if (Unit
->rtl8168u_priv
)
1207 FreeMem(Unit
->rtl8168u_priv
, sizeof(struct rtl8168_priv
));
1208 Unit
->rtl8168u_priv
= NULL
;
1211 if (Unit
->rtl8168u_BaseMem
)
1213 HIDD_PCIDriver_UnmapPCI(Unit
->rtl8168u_PCIDriver
,
1214 (APTR
)Unit
->rtl8168u_BaseMem
,
1215 Unit
->rtl8168u_SizeMem
);
1218 FreeMem(Unit
, sizeof(struct RTL8168Unit
));