revert between 56095 -> 55830 in arch
[AROS.git] / workbench / devs / networks / fec / fec_init.c
blobe3d3c1131d521e0a66230cf7690887e416c365d3
1 /*
2 * fec_init.c
4 * Created on: May 14, 2009
5 * Author: misc
6 */
8 #define DEBUG 1
9 #include <aros/debug.h>
10 #include <aros/libcall.h>
11 #include <aros/symbolsets.h>
13 #include <exec/memory.h>
14 #include <exec/io.h>
15 #include <exec/errors.h>
16 #include <exec/devices.h>
17 #include <exec/ports.h>
19 #include <utility/tagitem.h>
21 #include <devices/sana2.h>
22 #include <devices/sana2specialstats.h>
24 #include <proto/openfirmware.h>
25 #include <proto/exec.h>
26 #include <proto/utility.h>
28 #include <inttypes.h>
30 #include "fec.h"
32 #include LC_LIBDEFS_FILE
34 typedef struct {
35 uint8_t b[6];
36 } mac_addr_t;
38 typedef struct {
39 intptr_t addr;
40 intptr_t size;
41 } reg_t;
43 static int FEC_Init(struct FECBase *FECBase)
45 int retval = FALSE;
46 void *OpenFirmwareBase = NULL;
47 fec_t *fec = NULL;
49 D(bug("[FEC] Fast Ethernet Controller Init.\n"));
51 OpenFirmwareBase = OpenResource("openfirmware.resource");
53 if (OpenFirmwareBase)
55 void *key, *prop;
57 key = OF_OpenKey("/builtin/ethernet");
59 if (key)
61 prop = OF_FindProperty(key, "reg");
63 if (prop)
65 reg_t *reg = OF_GetPropValue(prop);
66 fec = (fec_t *)reg->addr;
68 D(bug("[FEC] FEC registers at %08x\n", fec));
70 prop = OF_FindProperty(key, "mac-address");
72 if (prop)
74 FECBase->feb_Pool = CreatePool(MEMF_CLEAR | MEMF_PUBLIC | MEMF_SEM_PROTECTED, 8192, 4096);
76 if (FECBase->feb_Pool)
78 if (FEC_CreateUnit(FECBase, fec))
80 mac_addr_t *mac = OF_GetPropValue(prop);
81 D(bug("[FEC] MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
82 mac->b[0], mac->b[1], mac->b[2], mac->b[3], mac->b[4], mac->b[5]));
84 FECBase->feb_Unit->feu_OrgAddr[0] = mac->b[0];
85 FECBase->feb_Unit->feu_OrgAddr[1] = mac->b[1];
86 FECBase->feb_Unit->feu_OrgAddr[2] = mac->b[2];
87 FECBase->feb_Unit->feu_OrgAddr[3] = mac->b[3];
88 FECBase->feb_Unit->feu_OrgAddr[4] = mac->b[4];
89 FECBase->feb_Unit->feu_OrgAddr[5] = mac->b[5];
91 retval = TRUE;
93 else
95 D(bug("[FEC] Failed to create the unit\n"));
97 DeletePool(FECBase->feb_Pool);
104 else
106 bug("[FEC] OpenFirmware not found. Aborting.\n");
109 return retval;
113 static const uintptr_t rx_tags[] = {
114 S2_CopyToBuff,
115 S2_CopyToBuff16
118 static const uintptr_t tx_tags[] = {
119 S2_CopyFromBuff,
120 S2_CopyFromBuff16,
121 S2_CopyFromBuff32
125 * Open device handles currently only one pcnet32 unit.
127 static int FEC_Open(struct FECBase *FECBase, struct IOSana2Req* req, ULONG unitnum, ULONG flags)
129 struct TagItem *tags;
130 struct FECUnit *unit = NULL;
131 struct Opener *opener;
132 BYTE error=0;
133 int i;
135 D(bug("[FEC] OpenDevice(%d)\n", unitnum));
137 req->ios2_Req.io_Unit = NULL;
138 tags = req->ios2_BufferManagement;
140 req->ios2_BufferManagement = NULL;
142 /* Check request size */
144 if(req->ios2_Req.io_Message.mn_Length < sizeof(struct IOSana2Req))
145 error = IOERR_OPENFAIL;
147 if ((error != 0) || (unitnum > 1))
149 error = IOERR_OPENFAIL;
151 else
153 unit = FECBase->feb_Unit;
154 req->ios2_Req.io_Unit = &unit->feu_Unit;
157 /* Handle device sharing */
158 if(error == 0)
160 if(unit->feu_OpenCount != 0 && ((unit->feu_Flags & IFF_SHARED) == 0 ||
161 (flags & SANA2OPF_MINE) != 0))
162 error = IOERR_UNITBUSY;
163 else
164 unit->feu_OpenCount++;
167 if(error == 0)
169 if((flags & SANA2OPF_MINE) == 0)
170 unit->feu_Flags |= IFF_SHARED;
171 else if((flags & SANA2OPF_PROM) != 0)
172 unit->feu_Flags |= IFF_PROMISC;
174 /* Set up buffer-management structure and get hooks */
175 opener = AllocVecPooled(FECBase->feb_Pool, sizeof(struct Opener));
176 req->ios2_BufferManagement = (APTR)opener;
178 if(opener == NULL)
179 error = IOERR_OPENFAIL;
182 if(error == 0)
184 NEWLIST(&opener->read_port.mp_MsgList);
185 opener->read_port.mp_Flags = PA_IGNORE;
186 NEWLIST((APTR)&opener->initial_stats);
188 for(i = 0; i < 2; i++)
189 opener->rx_function = (APTR)GetTagData(rx_tags[i], (IPTR)opener->rx_function, tags);
190 for(i = 0; i < 3; i++)
191 opener->tx_function = (APTR)GetTagData(tx_tags[i], (IPTR)opener->tx_function, tags);
193 opener->filter_hook = (APTR)GetTagData(S2_PacketFilter, 0, tags);
195 Disable();
196 AddTail((APTR)&unit->feu_Openers, (APTR)opener);
197 Enable();
200 if (error != 0)
201 CloseDevice((struct IORequest *)req);
202 else
203 unit->start(unit);
205 req->ios2_Req.io_Error = error;
206 return (error !=0) ? FALSE : TRUE;
209 static int FEC_Close(struct FECBase *FECBase, struct IOSana2Req* req)
211 struct FECUnit *unit = (struct FECUnit *)req->ios2_Req.io_Unit;
212 struct Opener *opener;
214 if (unit)
216 D(bug("[FEC] CloseDevice\n"));
218 unit->stop(unit);
220 opener = (APTR)req->ios2_BufferManagement;
221 if (opener != NULL)
223 Disable();
224 Remove((struct Node *)opener);
225 Enable();
226 FreeVecPooled(FECBase->feb_Pool, opener);
230 return TRUE;
233 ADD2INITLIB(FEC_Init,0)
234 ADD2OPENDEV(FEC_Open,0)
235 ADD2CLOSEDEV(FEC_Close,0)
237 AROS_LH1(void, beginio,
238 AROS_LHA(struct IOSana2Req *, req, A1),
239 LIBBASETYPEPTR, LIBBASE, 5, FEC)
241 AROS_LIBFUNC_INIT
243 struct FECUnit *unit;
245 req->ios2_Req.io_Error = 0;
246 unit = (APTR)req->ios2_Req.io_Unit;
248 if (unit)
250 D(bug("[FEC] BeginIO\n"));
252 if (AttemptSemaphore(&unit->feu_Lock))
254 handle_request(LIBBASE, req);
256 else
258 req->ios2_Req.io_Flags &= ~IOF_QUICK;
259 PutMsg(unit->feu_InputPort, (struct Message *)req);
263 AROS_LIBFUNC_EXIT
266 AROS_LH1(LONG, abortio,
267 AROS_LHA(struct IOSana2Req *, req, A1),
268 LIBBASETYPEPTR, LIBBASE, 6, FEC)
270 AROS_LIBFUNC_INIT
272 struct FECUnit *unit;
273 unit = (APTR)req->ios2_Req.io_Unit;
275 if (unit)
277 D(bug("[FEC] AbortIO\n"));
279 Disable();
280 if ((req->ios2_Req.io_Message.mn_Node.ln_Type == NT_MESSAGE) &&
281 (req->ios2_Req.io_Flags & IOF_QUICK) == 0)
283 Remove((struct Node *)req);
284 req->ios2_Req.io_Error = IOERR_ABORTED;
285 req->ios2_WireError = S2WERR_GENERIC_ERROR;
286 ReplyMsg((struct Message *)req);
288 Enable();
291 return 0;
293 AROS_LIBFUNC_EXIT