Annotation of sys/dev/pci/if_che.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: if_che.c,v 1.8 2007/05/30 05:11:53 reyk Exp $ */
2:
3: /*
4: * Copyright (c) 2007 Claudio Jeker <claudio@openbsd.org>
5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17: */
18:
19: #include "bpfilter.h"
20:
21: #include <sys/param.h>
22: #include <sys/systm.h>
23: #include <sys/sockio.h>
24: #include <sys/mbuf.h>
25: #include <sys/kernel.h>
26: #include <sys/socket.h>
27: #include <sys/malloc.h>
28: #include <sys/device.h>
29:
30: #include <machine/bus.h>
31:
32: #include <dev/pci/pcireg.h>
33: #include <dev/pci/pcivar.h>
34: #include <dev/pci/pcidevs.h>
35:
36: #include <net/if.h>
37: #include <net/if_dl.h>
38: #include <net/if_media.h>
39: #include <net/if_types.h>
40:
41: #if NBPFILTER > 0
42: #include <net/bpf.h>
43: #endif
44:
45: #include <netinet/in.h>
46: #include <netinet/if_ether.h>
47:
48: #include <dev/mii/mii.h>
49: #include <dev/mii/miivar.h>
50:
51: /* registers & defines */
52:
53: #define CHE_PCI_BAR 0x10
54: #define CHE_PCI_CAP_ID_VPD 0x03
55: #define CHE_PCI_VPD_DATA 0x4
56: #define CHE_PCI_F_VPD_ADDR 0x80000000
57: #define CHE_PCI_VPD_BASE 0xc00
58:
59: #define CHE_REG_T3DBG_GPIO_EN 0xd0
60: #define CHE_T3DBG_F_GPIO11_OEN 0x08000000
61: #define CHE_T3DBG_F_GPIO10_OEN 0x04000000
62: #define CHE_T3DBG_F_GPIO9_OEN 0x02000000
63: #define CHE_T3DBG_F_GPIO8_OEN 0x01000000
64: #define CHE_T3DBG_F_GPIO7_OEN 0x00800000
65: #define CHE_T3DBG_F_GPIO6_OEN 0x00400000
66: #define CHE_T3DBG_F_GPIO5_OEN 0x00200000
67: #define CHE_T3DBG_F_GPIO4_OEN 0x00100000
68: #define CHE_T3DBG_F_GPIO3_OEN 0x00080000
69: #define CHE_T3DBG_F_GPIO2_OEN 0x00040000
70: #define CHE_T3DBG_F_GPIO1_OEN 0x00020000
71: #define CHE_T3DBG_F_GPIO0_OEN 0x00010000
72: #define CHE_T3DBG_F_GPIO11_OUT_VAL 0x00000800
73: #define CHE_T3DBG_F_GPIO10_OUT_VAL 0x00000400
74: #define CHE_T3DBG_F_GPIO9_OUT_VAL 0x00000200
75: #define CHE_T3DBG_F_GPIO8_OUT_VAL 0x00000100
76: #define CHE_T3DBG_F_GPIO7_OUT_VAL 0x00000080
77: #define CHE_T3DBG_F_GPIO6_OUT_VAL 0x00000040
78: #define CHE_T3DBG_F_GPIO5_OUT_VAL 0x00000020
79: #define CHE_T3DBG_F_GPIO4_OUT_VAL 0x00000010
80: #define CHE_T3DBG_F_GPIO3_OUT_VAL 0x00000008
81: #define CHE_T3DBG_F_GPIO2_OUT_VAL 0x00000004
82: #define CHE_T3DBG_F_GPIO1_OUT_VAL 0x00000002
83: #define CHE_T3DBG_F_GPIO0_OUT_VAL 0x00000001
84: #define CHE_REG_I2C_CFG 0x6a0
85: #define CHE_I2C_CLKDIV(_x) ((_x) && 0xfff)
86: #define CHE_REG_MI1_CFG 0x6b0
87: #define CHE_REG_MI1_ADDR 0x6b4
88: #define CHE_REG_MI1_DATA 0x6b8
89: #define CHE_REG_MI1_OP 0x6bc
90: #define CHE_MI1_F_BUSY (1U << 31)
91: #define CHE_MI1_F_ST 0x8
92: #define CHE_MI1_F_PREEN 0x4
93: #define CHE_MI1_F_MDIINV 0x2
94: #define CHE_MI1_F_MDIEN 0x1
95: #define CHE_MI1_CLKDIV(_x) ((_x) << 5)
96: #define CHE_MI1_PHYADDR(_x) ((_x) << 5)
97: #define CHE_MI1_OP(_x) ((_x) & 0x3)
98: #define CHE_REG_PL_RST 0x6f0
99: #define CHE_RST_F_CRSTWRM 0x2
100: #define CHE_RST_F_CRSTWRMMODE 0x1
101: #define CHE_REG_PL_REV 0x6f4
102: #define CHE_REG_XGM_PORT_CFG 0x8b8
103: #define CHE_XGMAC0_0_BASE_ADDR 0x800
104: #define CHE_XGMAC0_1_BASE_ADDR 0xa00
105: #define CHE_XGM_REG(_r, _i) \
106: ((_r) + (_i) * (CHE_XGMAC0_1_BASE_ADDR - CHE_XGMAC0_0_BASE_ADDR))
107: #define CHE_XGM_PORTSPEED(_x) ((_x) << 1)
108: #define CHE_XGM_F_ENRGMII 0x1
109: #define CHE_XGM_F_CLKDIVRESET 0x8
110:
111: /* serial flash and firmware definitions */
112: #define CHE_REG_SF_DATA 0x6d8
113: #define CHE_REG_SF_OP 0x6dc
114: #define CHE_SF_SEC_SIZE (64 * 1024) /* serial flash sector size */
115: #define CHE_SF_SIZE (8 * CHE_SF_SEC_SIZE) /* serial flash size */
116: #define CHE_SF_PROG_PAGE 2
117: #define CHE_SF_WR_DISABLE 4
118: #define CHE_SF_RD_STATUS 5 /* read status register */
119: #define CHE_SF_WR_ENABLE 6
120: #define CHE_SF_RD_DATA 11
121: #define CHE_SF_SEC_ERASE 216
122: #define CHE_SF_F_BUSY (1U << 31)
123: #define CHE_SF_F_OP 0x1
124: #define CHE_SF_CONT(_x) ((_x) << 3)
125: #define CHE_SF_BYTECNT_MASK 0x3
126: #define CHE_SF_BYTECNT(_x) (((_x) & CHE_SF_BYTECNT_MASK) << 1)
127:
128: #define FW_FLASH_BOOT_ADDR 0x70000 /* start address of FW in flash */
129: #define FW_VERS_ADDR 0x77ffc /* flash address holding FW version */
130: #define FW_VERS_TYPE_N3 0
131: #define FW_VERS_TYPE_T3 1
132: #define FW_VERS_TYPE(_x) (((_x) >> 28) & 0xf)
133: #define FW_VERS_MAJOR(_x) (((_x) >> 16) & 0xfff)
134: #define FW_VERS_MINOR(_x) (((_x) >> 8) & 0xff)
135: #define FW_VERS_MICRO(_x) ((_x) & 0xff)
136:
137: /* Partial EEPROM Vital Product Data structure. */
138: struct che_vpd {
139: u_int8_t id_tag;
140: u_int8_t id_len[2];
141: u_int8_t id_data[16];
142: u_int8_t vpdr_tag;
143: u_int8_t vpdr_len[2];
144: u_int8_t pn_name[2]; /* part number */
145: u_int8_t pn_len;
146: u_int8_t pn_data[16];
147: u_int8_t ec_name[2]; /* EC level */
148: u_int8_t ec_len;
149: u_int8_t ec_data[16];
150: u_int8_t sn_name[2]; /* serial number */
151: u_int8_t sn_len;
152: u_int8_t sn_data[16];
153: u_int8_t na_name[2]; /* MAC address base */
154: u_int8_t na_len;
155: u_int8_t na_data[12];
156: u_int8_t cclk_name[2]; /* core clock */
157: u_int8_t cclk_len;
158: u_int8_t cclk_data[6];
159: u_int8_t mclk_name[2]; /* mem clock */
160: u_int8_t mclk_len;
161: u_int8_t mclk_data[6];
162: u_int8_t uclk_name[2]; /* uP clock */
163: u_int8_t uclk_len;
164: u_int8_t uclk_data[6];
165: u_int8_t mdc_name[2]; /* MDIO clock */
166: u_int8_t mdc_len;
167: u_int8_t mdc_data[6];
168: u_int8_t mt_name[2]; /* mem timing */
169: u_int8_t mt_len;
170: u_int8_t mt_data[2];
171: u_int8_t xaui0cfg_name[2]; /* XAUI0 config */
172: u_int8_t xaui0cfg_len;
173: u_int8_t xaui0cfg_data[6];
174: u_int8_t xaui1cfg_name[2]; /* XAUI1 config */
175: u_int8_t xaui1cfg_len;
176: u_int8_t xaui1cfg_data[6];
177: u_int8_t port0_name[2]; /* PHY0 */
178: u_int8_t port0_len;
179: u_int8_t port0_data[2];
180: u_int8_t port1_name[2]; /* PHY1 */
181: u_int8_t port1_len;
182: u_int8_t port1_data[2];
183: u_int8_t port2_name[2]; /* PHY2 */
184: u_int8_t port2_len;
185: u_int8_t port2_data[2];
186: u_int8_t port3_name[2]; /* PHY3 */
187: u_int8_t port3_len;
188: u_int8_t port3_data[2];
189: u_int8_t rv_name[2]; /* csum */
190: u_int8_t rv_len;
191: u_int8_t rv_data[1];
192: u_int8_t pad[4]; /* for multiple-of-4 sizing */
193: } __packed;
194:
195:
196: #define DEVNAME(_sc) ((_sc)->sc_dev.dv_xname)
197:
198: /* the pci controller */
199:
200: struct cheg_softc {
201: struct device sc_dev;
202:
203: bus_dma_tag_t sc_dmat;
204:
205: bus_space_tag_t sc_memt;
206: bus_space_handle_t sc_memh;
207: bus_size_t sc_mems;
208:
209: u_int32_t sc_rev; /* card revision */
210: u_int32_t sc_cclk; /* core clock */
211: u_int32_t sc_mdc; /* mdio clock */
212:
213: pci_vendor_id_t sc_product;
214: };
215:
216: int cheg_match(struct device *, void *, void *);
217: void cheg_attach(struct device *, struct device *, void *);
218: int cheg_print(void *, const char *);
219:
220: struct cfattach cheg_ca = {
221: sizeof(struct cheg_softc),
222: cheg_match,
223: cheg_attach
224: };
225:
226: struct cfdriver cheg_cd = {
227: NULL, "cheg", DV_DULL
228: };
229:
230: /* glue between the controller and the port */
231:
232: struct che_attach_args {
233: struct pci_attach_args *caa_pa;
234: pci_intr_handle_t caa_ih;
235: int caa_port;
236: u_int8_t caa_lladdr[ETHER_ADDR_LEN];
237: };
238:
239: /* che itself */
240:
241: struct che_softc {
242: struct device sc_dev;
243: struct arpcom sc_ac;
244: struct mii_data sc_mii;
245:
246: struct cheg_softc *sc_cheg;
247: void *sc_ih;
248: int sc_port;
249: };
250:
251: int che_match(struct device *, void *, void *);
252: void che_attach(struct device *, struct device *, void *);
253:
254: struct cfattach che_ca = {
255: sizeof(struct che_softc),
256: che_match,
257: che_attach
258: };
259:
260: struct cfdriver che_cd = {
261: NULL, "che", DV_IFNET
262: };
263:
264: int che_write_flash_reg(struct cheg_softc *, size_t, int,
265: u_int32_t);
266: int che_read_flash_reg(struct cheg_softc *, size_t, int,
267: u_int32_t *);
268: int che_read_flash_multi4(struct cheg_softc *, u_int, u_int32_t *,
269: size_t);
270: int che_read_eeprom(struct cheg_softc *, struct pci_attach_args *,
271: pcireg_t, pcireg_t *);
272: int che_get_vpd(struct cheg_softc *, struct pci_attach_args *,
273: void *, size_t);
274: void che_conv_lladdr(char *, u_int8_t *);
275: u_int32_t che_conv_num(char *, size_t);
276: void che_reset(struct cheg_softc *);
277: int che_ioctl(struct ifnet *, u_long, caddr_t);
278: void che_watchdog(struct ifnet *);
279: void che_start(struct ifnet *);
280:
281: /* ifmedia & mii helper functions */
282: int che_ifmedia_upd(struct ifnet *);
283: void che_ifmedia_sts(struct ifnet *, struct ifmediareq *);
284: int che_miibus_readreg(struct device *, int, int);
285: void che_miibus_writereg(struct device *, int, int, int);
286: int che_miibus_ind_readreg(struct device *, int, int);
287: void che_miibus_ind_writereg(struct device *, int, int, int);
288: void che_miibus_statchg(struct device *);
289:
290: /* bus_space wrappers */
291: u_int32_t che_read(struct cheg_softc *, bus_size_t);
292: void che_write(struct cheg_softc *, bus_size_t, u_int32_t);
293: int che_waitfor(struct cheg_softc *, bus_size_t, u_int32_t, int);
294:
295: /* HW low-level functions */
296: void che_hw_init(struct cheg_softc *);
297:
298: /* cheg */
299: struct cheg_device {
300: pci_vendor_id_t cd_vendor;
301: pci_vendor_id_t cd_product;
302: u_int cd_nports;
303: };
304:
305: const struct cheg_device *cheg_lookup(struct pci_attach_args *);
306:
307: const struct cheg_device che_devices[] = {
308: { PCI_VENDOR_CHELSIO, PCI_PRODUCT_CHELSIO_PE9000, 2 },
309: { PCI_VENDOR_CHELSIO, PCI_PRODUCT_CHELSIO_T302E, 2 },
310: { PCI_VENDOR_CHELSIO, PCI_PRODUCT_CHELSIO_T302X, 2 },
311: { PCI_VENDOR_CHELSIO, PCI_PRODUCT_CHELSIO_T310E, 1 },
312: { PCI_VENDOR_CHELSIO, PCI_PRODUCT_CHELSIO_T310X, 1 },
313: { PCI_VENDOR_CHELSIO, PCI_PRODUCT_CHELSIO_T320E, 2 },
314: { PCI_VENDOR_CHELSIO, PCI_PRODUCT_CHELSIO_T320X, 2 },
315: { PCI_VENDOR_CHELSIO, PCI_PRODUCT_CHELSIO_T3B02, 2 },
316: { PCI_VENDOR_CHELSIO, PCI_PRODUCT_CHELSIO_T3B10, 1 },
317: { PCI_VENDOR_CHELSIO, PCI_PRODUCT_CHELSIO_T3B20, 2 }
318: };
319:
320: const struct cheg_device *
321: cheg_lookup(struct pci_attach_args *pa)
322: {
323: int i;
324: const struct cheg_device *cd;
325:
326: for (i = 0; i < sizeof(che_devices)/sizeof(che_devices[0]); i++) {
327: cd = &che_devices[i];
328: if (cd->cd_vendor == PCI_VENDOR(pa->pa_id) &&
329: cd->cd_product == PCI_PRODUCT(pa->pa_id))
330: return (cd);
331: }
332:
333: return (NULL);
334: }
335:
336: int
337: cheg_match(struct device *parent, void *match, void *aux)
338: {
339: struct pci_attach_args *pa = aux;
340:
341: if (cheg_lookup(pa) != NULL)
342: return (1);
343:
344: return (0);
345: }
346:
347: void
348: cheg_attach(struct device *parent, struct device *self, void *aux)
349: {
350: struct cheg_softc *sc = (struct cheg_softc *)self;
351: struct pci_attach_args *pa = aux;
352: const struct cheg_device *cd;
353: struct che_attach_args caa;
354: struct che_vpd vpd;
355: pcireg_t memtype;
356: u_int32_t vers;
357: u_int i;
358:
359: bzero(&caa, sizeof(caa));
360: cd = cheg_lookup(pa);
361:
362: sc->sc_dmat = pa->pa_dmat;
363:
364: memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, CHE_PCI_BAR);
365: if (pci_mapreg_map(pa, CHE_PCI_BAR, memtype, 0, &sc->sc_memt,
366: &sc->sc_memh, NULL, &sc->sc_mems, 0) != 0) {
367: printf(": unable to map host registers\n");
368: return;
369: }
370:
371: if (pci_intr_map(pa, &caa.caa_ih) != 0) {
372: printf(": unable to map interrupt\n");
373: goto unmap;
374: }
375:
376: sc->sc_rev = che_read(sc, CHE_REG_PL_REV);
377:
378: /* reset the beast */
379: che_reset(sc);
380:
381: if (che_read_flash_multi4(sc, FW_VERS_ADDR, &vers, 1) != 0) {
382: printf(": unable to read flash version\n");
383: goto unmap;
384: }
385:
386: if (che_get_vpd(sc, pa, &vpd, sizeof(vpd)/sizeof(u_int32_t)) != 0) {
387: printf(": unable to get vital product data\n");
388: goto unmap;
389: }
390:
391: printf(": %s revision %d firmware %s-%d.%d.%d\n",
392: pci_intr_string(pa->pa_pc, caa.caa_ih), sc->sc_rev,
393: FW_VERS_TYPE(vers) ? "T" : "N",
394: FW_VERS_MAJOR(vers), FW_VERS_MINOR(vers), FW_VERS_MICRO(vers));
395:
396: sc->sc_product = PCI_PRODUCT(pa->pa_id);
397: sc->sc_cclk = che_conv_num(vpd.cclk_data, sizeof(vpd.cclk_data));
398: sc->sc_mdc = che_conv_num(vpd.mdc_data, sizeof(vpd.mdc_data));
399:
400: che_hw_init(sc);
401:
402: caa.caa_pa = pa;
403: che_conv_lladdr(vpd.na_data, caa.caa_lladdr);
404:
405: for (i = 0; i < cd->cd_nports; i++) {
406: caa.caa_port = i;
407:
408: config_found(self, &caa, cheg_print);
409:
410: /*
411: * The VPD EEPROM stores only the base Ethernet address for the
412: * card. The last octet is increased by one for every additional
413: * port.
414: */
415: caa.caa_lladdr[5] += 1;
416: }
417:
418: return;
419:
420: unmap:
421: bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_mems);
422: sc->sc_mems = 0;
423: }
424:
425: int
426: cheg_print(void *aux, const char *pnp)
427: {
428: struct che_attach_args *caa = aux;
429:
430: if (pnp != NULL)
431: printf("\"%s\" at %s", che_cd.cd_name, pnp);
432:
433: printf(" port %d", caa->caa_port);
434:
435: return (UNCONF);
436: }
437:
438: int
439: che_match(struct device *parent, void *match, void *aux)
440: {
441: return (1);
442: }
443:
444: void
445: che_attach(struct device *parent, struct device *self, void *aux)
446: {
447: struct cheg_softc *gsc = (struct cheg_softc *)parent;
448: struct che_softc *sc = (struct che_softc *)self;
449: struct che_attach_args *caa = aux;
450: struct ifnet *ifp;
451:
452: sc->sc_cheg = gsc;
453:
454: sc->sc_port = caa->caa_port;
455: bcopy(caa->caa_lladdr, sc->sc_ac.ac_enaddr, ETHER_ADDR_LEN);
456:
457: printf(": address %s\n", ether_sprintf(sc->sc_ac.ac_enaddr));
458:
459: ifp = &sc->sc_ac.ac_if;
460: ifp->if_softc = sc;
461: ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
462: ifp->if_ioctl = che_ioctl;
463: ifp->if_start = che_start;
464: ifp->if_watchdog = che_watchdog;
465: ifp->if_hardmtu = MCLBYTES - ETHER_HDR_LEN - ETHER_CRC_LEN; /* XXX */
466: strlcpy(ifp->if_xname, DEVNAME(sc), IFNAMSIZ);
467: IFQ_SET_MAXLEN(&ifp->if_snd, 400);
468: IFQ_SET_READY(&ifp->if_snd);
469:
470: ifmedia_init(&sc->sc_mii.mii_media, 0,
471: che_ifmedia_upd, che_ifmedia_sts);
472:
473: sc->sc_mii.mii_ifp = ifp;
474: sc->sc_mii.mii_readreg = che_miibus_ind_readreg;
475: sc->sc_mii.mii_writereg = che_miibus_ind_writereg;
476: sc->sc_mii.mii_statchg = che_miibus_statchg;
477:
478: mii_attach(self, &sc->sc_mii, 0xffffffff, MII_PHY_ANY,
479: MII_OFFSET_ANY, MIIF_DOPAUSE | MIIF_HAVEFIBER);
480:
481: if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
482: printf("%s: no PHY found!\n", sc->sc_dev.dv_xname);
483: ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_MANUAL,
484: 0, NULL);
485: ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_MANUAL);
486: } else
487: ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
488:
489: if_attach(ifp);
490: ether_ifattach(ifp);
491:
492: return;
493: }
494:
495: int
496: che_write_flash_reg(struct cheg_softc *sc, size_t bcnt, int cont, u_int32_t v)
497: {
498: if (che_read(sc, CHE_REG_SF_OP) & CHE_SF_F_BUSY)
499: return (EBUSY);
500:
501: che_write(sc, CHE_REG_SF_DATA, v);
502: che_write(sc, CHE_REG_SF_OP, CHE_SF_CONT(cont) |
503: CHE_SF_BYTECNT(bcnt - 1) | CHE_SF_F_OP);
504:
505: return (che_waitfor(sc, CHE_REG_SF_OP, CHE_SF_F_BUSY, 5));
506: }
507:
508: int
509: che_read_flash_reg(struct cheg_softc *sc, size_t bcnt, int cont, u_int32_t *vp)
510: {
511: if (che_read(sc, CHE_REG_SF_OP) & CHE_SF_F_BUSY)
512: return (EBUSY);
513:
514: che_write(sc, CHE_REG_SF_OP, CHE_SF_CONT(cont) |
515: CHE_SF_BYTECNT(bcnt - 1));
516:
517: if (che_waitfor(sc, CHE_REG_SF_OP, CHE_SF_F_BUSY, 5))
518: return (EAGAIN);
519:
520: *vp = che_read(sc, CHE_REG_SF_DATA);
521: return (0);
522: }
523:
524: int
525: che_read_flash_multi4(struct cheg_softc *sc, u_int addr, u_int32_t *datap,
526: size_t count)
527: {
528: int rv;
529:
530: if (addr + count * sizeof(u_int32_t) > CHE_SF_SIZE || (addr & 3))
531: panic("%s: che_read_flash_multi4 bad params\n", DEVNAME(sc));
532:
533: addr = swap32(addr) | CHE_SF_RD_DATA;
534:
535: if ((rv = che_write_flash_reg(sc, 4, 1, addr)))
536: return (rv);
537: if ((rv = che_read_flash_reg(sc, 1, 1, datap)))
538: return (rv);
539:
540: while (count) {
541: if ((rv = che_read_flash_reg(sc, 4, count > 1, datap)))
542: return (rv);
543: count--;
544: datap++;
545: }
546: return (0);
547: }
548:
549: int
550: che_read_eeprom(struct cheg_softc *sc, struct pci_attach_args *pa,
551: pcireg_t addr, pcireg_t *dp)
552: {
553: pcireg_t rv, base;
554: int i = 4;
555:
556: if (!pci_get_capability(pa->pa_pc, pa->pa_tag, CHE_PCI_CAP_ID_VPD,
557: &base, NULL)) {
558: printf("%s: VPD EEPROM not found\n",
559: DEVNAME(sc), addr);
560: return EIO;
561: }
562:
563: addr <<= 16;
564: pci_conf_write(pa->pa_pc, pa->pa_tag, base, addr);
565:
566: while(i--) {
567: delay(10);
568: rv = pci_conf_read(pa->pa_pc, pa->pa_tag, base);
569: if (rv & CHE_PCI_F_VPD_ADDR)
570: break;
571: }
572: if (!(rv & CHE_PCI_F_VPD_ADDR)) {
573: printf("%s: reading EEPROM address 0x%x failed\n",
574: DEVNAME(sc), addr);
575: return EIO;
576: }
577:
578: *dp = pci_conf_read(pa->pa_pc, pa->pa_tag, base + CHE_PCI_VPD_DATA);
579: return (0);
580: }
581:
582: int
583: che_get_vpd(struct cheg_softc *sc, struct pci_attach_args *pa,
584: void *vpd, size_t dwords)
585: {
586: pcireg_t dw0, *dw = vpd;
587: int i;
588: u_int16_t addr;
589:
590: /*
591: * Card information is normally at CHE_PCI_VPD_BASE but some early
592: * cards had it at 0.
593: */
594: if (che_read_eeprom(sc, pa, CHE_PCI_VPD_BASE, &dw0))
595: return (1);
596:
597: /* we compare the id_tag which is least significant byte */
598: addr = ((dw0 & 0xff) == 0x82) ? CHE_PCI_VPD_BASE : 0;
599:
600: for (i = 0; i < dwords; i++) {
601: if (che_read_eeprom(sc, pa, addr + i * 4, &dw[i]))
602: return (1);
603: }
604:
605: return (0);
606: }
607:
608: /*
609: * VPD mac addr is stored as ASCII string so we need to convert it to a
610: * sane representation form.
611: */
612: void
613: che_conv_lladdr(char *mac, u_int8_t *lladdr)
614: {
615: int i;
616: u_int8_t digit;
617:
618: bzero(lladdr, ETHER_ADDR_LEN);
619:
620: for (i = 0; i < ETHER_ADDR_LEN * 2; i++) {
621: if (mac[i] >= '0' && mac[i] <= '9')
622: digit = mac[i] - '0';
623: else if (mac[i] >= 'A' && mac[i] <= 'F')
624: digit = mac[i] - 'A' + 10;
625: else if (mac[i] >= 'a' && mac[i] <= 'f')
626: digit = mac[i] - 'a' + 10;
627:
628: if ((i & 1) == 0)
629: digit <<= 4;
630:
631: lladdr[i/2] |= digit;
632: }
633: }
634:
635: u_int32_t
636: che_conv_num(char *num, size_t len)
637: {
638: size_t i;
639: u_int32_t n = 0;
640:
641: for (i = 0; i < len; i++) {
642: if (num[i] >= '0' && num[i] <= '9')
643: n = 10 * n + (num[i] - '0');
644: else
645: break;
646: }
647: return (n);
648: }
649:
650: void
651: che_reset(struct cheg_softc *sc)
652: {
653: che_write(sc, CHE_REG_PL_RST, CHE_RST_F_CRSTWRM |
654: CHE_RST_F_CRSTWRMMODE);
655:
656: /* Give the card some time to boot */
657: delay(500);
658: }
659:
660: int
661: che_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr)
662: {
663: return (EIO);
664: }
665:
666: void
667: che_watchdog(struct ifnet *ifp)
668: {
669: /* XXX */
670: }
671:
672: void
673: che_start(struct ifnet *ifp)
674: {
675: /* XXX */
676: }
677:
678: int
679: che_ifmedia_upd(struct ifnet *ifp)
680: {
681: struct che_softc *sc = ifp->if_softc;
682:
683: mii_mediachg(&sc->sc_mii);
684: return (0);
685: }
686:
687: void
688: che_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr)
689: {
690: struct che_softc *sc = ifp->if_softc;
691:
692: mii_pollstat(&sc->sc_mii);
693: ifmr->ifm_active = sc->sc_mii.mii_media_active;
694: ifmr->ifm_status = sc->sc_mii.mii_media_status;
695: }
696:
697: int
698: che_miibus_readreg(struct device *dev, int phy, int reg)
699: {
700: struct che_softc *sc = (struct che_softc *)dev;
701: u_int32_t addr = CHE_MI1_PHYADDR(phy) | reg;
702:
703: che_write(sc->sc_cheg, CHE_REG_MI1_ADDR, addr);
704: che_write(sc->sc_cheg, CHE_REG_MI1_OP, CHE_MI1_OP(2));
705:
706: if (che_waitfor(sc->sc_cheg, CHE_REG_MI1_OP, CHE_MI1_F_BUSY, 20))
707: return (0);
708:
709: return ((int)che_read(sc->sc_cheg, CHE_REG_MI1_DATA));
710: }
711:
712: void
713: che_miibus_writereg(struct device *dev, int phy, int reg, int val)
714: {
715: struct che_softc *sc = (struct che_softc *)dev;
716: u_int32_t addr = CHE_MI1_PHYADDR(phy) | reg;
717:
718: che_write(sc->sc_cheg, CHE_REG_MI1_ADDR, addr);
719: che_write(sc->sc_cheg, CHE_REG_MI1_DATA, val);
720: che_write(sc->sc_cheg, CHE_REG_MI1_OP, CHE_MI1_OP(1));
721: che_waitfor(sc->sc_cheg, CHE_REG_MI1_OP, CHE_MI1_F_BUSY, 20);
722: }
723:
724: int
725: che_miibus_ind_readreg(struct device *dev, int phy, int reg)
726: {
727: struct che_softc *sc = (struct che_softc *)dev;
728:
729: che_write(sc->sc_cheg, CHE_REG_MI1_ADDR, CHE_MI1_PHYADDR(phy));
730: che_write(sc->sc_cheg, CHE_REG_MI1_DATA, reg);
731: che_write(sc->sc_cheg, CHE_REG_MI1_OP, CHE_MI1_OP(0));
732:
733: if (che_waitfor(sc->sc_cheg, CHE_REG_MI1_OP, CHE_MI1_F_BUSY, 20))
734: return (0);
735:
736: che_write(sc->sc_cheg, CHE_REG_MI1_OP, CHE_MI1_OP(3));
737:
738: if (che_waitfor(sc->sc_cheg, CHE_REG_MI1_OP, CHE_MI1_F_BUSY, 20))
739: return (0);
740:
741: return ((int)che_read(sc->sc_cheg, CHE_REG_MI1_DATA));
742: }
743:
744: void
745: che_miibus_ind_writereg(struct device *dev, int phy, int reg, int val)
746: {
747: struct che_softc *sc = (struct che_softc *)dev;
748:
749: che_write(sc->sc_cheg, CHE_REG_MI1_ADDR, CHE_MI1_PHYADDR(phy));
750: che_write(sc->sc_cheg, CHE_REG_MI1_DATA, reg);
751: che_write(sc->sc_cheg, CHE_REG_MI1_OP, CHE_MI1_OP(0));
752:
753: if (che_waitfor(sc->sc_cheg, CHE_REG_MI1_OP, CHE_MI1_F_BUSY, 20))
754: return;
755:
756: che_write(sc->sc_cheg, CHE_REG_MI1_DATA, val);
757: che_write(sc->sc_cheg, CHE_REG_MI1_OP, CHE_MI1_OP(1));
758:
759: che_waitfor(sc->sc_cheg, CHE_REG_MI1_OP, CHE_MI1_F_BUSY, 20);
760: }
761:
762: void
763: che_miibus_statchg(struct device *dev)
764: {
765: struct che_softc *sc = (struct che_softc *)dev;
766: //struct mii_data *mii = &sc->sc_mii;
767:
768: printf("%s: che_miibus_statchg\n", DEVNAME(sc));
769: }
770:
771: u_int32_t
772: che_read(struct cheg_softc *sc, bus_size_t r)
773: {
774: bus_space_barrier(sc->sc_memt, sc->sc_memh, r, 4,
775: BUS_SPACE_BARRIER_READ);
776: return (bus_space_read_4(sc->sc_memt, sc->sc_memh, r));
777: }
778:
779: void
780: che_write(struct cheg_softc *sc, bus_size_t r, u_int32_t v)
781: {
782: bus_space_write_4(sc->sc_memt, sc->sc_memh, r, v);
783: bus_space_barrier(sc->sc_memt, sc->sc_memh, r, 4,
784: BUS_SPACE_BARRIER_WRITE);
785: }
786:
787: int
788: che_waitfor(struct cheg_softc *sc, bus_size_t r, u_int32_t mask, int tries)
789: {
790: u_int32_t v;
791: int i;
792:
793: for (i = 0; i < tries; i++) {
794: v = che_read(sc, r);
795: if ((v & mask) == 0)
796: return (0);
797: delay(10);
798: }
799: return (EAGAIN);
800: }
801:
802: void
803: che_hw_init(struct cheg_softc *sc)
804: {
805: u_int32_t mi1_reg;
806: u_int32_t i2c_reg;
807: u_int32_t gpio_reg;
808: u_int32_t port_reg;
809:
810: mi1_reg = CHE_MI1_F_PREEN |
811: CHE_MI1_CLKDIV(sc->sc_cclk / (2 * sc->sc_mdc) - 1);
812:
813: i2c_reg = CHE_I2C_CLKDIV(sc->sc_cclk / 80 - 1); /* 80KHz */
814:
815: gpio_reg = CHE_T3DBG_F_GPIO0_OEN | CHE_T3DBG_F_GPIO0_OUT_VAL;
816:
817: switch (sc->sc_product) {
818: case PCI_PRODUCT_CHELSIO_PE9000:
819: gpio_reg |= CHE_T3DBG_F_GPIO2_OEN | CHE_T3DBG_F_GPIO2_OUT_VAL |
820: CHE_T3DBG_F_GPIO4_OEN | CHE_T3DBG_F_GPIO4_OUT_VAL;
821: port_reg = CHE_XGM_PORTSPEED(2);
822: break;
823: case PCI_PRODUCT_CHELSIO_T302E:
824: case PCI_PRODUCT_CHELSIO_T302X:
825: case PCI_PRODUCT_CHELSIO_T3B02:
826: gpio_reg |= CHE_T3DBG_F_GPIO2_OEN | CHE_T3DBG_F_GPIO2_OUT_VAL |
827: CHE_T3DBG_F_GPIO4_OEN | CHE_T3DBG_F_GPIO4_OUT_VAL;
828: port_reg = CHE_XGM_PORTSPEED(2);
829: break;
830: case PCI_PRODUCT_CHELSIO_T310E:
831: case PCI_PRODUCT_CHELSIO_T310X:
832: case PCI_PRODUCT_CHELSIO_T3B10:
833: mi1_reg |= CHE_MI1_F_ST;
834: gpio_reg |= CHE_T3DBG_F_GPIO1_OEN | CHE_T3DBG_F_GPIO1_OUT_VAL |
835: CHE_T3DBG_F_GPIO6_OEN | CHE_T3DBG_F_GPIO6_OUT_VAL |
836: CHE_T3DBG_F_GPIO7_OEN |
837: CHE_T3DBG_F_GPIO10_OEN | CHE_T3DBG_F_GPIO10_OUT_VAL;
838: port_reg = CHE_XGM_PORTSPEED(3);
839: port_reg |= CHE_XGM_F_ENRGMII;
840: break;
841: case PCI_PRODUCT_CHELSIO_T320X:
842: case PCI_PRODUCT_CHELSIO_T320E:
843: case PCI_PRODUCT_CHELSIO_T3B20:
844: mi1_reg |= CHE_MI1_F_ST;
845: gpio_reg |= CHE_T3DBG_F_GPIO1_OEN | CHE_T3DBG_F_GPIO1_OUT_VAL |
846: CHE_T3DBG_F_GPIO2_OEN |
847: CHE_T3DBG_F_GPIO4_OEN |
848: CHE_T3DBG_F_GPIO5_OEN | CHE_T3DBG_F_GPIO5_OUT_VAL |
849: CHE_T3DBG_F_GPIO6_OEN | CHE_T3DBG_F_GPIO6_OUT_VAL |
850: CHE_T3DBG_F_GPIO7_OEN |
851: CHE_T3DBG_F_GPIO10_OEN | CHE_T3DBG_F_GPIO10_OUT_VAL |
852: CHE_T3DBG_F_GPIO11_OEN;
853: port_reg = CHE_XGM_PORTSPEED(3);
854: port_reg |= CHE_XGM_F_ENRGMII;
855: break;
856: }
857:
858: if (sc->sc_rev == 0)
859: port_reg |= CHE_XGM_F_ENRGMII;
860:
861: /* write all registers */
862: che_write(sc, CHE_REG_MI1_CFG, mi1_reg);
863: che_write(sc, CHE_REG_I2C_CFG, i2c_reg);
864: che_write(sc, CHE_REG_T3DBG_GPIO_EN, gpio_reg);
865:
866: che_write(sc, CHE_REG_XGM_PORT_CFG, port_reg);
867: (void)che_read(sc, CHE_REG_XGM_PORT_CFG);
868:
869: port_reg |= CHE_XGM_F_CLKDIVRESET;
870:
871: che_write(sc, CHE_REG_XGM_PORT_CFG, port_reg);
872: (void)che_read(sc, CHE_REG_XGM_PORT_CFG);
873: che_write(sc, CHE_XGM_REG(CHE_REG_XGM_PORT_CFG, 1), port_reg);
874: (void)che_read(sc, CHE_REG_XGM_PORT_CFG);
875: }
CVSweb