This source file includes following definitions.
- epic_pci_subsys_lookup
- epic_pci_match
- epic_pci_attach
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 #if 0
47 #include <sys/cdefs.h>
48 __KERNEL_RCSID(0, "$NetBSD: if_epic_pci.c,v 1.28 2005/02/27 00:27:32 perry Exp $");
49 #endif
50
51 #include <sys/param.h>
52 #include <sys/systm.h>
53 #include <sys/mbuf.h>
54 #include <sys/malloc.h>
55 #include <sys/kernel.h>
56 #include <sys/socket.h>
57 #include <sys/ioctl.h>
58 #include <sys/errno.h>
59 #include <sys/device.h>
60
61 #include <net/if.h>
62 #include <net/if_dl.h>
63 #include <net/if_types.h>
64
65 #ifdef INET
66 #include <netinet/in.h>
67 #include <netinet/in_systm.h>
68 #include <netinet/in_var.h>
69 #include <netinet/ip.h>
70 #include <netinet/if_ether.h>
71 #endif
72
73 #include <net/if_media.h>
74
75 #include <machine/bus.h>
76 #include <machine/intr.h>
77
78 #include <dev/mii/miivar.h>
79
80 #include <dev/ic/smc83c170reg.h>
81 #include <dev/ic/smc83c170var.h>
82
83 #include <dev/pci/pcivar.h>
84 #include <dev/pci/pcireg.h>
85 #include <dev/pci/pcidevs.h>
86
87
88
89
90 #define EPIC_PCI_IOBA 0x10
91 #define EPIC_PCI_MMBA 0x14
92
93 struct epic_pci_softc {
94 struct epic_softc sc_epic;
95
96
97 void *sc_ih;
98 };
99
100 int epic_pci_match(struct device *, void *, void *);
101 void epic_pci_attach(struct device *, struct device *, void *);
102
103 struct cfattach epic_pci_ca = {
104 sizeof(struct epic_pci_softc), epic_pci_match, epic_pci_attach
105 };
106
107 const struct pci_matchid epic_pci_devices[] = {
108 { PCI_VENDOR_SMC, PCI_PRODUCT_SMC_83C170 },
109 { PCI_VENDOR_SMC, PCI_PRODUCT_SMC_83C175 },
110 };
111
112 static const struct epic_pci_subsys_info {
113 pcireg_t subsysid;
114 int flags;
115 } epic_pci_subsys_info[] = {
116 { PCI_ID_CODE(PCI_VENDOR_SMC, 0xa015),
117 EPIC_HAS_BNC },
118 { PCI_ID_CODE(PCI_VENDOR_SMC, 0xa024),
119 EPIC_HAS_BNC },
120 { PCI_ID_CODE(PCI_VENDOR_SMC, 0xa016),
121 EPIC_HAS_MII_FIBER | EPIC_DUPLEXLED_ON_694 },
122 { 0xffffffff,
123 0 }
124 };
125
126 static const struct epic_pci_subsys_info *
127 epic_pci_subsys_lookup(const struct pci_attach_args *pa)
128 {
129 pci_chipset_tag_t pc = pa->pa_pc;
130 pcireg_t reg;
131 const struct epic_pci_subsys_info *esp;
132
133 reg = pci_conf_read(pc, pa->pa_tag, PCI_SUBSYS_ID_REG);
134
135 for (esp = epic_pci_subsys_info; esp->subsysid != 0xffffffff; esp++)
136 if (esp->subsysid == reg)
137 return (esp);
138
139 return (NULL);
140 }
141
142 int
143 epic_pci_match(struct device *parent, void *match, void *aux)
144 {
145 return (pci_matchbyid((struct pci_attach_args *)aux, epic_pci_devices,
146 sizeof(epic_pci_devices)/sizeof(epic_pci_devices[0])));
147 }
148
149 void
150 epic_pci_attach(struct device *parent, struct device *self, void *aux)
151 {
152 struct epic_pci_softc *psc = (struct epic_pci_softc *)self;
153 struct epic_softc *sc = &psc->sc_epic;
154 struct pci_attach_args *pa = aux;
155 pci_chipset_tag_t pc = pa->pa_pc;
156 pci_intr_handle_t ih;
157 const char *intrstr = NULL;
158 const struct epic_pci_subsys_info *esp;
159 bus_space_tag_t iot, memt;
160 bus_space_handle_t ioh, memh;
161 pcireg_t reg;
162 int pmreg, ioh_valid, memh_valid;
163
164 if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PWRMGMT, &pmreg, 0)) {
165 reg = pci_conf_read(pc, pa->pa_tag, pmreg + PCI_PMCSR);
166 switch (reg & PCI_PMCSR_STATE_MASK) {
167 case PCI_PMCSR_STATE_D1:
168 case PCI_PMCSR_STATE_D2:
169 printf(": waking up from power state D%d\n",
170 reg & PCI_PMCSR_STATE_MASK);
171 pci_conf_write(pc, pa->pa_tag, pmreg + PCI_PMCSR,
172 (reg & ~PCI_PMCSR_STATE_MASK) |
173 PCI_PMCSR_STATE_D0);
174 break;
175 case PCI_PMCSR_STATE_D3:
176
177
178
179
180 printf(
181 ": unable to wake up from power state D3, "
182 "reboot required.\n");
183 pci_conf_write(pc, pa->pa_tag, pmreg + PCI_PMCSR,
184 (reg & ~PCI_PMCSR_STATE_MASK) |
185 PCI_PMCSR_STATE_D0);
186 return;
187 }
188 }
189
190
191
192
193 ioh_valid = (pci_mapreg_map(pa, EPIC_PCI_IOBA,
194 PCI_MAPREG_TYPE_IO, 0,
195 &iot, &ioh, NULL, NULL, 0) == 0);
196 memh_valid = (pci_mapreg_map(pa, EPIC_PCI_MMBA,
197 PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0,
198 &memt, &memh, NULL, NULL, 0) == 0);
199
200 if (memh_valid) {
201 sc->sc_st = memt;
202 sc->sc_sh = memh;
203 } else if (ioh_valid) {
204 sc->sc_st = iot;
205 sc->sc_sh = ioh;
206 } else {
207 printf(": unable to map device registers\n");
208 return;
209 }
210
211 sc->sc_dmat = pa->pa_dmat;
212
213
214
215
216 if (pci_intr_map(pa, &ih)) {
217 printf(": unable to map interrupt\n");
218 return;
219 }
220 intrstr = pci_intr_string(pc, ih);
221 psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, epic_intr, sc,
222 self->dv_xname);
223 if (psc->sc_ih == NULL) {
224 printf(": unable to establish interrupt");
225 if (intrstr != NULL)
226 printf(" at %s", intrstr);
227 printf("\n");
228 return;
229 }
230
231 esp = epic_pci_subsys_lookup(pa);
232 if (esp)
233 sc->sc_hwflags = esp->flags;
234
235
236
237
238 epic_attach(sc, intrstr);
239 }