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/errors.h>
26 #include <exec/lists.h>
28 #include <aros/libcall.h>
29 #include <aros/symbolsets.h>
33 #include <devices/sana2.h>
34 #include <devices/sana2specialstats.h>
36 #include <utility/utility.h>
37 #include <utility/tagitem.h>
38 #include <utility/hooks.h>
42 #include <proto/oop.h>
43 #include <proto/exec.h>
44 #include <proto/utility.h>
46 #include "via-rhine.h"
48 #include LC_LIBDEFS_FILE
50 AROS_UFH3(void, Enumerator
,
51 AROS_UFHA(struct Hook
*, hook
, A0
),
52 AROS_UFHA(OOP_Object
*, pciDevice
, A2
),
53 AROS_UFHA(APTR
, message
, A1
))
57 D(bug("[VIA-RHINE] init.PCI_Enumerator()\n"));
59 LIBBASETYPEPTR LIBBASE
= (LIBBASETYPEPTR
)hook
->h_Data
;
61 BOOL FoundCompatNIC
= FALSE
;
62 IPTR DeviceID
, VendorID
, RevisionID
, CardCapabilities
;
63 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_VendorID
, &VendorID
);
64 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_ProductID
, &DeviceID
);
65 OOP_GetAttr(pciDevice
, aHidd_PCIDevice_RevisionID
, &RevisionID
);
68 if (DeviceID
== 0x6100)
70 FoundCompatNIC
= TRUE
;
71 CardCapabilities
= RTLc_CanHaveMII
;
72 CardName
= "VIA VT86C100A Rhine-II";
74 else if (DeviceID
== 0x3043)
76 FoundCompatNIC
= TRUE
;
77 CardCapabilities
= RTLc_CanHaveMII
;
78 CardName
= "VIA VT3042 Rhine";
80 else if (DeviceID
== 0x3065)
82 FoundCompatNIC
= TRUE
;
83 CardCapabilities
= RTLc_CanHaveMII
;
84 CardName
= "VIA VT6102 Rhine-II/VT6103 Tahoe 10/100M Fast Ethernet Adapter";
86 else if (DeviceID
== 0x3106)
88 FoundCompatNIC
= TRUE
;
89 CardCapabilities
= RTLc_CanHaveMII
;
90 CardName
= "VIA VT6105 Rhine-III Management Adapter";
92 else if (DeviceID
== 0x3053)
94 FoundCompatNIC
= TRUE
;
95 CardCapabilities
= RTLc_CanHaveMII
;
96 CardName
= "VIA VT6105M Rhine-III Management Adapter";
101 D(bug("[VIA-RHINE] Found %s NIC, PCI_ID %04x:%04x Rev:%d\n", CardName
, VendorID
, DeviceID
, RevisionID
));
103 struct VIARHINEUnit
*unit
= CreateUnit(LIBBASE
, pciDevice
, CardCapabilities
, CardName
);
104 LIBBASE
->rhineb_unit
= unit
;
106 D(bug("%s %s NIC I/O MEM @ %08x\n", unit
->rhineu_name
, unit
->rhineu_cardname
, unit
->rhineu_BaseMem
));
112 static int GM_UNIQUENAME(Init
)(LIBBASETYPEPTR LIBBASE
)
114 D(bug("[VIA-RHINE] init.Init()\n"));
116 if (FindTask(VIARHINE_TASK_NAME
) != NULL
)
118 D(bug("[VIA-RHINE] device already up and running.\n"));
122 LIBBASE
->rhineb_Sana2Info
.HardwareType
= S2WireType_Ethernet
;
123 LIBBASE
->rhineb_Sana2Info
.MTU
= ETH_MTU
;
124 LIBBASE
->rhineb_Sana2Info
.AddrFieldSize
= 8 * ETH_ADDRESSSIZE
;
126 LIBBASE
->rhineb_pciDeviceAttrBase
= OOP_ObtainAttrBase(IID_Hidd_PCIDevice
);
128 if (LIBBASE
->rhineb_pciDeviceAttrBase
!= 0)
130 D(bug("[VIA-RHINE] Got HiddPCIDeviceAttrBase\n"));
132 LIBBASE
->rhineb_pci
= OOP_NewObject(NULL
, CLID_Hidd_PCI
, NULL
);
134 if (LIBBASE
->rhineb_pci
)
136 D(bug("[VIA-RHINE] Got PCI object\n"));
138 struct Hook FindHook
= {
139 h_Entry
: (IPTR (*)())Enumerator
,
143 struct TagItem Requirements
[] = {
144 { tHidd_PCI_VendorID
, 0x1106 },
148 HIDD_PCI_EnumDevices( LIBBASE
->rhineb_pci
,
150 (struct TagItem
*)&Requirements
153 if (LIBBASE
->rhineb_unit
)
163 static int GM_UNIQUENAME(Expunge
)(LIBBASETYPEPTR LIBBASE
)
165 D(bug("[VIA-RHINE] init.Expunge\n"));
167 if (LIBBASE
->rhineb_unit
)
169 DeleteUnit(LIBBASE
, LIBBASE
->rhineb_unit
);
170 LIBBASE
->rhineb_unit
= NULL
;
173 if (LIBBASE
->rhineb_pciDeviceAttrBase
!= 0)
174 OOP_ReleaseAttrBase(IID_Hidd_PCIDevice
);
176 LIBBASE
->rhineb_pciDeviceAttrBase
= 0;
178 if (LIBBASE
->rhineb_pci
!= NULL
)
179 OOP_DisposeObject(LIBBASE
->rhineb_pci
);
184 static const ULONG rx_tags
[] = {
189 static const ULONG tx_tags
[] = {
196 * Open device handles currently only one pcnet32 unit.
198 static int GM_UNIQUENAME(Open
)
200 LIBBASETYPEPTR LIBBASE
,
201 struct IOSana2Req
* req
,
206 struct TagItem
*tags
;
207 struct VIARHINEUnit
*unit
= LIBBASE
->rhineb_unit
;
208 struct Opener
*opener
;
212 D(bug("[VIA-RHINE] init.OpenDevice\n"));
214 req
->ios2_Req
.io_Unit
= NULL
;
215 tags
= req
->ios2_BufferManagement
;
217 req
->ios2_BufferManagement
= NULL
;
219 /* Check request size */
221 if(req
->ios2_Req
.io_Message
.mn_Length
< sizeof(struct IOSana2Req
))
222 error
= IOERR_OPENFAIL
;
224 /* Get the requested unit */
225 if((error
== 0) && (unitnum
== 0))
227 req
->ios2_Req
.io_Unit
= (APTR
)unit
;
229 else error
= IOERR_OPENFAIL
;
231 /* Handle device sharing */
235 if(unit
->rhineu_open_count
!= 0 && ((unit
->rhineu_flags
& IFF_SHARED
) == 0 ||
236 (flags
& SANA2OPF_MINE
) != 0))
237 error
= IOERR_UNITBUSY
;
238 unit
->rhineu_open_count
++;
243 if((flags
& SANA2OPF_MINE
) == 0)
244 unit
->rhineu_flags
|= IFF_SHARED
;
245 else if((flags
& SANA2OPF_PROM
) != 0)
246 unit
->rhineu_flags
|= IFF_PROMISC
;
248 /* Set up buffer-management structure and get hooks */
249 opener
= AllocVec(sizeof(struct Opener
), MEMF_PUBLIC
| MEMF_CLEAR
);
250 req
->ios2_BufferManagement
= (APTR
)opener
;
253 error
= IOERR_OPENFAIL
;
258 NEWLIST(&opener
->read_port
.mp_MsgList
);
259 opener
->read_port
.mp_Flags
= PA_IGNORE
;
260 NEWLIST((APTR
)&opener
->initial_stats
);
262 for(i
= 0; i
< 2; i
++)
263 opener
->rx_function
= (APTR
)GetTagData(rx_tags
[i
], (IPTR
)opener
->rx_function
, tags
);
264 for(i
= 0; i
< 3; i
++)
265 opener
->tx_function
= (APTR
)GetTagData(tx_tags
[i
], (IPTR
)opener
->tx_function
, tags
);
267 opener
->filter_hook
= (APTR
)GetTagData(S2_PacketFilter
, 0, tags
);
270 AddTail((APTR
)&unit
->rhineu_Openers
, (APTR
)opener
);
275 CloseDevice((struct IORequest
*)req
);
279 req
->ios2_Req
.io_Error
= error
;
281 return (error
!=0) ? FALSE
: TRUE
;
284 static int GM_UNIQUENAME(Close
)
286 LIBBASETYPEPTR LIBBASE
,
287 struct IOSana2Req
* req
290 struct VIARHINEUnit
*unit
= LIBBASE
->rhineb_unit
;
291 struct Opener
*opener
;
293 D(bug("[VIA-RHINE] init.CloseDevice\n"));
297 opener
= (APTR
)req
->ios2_BufferManagement
;
301 Remove((struct Node
*)opener
);
310 ADD2INITLIB(GM_UNIQUENAME(Init
),0)
311 ADD2EXPUNGELIB(GM_UNIQUENAME(Expunge
),0)
312 ADD2OPENDEV(GM_UNIQUENAME(Open
),0)
313 ADD2CLOSEDEV(GM_UNIQUENAME(Close
),0)
315 AROS_LH1(void, beginio
,
316 AROS_LHA(struct IOSana2Req
*, req
, A1
),
317 LIBBASETYPEPTR
, LIBBASE
, 5, VIARHINEDev
)
320 struct VIARHINEUnit
*dev
;
322 D(bug("[VIA-RHINE] init.BeginIO\n"));
324 req
->ios2_Req
.io_Error
= 0;
325 dev
= (APTR
)req
->ios2_Req
.io_Unit
;
327 if (AttemptSemaphore(&dev
->rhineu_unit_lock
))
329 handle_request(LIBBASE
, req
);
333 req
->ios2_Req
.io_Flags
&= ~IOF_QUICK
;
334 PutMsg(dev
->rhineu_input_port
, (struct Message
*)req
);
340 AROS_LH1(LONG
, abortio
,
341 AROS_LHA(struct IOSana2Req
*, req
, A1
),
342 LIBBASETYPEPTR
, LIBBASE
, 6, VIARHINEDev
)
346 D(bug("[VIA-RHINE] init.AbortIO\n"));
349 if ((req
->ios2_Req
.io_Message
.mn_Node
.ln_Type
== NT_MESSAGE
) &&
350 (req
->ios2_Req
.io_Flags
& IOF_QUICK
) == 0)
352 Remove((struct Node
*)req
);
353 req
->ios2_Req
.io_Error
= IOERR_ABORTED
;
354 req
->ios2_WireError
= S2WERR_GENERIC_ERROR
;
355 ReplyMsg((struct Message
*)req
);