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 cxt1e1_log_level
;
35 extern int error_flag
;
36 extern int drvr_state
;
38 /* forward references */
39 void c4_stopwd (ci_t
*);
40 struct net_device
* __init
c4_add_dev (hdw_info_t
*, int, unsigned long, unsigned long, int, int);
43 struct s_hdw_info hdw_info
[MAX_BOARDS
];
47 show_two (hdw_info_t
*hi
, int brdno
)
56 memset (banner
, 0, 80); /* clear print buffer */
58 ci
= (ci_t
*)(netdev_priv(hi
->ndev
));
59 bid
= sbeid_get_bdname (ci
);
62 case PROM_FORMAT_TYPE1
:
63 memcpy (sn
, (FLD_TYPE1
*) (hi
->mfg_info
.pft1
.Serial
), 6);
65 case PROM_FORMAT_TYPE2
:
66 memcpy (sn
, (FLD_TYPE2
*) (hi
->mfg_info
.pft2
.Serial
), 6);
73 sprintf (banner
, "%s: %s S/N %06X, MUSYCC Rev %02X",
75 ((sn
[3] << 16) & 0xff0000) |
76 ((sn
[4] << 8) & 0x00ff00) |
78 (u_int8_t
) hi
->revid
[0]);
80 pr_info("%s\n", banner
);
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
);
90 pr_info("%s: %s at v/p=%lx/%lx (%02x:%02x.%x) irq %d\n",
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
);
99 hdw_sn_get (hdw_info_t
*hi
, int brdno
)
101 /* obtain hardware EEPROM information */
104 addr
= (long) hi
->addr_mapped
[1] + EEPROM_OFFSET
;
106 /* read EEPROM with largest known format size... */
107 pmc_eeprom_read_buffer (addr
, 0, (char *) hi
->mfg_info
.data
, sizeof (FLD_TYPE2
));
111 unsigned char *ucp
= (unsigned char *) &hi
->mfg_info
.data
;
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));
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 if ((hi
->promfmt
= pmc_verify_cksum (&hi
->mfg_info
.data
)) == 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
++)
156 hi
->pci_busno
= 0xff;
163 hi
->addr_mapped
[0] = 0L;
164 hi
->addr_mapped
[1] = 0L;
169 cleanup_ioremap (void)
174 for (i
= 0, hi
= hdw_info
; i
< MAX_BOARDS
; i
++, hi
++)
176 if (hi
->pci_slot
== 0xff)
178 if (hi
->addr_mapped
[0])
180 iounmap ((void *) (hi
->addr_mapped
[0]));
181 release_mem_region ((long) hi
->addr
[0], hi
->len
[0]);
182 hi
->addr_mapped
[0] = 0;
184 if (hi
->addr_mapped
[1])
186 iounmap ((void *) (hi
->addr_mapped
[1]));
187 release_mem_region ((long) hi
->addr
[1], hi
->len
[1]);
188 hi
->addr_mapped
[1] = 0;
200 for (i
= 0, hi
= hdw_info
; i
< MAX_BOARDS
; i
++, hi
++)
202 if (hi
->pci_slot
== 0xff || !hi
->ndev
)
204 c4_stopwd(netdev_priv(hi
->ndev
));
205 #ifdef CONFIG_PROC_FS
206 sbecom_proc_brd_cleanup(netdev_priv(hi
->ndev
));
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
);
219 c4_hdw_init (struct pci_dev
*pdev
, int found
)
224 unsigned char busno
= 0xff;
226 /* our MUSYCC chip supports two functions, 0 & 1 */
227 if ((fun
= PCI_FUNC (pdev
->devfn
)) > 1)
229 pr_warning("unexpected devfun: 0x%x\n", pdev
->devfn
);
232 if (pdev
->bus
) /* obtain bus number */
233 busno
= pdev
->bus
->number
;
235 busno
= 0; /* default for system PCI inconsistency */
236 slot
= pdev
->devfn
& ~0x07;
239 * Functions 0 & 1 for a given board (identified by same bus(busno) and
240 * slot(slot)) are placed into the same 'hardware' structure. The first
241 * part of the board's functionality will be placed into an unpopulated
242 * element, identified by "slot==(0xff)". The second part of a board's
243 * functionality will match the previously loaded slot/busno.
245 for (i
= 0, hi
= hdw_info
; i
< MAX_BOARDS
; i
++, hi
++)
248 * match with board's first found interface, otherwise this is first
251 if ((hi
->pci_slot
== 0xff) || /* new board */
252 ((hi
->pci_slot
== slot
) && (hi
->bus
== pdev
->bus
)))
253 break; /* found for-loop exit */
255 if (i
== MAX_BOARDS
) /* no match in above loop means MAX
258 pr_warning("exceeded number of allowed devices (>%d)?\n", MAX_BOARDS
);
262 hi
->pci_busno
= pdev
->bus
->number
;
264 hi
->pci_busno
= 0; /* default for system PCI inconsistency */
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
]);
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
;
275 * create device name from module name, plus add the appropriate
278 char *cp
= hi
->devname
;
280 strcpy (cp
, KBUILD_MODNAME
);
281 cp
+= strlen (cp
); /* reposition */
283 *cp
++ = '0' + (found
/ 2); /* there are two found interfaces per
285 *cp
= 0; /* termination */
293 c4hw_attach_all (void)
296 struct pci_dev
*pdev
= NULL
;
301 /*** scan PCI bus for all possible boards */
302 while ((pdev
= pci_get_device (PCI_VENDOR_ID_CONEXANT
,
303 PCI_DEVICE_ID_CN8474
,
306 if (c4_hdw_init (pdev
, found
))
311 pr_warning("No boards found\n");
314 /* sanity check for consistent hardware found */
315 for (i
= 0, hi
= hdw_info
; i
< MAX_BOARDS
; i
++, hi
++)
317 if (hi
->pci_slot
!= 0xff && (!hi
->addr
[0] || !hi
->addr
[1]))
319 pr_warning("%s: something very wrong with pci_get_device\n",
324 /* bring board's memory regions on/line */
325 for (i
= 0, hi
= hdw_info
; i
< MAX_BOARDS
; i
++, hi
++)
327 if (hi
->pci_slot
== 0xff)
329 for (j
= 0; j
< 2; j
++)
331 if (!request_mem_region (hi
->addr
[j
], hi
->len
[j
], hi
->devname
))
333 pr_warning("%s: memory in use, addr=0x%lx, len=0x%lx ?\n",
334 hi
->devname
, hi
->addr
[j
], hi
->len
[j
]);
338 hi
->addr_mapped
[j
] = (unsigned long) ioremap (hi
->addr
[j
], hi
->len
[j
]);
339 if (!hi
->addr_mapped
[j
])
341 pr_warning("%s: ioremap fails, addr=0x%lx, len=0x%lx ?\n",
342 hi
->devname
, hi
->addr
[j
], hi
->len
[j
]);
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
]);
353 drvr_state
= SBE_DRVR_AVAILABLE
;
355 /* Have now memory mapped all boards. Now allow board's access to system */
356 for (i
= 0, hi
= hdw_info
; i
< MAX_BOARDS
; i
++, hi
++)
358 if (hi
->pci_slot
== 0xff)
360 if (pci_enable_device (hi
->pdev
[0]) ||
361 pci_enable_device (hi
->pdev
[1]))
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
);
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],
377 drvr_state
= SBE_DRVR_DOWN
;
379 /* NOTE: c4_add_dev() does its own device cleanup */
383 return error_flag
; /* error_flag set w/in add_dev() */
385 show_two (hi
, i
); /* displays found information */
390 /*** End-of-File ***/