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 #ifdef SBE_INCLUDE_SYMBOLS
41 extern int error_flag
;
42 extern int drvr_state
;
44 /* forward references */
45 void c4_stopwd (ci_t
*);
46 struct net_device
* __init
c4_add_dev (hdw_info_t
*, int, unsigned long, unsigned long, int, int);
49 struct s_hdw_info hdw_info
[MAX_BOARDS
];
53 show_two (hdw_info_t
* hi
, int brdno
)
62 memset (banner
, 0, 80); /* clear print buffer */
64 ci
= (ci_t
*)(netdev_priv(hi
->ndev
));
65 bid
= sbeid_get_bdname (ci
);
68 case PROM_FORMAT_TYPE1
:
69 memcpy (sn
, (FLD_TYPE1
*) (hi
->mfg_info
.pft1
.Serial
), 6);
71 case PROM_FORMAT_TYPE2
:
72 memcpy (sn
, (FLD_TYPE2
*) (hi
->mfg_info
.pft2
.Serial
), 6);
79 sprintf (banner
, "%s: %s S/N %06X, MUSYCC Rev %02X",
81 ((sn
[3] << 16) & 0xff0000) |
82 ((sn
[4] << 8) & 0x00ff00) |
84 (u_int8_t
) hi
->revid
[0]);
86 pr_info("%s\n", banner
);
89 pr_info("%s: %s at v/p=%lx/%lx (%02x:%02x.%x) irq %d\n",
90 hi
->devname
, "MUSYCC",
91 (unsigned long) hi
->addr_mapped
[0], hi
->addr
[0],
92 hi
->pci_busno
, (u_int8_t
) PCI_SLOT (pdev
->devfn
),
93 (u_int8_t
) PCI_FUNC (pdev
->devfn
), pdev
->irq
);
96 pr_info("%s: %s at v/p=%lx/%lx (%02x:%02x.%x) irq %d\n",
98 (unsigned long) hi
->addr_mapped
[1], hi
->addr
[1],
99 hi
->pci_busno
, (u_int8_t
) PCI_SLOT (pdev
->devfn
),
100 (u_int8_t
) PCI_FUNC (pdev
->devfn
), pdev
->irq
);
105 hdw_sn_get (hdw_info_t
* hi
, int brdno
)
107 /* obtain hardware EEPROM information */
110 addr
= (long) hi
->addr_mapped
[1] + EEPROM_OFFSET
;
112 /* read EEPROM with largest known format size... */
113 pmc_eeprom_read_buffer (addr
, 0, (char *) hi
->mfg_info
.data
, sizeof (FLD_TYPE2
));
117 unsigned char *ucp
= (unsigned char *) &hi
->mfg_info
.data
;
119 pr_info("eeprom[00]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
120 *(ucp
+ 0), *(ucp
+ 1), *(ucp
+ 2), *(ucp
+ 3), *(ucp
+ 4), *(ucp
+ 5), *(ucp
+ 6), *(ucp
+ 7));
121 pr_info("eeprom[08]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
122 *(ucp
+ 8), *(ucp
+ 9), *(ucp
+ 10), *(ucp
+ 11), *(ucp
+ 12), *(ucp
+ 13), *(ucp
+ 14), *(ucp
+ 15));
123 pr_info("eeprom[16]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
124 *(ucp
+ 16), *(ucp
+ 17), *(ucp
+ 18), *(ucp
+ 19), *(ucp
+ 20), *(ucp
+ 21), *(ucp
+ 22), *(ucp
+ 23));
125 pr_info("eeprom[24]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
126 *(ucp
+ 24), *(ucp
+ 25), *(ucp
+ 26), *(ucp
+ 27), *(ucp
+ 28), *(ucp
+ 29), *(ucp
+ 30), *(ucp
+ 31));
127 pr_info("eeprom[32]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
128 *(ucp
+ 32), *(ucp
+ 33), *(ucp
+ 34), *(ucp
+ 35), *(ucp
+ 36), *(ucp
+ 37), *(ucp
+ 38), *(ucp
+ 39));
129 pr_info("eeprom[40]: %02x %02x %02x %02x %02x %02x %02x %02x\n",
130 *(ucp
+ 40), *(ucp
+ 41), *(ucp
+ 42), *(ucp
+ 43), *(ucp
+ 44), *(ucp
+ 45), *(ucp
+ 46), *(ucp
+ 47));
134 pr_info("sn: %x %x %x %x %x %x\n",
135 hi
->mfg_info
.Serial
[0],
136 hi
->mfg_info
.Serial
[1],
137 hi
->mfg_info
.Serial
[2],
138 hi
->mfg_info
.Serial
[3],
139 hi
->mfg_info
.Serial
[4],
140 hi
->mfg_info
.Serial
[5]);
143 if ((hi
->promfmt
= pmc_verify_cksum (&hi
->mfg_info
.data
)) == PROM_FORMAT_Unk
)
145 /* bad crc, data is suspect */
146 if (log_level
>= LOG_WARN
)
147 pr_info("%s: EEPROM cksum error\n", hi
->devname
);
148 hi
->mfg_info_sts
= EEPROM_CRCERR
;
150 hi
->mfg_info_sts
= EEPROM_OK
;
160 for (i
= 0, hi
= hdw_info
; i
< MAX_BOARDS
; i
++, hi
++)
162 hi
->pci_busno
= 0xff;
169 hi
->addr_mapped
[0] = 0L;
170 hi
->addr_mapped
[1] = 0L;
175 cleanup_ioremap (void)
180 for (i
= 0, hi
= hdw_info
; i
< MAX_BOARDS
; i
++, hi
++)
182 if (hi
->pci_slot
== 0xff)
184 if (hi
->addr_mapped
[0])
186 iounmap ((void *) (hi
->addr_mapped
[0]));
187 release_mem_region ((long) hi
->addr
[0], hi
->len
[0]);
188 hi
->addr_mapped
[0] = 0;
190 if (hi
->addr_mapped
[1])
192 iounmap ((void *) (hi
->addr_mapped
[1]));
193 release_mem_region ((long) hi
->addr
[1], hi
->len
[1]);
194 hi
->addr_mapped
[1] = 0;
206 for (i
= 0, hi
= hdw_info
; i
< MAX_BOARDS
; i
++, hi
++)
208 if (hi
->pci_slot
== 0xff || !hi
->ndev
)
210 c4_stopwd(netdev_priv(hi
->ndev
));
211 #ifdef CONFIG_PROC_FS
212 sbecom_proc_brd_cleanup(netdev_priv(hi
->ndev
));
214 unregister_netdev (hi
->ndev
);
215 free_irq (hi
->pdev
[0]->irq
, hi
->ndev
);
216 #ifdef CONFIG_SBE_PMCC4_NCOMM
217 free_irq (hi
->pdev
[1]->irq
, hi
->ndev
);
225 c4_hdw_init (struct pci_dev
* pdev
, int found
)
230 unsigned char busno
= 0xff;
232 /* our MUSYCC chip supports two functions, 0 & 1 */
233 if ((fun
= PCI_FUNC (pdev
->devfn
)) > 1)
235 pr_warning("unexpected devfun: 0x%x\n", pdev
->devfn
);
238 if (pdev
->bus
) /* obtain bus number */
239 busno
= pdev
->bus
->number
;
241 busno
= 0; /* default for system PCI inconsistency */
242 slot
= pdev
->devfn
& ~0x07;
245 * Functions 0 & 1 for a given board (identified by same bus(busno) and
246 * slot(slot)) are placed into the same 'hardware' structure. The first
247 * part of the board's functionality will be placed into an unpopulated
248 * element, identified by "slot==(0xff)". The second part of a board's
249 * functionality will match the previously loaded slot/busno.
251 for (i
= 0, hi
= hdw_info
; i
< MAX_BOARDS
; i
++, hi
++)
254 * match with board's first found interface, otherwise this is first
257 if ((hi
->pci_slot
== 0xff) || /* new board */
258 ((hi
->pci_slot
== slot
) && (hi
->bus
== pdev
->bus
)))
259 break; /* found for-loop exit */
261 if (i
== MAX_BOARDS
) /* no match in above loop means MAX
264 pr_warning("exceeded number of allowed devices (>%d)?\n", MAX_BOARDS
);
268 hi
->pci_busno
= pdev
->bus
->number
;
270 hi
->pci_busno
= 0; /* default for system PCI inconsistency */
272 pci_read_config_byte (pdev
, PCI_INTERRUPT_PIN
, &hi
->pci_pin
[fun
]);
273 pci_read_config_byte (pdev
, PCI_REVISION_ID
, &hi
->revid
[fun
]);
275 hi
->addr
[fun
] = pci_resource_start (pdev
, 0);
276 hi
->len
[fun
] = pci_resource_end (pdev
, 0) - hi
->addr
[fun
] + 1;
277 hi
->pdev
[fun
] = pdev
;
281 * create device name from module name, plus add the appropriate
284 char *cp
= hi
->devname
;
286 strcpy (cp
, KBUILD_MODNAME
);
287 cp
+= strlen (cp
); /* reposition */
289 *cp
++ = '0' + (found
/ 2); /* there are two found interfaces per
291 *cp
= 0; /* termination */
299 c4hw_attach_all (void)
302 struct pci_dev
*pdev
= NULL
;
307 /*** scan PCI bus for all possible boards */
308 while ((pdev
= pci_get_device (PCI_VENDOR_ID_CONEXANT
,
309 PCI_DEVICE_ID_CN8474
,
312 if (c4_hdw_init (pdev
, found
))
317 pr_warning("No boards found\n");
320 /* sanity check for consistant hardware found */
321 for (i
= 0, hi
= hdw_info
; i
< MAX_BOARDS
; i
++, hi
++)
323 if (hi
->pci_slot
!= 0xff && (!hi
->addr
[0] || !hi
->addr
[1]))
325 pr_warning("%s: something very wrong with pci_get_device\n",
330 /* bring board's memory regions on/line */
331 for (i
= 0, hi
= hdw_info
; i
< MAX_BOARDS
; i
++, hi
++)
333 if (hi
->pci_slot
== 0xff)
335 for (j
= 0; j
< 2; j
++)
337 if (request_mem_region (hi
->addr
[j
], hi
->len
[j
], hi
->devname
) == 0)
339 pr_warning("%s: memory in use, addr=0x%lx, len=0x%lx ?\n",
340 hi
->devname
, hi
->addr
[j
], hi
->len
[j
]);
344 hi
->addr_mapped
[j
] = (unsigned long) ioremap (hi
->addr
[j
], hi
->len
[j
]);
345 if (!hi
->addr_mapped
[j
])
347 pr_warning("%s: ioremap fails, addr=0x%lx, len=0x%lx ?\n",
348 hi
->devname
, hi
->addr
[j
], hi
->len
[j
]);
353 pr_warning("%s: io remapped from phys %x to virt %x\n",
354 hi
->devname
, (u_int32_t
) hi
->addr
[j
], (u_int32_t
) hi
->addr_mapped
[j
]);
359 drvr_state
= SBE_DRVR_AVAILABLE
;
361 /* Have now memory mapped all boards. Now allow board's access to system */
362 for (i
= 0, hi
= hdw_info
; i
< MAX_BOARDS
; i
++, hi
++)
364 if (hi
->pci_slot
== 0xff)
366 if (pci_enable_device (hi
->pdev
[0]) ||
367 pci_enable_device (hi
->pdev
[1]))
369 drvr_state
= SBE_DRVR_DOWN
;
370 pr_warning("%s: failed to enable card %d slot %d\n",
371 hi
->devname
, i
, hi
->pci_slot
);
376 pci_set_master (hi
->pdev
[0]);
377 pci_set_master (hi
->pdev
[1]);
378 if (!(hi
->ndev
= c4_add_dev (hi
, i
, (long) hi
->addr_mapped
[0],
379 (long) hi
->addr_mapped
[1],
383 drvr_state
= SBE_DRVR_DOWN
;
385 /* NOTE: c4_add_dev() does its own device cleanup */
389 return error_flag
; /* error_flag set w/in add_dev() */
391 show_two (hi
, i
); /* displays found information */
396 /*** End-of-File ***/