New WPA-capable version of prism2.device.
[AROS.git] / workbench / devs / networks / prism2 / prometheus.c
blobfaf255a9169e2a3a565fef8dc81d90801808a730
1 /*
3 Copyright (C) 2004-2012 Neil Cafferkey
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,
18 MA 02111-1307, USA.
23 #include <exec/types.h>
24 #include <libraries/prometheus.h>
26 #include <proto/exec.h>
27 #include <proto/prometheus.h>
29 #include "pci.h"
30 #include "plx9052.h"
31 #include "prism2.h"
33 #include "pci_protos.h"
34 #include "prometheus_protos.h"
35 #include "timer_protos.h"
38 /****i* prism2.device/GetPrometheusCount ***********************************
40 * NAME
41 * GetPrometheusCount
43 * SYNOPSIS
44 * count = GetPrometheusCount()
46 * ULONG GetPrometheusCount();
48 ****************************************************************************
52 ULONG GetPrometheusCount(struct DevBase *base)
54 ULONG count = 0;
55 PCIBoard *card = NULL;
56 UPINT vendor_id, product_id;
58 while((card = Prm_FindBoardTagList(card, NULL)) != NULL)
60 Prm_GetBoardAttrsTags(card, PRM_Vendor, (UPINT)&vendor_id,
61 PRM_Device, (UPINT)&product_id, TAG_END);
62 if(IsCardCompatible(vendor_id, product_id, base))
63 count++;
66 return count;
71 /****i* prism2.device/AllocPrometheusCard **********************************
73 * NAME
74 * AllocPrometheusCard -- Create a unit.
76 * SYNOPSIS
77 * context = AllocPrometheusCard(index)
79 * struct BusContext *AllocPrometheusCard(ULONG);
81 ****************************************************************************
85 struct BusContext *AllocPrometheusCard(ULONG index, struct DevBase *base)
87 BOOL success = TRUE;
88 struct BusContext *context;
89 PCIBoard *card = NULL;
90 UWORD i = 0;
91 UPINT vendor_id, product_id, plx_base, int_reg;
92 UBYTE io_range_no;
93 ULONG value;
94 volatile UBYTE *cor_reg;
96 /* Find a compatible card */
98 context = AllocMem(sizeof(struct BusContext), MEMF_PUBLIC | MEMF_CLEAR);
99 if(context == NULL)
100 success = FALSE;
102 if(success)
104 while(i <= index)
106 card = Prm_FindBoardTagList(card, NULL);
107 Prm_GetBoardAttrsTags(card, PRM_Vendor, (UPINT)&vendor_id,
108 PRM_Device, (UPINT)&product_id, TAG_END);
109 if(IsCardCompatible(vendor_id, product_id, base))
110 i++;
113 context->card = card;
114 if(card == NULL)
115 success = FALSE;
118 if(success)
120 /* Find out what type of Prism II PCI card this is */
122 context->bus_type = GetBusType(product_id, base);
124 if(context->bus_type == TMD_BUS)
126 /* Enable the PCCard */
128 Prm_GetBoardAttrsTags(card, PRM_MemoryAddr1, (UPINT)&cor_reg,
129 TAG_END);
130 BYTEOUT((UPINT)cor_reg, COR_RESET);
131 BusyMilliDelay(RESET_DELAY, base);
132 BYTEOUT((UPINT)cor_reg, COR_ENABLE);
133 BusyMilliDelay(RESET_DELAY, base);
134 io_range_no = 2;
136 else if(context->bus_type == PLX_BUS)
138 /* Reset and enable the PCCard */
140 Prm_GetBoardAttrsTags(card, PRM_MemoryAddr2, (UPINT)&cor_reg,
141 TAG_END);
142 cor_reg += 0x3e0;
143 *cor_reg = COR_ENABLE;
144 BusyMilliDelay(RESET_DELAY, base);
146 /* Enable interrupts on the bridge */
148 Prm_GetBoardAttrsTags(card, PRM_MemoryAddr1, (UPINT)&plx_base,
149 TAG_END);
150 int_reg = plx_base + PLX9052_INTS;
151 value = LELONGIN(int_reg);
152 LELONGOUT(int_reg, value | (1 << 6));
153 if((LELONGIN(int_reg) & (1 << 6)) == 0)
154 success = FALSE;
155 io_range_no = 3;
157 else
158 io_range_no = 0;
160 /* Get the I/O base of the wireless chip */
162 Prm_GetBoardAttrsTags(card, PRM_MemoryAddr0 + io_range_no,
163 (UPINT)&context->io_base, TAG_END);
164 if(context->io_base == 0)
165 success = FALSE;
167 if(context->bus_type == PCI_BUS)
169 /* Reset and enable the card */
171 cor_reg = (volatile UBYTE *)context->io_base + (P2_REG_PCICOR * 2);
172 *cor_reg = COR_RESET;
173 BusyMilliDelay(250, base);
174 *cor_reg = 0;
175 BusyMilliDelay(500, base);
179 /* Lock card */
181 if(success)
183 if(!Prm_SetBoardAttrsTags(card, PRM_BoardOwner, (UPINT)base, TAG_END))
184 success = FALSE;
187 if(!success)
189 FreePrometheusCard(context, base);
190 context = NULL;
193 return context;
198 /****i* prism2.device/FreePrometheusCard ***********************************
200 * NAME
201 * FreePrometheusCard
203 * SYNOPSIS
204 * FreePrometheusCard(context)
206 * VOID FreePrometheusCard(struct BusContext *);
208 ****************************************************************************
212 VOID FreePrometheusCard(struct BusContext *context, struct DevBase *base)
214 PCIBoard *card;
215 ULONG value;
216 UPINT plx_base, int_reg;
217 volatile UBYTE *cor_reg;
218 APTR owner;
220 if(context != NULL)
222 card = context->card;
223 if(card != NULL)
225 if(context->bus_type == TMD_BUS)
227 /* Disable the PCCard */
229 Prm_GetBoardAttrsTags(card, PRM_MemoryAddr1, (UPINT)&cor_reg,
230 TAG_END);
231 BYTEOUT((UPINT)cor_reg, 0);
233 else if(context->bus_type == PLX_BUS)
235 /* Disable interrupts on the bridge */
237 Prm_GetBoardAttrsTags(card, PRM_MemoryAddr1, (UPINT)&plx_base,
238 TAG_END);
239 int_reg = plx_base + PLX9052_INTS;
240 value = LELONGIN(int_reg);
241 LELONGOUT(int_reg, value & ~(1 << 6));
243 /* Disable the PCCard */
245 Prm_GetBoardAttrsTags(card, PRM_MemoryAddr2, (UPINT)&cor_reg,
246 TAG_END);
247 cor_reg += 0x3e0;
248 *cor_reg = COR_RESET;
249 BusyMilliDelay(250, base);
250 *cor_reg = 0;
253 /* Unlock board */
255 Prm_GetBoardAttrsTags(card, PRM_BoardOwner, (UPINT)&owner,
256 TAG_END);
257 if(owner == base)
258 Prm_SetBoardAttrsTags(card, PRM_BoardOwner, NULL, TAG_END);
261 FreeMem(context, sizeof(struct BusContext));
264 return;
269 /****i* prism2.device/AddPrometheusIntServer *******************************
271 * NAME
272 * AddPrometheusIntServer
274 * SYNOPSIS
275 * success = AddPrometheusIntServer(card, interrupt)
277 * BOOL AddPrometheusIntServer(APTR, struct Interrupt *);
279 ****************************************************************************
283 BOOL AddPrometheusIntServer(APTR card, struct Interrupt *interrupt,
284 struct DevBase *base)
286 return Prm_AddIntServer(card, interrupt);
291 /****i* prism2.device/RemPrometheusIntServer *******************************
293 * NAME
294 * RemPrometheusIntServer
296 * SYNOPSIS
297 * RemPrometheusIntServer(card, interrupt)
299 * VOID RemPrometheusIntServer(APTR, struct Interrupt *);
301 ****************************************************************************
305 VOID RemPrometheusIntServer(APTR card, struct Interrupt *interrupt,
306 struct DevBase *base)
308 Prm_RemIntServer(card, interrupt);
310 return;