1 /* Copyright (C) 2007 One Stop Systems
2 * Copyright (C) 2003-2005 SBE, Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
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"
26 #include "pmcc4_private.h"
28 #include "pmcc4_ioctls.h"
29 #include "pmc93x6_eeprom.h"
34 extern int error_flag
;
35 extern int drvr_state
;
37 /* forward references */
38 void c4_stopwd(ci_t
*);
39 struct net_device
* __init
c4_add_dev(hdw_info_t
*, int, unsigned long,
40 unsigned long, int, int);
43 struct s_hdw_info hdw_info
[MAX_BOARDS
];
47 show_two(hdw_info_t
*hi
, int brdno
)
55 ci
= (ci_t
*)(netdev_priv(hi
->ndev
));
56 bid
= sbeid_get_bdname(ci
);
57 switch (hi
->promfmt
) {
58 case PROM_FORMAT_TYPE1
:
59 memcpy(sn
, hi
->mfg_info
.pft1
.Serial
, 6);
61 case PROM_FORMAT_TYPE2
:
62 memcpy(sn
, hi
->mfg_info
.pft2
.Serial
, 6);
66 sprintf(banner
, "%s: %s S/N %06X, MUSYCC Rev %02X",
68 ((sn
[3] << 16) & 0xff0000) |
69 ((sn
[4] << 8) & 0x00ff00) |
71 (u_int8_t
) hi
->revid
[0]);
73 pr_info("%s\n", banner
);
76 pr_info("%s: %s at v/p=%lx/%lx (%02x:%02x.%x) irq %d\n",
77 hi
->devname
, "MUSYCC",
78 (unsigned long) hi
->addr_mapped
[0], hi
->addr
[0],
79 hi
->pci_busno
, (u_int8_t
) PCI_SLOT(pdev
->devfn
),
80 (u_int8_t
) PCI_FUNC(pdev
->devfn
), pdev
->irq
);
83 pr_info("%s: %s at v/p=%lx/%lx (%02x:%02x.%x) irq %d\n",
85 (unsigned long) hi
->addr_mapped
[1], hi
->addr
[1],
86 hi
->pci_busno
, (u_int8_t
) PCI_SLOT(pdev
->devfn
),
87 (u_int8_t
) PCI_FUNC(pdev
->devfn
), pdev
->irq
);
92 hdw_sn_get(hdw_info_t
*hi
, int brdno
)
94 /* obtain hardware EEPROM information */
97 addr
= (long) hi
->addr_mapped
[1] + EEPROM_OFFSET
;
99 /* read EEPROM with largest known format size... */
100 pmc_eeprom_read_buffer(addr
, 0, (char *)hi
->mfg_info
.data
,
105 unsigned char *ucp
= (unsigned char *) &hi
->mfg_info
.data
;
107 pr_info("eeprom[00]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
108 *(ucp
+ 0), *(ucp
+ 1), *(ucp
+ 2), *(ucp
+ 3),
109 *(ucp
+ 4), *(ucp
+ 5), *(ucp
+ 6), *(ucp
+ 7));
110 pr_info("eeprom[08]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
111 *(ucp
+ 8), *(ucp
+ 9), *(ucp
+ 10), *(ucp
+ 11),
112 *(ucp
+ 12), *(ucp
+ 13), *(ucp
+ 14), *(ucp
+ 15));
113 pr_info("eeprom[16]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
114 *(ucp
+ 16), *(ucp
+ 17), *(ucp
+ 18), *(ucp
+ 19),
115 *(ucp
+ 20), *(ucp
+ 21), *(ucp
+ 22), *(ucp
+ 23));
116 pr_info("eeprom[24]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
117 *(ucp
+ 24), *(ucp
+ 25), *(ucp
+ 26), *(ucp
+ 27),
118 *(ucp
+ 28), *(ucp
+ 29), *(ucp
+ 30), *(ucp
+ 31));
119 pr_info("eeprom[32]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
120 *(ucp
+ 32), *(ucp
+ 33), *(ucp
+ 34), *(ucp
+ 35),
121 *(ucp
+ 36), *(ucp
+ 37), *(ucp
+ 38), *(ucp
+ 39));
122 pr_info("eeprom[40]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
123 *(ucp
+ 40), *(ucp
+ 41), *(ucp
+ 42), *(ucp
+ 43),
124 *(ucp
+ 44), *(ucp
+ 45), *(ucp
+ 46), *(ucp
+ 47));
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]);
137 hi
->promfmt
= pmc_verify_cksum(&hi
->mfg_info
.data
);
138 if (hi
->promfmt
== PROM_FORMAT_Unk
) {
139 /* bad crc, data is suspect */
140 if (cxt1e1_log_level
>= LOG_WARN
)
141 pr_info("%s: EEPROM cksum error\n", hi
->devname
);
142 hi
->mfg_info_sts
= EEPROM_CRCERR
;
144 hi
->mfg_info_sts
= EEPROM_OK
;
154 for (i
= 0, hi
= hdw_info
; i
< MAX_BOARDS
; i
++, hi
++) {
155 hi
->pci_busno
= 0xff;
162 hi
->addr_mapped
[0] = NULL
;
163 hi
->addr_mapped
[1] = NULL
;
168 cleanup_ioremap(void)
173 for (i
= 0, hi
= hdw_info
; i
< MAX_BOARDS
; i
++, hi
++) {
174 if (hi
->pci_slot
== 0xff)
176 if (hi
->addr_mapped
[0]) {
177 iounmap(hi
->addr_mapped
[0]);
178 release_mem_region((long) hi
->addr
[0], hi
->len
[0]);
179 hi
->addr_mapped
[0] = NULL
;
181 if (hi
->addr_mapped
[1]) {
182 iounmap(hi
->addr_mapped
[1]);
183 release_mem_region((long) hi
->addr
[1], hi
->len
[1]);
184 hi
->addr_mapped
[1] = NULL
;
196 for (i
= 0, hi
= hdw_info
; i
< MAX_BOARDS
; i
++, hi
++) {
197 if (hi
->pci_slot
== 0xff || !hi
->ndev
)
199 c4_stopwd(netdev_priv(hi
->ndev
));
200 #ifdef CONFIG_PROC_FS
201 sbecom_proc_brd_cleanup(netdev_priv(hi
->ndev
));
203 unregister_netdev(hi
->ndev
);
204 free_irq(hi
->pdev
[0]->irq
, hi
->ndev
);
205 #ifdef CONFIG_SBE_PMCC4_NCOMM
206 free_irq(hi
->pdev
[1]->irq
, hi
->ndev
);
214 c4_hdw_init(struct pci_dev
*pdev
, int found
)
219 unsigned char busno
= 0xff;
221 /* our MUSYCC chip supports two functions, 0 & 1 */
222 fun
= PCI_FUNC(pdev
->devfn
);
224 pr_warning("unexpected devfun: 0x%x\n", pdev
->devfn
);
228 /* obtain bus number */
230 busno
= pdev
->bus
->number
;
232 busno
= 0; /* default for system PCI inconsistency */
233 slot
= pdev
->devfn
& ~0x07;
236 * Functions 0 & 1 for a given board (identified by same bus(busno) and
237 * slot(slot)) are placed into the same 'hardware' structure. The first
238 * part of the board's functionality will be placed into an unpopulated
239 * element, identified by "slot==(0xff)". The second part of a board's
240 * functionality will match the previously loaded slot/busno.
242 for (i
= 0, hi
= hdw_info
; i
< MAX_BOARDS
; i
++, hi
++) {
244 * match with board's first found interface, otherwise this is
247 if ((hi
->pci_slot
== 0xff) || /* new board */
248 ((hi
->pci_slot
== slot
) && (hi
->bus
== pdev
->bus
)))
249 break; /* found for-loop exit */
252 /* no match in above loop means MAX exceeded */
253 if (i
== MAX_BOARDS
) {
254 pr_warning("exceeded number of allowed devices (>%d)?\n",
260 hi
->pci_busno
= pdev
->bus
->number
;
262 hi
->pci_busno
= 0; /* default for system PCI inconsistency */
265 pci_read_config_byte(pdev
, PCI_INTERRUPT_PIN
, &hi
->pci_pin
[fun
]);
266 pci_read_config_byte(pdev
, PCI_REVISION_ID
, &hi
->revid
[fun
]);
268 hi
->addr
[fun
] = pci_resource_start(pdev
, 0);
269 hi
->len
[fun
] = pci_resource_end(pdev
, 0) - hi
->addr
[fun
] + 1;
270 hi
->pdev
[fun
] = pdev
;
274 * create device name from module name, plus add the appropriate
277 char *cp
= hi
->devname
;
279 strcpy(cp
, KBUILD_MODNAME
);
280 cp
+= strlen(cp
); /* reposition */
282 *cp
++ = '0' + (found
/ 2); /* there are two found interfaces per
284 *cp
= 0; /* termination */
291 c4hw_attach_all(void)
294 struct pci_dev
*pdev
= NULL
;
299 /*** scan PCI bus for all possible boards */
300 while ((pdev
= pci_get_device(PCI_VENDOR_ID_CONEXANT
,
301 PCI_DEVICE_ID_CN8474
,
303 if (c4_hdw_init(pdev
, found
))
308 pr_warning("No boards found\n");
312 /* sanity check for consistent hardware found */
313 for (i
= 0, hi
= hdw_info
; i
< MAX_BOARDS
; i
++, hi
++) {
314 if (hi
->pci_slot
!= 0xff && (!hi
->addr
[0] || !hi
->addr
[1])) {
315 pr_warning("%s: something very wrong with pci_get_device\n",
320 /* bring board's memory regions on/line */
321 for (i
= 0, hi
= hdw_info
; i
< MAX_BOARDS
; i
++, hi
++) {
322 if (hi
->pci_slot
== 0xff)
324 for (j
= 0; j
< 2; j
++) {
325 if (!request_mem_region(hi
->addr
[j
], hi
->len
[j
], hi
->devname
)) {
326 pr_warning("%s: memory in use, addr=0x%lx, len=0x%lx ?\n",
327 hi
->devname
, hi
->addr
[j
], hi
->len
[j
]);
332 hi
->addr_mapped
[j
] = ioremap(hi
->addr
[j
], hi
->len
[j
]);
333 if (!hi
->addr_mapped
[j
]) {
334 pr_warning("%s: ioremap fails, addr=0x%lx, len=0x%lx ?\n",
335 hi
->devname
, hi
->addr
[j
], hi
->len
[j
]);
340 pr_warning("%s: io remapped from phys %x to virt %x\n",
341 hi
->devname
, (u_int32_t
) hi
->addr
[j
],
342 (u_int32_t
) hi
->addr_mapped
[j
]);
347 drvr_state
= SBE_DRVR_AVAILABLE
;
349 /* Have now memory mapped all boards. Now allow board's access to system */
350 for (i
= 0, hi
= hdw_info
; i
< MAX_BOARDS
; i
++, hi
++) {
351 if (hi
->pci_slot
== 0xff)
353 if (pci_enable_device(hi
->pdev
[0]) ||
354 pci_enable_device(hi
->pdev
[1])) {
355 drvr_state
= SBE_DRVR_DOWN
;
356 pr_warning("%s: failed to enable card %d slot %d\n",
357 hi
->devname
, i
, hi
->pci_slot
);
362 pci_set_master(hi
->pdev
[0]);
363 pci_set_master(hi
->pdev
[1]);
364 hi
->ndev
= c4_add_dev(hi
, i
, (long) hi
->addr_mapped
[0],
365 (long) hi
->addr_mapped
[1],
369 drvr_state
= SBE_DRVR_DOWN
;
371 /* NOTE: c4_add_dev() does its own device cleanup */
375 return error_flag
; /* error_flag set w/in add_dev() */
377 show_two(hi
, i
); /* displays found information */
382 /*** End-of-File ***/