1 /*	$OpenBSD: if_dc_cardbus.c,v 1.21 2005/06/15 20:53:32 brad Exp $	*/
2 
3 #include <sys/param.h>
4 #include <sys/systm.h>
5 #include <sys/mbuf.h>
6 #include <sys/socket.h>
7 #include <sys/ioctl.h>
8 #include <sys/errno.h>
9 #include <sys/malloc.h>
10 #include <sys/kernel.h>
11 #include <sys/proc.h>
12 #include <sys/device.h>
13 
14 #include <net/if.h>
15 #include <net/if_dl.h>
16 #include <net/if_types.h>
17 #include <net/if_media.h>
18 
19 #include <netinet/in.h>
20 #include <netinet/if_ether.h>
21 
22 #include <dev/mii/mii.h>
23 #include <dev/mii/miivar.h>
24 
25 #include <machine/bus.h>
26 
27 #include <dev/pci/pcivar.h>
28 #include <dev/pci/pcireg.h>
29 #include <dev/pci/pcidevs.h>
30 
31 #include <dev/cardbus/cardbusvar.h>
32 
33 #include <dev/ic/dcreg.h>
34 
35 /* PCI configuration regs */
36 #define	PCI_CBIO	0x10
37 #define	PCI_CBMEM	0x14
38 #define	PCI_CFDA	0x40
39 
40 #define	DC_CFDA_SUSPEND	0x80000000
41 #define	DC_CFDA_STANDBY	0x40000000
42 
43 struct dc_cardbus_softc {
44 	struct dc_softc		sc_dc;
45 	int			sc_intrline;
46 
47 	cardbus_devfunc_t	sc_ct;
48 	cardbustag_t		sc_tag;
49 	bus_size_t		sc_mapsize;
50 	int			sc_actype;
51 };
52 
53 int dc_cardbus_match(struct device *, void *, void *);
54 void dc_cardbus_attach(struct device *, struct device *,void *);
55 int dc_cardbus_detach(struct device *, int);
56 
57 void dc_cardbus_setup(struct dc_cardbus_softc *csc);
58 
59 struct cfattach dc_cardbus_ca = {
60 	sizeof(struct dc_cardbus_softc), dc_cardbus_match, dc_cardbus_attach,
61 	    dc_cardbus_detach
62 };
63 
64 const struct cardbus_matchid dc_cardbus_devices[] = {
65 	{ PCI_VENDOR_DEC, PCI_PRODUCT_DEC_21142 },
66 	{ PCI_VENDOR_XIRCOM, PCI_PRODUCT_XIRCOM_X3201_3_21143 },
67 	{ PCI_VENDOR_ADMTEK, PCI_PRODUCT_ADMTEK_AN985 },
68 	{ PCI_VENDOR_ACCTON, PCI_PRODUCT_ACCTON_EN2242 },
69 	{ PCI_VENDOR_ABOCOM, PCI_PRODUCT_ABOCOM_FE2500 },
70 	{ PCI_VENDOR_ABOCOM, PCI_PRODUCT_ABOCOM_FE2500MX },
71 	{ PCI_VENDOR_ABOCOM, PCI_PRODUCT_ABOCOM_PCM200 },
72 	{ PCI_VENDOR_LINKSYS, PCI_PRODUCT_LINKSYS_PCMPC200 },
73 	{ PCI_VENDOR_LINKSYS, PCI_PRODUCT_LINKSYS_PCM200 },
74 	{ PCI_VENDOR_HAWKING, PCI_PRODUCT_HAWKING_PN672TX },
75 	{ PCI_VENDOR_MICROSOFT, PCI_PRODUCT_MICROSOFT_MN120 },
76 };
77 
78 int
dc_cardbus_match(parent,match,aux)79 dc_cardbus_match(parent, match, aux)
80 	struct device *parent;
81 	void *match, *aux;
82 {
83 	return (cardbus_matchbyid((struct cardbus_attach_args *)aux,
84 	    dc_cardbus_devices,
85 	    sizeof(dc_cardbus_devices)/sizeof(dc_cardbus_devices[0])));
86 }
87 
88 void
dc_cardbus_attach(parent,self,aux)89 dc_cardbus_attach(parent, self, aux)
90 	struct device *parent, *self;
91 	void *aux;
92 {
93 	struct dc_cardbus_softc *csc = (struct dc_cardbus_softc *)self;
94 	struct dc_softc *sc = &csc->sc_dc;
95 	struct cardbus_attach_args *ca = aux;
96 	struct cardbus_devfunc *ct = ca->ca_ct;
97 	cardbus_chipset_tag_t cc = ct->ct_cc;
98 	cardbus_function_tag_t cf = ct->ct_cf;
99 	cardbusreg_t reg;
100 	bus_addr_t addr;
101 
102 	sc->sc_dmat = ca->ca_dmat;
103 	csc->sc_ct = ct;
104 	csc->sc_tag = ca->ca_tag;
105 
106 	Cardbus_function_enable(ct);
107 
108 	if (Cardbus_mapreg_map(ct, PCI_CBIO,
109 	    PCI_MAPREG_TYPE_IO, 0, &sc->dc_btag, &sc->dc_bhandle, &addr,
110 	    &csc->sc_mapsize) == 0) {
111 
112 		csc->sc_actype = CARDBUS_IO_ENABLE;
113 	} else if (Cardbus_mapreg_map(ct, PCI_CBMEM,
114 	    PCI_MAPREG_TYPE_MEM|PCI_MAPREG_MEM_TYPE_32BIT, 0,
115 	    &sc->dc_btag, &sc->dc_bhandle, &addr, &csc->sc_mapsize) == 0) {
116 		csc->sc_actype = CARDBUS_MEM_ENABLE;
117 	} else {
118 		printf(": can\'t map device registers\n");
119 		return;
120 	}
121 
122 	csc->sc_intrline = ca->ca_intrline;
123 
124 	sc->dc_cachesize = cardbus_conf_read(cc, cf, ca->ca_tag, DC_PCI_CFLT)
125 	    & 0xFF;
126 
127 	dc_cardbus_setup(csc);
128 
129 	/* Get the eeprom width, but XIRCOM has no eeprom */
130 	if (!(PCI_VENDOR(ca->ca_id) == PCI_VENDOR_XIRCOM &&
131 	      PCI_PRODUCT(ca->ca_id) == PCI_PRODUCT_XIRCOM_X3201_3_21143))
132 		dc_eeprom_width(sc);
133 
134 	switch (PCI_VENDOR(ca->ca_id)) {
135 	case PCI_VENDOR_DEC:
136 		if (PCI_PRODUCT(ca->ca_id) == PCI_PRODUCT_DEC_21142) {
137 			sc->dc_type = DC_TYPE_21143;
138 			sc->dc_flags |= DC_TX_POLL|DC_TX_USE_TX_INTR;
139 			sc->dc_flags |= DC_REDUCED_MII_POLL;
140 			dc_read_srom(sc, sc->dc_romwidth);
141 			dc_parse_21143_srom(sc);
142 		}
143 		break;
144 	case PCI_VENDOR_XIRCOM:
145 		if (PCI_PRODUCT(ca->ca_id) ==
146 		    PCI_PRODUCT_XIRCOM_X3201_3_21143) {
147 			sc->dc_type = DC_TYPE_XIRCOM;
148 			sc->dc_flags |= DC_TX_INTR_ALWAYS|DC_TX_COALESCE |
149 					DC_TX_ALIGN;
150 			sc->dc_pmode = DC_PMODE_MII;
151 
152 			bcopy(ca->ca_cis.funce.network.netid,
153 			    &sc->sc_arpcom.ac_enaddr,
154 			    sizeof sc->sc_arpcom.ac_enaddr);
155 		}
156 		break;
157 	case PCI_VENDOR_ADMTEK:
158 	case PCI_VENDOR_ACCTON:
159 	case PCI_VENDOR_ABOCOM:
160 	case PCI_VENDOR_LINKSYS:
161 	case PCI_VENDOR_HAWKING:
162 	case PCI_VENDOR_MICROSOFT:
163 		if (PCI_PRODUCT(ca->ca_id) == PCI_PRODUCT_ADMTEK_AN985 ||
164 		    PCI_PRODUCT(ca->ca_id) == PCI_PRODUCT_ACCTON_EN2242 ||
165 		    PCI_PRODUCT(ca->ca_id) == PCI_PRODUCT_ABOCOM_FE2500 ||
166 		    PCI_PRODUCT(ca->ca_id) == PCI_PRODUCT_ABOCOM_FE2500MX ||
167 		    PCI_PRODUCT(ca->ca_id) == PCI_PRODUCT_ABOCOM_PCM200 ||
168 		    PCI_PRODUCT(ca->ca_id) == PCI_PRODUCT_LINKSYS_PCMPC200 ||
169 		    PCI_PRODUCT(ca->ca_id) == PCI_PRODUCT_LINKSYS_PCM200 ||
170 		    PCI_PRODUCT(ca->ca_id) == PCI_PRODUCT_HAWKING_PN672TX ||
171 		    PCI_PRODUCT(ca->ca_id) == PCI_PRODUCT_MICROSOFT_MN120) {
172 			sc->dc_type = DC_TYPE_AN983;
173 			sc->dc_flags |= DC_TX_USE_TX_INTR|DC_TX_ADMTEK_WAR |
174 					DC_64BIT_HASH;
175 			sc->dc_pmode = DC_PMODE_MII;
176 			/* Don't read SROM for - auto-loaded on reset */
177 		}
178 		break;
179 	default:
180 		printf(": unknown device\n");
181 		return;
182 	}
183 
184  	/*
185 	 * set latency timer, do we really need this?
186 	 */
187 	reg = cardbus_conf_read(cc, cf, ca->ca_tag, PCI_BHLC_REG);
188 	if (PCI_LATTIMER(reg) < 0x20) {
189 		reg &= ~(PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT);
190 		reg |= (0x20 << PCI_LATTIMER_SHIFT);
191 		cardbus_conf_write(cc, cf, ca->ca_tag, PCI_BHLC_REG, reg);
192 	}
193 
194 	sc->sc_ih = cardbus_intr_establish(cc, cf, ca->ca_intrline, IPL_NET,
195 	    dc_intr, csc);
196 	if (sc->sc_ih == NULL) {
197 		printf(": can't establish interrupt at %d\n",
198 		    ca->ca_intrline);
199 		return;
200 	} else
201 		printf(" irq %d", ca->ca_intrline);
202 
203 	dc_reset(sc);
204 
205 	sc->dc_revision = PCI_REVISION(ca->ca_class);
206 	dc_attach(sc);
207 }
208 
209 int
dc_cardbus_detach(self,flags)210 dc_cardbus_detach(self, flags)
211 	struct device *self;
212 	int flags;
213 {
214 	struct dc_cardbus_softc *csc = (struct dc_cardbus_softc *)self;
215 	struct dc_softc *sc = &csc->sc_dc;
216 	struct cardbus_devfunc *ct = csc->sc_ct;
217 	int rv = 0;
218 
219 	rv = dc_detach(sc);
220 	if (rv)
221 		return (rv);
222 
223 	cardbus_intr_disestablish(ct->ct_cc, ct->ct_cf, sc->sc_ih);
224 
225 	/* unmap cardbus resources */
226 	Cardbus_mapreg_unmap(ct,
227 	    csc->sc_actype == CARDBUS_IO_ENABLE ? PCI_CBIO : PCI_CBMEM,
228 	    sc->dc_btag, sc->dc_bhandle, csc->sc_mapsize);
229 
230 	return (rv);
231 }
232 
233 void
dc_cardbus_setup(csc)234 dc_cardbus_setup(csc)
235 	struct dc_cardbus_softc *csc;
236 {
237 	cardbus_devfunc_t ct = csc->sc_ct;
238 	cardbus_chipset_tag_t cc = ct->ct_cc;
239 	cardbus_function_tag_t cf = ct->ct_cf;
240 	cardbusreg_t reg;
241 	int r;
242 
243 	/* wakeup the card if needed */
244 	reg = cardbus_conf_read(cc, cf, csc->sc_tag, PCI_CFDA);
245 	if (reg | (DC_CFDA_SUSPEND|DC_CFDA_STANDBY)) {
246 		cardbus_conf_write(cc, cf, csc->sc_tag, PCI_CFDA,
247 		    reg & ~(DC_CFDA_SUSPEND|DC_CFDA_STANDBY));
248 	}
249 
250 	if (cardbus_get_capability(cc, cf, csc->sc_tag, PCI_CAP_PWRMGMT, &r,
251 	    0)) {
252 		r = cardbus_conf_read(cc, cf, csc->sc_tag, r + 4) & 3;
253 		if (r) {
254 			printf("%s: awakening from state D%d\n",
255 			    csc->sc_dc.sc_dev.dv_xname, r);
256 			cardbus_conf_write(cc, cf, csc->sc_tag, r + 4, 0);
257 		}
258 	}
259 
260 	(*ct->ct_cf->cardbus_ctrl)(cc, csc->sc_actype);
261 	(*ct->ct_cf->cardbus_ctrl)(cc, CARDBUS_BM_ENABLE);
262 
263 	reg = cardbus_conf_read(cc, cf, csc->sc_tag, PCI_COMMAND_STATUS_REG);
264 	reg |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE |
265 	    PCI_COMMAND_MASTER_ENABLE;
266 	cardbus_conf_write(cc, cf, csc->sc_tag, PCI_COMMAND_STATUS_REG, reg);
267 	reg = cardbus_conf_read(cc, cf, csc->sc_tag, PCI_COMMAND_STATUS_REG);
268 }
269