grub2: bring back build of aros-side grub2 tools
[AROS.git] / workbench / devs / networks / rtl8168 / rtl8168_init.c
blobe3e286ba4df45869c1ea021842ef6e46b320299e
1 /*
2 * $Id$
3 */
5 /*
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.
22 #include "rtl8168.h"
24 #include <exec/types.h>
25 #include <exec/resident.h>
26 #include <exec/io.h>
27 #include <exec/errors.h>
28 #include <exec/lists.h>
30 #include <aros/libcall.h>
31 #include <aros/symbolsets.h>
33 #include <oop/oop.h>
35 #include <devices/sana2.h>
36 #include <devices/sana2specialstats.h>
38 #include <utility/utility.h>
39 #include <utility/tagitem.h>
40 #include <utility/hooks.h>
42 #include <hidd/pci.h>
44 #include <proto/oop.h>
45 #include <proto/exec.h>
46 #include <proto/utility.h>
48 #include <stdio.h>
50 #include "unit.h"
51 #include LC_LIBDEFS_FILE
53 AROS_UFH3(void, PCI_Enumerator,
54 AROS_UFHA(struct Hook *, hook, A0),
55 AROS_UFHA(OOP_Object *, pciDevice, A2),
56 AROS_UFHA(APTR, message, A1))
58 AROS_USERFUNC_INIT
60 struct RTL8168Unit *unit = NULL;
61 IPTR RevisionID;
63 D(bug("[rtl8168] PCI_Enumerator(PCI Device Obj @ %p)\n", pciDevice));
65 LIBBASETYPEPTR LIBBASE = (LIBBASETYPEPTR)hook->h_Data;
67 OOP_GetAttr(pciDevice, aHidd_PCIDevice_RevisionID, &RevisionID);
69 D(bug("[rtl8168] PCI_Enumerator: Found RTL8168 NIC Rev:%d\n", RevisionID));
71 if ((LIBBASE->rtl8168b_UnitCount < MAX_UNITS) && ((unit = CreateUnit(LIBBASE, pciDevice, RevisionID)) != NULL))
73 AddTail(&LIBBASE->rtl8168b_Units, (struct Node *)&unit->rtl8168u_Node);
75 else if (LIBBASE->rtl8168b_UnitCount < MAX_UNITS)
77 D(bug("[rtl8168] PCI_Enumerator: Failed to create unit!\n"));
78 return;
80 else
82 D(bug("[rtl8168] PCI_Enumerator: Max supported units already reached\n"));
83 return;
85 RTLD(bug("[%s] PCI_Enumerator: %s NIC MMIO @ %p\n", unit->rtl8168u_name, unit->rtl8168u_rtl_chipname, unit->rtl8168u_BaseMem))
87 AROS_USERFUNC_EXIT
90 static int GM_UNIQUENAME(Init)(LIBBASETYPEPTR LIBBASE)
92 D(bug("[rtl8168] Init()\n"));
94 UBYTE tmpbuff[100];
95 int i;
97 sprintf((char *)tmpbuff, RTL8168_TASK_NAME, "rtl8168.0");
99 if (FindTask(tmpbuff) != NULL)
101 D(bug("[rtl8168] Init: Found Task '%s'! - Device already up and running.\n", tmpbuff));
102 return FALSE;
105 /* Load config options */
106 LIBBASE->rtl8168b_MaxIntWork = 20;
107 LIBBASE->rtl8168b_MulticastFilterLimit = 32;
109 for (i = 0; i < MAX_UNITS; i++)
111 LIBBASE->speed[i] = -1;
112 LIBBASE->duplex[i] = -1;
113 LIBBASE->autoneg[i] = -1;
116 NEWLIST(&LIBBASE->rtl8168b_Units);
118 LIBBASE->rtl8168b_PCIDeviceAttrBase = OOP_ObtainAttrBase(IID_Hidd_PCIDevice);
120 if (LIBBASE->rtl8168b_PCIDeviceAttrBase != 0)
122 D(bug("[rtl8168] Init: HiddPCIDeviceAttrBase @ %p\n", LIBBASE->rtl8168b_PCIDeviceAttrBase));
124 LIBBASE->rtl8168b_PCI = OOP_NewObject(NULL, CLID_Hidd_PCI, NULL);
126 if (LIBBASE->rtl8168b_PCI)
128 D(bug("[rtl8168] Init: PCI Subsystem HIDD object @ %p\n", LIBBASE->rtl8168b_PCI));
130 struct TagItem Requirements[] = {
131 {tHidd_PCI_VendorID, 0x10ec},
132 {tHidd_PCI_ProductID, 0x8168},
133 {TAG_DONE, 0x00}
136 struct Hook FindHook = {
137 h_Entry: (IPTR (*)())PCI_Enumerator,
138 h_Data: LIBBASE,
141 struct pHidd_PCI_EnumDevices enummsg = {
142 mID: OOP_GetMethodID(IID_Hidd_PCI, moHidd_PCI_EnumDevices),
143 callback: &FindHook,
144 requirements: (struct TagItem *)&Requirements,
145 }, *msg = &enummsg;
147 OOP_DoMethod(LIBBASE->rtl8168b_PCI, (OOP_Msg)msg);
149 if (!(IsListEmpty(&LIBBASE->rtl8168b_Units)))
151 return TRUE;
155 return FALSE;
158 static int GM_UNIQUENAME(Expunge)(LIBBASETYPEPTR LIBBASE)
160 D(bug("[rtl8168] Expunge()\n"));
162 struct RTL8168Unit *unit_current, *unit_tmp;
164 if (!(IsListEmpty(&LIBBASE->rtl8168b_Units)))
166 ForeachNodeSafe(&LIBBASE->rtl8168b_Units, unit_current, unit_tmp)
168 DeleteUnit(LIBBASE, unit_current);
172 if (LIBBASE->rtl8168b_PCIDeviceAttrBase != 0)
173 OOP_ReleaseAttrBase(IID_Hidd_PCIDevice);
175 LIBBASE->rtl8168b_PCIDeviceAttrBase = 0;
177 if (LIBBASE->rtl8168b_PCI != NULL)
178 OOP_DisposeObject(LIBBASE->rtl8168b_PCI);
180 return TRUE;
183 static const ULONG rx_tags[] = {
184 S2_CopyToBuff,
185 S2_CopyToBuff16
188 static const ULONG tx_tags[] = {
189 S2_CopyFromBuff,
190 S2_CopyFromBuff16,
191 S2_CopyFromBuff32
194 static int GM_UNIQUENAME(Open)
196 LIBBASETYPEPTR LIBBASE,
197 struct IOSana2Req* req,
198 ULONG unitnum,
199 ULONG flags
202 struct TagItem *tags;
203 struct RTL8168Unit *unit = NULL, *unit_current;
204 struct Opener *opener;
205 BYTE error=0;
206 int i;
208 if (!(IsListEmpty(&LIBBASE->rtl8168b_Units)))
210 ForeachNode(&LIBBASE->rtl8168b_Units, unit_current)
212 if (unit_current->rtl8168u_UnitNum == unitnum)
213 unit = unit_current;
217 D(bug("[rtl8168] OpenDevice(%d)\n", unitnum));
219 if (unit != NULL)
221 RTLD(bug("[%s] OpenDevice: Unit %d @ %p\n", unit->rtl8168u_name, unitnum, unit))
223 req->ios2_Req.io_Unit = NULL;
224 tags = req->ios2_BufferManagement;
226 req->ios2_BufferManagement = NULL;
228 /* Check request size */
229 if (req->ios2_Req.io_Message.mn_Length < sizeof(struct IOSana2Req))
230 error = IOERR_OPENFAIL;
232 /* Get the requested unit */
233 if (error == 0)
234 req->ios2_Req.io_Unit = (APTR)unit;
236 /* Handle device sharing */
237 if (error == 0)
239 if ((unit->rtl8168u_open_count != 0) &&
240 ((unit->rtl8168u_flags & IFF_SHARED) == 0 ||
241 (flags & SANA2OPF_MINE) != 0))
242 error = IOERR_UNITBUSY;
243 else
244 unit->rtl8168u_open_count++;
247 if (error == 0)
249 if ((flags & SANA2OPF_MINE) == 0)
250 unit->rtl8168u_flags |= IFF_SHARED;
251 else if ((flags & SANA2OPF_PROM) != 0)
252 unit->rtl8168u_flags |= IFF_PROMISC;
254 /* Set up buffer-management structure and get hooks */
255 opener = AllocVec(sizeof(struct Opener), MEMF_PUBLIC | MEMF_CLEAR);
256 req->ios2_BufferManagement = (APTR)opener;
258 if(opener == NULL)
259 error = IOERR_OPENFAIL;
262 if (error == 0)
264 NEWLIST(&opener->read_port.mp_MsgList);
265 opener->read_port.mp_Flags = PA_IGNORE;
266 NEWLIST((APTR)&opener->initial_stats);
268 for (i = 0; i < 2; i++)
269 opener->rx_function = (APTR)GetTagData(rx_tags[i], (IPTR)opener->rx_function, tags);
270 for (i = 0; i < 3; i++)
271 opener->tx_function = (APTR)GetTagData(tx_tags[i], (IPTR)opener->tx_function, tags);
273 opener->filter_hook = (APTR)GetTagData(S2_PacketFilter, 0, tags);
275 Disable();
276 AddTail((APTR)&unit->rtl8168u_Openers, (APTR)opener);
277 Enable();
280 if (error != 0)
281 CloseDevice((struct IORequest *)req);
282 else
283 unit->start(unit);
285 else
287 D(bug("[rtl8168] OpenDevice: Invalid Unit! (unitno = %d)\n", unitnum));
288 error = IOERR_OPENFAIL;
291 req->ios2_Req.io_Error = error;
293 return (error != 0) ? FALSE : TRUE;
296 static int GM_UNIQUENAME(Close)
298 LIBBASETYPEPTR LIBBASE,
299 struct IOSana2Req* req
302 struct RTL8168Unit *unit = (struct RTL8168Unit *)req->ios2_Req.io_Unit;
303 struct Opener *opener;
305 if ((unit = (struct RTL8168Unit *)req->ios2_Req.io_Unit) != NULL)
307 RTLD(bug("[rtl8168] CloseDevice(unit @ %p, unitno %d)\n", unit, unit->rtl8168u_UnitNum))
309 unit->stop(unit);
311 opener = (APTR)req->ios2_BufferManagement;
312 if (opener != NULL)
314 Disable();
315 Remove((struct Node *)opener);
316 Enable();
317 FreeVec(opener);
320 return TRUE;
324 ADD2INITLIB(GM_UNIQUENAME(Init),0)
325 ADD2EXPUNGELIB(GM_UNIQUENAME(Expunge),0)
326 ADD2OPENDEV(GM_UNIQUENAME(Open),0)
327 ADD2CLOSEDEV(GM_UNIQUENAME(Close),0)
329 AROS_LH1(void, BeginIO,
330 AROS_LHA(struct IOSana2Req *, req, A1),
331 LIBBASETYPEPTR, LIBBASE, 5, RTL8168Dev)
333 AROS_LIBFUNC_INIT
334 struct RTL8168Unit *unit;
336 D(bug("[rtl8168] BeginIO()\n"));
338 req->ios2_Req.io_Error = 0;
339 if ((unit = (struct RTL8168Unit *)req->ios2_Req.io_Unit) != NULL)
341 if (AttemptSemaphore(&unit->rtl8168u_unit_lock))
343 handle_request(LIBBASE, req);
345 else
347 req->ios2_Req.io_Flags &= ~IOF_QUICK;
348 PutMsg(unit->rtl8168u_input_port, (struct Message *)req);
351 else
353 D(bug("[rtl8168] BeginIO: Called with unit == NULL\n"));
356 AROS_LIBFUNC_EXIT
359 AROS_LH1(LONG, AbortIO,
360 AROS_LHA(struct IOSana2Req *, req, A1),
361 LIBBASETYPEPTR, LIBBASE, 6, RTL8168Dev)
363 AROS_LIBFUNC_INIT
364 struct RTL8168Unit *unit;
366 D(bug("[rtl8168] AbortIO()\n"));
368 if ((unit = (struct RTL8168Unit *)req->ios2_Req.io_Unit) != NULL)
370 Disable();
371 if ((req->ios2_Req.io_Message.mn_Node.ln_Type == NT_MESSAGE) &&
372 (req->ios2_Req.io_Flags & IOF_QUICK) == 0)
374 Remove((struct Node *)req);
375 req->ios2_Req.io_Error = IOERR_ABORTED;
376 req->ios2_WireError = S2WERR_GENERIC_ERROR;
377 ReplyMsg((struct Message *)req);
379 Enable();
381 return 0;
383 AROS_LIBFUNC_EXIT