1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
16
17#include <linux/netdevice.h>
18#include <linux/hdlc.h>
19#include <linux/if_arp.h>
20#include <asm/uaccess.h>
21#include <linux/rtnetlink.h>
22#include <linux/pci.h>
23#include "pmcc4_sysdep.h"
24#include "sbecom_inline_linux.h"
25#include "libsbew.h"
26#include "pmcc4_private.h"
27#include "pmcc4.h"
28#include "pmcc4_ioctls.h"
29#include "pmc93x6_eeprom.h"
30#ifdef CONFIG_PROC_FS
31#include "sbeproc.h"
32#endif
33
34extern int cxt1e1_log_level;
35extern int error_flag;
36extern int drvr_state;
37
38
39void c4_stopwd (ci_t *);
40struct net_device * __init c4_add_dev (hdw_info_t *, int, unsigned long, unsigned long, int, int);
41
42
43struct s_hdw_info hdw_info[MAX_BOARDS];
44
45
46void __init
47show_two (hdw_info_t *hi, int brdno)
48{
49 ci_t *ci;
50 struct pci_dev *pdev;
51 char *bid;
52 char *bp, banner[80];
53 char sn[6];
54
55 bp = banner;
56 memset (banner, 0, 80);
57
58 ci = (ci_t *)(netdev_priv(hi->ndev));
59 bid = sbeid_get_bdname (ci);
60 switch (hi->promfmt)
61 {
62 case PROM_FORMAT_TYPE1:
63 memcpy (sn, (FLD_TYPE1 *) (hi->mfg_info.pft1.Serial), 6);
64 break;
65 case PROM_FORMAT_TYPE2:
66 memcpy (sn, (FLD_TYPE2 *) (hi->mfg_info.pft2.Serial), 6);
67 break;
68 default:
69 memset (sn, 0, 6);
70 break;
71 }
72
73 sprintf (banner, "%s: %s S/N %06X, MUSYCC Rev %02X",
74 hi->devname, bid,
75 ((sn[3] << 16) & 0xff0000) |
76 ((sn[4] << 8) & 0x00ff00) |
77 (sn[5] & 0x0000ff),
78 (u_int8_t) hi->revid[0]);
79
80 pr_info("%s\n", banner);
81
82 pdev = hi->pdev[0];
83 pr_info("%s: %s at v/p=%lx/%lx (%02x:%02x.%x) irq %d\n",
84 hi->devname, "MUSYCC",
85 (unsigned long) hi->addr_mapped[0], hi->addr[0],
86 hi->pci_busno, (u_int8_t) PCI_SLOT (pdev->devfn),
87 (u_int8_t) PCI_FUNC (pdev->devfn), pdev->irq);
88
89 pdev = hi->pdev[1];
90 pr_info("%s: %s at v/p=%lx/%lx (%02x:%02x.%x) irq %d\n",
91 hi->devname, "EBUS ",
92 (unsigned long) hi->addr_mapped[1], hi->addr[1],
93 hi->pci_busno, (u_int8_t) PCI_SLOT (pdev->devfn),
94 (u_int8_t) PCI_FUNC (pdev->devfn), pdev->irq);
95}
96
97
98void __init
99hdw_sn_get (hdw_info_t *hi, int brdno)
100{
101
102 long addr;
103
104 addr = (long) hi->addr_mapped[1] + EEPROM_OFFSET;
105
106
107 pmc_eeprom_read_buffer (addr, 0, (char *) hi->mfg_info.data, sizeof (FLD_TYPE2));
108
109#if 0
110 {
111 unsigned char *ucp = (unsigned char *) &hi->mfg_info.data;
112
113 pr_info("eeprom[00]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
114 *(ucp + 0), *(ucp + 1), *(ucp + 2), *(ucp + 3), *(ucp + 4), *(ucp + 5), *(ucp + 6), *(ucp + 7));
115 pr_info("eeprom[08]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
116 *(ucp + 8), *(ucp + 9), *(ucp + 10), *(ucp + 11), *(ucp + 12), *(ucp + 13), *(ucp + 14), *(ucp + 15));
117 pr_info("eeprom[16]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
118 *(ucp + 16), *(ucp + 17), *(ucp + 18), *(ucp + 19), *(ucp + 20), *(ucp + 21), *(ucp + 22), *(ucp + 23));
119 pr_info("eeprom[24]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
120 *(ucp + 24), *(ucp + 25), *(ucp + 26), *(ucp + 27), *(ucp + 28), *(ucp + 29), *(ucp + 30), *(ucp + 31));
121 pr_info("eeprom[32]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
122 *(ucp + 32), *(ucp + 33), *(ucp + 34), *(ucp + 35), *(ucp + 36), *(ucp + 37), *(ucp + 38), *(ucp + 39));
123 pr_info("eeprom[40]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
124 *(ucp + 40), *(ucp + 41), *(ucp + 42), *(ucp + 43), *(ucp + 44), *(ucp + 45), *(ucp + 46), *(ucp + 47));
125 }
126#endif
127#if 0
128 pr_info("sn: %x %x %x %x %x %x\n",
129 hi->mfg_info.Serial[0],
130 hi->mfg_info.Serial[1],
131 hi->mfg_info.Serial[2],
132 hi->mfg_info.Serial[3],
133 hi->mfg_info.Serial[4],
134 hi->mfg_info.Serial[5]);
135#endif
136
137 if ((hi->promfmt = pmc_verify_cksum (&hi->mfg_info.data)) == PROM_FORMAT_Unk)
138 {
139
140 if (cxt1e1_log_level >= LOG_WARN)
141 pr_info("%s: EEPROM cksum error\n", hi->devname);
142 hi->mfg_info_sts = EEPROM_CRCERR;
143 } else
144 hi->mfg_info_sts = EEPROM_OK;
145}
146
147
148void __init
149prep_hdw_info (void)
150{
151 hdw_info_t *hi;
152 int i;
153
154 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
155 {
156 hi->pci_busno = 0xff;
157 hi->pci_slot = 0xff;
158 hi->pci_pin[0] = 0;
159 hi->pci_pin[1] = 0;
160 hi->ndev = 0;
161 hi->addr[0] = 0L;
162 hi->addr[1] = 0L;
163 hi->addr_mapped[0] = 0L;
164 hi->addr_mapped[1] = 0L;
165 }
166}
167
168void
169cleanup_ioremap (void)
170{
171 hdw_info_t *hi;
172 int i;
173
174 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
175 {
176 if (hi->pci_slot == 0xff)
177 break;
178 if (hi->addr_mapped[0])
179 {
180 iounmap ((void *) (hi->addr_mapped[0]));
181 release_mem_region ((long) hi->addr[0], hi->len[0]);
182 hi->addr_mapped[0] = 0;
183 }
184 if (hi->addr_mapped[1])
185 {
186 iounmap ((void *) (hi->addr_mapped[1]));
187 release_mem_region ((long) hi->addr[1], hi->len[1]);
188 hi->addr_mapped[1] = 0;
189 }
190 }
191}
192
193
194void
195cleanup_devs (void)
196{
197 hdw_info_t *hi;
198 int i;
199
200 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
201 {
202 if (hi->pci_slot == 0xff || !hi->ndev)
203 break;
204 c4_stopwd(netdev_priv(hi->ndev));
205#ifdef CONFIG_PROC_FS
206 sbecom_proc_brd_cleanup(netdev_priv(hi->ndev));
207#endif
208 unregister_netdev (hi->ndev);
209 free_irq (hi->pdev[0]->irq, hi->ndev);
210#ifdef CONFIG_SBE_PMCC4_NCOMM
211 free_irq (hi->pdev[1]->irq, hi->ndev);
212#endif
213 OS_kfree (hi->ndev);
214 }
215}
216
217
218static int __init
219c4_hdw_init (struct pci_dev *pdev, int found)
220{
221 hdw_info_t *hi;
222 int i;
223 int fun, slot;
224 unsigned char busno = 0xff;
225
226
227 if ((fun = PCI_FUNC (pdev->devfn)) > 1)
228 {
229 pr_warning("unexpected devfun: 0x%x\n", pdev->devfn);
230 return 0;
231 }
232 if (pdev->bus)
233 busno = pdev->bus->number;
234 else
235 busno = 0;
236 slot = pdev->devfn & ~0x07;
237
238
239
240
241
242
243
244
245 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
246 {
247
248
249
250
251 if ((hi->pci_slot == 0xff) ||
252 ((hi->pci_slot == slot) && (hi->bus == pdev->bus)))
253 break;
254 }
255 if (i == MAX_BOARDS)
256
257 {
258 pr_warning("exceeded number of allowed devices (>%d)?\n", MAX_BOARDS);
259 return 0;
260 }
261 if (pdev->bus)
262 hi->pci_busno = pdev->bus->number;
263 else
264 hi->pci_busno = 0;
265 hi->pci_slot = slot;
266 pci_read_config_byte (pdev, PCI_INTERRUPT_PIN, &hi->pci_pin[fun]);
267 pci_read_config_byte (pdev, PCI_REVISION_ID, &hi->revid[fun]);
268 hi->bus = pdev->bus;
269 hi->addr[fun] = pci_resource_start (pdev, 0);
270 hi->len[fun] = pci_resource_end (pdev, 0) - hi->addr[fun] + 1;
271 hi->pdev[fun] = pdev;
272
273 {
274
275
276
277
278 char *cp = hi->devname;
279
280 strcpy (cp, KBUILD_MODNAME);
281 cp += strlen (cp);
282 *cp++ = '-';
283 *cp++ = '0' + (found / 2);
284
285 *cp = 0;
286 }
287
288 return 1;
289}
290
291
292status_t __init
293c4hw_attach_all (void)
294{
295 hdw_info_t *hi;
296 struct pci_dev *pdev = NULL;
297 int found = 0, i, j;
298
299 error_flag = 0;
300 prep_hdw_info ();
301
302 while ((pdev = pci_get_device (PCI_VENDOR_ID_CONEXANT,
303 PCI_DEVICE_ID_CN8474,
304 pdev)))
305 {
306 if (c4_hdw_init (pdev, found))
307 found++;
308 }
309 if (!found)
310 {
311 pr_warning("No boards found\n");
312 return ENODEV;
313 }
314
315 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
316 {
317 if (hi->pci_slot != 0xff && (!hi->addr[0] || !hi->addr[1]))
318 {
319 pr_warning("%s: something very wrong with pci_get_device\n",
320 hi->devname);
321 return EIO;
322 }
323 }
324
325 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
326 {
327 if (hi->pci_slot == 0xff)
328 break;
329 for (j = 0; j < 2; j++)
330 {
331 if (request_mem_region (hi->addr[j], hi->len[j], hi->devname) == 0)
332 {
333 pr_warning("%s: memory in use, addr=0x%lx, len=0x%lx ?\n",
334 hi->devname, hi->addr[j], hi->len[j]);
335 cleanup_ioremap ();
336 return ENOMEM;
337 }
338 hi->addr_mapped[j] = (unsigned long) ioremap (hi->addr[j], hi->len[j]);
339 if (!hi->addr_mapped[j])
340 {
341 pr_warning("%s: ioremap fails, addr=0x%lx, len=0x%lx ?\n",
342 hi->devname, hi->addr[j], hi->len[j]);
343 cleanup_ioremap ();
344 return ENOMEM;
345 }
346#ifdef SBE_MAP_DEBUG
347 pr_warning("%s: io remapped from phys %x to virt %x\n",
348 hi->devname, (u_int32_t) hi->addr[j], (u_int32_t) hi->addr_mapped[j]);
349#endif
350 }
351 }
352
353 drvr_state = SBE_DRVR_AVAILABLE;
354
355
356 for (i = 0, hi = hdw_info; i < MAX_BOARDS; i++, hi++)
357 {
358 if (hi->pci_slot == 0xff)
359 break;
360 if (pci_enable_device (hi->pdev[0]) ||
361 pci_enable_device (hi->pdev[1]))
362 {
363 drvr_state = SBE_DRVR_DOWN;
364 pr_warning("%s: failed to enable card %d slot %d\n",
365 hi->devname, i, hi->pci_slot);
366 cleanup_devs ();
367 cleanup_ioremap ();
368 return EIO;
369 }
370 pci_set_master (hi->pdev[0]);
371 pci_set_master (hi->pdev[1]);
372 if (!(hi->ndev = c4_add_dev (hi, i, (long) hi->addr_mapped[0],
373 (long) hi->addr_mapped[1],
374 hi->pdev[0]->irq,
375 hi->pdev[1]->irq)))
376 {
377 drvr_state = SBE_DRVR_DOWN;
378 cleanup_ioremap ();
379
380#if 0
381 cleanup_devs ();
382#endif
383 return error_flag;
384 }
385 show_two (hi, i);
386 }
387 return 0;
388}
389
390
391