1 | /* $NetBSD: cs89x0.c,v 1.37 2016/06/10 13:27:13 ozaki-r Exp $ */ |
2 | |
3 | /* |
4 | * Copyright (c) 2004 Christopher Gilbert |
5 | * All rights reserved. |
6 | * |
7 | * 1. Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. |
9 | * 2. Redistributions in binary form must reproduce the above copyright |
10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. |
12 | * 3. The name of the company nor the name of the author may be used to |
13 | * endorse or promote products derived from this software without specific |
14 | * prior written permission. |
15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED |
17 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
18 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
19 | * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
20 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
22 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
23 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
24 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
25 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
26 | * SUCH DAMAGE. |
27 | */ |
28 | |
29 | /* |
30 | * Copyright 1997 |
31 | * Digital Equipment Corporation. All rights reserved. |
32 | * |
33 | * This software is furnished under license and may be used and |
34 | * copied only in accordance with the following terms and conditions. |
35 | * Subject to these conditions, you may download, copy, install, |
36 | * use, modify and distribute this software in source and/or binary |
37 | * form. No title or ownership is transferred hereby. |
38 | * |
39 | * 1) Any source code used, modified or distributed must reproduce |
40 | * and retain this copyright notice and list of conditions as |
41 | * they appear in the source file. |
42 | * |
43 | * 2) No right is granted to use any trade name, trademark, or logo of |
44 | * Digital Equipment Corporation. Neither the "Digital Equipment |
45 | * Corporation" name nor any trademark or logo of Digital Equipment |
46 | * Corporation may be used to endorse or promote products derived |
47 | * from this software without the prior written permission of |
48 | * Digital Equipment Corporation. |
49 | * |
50 | * 3) This software is provided "AS-IS" and any express or implied |
51 | * warranties, including but not limited to, any implied warranties |
52 | * of merchantability, fitness for a particular purpose, or |
53 | * non-infringement are disclaimed. In no event shall DIGITAL be |
54 | * liable for any damages whatsoever, and in particular, DIGITAL |
55 | * shall not be liable for special, indirect, consequential, or |
56 | * incidental damages or damages for lost profits, loss of |
57 | * revenue or loss of use, whether such damages arise in contract, |
58 | * negligence, tort, under statute, in equity, at law or otherwise, |
59 | * even if advised of the possibility of such damage. |
60 | */ |
61 | |
62 | /* |
63 | **++ |
64 | ** FACILITY |
65 | ** |
66 | ** Device Driver for the Crystal CS8900 ISA Ethernet Controller. |
67 | ** |
68 | ** ABSTRACT |
69 | ** |
70 | ** This module provides standard ethernet access for INET protocols |
71 | ** only. |
72 | ** |
73 | ** AUTHORS |
74 | ** |
75 | ** Peter Dettori SEA - Software Engineering. |
76 | ** |
77 | ** CREATION DATE: |
78 | ** |
79 | ** 13-Feb-1997. |
80 | ** |
81 | ** MODIFICATION HISTORY (Digital): |
82 | ** |
83 | ** Revision 1.27 1998/01/20 17:59:40 cgd |
84 | ** update for moved headers |
85 | ** |
86 | ** Revision 1.26 1998/01/12 19:29:36 cgd |
87 | ** use arm32/isa versions of isadma code. |
88 | ** |
89 | ** Revision 1.25 1997/12/12 01:35:27 cgd |
90 | ** convert to use new arp code (from Brini) |
91 | ** |
92 | ** Revision 1.24 1997/12/10 22:31:56 cgd |
93 | ** trim some fat (get rid of ability to explicitly supply enet addr, since |
94 | ** it was never used and added a bunch of code which really doesn't belong in |
95 | ** an enet driver), and clean up slightly. |
96 | ** |
97 | ** Revision 1.23 1997/10/06 16:42:12 cgd |
98 | ** copyright notices |
99 | ** |
100 | ** Revision 1.22 1997/06/20 19:38:01 chaiken |
101 | ** fixes some smartcard problems |
102 | ** |
103 | ** Revision 1.21 1997/06/10 02:56:20 grohn |
104 | ** Added call to ledNetActive |
105 | ** |
106 | ** Revision 1.20 1997/06/05 00:47:06 dettori |
107 | ** Changed cs_process_rx_dma to reset and re-initialise the |
108 | ** ethernet chip when DMA gets out of sync, or mbufs |
109 | ** can't be allocated. |
110 | ** |
111 | ** Revision 1.19 1997/06/03 03:09:58 dettori |
112 | ** Turn off sc_txbusy flag when a transmit underrun |
113 | ** occurs. |
114 | ** |
115 | ** Revision 1.18 1997/06/02 00:04:35 dettori |
116 | ** redefined the transmit table to get around the nfs_timer bug while we are |
117 | ** looking into it further. |
118 | ** |
119 | ** Also changed interrupts from EDGE to LEVEL. |
120 | ** |
121 | ** Revision 1.17 1997/05/27 23:31:01 dettori |
122 | ** Pulled out changes to DMAMODE defines. |
123 | ** |
124 | ** Revision 1.16 1997/05/23 04:25:16 cgd |
125 | ** reformat log so it fits in 80cols |
126 | ** |
127 | ** Revision 1.15 1997/05/23 04:22:18 cgd |
128 | ** remove the existing copyright notice (which Peter Dettori indicated |
129 | ** was incorrect, copied from an existing NetBSD file only so that the |
130 | ** file would have a copyright notice on it, and which he'd intended to |
131 | ** replace). Replace it with a Digital copyright notice, cloned from |
132 | ** ess.c. It's not really correct either (it indicates that the source |
133 | ** is Digital confidential!), but is better than nothing and more |
134 | ** correct than what was there before. |
135 | ** |
136 | ** Revision 1.14 1997/05/23 04:12:50 cgd |
137 | ** use an adaptive transmit start algorithm: start by telling the chip |
138 | ** to start transmitting after 381 bytes have been fed to it. if that |
139 | ** gets transmit underruns, ramp down to 1021 bytes then "whole |
140 | ** packet." If successful at a given level for a while, try the next |
141 | ** more agressive level. This code doesn't ever try to start |
142 | ** transmitting after 5 bytes have been sent to the NIC, because |
143 | ** that underruns rather regularly. The back-off and ramp-up mechanism |
144 | ** could probably be tuned a little bit, but this works well enough to |
145 | ** support > 1MB/s transmit rates on a clear ethernet (which is about |
146 | ** 20-25% better than the driver had previously been getting). |
147 | ** |
148 | ** Revision 1.13 1997/05/22 21:06:54 cgd |
149 | ** redo cs_copy_tx_frame() from scratch. It had a fatal flaw: it was blindly |
150 | ** casting from u_int8_t * to u_int16_t * without worrying about alignment |
151 | ** issues. This would cause bogus data to be spit out for mbufs with |
152 | ** misaligned data. For instance, it caused the following bits to appear |
153 | ** on the wire: |
154 | ** ... etBND 1S2C .SHA(K) R ... |
155 | ** 11112222333344445555 |
156 | ** which should have appeared as: |
157 | ** ... NetBSD 1.2C (SHARK) ... |
158 | ** 11112222333344445555 |
159 | ** Note the apparent 'rotate' of the bytes in the word, which was due to |
160 | ** incorrect unaligned accesses. This data corruption was the cause of |
161 | ** incoming telnet/rlogin hangs. |
162 | ** |
163 | ** Revision 1.12 1997/05/22 01:55:32 cgd |
164 | ** reformat log so it fits in 80cols |
165 | ** |
166 | ** Revision 1.11 1997/05/22 01:50:27 cgd |
167 | ** * enable input packet address checking in the BPF+IFF_PROMISCUOUS case, |
168 | ** so packets aimed at other hosts don't get sent to ether_input(). |
169 | ** * Add a static const char *rcsid initialized with an RCS Id tag, so that |
170 | ** you can easily tell (`strings`) what version of the driver is in your |
171 | ** kernel binary. |
172 | ** * get rid of ether_cmp(). It was inconsistently used, not necessarily |
173 | ** safe, and not really a performance win anyway. (It was only used when |
174 | ** setting up the multicast logical address filter, which is an |
175 | ** infrequent event. It could have been used in the IFF_PROMISCUOUS |
176 | ** address check above, but the benefit of it vs. memcmp would be |
177 | ** inconsequential, there.) Use memcmp() instead. |
178 | ** * restructure csStartOuput to avoid the following bugs in the case where |
179 | ** txWait was being set: |
180 | ** * it would accidentally drop the outgoing packet if told to wait |
181 | ** but the outgoing packet queue was empty. |
182 | ** * it would bpf_mtap() the outgoing packet multiple times (once for |
183 | ** each time it was told to wait), and would also recalculate |
184 | ** the length of the outgoing packet each time it was told to |
185 | ** wait. |
186 | ** While there, rename txWait to txLoop, since with the new structure of |
187 | ** the code, the latter name makes more sense. |
188 | ** |
189 | ** Revision 1.10 1997/05/19 02:03:20 cgd |
190 | ** Set RX_CTL in cs_set_ladr_filt(), rather than cs_initChip(). cs_initChip() |
191 | ** is the only caller of cs_set_ladr_filt(), and always calls it, so this |
192 | ** ends up being logically the same. In cs_set_ladr_filt(), if IFF_PROMISC |
193 | ** is set, enable promiscuous mode (and set IFF_ALLMULTI), otherwise behave |
194 | ** as before. |
195 | ** |
196 | ** Revision 1.9 1997/05/19 01:45:37 cgd |
197 | ** create a new function, cs_ether_input(), which does received-packet |
198 | ** BPF and ether_input processing. This code used to be in three places, |
199 | ** and centralizing it will make adding IFF_PROMISC support much easier. |
200 | ** Also, in cs_copy_tx_frame(), put it some (currently disabled) code to |
201 | ** do copies with bus_space_write_region_2(). It's more correct, and |
202 | ** potentially more efficient. That function needs to be gutted (to |
203 | ** deal properly with alignment issues, which it currently does wrong), |
204 | ** however, and the change doesn't gain much, so there's no point in |
205 | ** enabling it now. |
206 | ** |
207 | ** Revision 1.8 1997/05/19 01:17:10 cgd |
208 | ** fix a comment re: the setting of the TxConfig register. Clean up |
209 | ** interface counter maintenance (make it use standard idiom). |
210 | ** |
211 | **-- |
212 | */ |
213 | |
214 | #include <sys/cdefs.h> |
215 | __KERNEL_RCSID(0, "$NetBSD: cs89x0.c,v 1.37 2016/06/10 13:27:13 ozaki-r Exp $" ); |
216 | |
217 | #include "opt_inet.h" |
218 | |
219 | #include <sys/param.h> |
220 | #include <sys/systm.h> |
221 | #include <sys/mbuf.h> |
222 | #include <sys/syslog.h> |
223 | #include <sys/socket.h> |
224 | #include <sys/device.h> |
225 | #include <sys/malloc.h> |
226 | #include <sys/ioctl.h> |
227 | #include <sys/errno.h> |
228 | |
229 | #include <sys/rndsource.h> |
230 | |
231 | #include <net/if.h> |
232 | #include <net/if_ether.h> |
233 | #include <net/if_media.h> |
234 | #ifdef INET |
235 | #include <netinet/in.h> |
236 | #include <netinet/if_inarp.h> |
237 | #endif |
238 | |
239 | #include <net/bpf.h> |
240 | #include <net/bpfdesc.h> |
241 | |
242 | #include <sys/bus.h> |
243 | #include <sys/intr.h> |
244 | |
245 | #include <dev/ic/cs89x0reg.h> |
246 | #include <dev/ic/cs89x0var.h> |
247 | |
248 | #ifdef SHARK |
249 | #include <shark/shark/sequoia.h> |
250 | #endif |
251 | |
252 | /* |
253 | * MACRO DEFINITIONS |
254 | */ |
255 | #define CS_OUTPUT_LOOP_MAX 100 /* max times round notorious tx loop */ |
256 | |
257 | /* |
258 | * FUNCTION PROTOTYPES |
259 | */ |
260 | static void cs_get_default_media(struct cs_softc *); |
261 | static int cs_get_params(struct cs_softc *); |
262 | static int cs_get_enaddr(struct cs_softc *); |
263 | static int cs_reset_chip(struct cs_softc *); |
264 | static void cs_reset(struct cs_softc *); |
265 | static int cs_ioctl(struct ifnet *, u_long, void *); |
266 | static void cs_initChip(struct cs_softc *); |
267 | static void cs_buffer_event(struct cs_softc *, u_int16_t); |
268 | static void cs_transmit_event(struct cs_softc *, u_int16_t); |
269 | static void cs_receive_event(struct cs_softc *, u_int16_t); |
270 | static void cs_process_receive(struct cs_softc *); |
271 | static void cs_process_rx_early(struct cs_softc *); |
272 | static void cs_start_output(struct ifnet *); |
273 | static void cs_copy_tx_frame(struct cs_softc *, struct mbuf *); |
274 | static void cs_set_ladr_filt(struct cs_softc *, struct ethercom *); |
275 | static u_int16_t cs_hash_index(char *); |
276 | static void cs_counter_event(struct cs_softc *, u_int16_t); |
277 | |
278 | static int cs_mediachange(struct ifnet *); |
279 | static void cs_mediastatus(struct ifnet *, struct ifmediareq *); |
280 | |
281 | static bool cs_shutdown(device_t, int); |
282 | static int cs_enable(struct cs_softc *); |
283 | static void cs_disable(struct cs_softc *); |
284 | static void cs_stop(struct ifnet *, int); |
285 | static int cs_scan_eeprom(struct cs_softc *); |
286 | static int cs_read_pktpg_from_eeprom(struct cs_softc *, int, u_int16_t *); |
287 | |
288 | |
289 | /* |
290 | * GLOBAL DECLARATIONS |
291 | */ |
292 | |
293 | /* |
294 | * Xmit-early table. |
295 | * |
296 | * To get better performance, we tell the chip to start packet |
297 | * transmission before the whole packet is copied to the chip. |
298 | * However, this can fail under load. When it fails, we back off |
299 | * to a safer setting for a little while. |
300 | * |
301 | * txcmd is the value of txcmd used to indicate when to start transmission. |
302 | * better is the next 'better' state in the table. |
303 | * better_count is the number of output packets before transition to the |
304 | * better state. |
305 | * worse is the next 'worse' state in the table. |
306 | * |
307 | * Transition to the next worse state happens automatically when a |
308 | * transmittion underrun occurs. |
309 | */ |
310 | struct cs_xmit_early { |
311 | u_int16_t txcmd; |
312 | int better; |
313 | int better_count; |
314 | int worse; |
315 | } cs_xmit_early_table[3] = { |
316 | { TX_CMD_START_381, 0, INT_MAX, 1, }, |
317 | { TX_CMD_START_1021, 0, 50000, 2, }, |
318 | { TX_CMD_START_ALL, 1, 5000, 2, }, |
319 | }; |
320 | |
321 | int cs_default_media[] = { |
322 | IFM_ETHER|IFM_10_2, |
323 | IFM_ETHER|IFM_10_5, |
324 | IFM_ETHER|IFM_10_T, |
325 | IFM_ETHER|IFM_10_T|IFM_FDX, |
326 | }; |
327 | int cs_default_nmedia = sizeof(cs_default_media) / sizeof(cs_default_media[0]); |
328 | |
329 | int |
330 | cs_attach(struct cs_softc *sc, u_int8_t *enaddr, int *media, |
331 | int nmedia, int defmedia) |
332 | { |
333 | struct ifnet *ifp = &sc->sc_ethercom.ec_if; |
334 | const char *chipname, *medname; |
335 | u_int16_t reg; |
336 | int i; |
337 | |
338 | /* Start out in IO mode */ |
339 | sc->sc_memorymode = FALSE; |
340 | |
341 | /* make sure we're right */ |
342 | for (i = 0; i < 10000; i++) { |
343 | reg = CS_READ_PACKET_PAGE(sc, PKTPG_EISA_NUM); |
344 | if (reg == EISA_NUM_CRYSTAL) { |
345 | break; |
346 | } |
347 | } |
348 | if (i == 10000) { |
349 | aprint_error_dev(sc->sc_dev, "wrong id(0x%x)\n" , reg); |
350 | return 1; /* XXX should panic? */ |
351 | } |
352 | |
353 | reg = CS_READ_PACKET_PAGE(sc, PKTPG_PRODUCT_ID); |
354 | sc->sc_prodid = reg & PROD_ID_MASK; |
355 | sc->sc_prodrev = (reg & PROD_REV_MASK) >> 8; |
356 | |
357 | switch (sc->sc_prodid) { |
358 | case PROD_ID_CS8900: |
359 | chipname = "CS8900" ; |
360 | break; |
361 | case PROD_ID_CS8920: |
362 | chipname = "CS8920" ; |
363 | break; |
364 | case PROD_ID_CS8920M: |
365 | chipname = "CS8920M" ; |
366 | break; |
367 | default: |
368 | panic("cs_attach: impossible" ); |
369 | } |
370 | |
371 | /* |
372 | * the first thing to do is check that the mbuf cluster size is |
373 | * greater than the MTU for an ethernet frame. The code depends on |
374 | * this and to port this to a OS where this was not the case would |
375 | * not be straightforward. |
376 | * |
377 | * we need 1 byte spare because our |
378 | * packet read loop can overrun. |
379 | * and we may need pad bytes to align ip header. |
380 | */ |
381 | if (MCLBYTES < ETHER_MAX_LEN + 1 + |
382 | ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header)) { |
383 | printf("%s: MCLBYTES too small for Ethernet frame\n" , |
384 | device_xname(sc->sc_dev)); |
385 | return 1; |
386 | } |
387 | |
388 | /* Start out not transmitting */ |
389 | sc->sc_txbusy = FALSE; |
390 | |
391 | /* Set up early transmit threshhold */ |
392 | sc->sc_xe_ent = 0; |
393 | sc->sc_xe_togo = cs_xmit_early_table[sc->sc_xe_ent].better_count; |
394 | |
395 | /* Initialize ifnet structure. */ |
396 | strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); |
397 | ifp->if_softc = sc; |
398 | ifp->if_start = cs_start_output; |
399 | ifp->if_init = cs_init; |
400 | ifp->if_ioctl = cs_ioctl; |
401 | ifp->if_stop = cs_stop; |
402 | ifp->if_watchdog = NULL; /* no watchdog at this stage */ |
403 | ifp->if_flags = IFF_SIMPLEX | IFF_NOTRAILERS | |
404 | IFF_BROADCAST | IFF_MULTICAST; |
405 | IFQ_SET_READY(&ifp->if_snd); |
406 | |
407 | /* Initialize ifmedia structures. */ |
408 | ifmedia_init(&sc->sc_media, 0, cs_mediachange, cs_mediastatus); |
409 | |
410 | if (media != NULL) { |
411 | for (i = 0; i < nmedia; i++) |
412 | ifmedia_add(&sc->sc_media, media[i], 0, NULL); |
413 | ifmedia_set(&sc->sc_media, defmedia); |
414 | } else { |
415 | for (i = 0; i < cs_default_nmedia; i++) |
416 | ifmedia_add(&sc->sc_media, cs_default_media[i], |
417 | 0, NULL); |
418 | cs_get_default_media(sc); |
419 | } |
420 | |
421 | if (sc->sc_cfgflags & CFGFLG_PARSE_EEPROM) { |
422 | if (cs_scan_eeprom(sc) == CS_ERROR) { |
423 | /* failed to scan the eeprom, pretend there isn't an eeprom */ |
424 | aprint_error_dev(sc->sc_dev, "unable to scan EEPROM\n" ); |
425 | sc->sc_cfgflags |= CFGFLG_NOT_EEPROM; |
426 | } |
427 | } |
428 | |
429 | if ((sc->sc_cfgflags & CFGFLG_NOT_EEPROM) == 0) { |
430 | /* Get parameters from the EEPROM */ |
431 | if (cs_get_params(sc) == CS_ERROR) { |
432 | aprint_error_dev(sc->sc_dev, |
433 | "unable to get settings from EEPROM\n" ); |
434 | return 1; |
435 | } |
436 | } |
437 | |
438 | if (enaddr != NULL) |
439 | memcpy(sc->sc_enaddr, enaddr, sizeof(sc->sc_enaddr)); |
440 | else if ((sc->sc_cfgflags & CFGFLG_NOT_EEPROM) == 0) { |
441 | /* Get and store the Ethernet address */ |
442 | if (cs_get_enaddr(sc) == CS_ERROR) { |
443 | aprint_error_dev(sc->sc_dev, |
444 | "unable to read Ethernet address\n" ); |
445 | return 1; |
446 | } |
447 | } else { |
448 | #if 1 |
449 | int j; |
450 | uint v; |
451 | |
452 | for (j = 0; j < 6; j += 2) { |
453 | v = CS_READ_PACKET_PAGE(sc, PKTPG_IND_ADDR + j); |
454 | sc->sc_enaddr[j + 0] = v; |
455 | sc->sc_enaddr[j + 1] = v >> 8; |
456 | } |
457 | #else |
458 | printf("%s: no Ethernet address!\n" , device_xname(sc->sc_dev)); |
459 | return 1; |
460 | #endif |
461 | } |
462 | |
463 | switch (IFM_SUBTYPE(sc->sc_media.ifm_cur->ifm_media)) { |
464 | case IFM_10_2: |
465 | medname = "BNC" ; |
466 | break; |
467 | case IFM_10_5: |
468 | medname = "AUI" ; |
469 | break; |
470 | case IFM_10_T: |
471 | if (sc->sc_media.ifm_cur->ifm_media & IFM_FDX) |
472 | medname = "UTP <full-duplex>" ; |
473 | else |
474 | medname = "UTP" ; |
475 | break; |
476 | default: |
477 | panic("cs_attach: impossible" ); |
478 | } |
479 | printf("%s: %s rev. %c, address %s, media %s\n" , |
480 | device_xname(sc->sc_dev), |
481 | chipname, sc->sc_prodrev + 'A', ether_sprintf(sc->sc_enaddr), |
482 | medname); |
483 | |
484 | if (sc->sc_dma_attach) |
485 | (*sc->sc_dma_attach)(sc); |
486 | |
487 | /* Attach the interface. */ |
488 | if_attach(ifp); |
489 | ether_ifattach(ifp, sc->sc_enaddr); |
490 | |
491 | rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), |
492 | RND_TYPE_NET, RND_FLAG_DEFAULT); |
493 | sc->sc_cfgflags |= CFGFLG_ATTACHED; |
494 | |
495 | if (pmf_device_register1(sc->sc_dev, NULL, NULL, cs_shutdown)) |
496 | pmf_class_network_register(sc->sc_dev, ifp); |
497 | else |
498 | aprint_error_dev(sc->sc_dev, |
499 | "couldn't establish power handler\n" ); |
500 | |
501 | /* Reset the chip */ |
502 | if (cs_reset_chip(sc) == CS_ERROR) { |
503 | aprint_error_dev(sc->sc_dev, "reset failed\n" ); |
504 | cs_detach(sc); |
505 | return 1; |
506 | } |
507 | |
508 | return 0; |
509 | } |
510 | |
511 | int |
512 | cs_detach(struct cs_softc *sc) |
513 | { |
514 | struct ifnet *ifp = &sc->sc_ethercom.ec_if; |
515 | |
516 | if (sc->sc_cfgflags & CFGFLG_ATTACHED) { |
517 | rnd_detach_source(&sc->rnd_source); |
518 | ether_ifdetach(ifp); |
519 | if_detach(ifp); |
520 | sc->sc_cfgflags &= ~CFGFLG_ATTACHED; |
521 | } |
522 | |
523 | #if 0 |
524 | /* |
525 | * XXX not necessary |
526 | */ |
527 | if (sc->sc_cfgflags & CFGFLG_DMA_MODE) { |
528 | isa_dmamem_unmap(sc->sc_ic, sc->sc_drq, sc->sc_dmabase, sc->sc_dmasize); |
529 | isa_dmamem_free(sc->sc_ic, sc->sc_drq, sc->sc_dmaaddr, sc->sc_dmasize); |
530 | isa_dmamap_destroy(sc->sc_ic, sc->sc_drq); |
531 | sc->sc_cfgflags &= ~CFGFLG_DMA_MODE; |
532 | } |
533 | #endif |
534 | |
535 | pmf_device_deregister(sc->sc_dev); |
536 | |
537 | return 0; |
538 | } |
539 | |
540 | bool |
541 | cs_shutdown(device_t self, int howto) |
542 | { |
543 | struct cs_softc *sc; |
544 | |
545 | sc = device_private(self); |
546 | cs_reset(sc); |
547 | |
548 | return true; |
549 | } |
550 | |
551 | void |
552 | cs_get_default_media(struct cs_softc *sc) |
553 | { |
554 | u_int16_t adp_cfg, xmit_ctl; |
555 | |
556 | if (cs_verify_eeprom(sc) == CS_ERROR) { |
557 | aprint_error_dev(sc->sc_dev, |
558 | "cs_get_default_media: EEPROM missing or bad\n" ); |
559 | goto fakeit; |
560 | } |
561 | |
562 | if (cs_read_eeprom(sc, EEPROM_ADPTR_CFG, &adp_cfg) == CS_ERROR) { |
563 | aprint_error_dev(sc->sc_dev, |
564 | "unable to read adapter config from EEPROM\n" ); |
565 | goto fakeit; |
566 | } |
567 | |
568 | if (cs_read_eeprom(sc, EEPROM_XMIT_CTL, &xmit_ctl) == CS_ERROR) { |
569 | aprint_error_dev(sc->sc_dev, |
570 | "unable to read transmit control from EEPROM\n" ); |
571 | goto fakeit; |
572 | } |
573 | |
574 | switch (adp_cfg & ADPTR_CFG_MEDIA) { |
575 | case ADPTR_CFG_AUI: |
576 | ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_10_5); |
577 | break; |
578 | case ADPTR_CFG_10BASE2: |
579 | ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_10_2); |
580 | break; |
581 | case ADPTR_CFG_10BASET: |
582 | default: |
583 | if (xmit_ctl & XMIT_CTL_FDX) |
584 | ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_10_T|IFM_FDX); |
585 | else |
586 | ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_10_T); |
587 | break; |
588 | } |
589 | return; |
590 | |
591 | fakeit: |
592 | aprint_error_dev(sc->sc_dev, |
593 | "WARNING: default media setting may be inaccurate\n" ); |
594 | /* XXX Arbitrary... */ |
595 | ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_10_T); |
596 | } |
597 | |
598 | /* |
599 | * cs_scan_eeprom |
600 | * |
601 | * Attempt to take a complete copy of the eeprom into main memory. |
602 | * this will allow faster parsing of the eeprom data. |
603 | * |
604 | * Only tested against a 8920M's eeprom, but the data sheet for the |
605 | * 8920A indicates that is uses the same layout. |
606 | */ |
607 | int |
608 | cs_scan_eeprom(struct cs_softc *sc) |
609 | { |
610 | u_int16_t result; |
611 | int i; |
612 | int eeprom_size; |
613 | u_int8_t checksum = 0; |
614 | |
615 | if (cs_verify_eeprom(sc) == CS_ERROR) { |
616 | aprint_error_dev(sc->sc_dev, |
617 | "cs_scan_params: EEPROM missing or bad\n" ); |
618 | return (CS_ERROR); |
619 | } |
620 | |
621 | /* |
622 | * read the 0th word from the eeprom, it will tell us the length |
623 | * and if the eeprom is valid |
624 | */ |
625 | cs_read_eeprom(sc, 0, &result); |
626 | |
627 | /* check the eeprom signature */ |
628 | if ((result & 0xE000) != 0xA000) { |
629 | /* empty eeprom */ |
630 | return (CS_ERROR); |
631 | } |
632 | |
633 | /* |
634 | * take the eeprom size (note the read value doesn't include the header |
635 | * word) |
636 | */ |
637 | eeprom_size = (result & 0xff) + 2; |
638 | |
639 | sc->eeprom_data = malloc(eeprom_size, M_DEVBUF, M_WAITOK); |
640 | if (sc->eeprom_data == NULL) { |
641 | /* no memory, treat this as if there's no eeprom */ |
642 | return (CS_ERROR); |
643 | } |
644 | |
645 | sc->eeprom_size = eeprom_size; |
646 | |
647 | /* read the eeprom into the buffer, also calculate the checksum */ |
648 | for (i = 0; i < (eeprom_size >> 1); i++) { |
649 | cs_read_eeprom(sc, i, &(sc->eeprom_data[i])); |
650 | checksum += (sc->eeprom_data[i] & 0xff00) >> 8; |
651 | checksum += (sc->eeprom_data[i] & 0x00ff); |
652 | } |
653 | |
654 | /* |
655 | * validate checksum calculation, the sum of all the bytes should be 0, |
656 | * as the high byte of the last word is the 2's complement of the |
657 | * sum to that point. |
658 | */ |
659 | if (checksum != 0) { |
660 | aprint_error_dev(sc->sc_dev, "eeprom checksum failure\n" ); |
661 | return (CS_ERROR); |
662 | } |
663 | |
664 | return (CS_OK); |
665 | } |
666 | |
667 | static int |
668 | cs_read_pktpg_from_eeprom(struct cs_softc *sc, int pktpg, u_int16_t *pValue) |
669 | { |
670 | int x, maxword; |
671 | |
672 | /* Check that we have eeprom data */ |
673 | if ((sc->eeprom_data == NULL) || (sc->eeprom_size < 2)) |
674 | return (CS_ERROR); |
675 | |
676 | /* |
677 | * We only want to read the data words, the last word contains the |
678 | * checksum |
679 | */ |
680 | maxword = (sc->eeprom_size - 2) >> 1; |
681 | |
682 | /* start 1 word in, as the first word is the length and signature */ |
683 | x = 1; |
684 | |
685 | while ( x < (maxword)) { |
686 | u_int16_t ; |
687 | int group_size; |
688 | int offset; |
689 | int offset_max; |
690 | |
691 | /* read in the group header word */ |
692 | header = sc->eeprom_data[x]; |
693 | x++; /* skip group header */ |
694 | |
695 | /* |
696 | * size of group in words is in the top 4 bits, note that it |
697 | * is one less than the number of words |
698 | */ |
699 | group_size = header & 0xF000; |
700 | |
701 | /* |
702 | * CS8900 Data sheet says this should be 0x01ff, |
703 | * but my cs8920 eeprom has higher offsets, |
704 | * perhaps the 8920 allows higher offsets, otherwise |
705 | * it's writing to places that it shouldn't |
706 | */ |
707 | /* work out the offsets this group covers */ |
708 | offset = header & 0x0FFF; |
709 | offset_max = offset + (group_size << 1); |
710 | |
711 | /* check if the pkgpg we're after is in this group */ |
712 | if ((offset <= pktpg) && (pktpg <= offset_max)) { |
713 | /* the pkgpg value we want is in here */ |
714 | int eeprom_location; |
715 | |
716 | eeprom_location = ((pktpg - offset) >> 1) ; |
717 | |
718 | *pValue = sc->eeprom_data[x + eeprom_location]; |
719 | return (CS_OK); |
720 | } else { |
721 | /* skip this group (+ 1 for first entry) */ |
722 | x += group_size + 1; |
723 | } |
724 | } |
725 | |
726 | /* |
727 | * if we've fallen out here then we don't have a value in the EEPROM |
728 | * for this pktpg so return an error |
729 | */ |
730 | return (CS_ERROR); |
731 | } |
732 | |
733 | int |
734 | cs_get_params(struct cs_softc *sc) |
735 | { |
736 | u_int16_t isaConfig; |
737 | u_int16_t adapterConfig; |
738 | |
739 | if (cs_verify_eeprom(sc) == CS_ERROR) { |
740 | aprint_error_dev(sc->sc_dev, |
741 | "cs_get_params: EEPROM missing or bad\n" ); |
742 | return (CS_ERROR); |
743 | } |
744 | |
745 | if (sc->sc_cfgflags & CFGFLG_PARSE_EEPROM) { |
746 | /* Get ISA configuration from the EEPROM */ |
747 | if (cs_read_pktpg_from_eeprom(sc, PKTPG_BUS_CTL, &isaConfig) |
748 | == CS_ERROR) { |
749 | /* eeprom doesn't have this value, use data sheet default */ |
750 | isaConfig = 0x0017; |
751 | } |
752 | |
753 | /* Get adapter configuration from the EEPROM */ |
754 | if (cs_read_pktpg_from_eeprom(sc, PKTPG_SELF_CTL, &adapterConfig) |
755 | == CS_ERROR) { |
756 | /* eeprom doesn't have this value, use data sheet default */ |
757 | adapterConfig = 0x0015; |
758 | } |
759 | |
760 | /* Copy the USE_SA flag */ |
761 | if (isaConfig & BUS_CTL_USE_SA) |
762 | sc->sc_cfgflags |= CFGFLG_USE_SA; |
763 | |
764 | /* Copy the IO Channel Ready flag */ |
765 | if (isaConfig & BUS_CTL_IOCHRDY) |
766 | sc->sc_cfgflags |= CFGFLG_IOCHRDY; |
767 | |
768 | /* Copy the DC/DC Polarity flag */ |
769 | if (adapterConfig & SELF_CTL_HCB1) |
770 | sc->sc_cfgflags |= CFGFLG_DCDC_POL; |
771 | } else { |
772 | /* Get ISA configuration from the EEPROM */ |
773 | if (cs_read_eeprom(sc, EEPROM_ISA_CFG, &isaConfig) == CS_ERROR) |
774 | goto eeprom_bad; |
775 | |
776 | /* Get adapter configuration from the EEPROM */ |
777 | if (cs_read_eeprom(sc, EEPROM_ADPTR_CFG, &adapterConfig) == CS_ERROR) |
778 | goto eeprom_bad; |
779 | |
780 | /* Copy the USE_SA flag */ |
781 | if (isaConfig & ISA_CFG_USE_SA) |
782 | sc->sc_cfgflags |= CFGFLG_USE_SA; |
783 | |
784 | /* Copy the IO Channel Ready flag */ |
785 | if (isaConfig & ISA_CFG_IOCHRDY) |
786 | sc->sc_cfgflags |= CFGFLG_IOCHRDY; |
787 | |
788 | /* Copy the DC/DC Polarity flag */ |
789 | if (adapterConfig & ADPTR_CFG_DCDC_POL) |
790 | sc->sc_cfgflags |= CFGFLG_DCDC_POL; |
791 | } |
792 | |
793 | return (CS_OK); |
794 | eeprom_bad: |
795 | aprint_error_dev(sc->sc_dev, |
796 | "cs_get_params: unable to read from EEPROM\n" ); |
797 | return (CS_ERROR); |
798 | } |
799 | |
800 | int |
801 | cs_get_enaddr(struct cs_softc *sc) |
802 | { |
803 | uint16_t myea[ETHER_ADDR_LEN / sizeof(uint16_t)]; |
804 | int i; |
805 | |
806 | if (cs_verify_eeprom(sc) == CS_ERROR) { |
807 | aprint_error_dev(sc->sc_dev, |
808 | "cs_get_enaddr: EEPROM missing or bad\n" ); |
809 | return (CS_ERROR); |
810 | } |
811 | |
812 | /* Get Ethernet address from the EEPROM */ |
813 | if (sc->sc_cfgflags & CFGFLG_PARSE_EEPROM) { |
814 | if (cs_read_pktpg_from_eeprom(sc, PKTPG_IND_ADDR, &myea[0]) |
815 | == CS_ERROR) |
816 | goto eeprom_bad; |
817 | if (cs_read_pktpg_from_eeprom(sc, PKTPG_IND_ADDR + 2, &myea[1]) |
818 | == CS_ERROR) |
819 | goto eeprom_bad; |
820 | if (cs_read_pktpg_from_eeprom(sc, PKTPG_IND_ADDR + 4, &myea[2]) |
821 | == CS_ERROR) |
822 | goto eeprom_bad; |
823 | } else { |
824 | if (cs_read_eeprom(sc, EEPROM_IND_ADDR_H, &myea[0]) == CS_ERROR) |
825 | goto eeprom_bad; |
826 | if (cs_read_eeprom(sc, EEPROM_IND_ADDR_M, &myea[1]) == CS_ERROR) |
827 | goto eeprom_bad; |
828 | if (cs_read_eeprom(sc, EEPROM_IND_ADDR_L, &myea[2]) == CS_ERROR) |
829 | goto eeprom_bad; |
830 | } |
831 | |
832 | for (i = 0; i < __arraycount(myea); i++) { |
833 | sc->sc_enaddr[i * 2 + 0] = myea[i]; |
834 | sc->sc_enaddr[i * 2 + 1] = myea[i] >> 8; |
835 | } |
836 | |
837 | return (CS_OK); |
838 | |
839 | eeprom_bad: |
840 | aprint_error_dev(sc->sc_dev, |
841 | "cs_get_enaddr: unable to read from EEPROM\n" ); |
842 | return (CS_ERROR); |
843 | } |
844 | |
845 | int |
846 | cs_reset_chip(struct cs_softc *sc) |
847 | { |
848 | int intState; |
849 | int x; |
850 | |
851 | /* Disable interrupts at the CPU so reset command is atomic */ |
852 | intState = splnet(); |
853 | |
854 | /* |
855 | * We are now resetting the chip |
856 | * |
857 | * A spurious interrupt is generated by the chip when it is reset. This |
858 | * variable informs the interrupt handler to ignore this interrupt. |
859 | */ |
860 | sc->sc_resetting = TRUE; |
861 | |
862 | /* Issue a reset command to the chip */ |
863 | CS_WRITE_PACKET_PAGE(sc, PKTPG_SELF_CTL, SELF_CTL_RESET); |
864 | |
865 | /* Re-enable interrupts at the CPU */ |
866 | splx(intState); |
867 | |
868 | /* The chip is always in IO mode after a reset */ |
869 | sc->sc_memorymode = FALSE; |
870 | |
871 | /* If transmission was in progress, it is not now */ |
872 | sc->sc_txbusy = FALSE; |
873 | |
874 | /* |
875 | * there was a delay(125); here, but it seems uneccesary 125 usec is |
876 | * 1/8000 of a second, not 1/8 of a second. the data sheet advises |
877 | * 1/10 of a second here, but the SI_BUSY and INIT_DONE loops below |
878 | * should be sufficient. |
879 | */ |
880 | |
881 | /* Transition SBHE to switch chip from 8-bit to 16-bit */ |
882 | IO_READ_1(sc, PORT_PKTPG_PTR + 0); |
883 | IO_READ_1(sc, PORT_PKTPG_PTR + 1); |
884 | IO_READ_1(sc, PORT_PKTPG_PTR + 0); |
885 | IO_READ_1(sc, PORT_PKTPG_PTR + 1); |
886 | |
887 | /* Wait until the EEPROM is not busy */ |
888 | for (x = 0; x < MAXLOOP; x++) { |
889 | if (!(CS_READ_PACKET_PAGE(sc, PKTPG_SELF_ST) & SELF_ST_SI_BUSY)) |
890 | break; |
891 | } |
892 | |
893 | if (x == MAXLOOP) |
894 | return CS_ERROR; |
895 | |
896 | /* Wait until initialization is done */ |
897 | for (x = 0; x < MAXLOOP; x++) { |
898 | if (CS_READ_PACKET_PAGE(sc, PKTPG_SELF_ST) & SELF_ST_INIT_DONE) |
899 | break; |
900 | } |
901 | |
902 | if (x == MAXLOOP) |
903 | return CS_ERROR; |
904 | |
905 | /* Reset is no longer in progress */ |
906 | sc->sc_resetting = FALSE; |
907 | |
908 | return CS_OK; |
909 | } |
910 | |
911 | int |
912 | cs_verify_eeprom(struct cs_softc *sc) |
913 | { |
914 | u_int16_t self_status; |
915 | |
916 | /* Verify that the EEPROM is present and OK */ |
917 | self_status = CS_READ_PACKET_PAGE_IO(sc, PKTPG_SELF_ST); |
918 | if (((self_status & SELF_ST_EEP_PRES) && |
919 | (self_status & SELF_ST_EEP_OK)) == 0) |
920 | return (CS_ERROR); |
921 | |
922 | return (CS_OK); |
923 | } |
924 | |
925 | int |
926 | cs_read_eeprom(struct cs_softc *sc, int offset, u_int16_t *pValue) |
927 | { |
928 | int x; |
929 | |
930 | /* Ensure that the EEPROM is not busy */ |
931 | for (x = 0; x < MAXLOOP; x++) { |
932 | if (!(CS_READ_PACKET_PAGE_IO(sc, PKTPG_SELF_ST) & |
933 | SELF_ST_SI_BUSY)) |
934 | break; |
935 | } |
936 | |
937 | if (x == MAXLOOP) |
938 | return (CS_ERROR); |
939 | |
940 | /* Issue the command to read the offset within the EEPROM */ |
941 | CS_WRITE_PACKET_PAGE_IO(sc, PKTPG_EEPROM_CMD, |
942 | offset | EEPROM_CMD_READ); |
943 | |
944 | /* Wait until the command is completed */ |
945 | for (x = 0; x < MAXLOOP; x++) { |
946 | if (!(CS_READ_PACKET_PAGE_IO(sc, PKTPG_SELF_ST) & |
947 | SELF_ST_SI_BUSY)) |
948 | break; |
949 | } |
950 | |
951 | if (x == MAXLOOP) |
952 | return (CS_ERROR); |
953 | |
954 | /* Get the EEPROM data from the EEPROM Data register */ |
955 | *pValue = CS_READ_PACKET_PAGE_IO(sc, PKTPG_EEPROM_DATA); |
956 | |
957 | return (CS_OK); |
958 | } |
959 | |
960 | void |
961 | cs_initChip(struct cs_softc *sc) |
962 | { |
963 | u_int16_t busCtl; |
964 | u_int16_t selfCtl; |
965 | u_int16_t v; |
966 | u_int16_t isaId; |
967 | int i; |
968 | int media = IFM_SUBTYPE(sc->sc_media.ifm_cur->ifm_media); |
969 | |
970 | /* Disable reception and transmission of frames */ |
971 | CS_WRITE_PACKET_PAGE(sc, PKTPG_LINE_CTL, |
972 | CS_READ_PACKET_PAGE(sc, PKTPG_LINE_CTL) & |
973 | ~LINE_CTL_RX_ON & ~LINE_CTL_TX_ON); |
974 | |
975 | /* Disable interrupt at the chip */ |
976 | CS_WRITE_PACKET_PAGE(sc, PKTPG_BUS_CTL, |
977 | CS_READ_PACKET_PAGE(sc, PKTPG_BUS_CTL) & ~BUS_CTL_INT_ENBL); |
978 | |
979 | /* If IOCHRDY is enabled then clear the bit in the busCtl register */ |
980 | busCtl = CS_READ_PACKET_PAGE(sc, PKTPG_BUS_CTL); |
981 | if (sc->sc_cfgflags & CFGFLG_IOCHRDY) { |
982 | CS_WRITE_PACKET_PAGE(sc, PKTPG_BUS_CTL, |
983 | busCtl & ~BUS_CTL_IOCHRDY); |
984 | } else { |
985 | CS_WRITE_PACKET_PAGE(sc, PKTPG_BUS_CTL, |
986 | busCtl | BUS_CTL_IOCHRDY); |
987 | } |
988 | |
989 | /* Set the Line Control register to match the media type */ |
990 | if (media == IFM_10_T) |
991 | CS_WRITE_PACKET_PAGE(sc, PKTPG_LINE_CTL, LINE_CTL_10BASET); |
992 | else |
993 | CS_WRITE_PACKET_PAGE(sc, PKTPG_LINE_CTL, LINE_CTL_AUI_ONLY); |
994 | |
995 | /* |
996 | * Set the BSTATUS/HC1 pin to be used as HC1. HC1 is used to |
997 | * enable the DC/DC converter |
998 | */ |
999 | selfCtl = SELF_CTL_HC1E; |
1000 | |
1001 | /* If the media type is 10Base2 */ |
1002 | if (media == IFM_10_2) { |
1003 | /* |
1004 | * Enable the DC/DC converter if it has a low enable. |
1005 | */ |
1006 | if ((sc->sc_cfgflags & CFGFLG_DCDC_POL) == 0) |
1007 | /* |
1008 | * Set the HCB1 bit, which causes the HC1 pin to go |
1009 | * low. |
1010 | */ |
1011 | selfCtl |= SELF_CTL_HCB1; |
1012 | } else { /* Media type is 10BaseT or AUI */ |
1013 | /* |
1014 | * Disable the DC/DC converter if it has a high enable. |
1015 | */ |
1016 | if ((sc->sc_cfgflags & CFGFLG_DCDC_POL) != 0) { |
1017 | /* |
1018 | * Set the HCB1 bit, which causes the HC1 pin to go |
1019 | * low. |
1020 | */ |
1021 | selfCtl |= SELF_CTL_HCB1; |
1022 | } |
1023 | } |
1024 | CS_WRITE_PACKET_PAGE(sc, PKTPG_SELF_CTL, selfCtl); |
1025 | |
1026 | /* enable normal link pulse */ |
1027 | if (sc->sc_prodid == PROD_ID_CS8920 || sc->sc_prodid == PROD_ID_CS8920M) |
1028 | CS_WRITE_PACKET_PAGE(sc, PKTPG_AUTONEG_CTL, AUTOCTL_NLP_ENABLE); |
1029 | |
1030 | /* Enable full-duplex, if appropriate */ |
1031 | if (sc->sc_media.ifm_cur->ifm_media & IFM_FDX) |
1032 | CS_WRITE_PACKET_PAGE(sc, PKTPG_TEST_CTL, TEST_CTL_FDX); |
1033 | |
1034 | /* RX_CTL set in cs_set_ladr_filt(), below */ |
1035 | |
1036 | /* enable all transmission interrupts */ |
1037 | CS_WRITE_PACKET_PAGE(sc, PKTPG_TX_CFG, TX_CFG_ALL_IE); |
1038 | |
1039 | /* Accept all receive interrupts */ |
1040 | CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG, RX_CFG_ALL_IE); |
1041 | |
1042 | /* |
1043 | * Configure Operational Modes |
1044 | * |
1045 | * I have turned off the BUF_CFG_RX_MISS_IE, to speed things up, this is |
1046 | * a better way to do it because the card has a counter which can be |
1047 | * read to update the RX_MISS counter. This saves many interrupts. |
1048 | * |
1049 | * I have turned on the tx and rx overflow interrupts to counter using |
1050 | * the receive miss interrupt. This is a better estimate of errors |
1051 | * and requires lower system overhead. |
1052 | */ |
1053 | CS_WRITE_PACKET_PAGE(sc, PKTPG_BUF_CFG, BUF_CFG_TX_UNDR_IE | |
1054 | BUF_CFG_RX_DMA_IE); |
1055 | |
1056 | if (sc->sc_dma_chipinit) |
1057 | (*sc->sc_dma_chipinit)(sc); |
1058 | |
1059 | /* If memory mode is enabled */ |
1060 | if (sc->sc_cfgflags & CFGFLG_MEM_MODE) { |
1061 | /* If external logic is present for address decoding */ |
1062 | if (CS_READ_PACKET_PAGE(sc, PKTPG_SELF_ST) & SELF_ST_EL_PRES) { |
1063 | /* |
1064 | * Program the external logic to decode address bits |
1065 | * SA20-SA23 |
1066 | */ |
1067 | CS_WRITE_PACKET_PAGE(sc, PKTPG_EEPROM_CMD, |
1068 | ((sc->sc_pktpgaddr & 0xffffff) >> 20) | |
1069 | EEPROM_CMD_ELSEL); |
1070 | } |
1071 | |
1072 | /* |
1073 | * Write the packet page base physical address to the memory |
1074 | * base register. |
1075 | */ |
1076 | CS_WRITE_PACKET_PAGE(sc, PKTPG_MEM_BASE + 0, |
1077 | sc->sc_pktpgaddr & 0xFFFF); |
1078 | CS_WRITE_PACKET_PAGE(sc, PKTPG_MEM_BASE + 2, |
1079 | sc->sc_pktpgaddr >> 16); |
1080 | busCtl = BUS_CTL_MEM_MODE; |
1081 | |
1082 | /* tell the chip to read the addresses off the SA pins */ |
1083 | if (sc->sc_cfgflags & CFGFLG_USE_SA) { |
1084 | busCtl |= BUS_CTL_USE_SA; |
1085 | } |
1086 | CS_WRITE_PACKET_PAGE(sc, PKTPG_BUS_CTL, |
1087 | CS_READ_PACKET_PAGE(sc, PKTPG_BUS_CTL) | busCtl); |
1088 | |
1089 | /* We are in memory mode now! */ |
1090 | sc->sc_memorymode = TRUE; |
1091 | |
1092 | /* |
1093 | * wait here (10ms) for the chip to swap over. this is the |
1094 | * maximum time that this could take. |
1095 | */ |
1096 | delay(10000); |
1097 | |
1098 | /* Verify that we can read from the chip */ |
1099 | isaId = CS_READ_PACKET_PAGE(sc, PKTPG_EISA_NUM); |
1100 | |
1101 | /* |
1102 | * As a last minute sanity check before actually using mapped |
1103 | * memory we verify that we can read the isa number from the |
1104 | * chip in memory mode. |
1105 | */ |
1106 | if (isaId != EISA_NUM_CRYSTAL) { |
1107 | aprint_error_dev(sc->sc_dev, |
1108 | "failed to enable memory mode\n" ); |
1109 | sc->sc_memorymode = FALSE; |
1110 | } else { |
1111 | /* |
1112 | * we are in memory mode so if we aren't using DMA, |
1113 | * then program the chip to interrupt early. |
1114 | */ |
1115 | if ((sc->sc_cfgflags & CFGFLG_DMA_MODE) == 0) { |
1116 | CS_WRITE_PACKET_PAGE(sc, PKTPG_BUF_CFG, |
1117 | BUF_CFG_RX_DEST_IE | |
1118 | BUF_CFG_RX_MISS_OVER_IE | |
1119 | BUF_CFG_TX_COL_OVER_IE); |
1120 | } |
1121 | } |
1122 | |
1123 | } |
1124 | |
1125 | /* Put Ethernet address into the Individual Address register */ |
1126 | for (i = 0; i < 6; i += 2) { |
1127 | v = sc->sc_enaddr[i + 0] | (sc->sc_enaddr[i + 1]) << 8; |
1128 | CS_WRITE_PACKET_PAGE(sc, PKTPG_IND_ADDR + i, v); |
1129 | } |
1130 | |
1131 | if (sc->sc_irq != -1) { |
1132 | /* Set the interrupt level in the chip */ |
1133 | if (sc->sc_prodid == PROD_ID_CS8900) { |
1134 | if (sc->sc_irq == 5) { |
1135 | CS_WRITE_PACKET_PAGE(sc, PKTPG_INT_NUM, 3); |
1136 | } else { |
1137 | CS_WRITE_PACKET_PAGE(sc, PKTPG_INT_NUM, (sc->sc_irq) - 10); |
1138 | } |
1139 | } |
1140 | else { /* CS8920 */ |
1141 | CS_WRITE_PACKET_PAGE(sc, PKTPG_8920_INT_NUM, sc->sc_irq); |
1142 | } |
1143 | } |
1144 | |
1145 | /* write the multicast mask to the address filter register */ |
1146 | cs_set_ladr_filt(sc, &sc->sc_ethercom); |
1147 | |
1148 | /* Enable reception and transmission of frames */ |
1149 | CS_WRITE_PACKET_PAGE(sc, PKTPG_LINE_CTL, |
1150 | CS_READ_PACKET_PAGE(sc, PKTPG_LINE_CTL) | |
1151 | LINE_CTL_RX_ON | LINE_CTL_TX_ON); |
1152 | |
1153 | /* Enable interrupt at the chip */ |
1154 | CS_WRITE_PACKET_PAGE(sc, PKTPG_BUS_CTL, |
1155 | CS_READ_PACKET_PAGE(sc, PKTPG_BUS_CTL) | BUS_CTL_INT_ENBL); |
1156 | } |
1157 | |
1158 | int |
1159 | cs_init(struct ifnet *ifp) |
1160 | { |
1161 | int intState; |
1162 | int error = CS_OK; |
1163 | struct cs_softc *sc = ifp->if_softc; |
1164 | |
1165 | if (cs_enable(sc)) |
1166 | goto out; |
1167 | |
1168 | cs_stop(ifp, 0); |
1169 | |
1170 | intState = splnet(); |
1171 | |
1172 | #if 0 |
1173 | /* Mark the interface as down */ |
1174 | sc->sc_ethercom.ec_if.if_flags &= ~(IFF_UP | IFF_RUNNING); |
1175 | #endif |
1176 | |
1177 | #ifdef CS_DEBUG |
1178 | /* Enable debugging */ |
1179 | sc->sc_ethercom.ec_if.if_flags |= IFF_DEBUG; |
1180 | #endif |
1181 | |
1182 | /* Reset the chip */ |
1183 | if ((error = cs_reset_chip(sc)) == CS_OK) { |
1184 | /* Initialize the chip */ |
1185 | cs_initChip(sc); |
1186 | |
1187 | /* Mark the interface as running */ |
1188 | sc->sc_ethercom.ec_if.if_flags |= IFF_RUNNING; |
1189 | sc->sc_ethercom.ec_if.if_flags &= ~IFF_OACTIVE; |
1190 | sc->sc_ethercom.ec_if.if_timer = 0; |
1191 | |
1192 | /* Assume we have carrier until we are told otherwise. */ |
1193 | sc->sc_carrier = 1; |
1194 | } else { |
1195 | aprint_error_dev(sc->sc_dev, "unable to reset chip\n" ); |
1196 | } |
1197 | |
1198 | splx(intState); |
1199 | out: |
1200 | if (error == CS_OK) |
1201 | return 0; |
1202 | return EIO; |
1203 | } |
1204 | |
1205 | void |
1206 | cs_set_ladr_filt(struct cs_softc *sc, struct ethercom *ec) |
1207 | { |
1208 | struct ifnet *ifp = &ec->ec_if; |
1209 | struct ether_multi *enm; |
1210 | struct ether_multistep step; |
1211 | u_int16_t af[4]; |
1212 | u_int16_t port, mask, index; |
1213 | |
1214 | /* |
1215 | * Set up multicast address filter by passing all multicast addresses |
1216 | * through a crc generator, and then using the high order 6 bits as an |
1217 | * index into the 64 bit logical address filter. The high order bit |
1218 | * selects the word, while the rest of the bits select the bit within |
1219 | * the word. |
1220 | */ |
1221 | if (ifp->if_flags & IFF_PROMISC) { |
1222 | /* accept all valid frames. */ |
1223 | CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CTL, |
1224 | RX_CTL_PROMISC_A | RX_CTL_RX_OK_A | |
1225 | RX_CTL_IND_A | RX_CTL_BCAST_A | RX_CTL_MCAST_A); |
1226 | ifp->if_flags |= IFF_ALLMULTI; |
1227 | return; |
1228 | } |
1229 | |
1230 | /* |
1231 | * accept frames if a. crc valid, b. individual address match c. |
1232 | * broadcast address,and d. multicast addresses matched in the hash |
1233 | * filter |
1234 | */ |
1235 | CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CTL, |
1236 | RX_CTL_RX_OK_A | RX_CTL_IND_A | RX_CTL_BCAST_A | RX_CTL_MCAST_A); |
1237 | |
1238 | |
1239 | /* |
1240 | * start off with all multicast flag clear, set it if we need to |
1241 | * later, otherwise we will leave it. |
1242 | */ |
1243 | ifp->if_flags &= ~IFF_ALLMULTI; |
1244 | af[0] = af[1] = af[2] = af[3] = 0x0000; |
1245 | |
1246 | /* |
1247 | * Loop through all the multicast addresses unless we get a range of |
1248 | * addresses, in which case we will just accept all packets. |
1249 | * Justification for this is given in the next comment. |
1250 | */ |
1251 | ETHER_FIRST_MULTI(step, ec, enm); |
1252 | while (enm != NULL) { |
1253 | if (memcmp(enm->enm_addrlo, enm->enm_addrhi, |
1254 | sizeof enm->enm_addrlo)) { |
1255 | /* |
1256 | * We must listen to a range of multicast addresses. |
1257 | * For now, just accept all multicasts, rather than |
1258 | * trying to set only those filter bits needed to match |
1259 | * the range. (At this time, the only use of address |
1260 | * ranges is for IP multicast routing, for which the |
1261 | * range is big enough to require all bits set.) |
1262 | */ |
1263 | ifp->if_flags |= IFF_ALLMULTI; |
1264 | af[0] = af[1] = af[2] = af[3] = 0xffff; |
1265 | break; |
1266 | } else { |
1267 | /* |
1268 | * we have got an individual address so just set that |
1269 | * bit. |
1270 | */ |
1271 | index = cs_hash_index(enm->enm_addrlo); |
1272 | |
1273 | /* Set the bit the Logical address filter. */ |
1274 | port = (u_int16_t) (index >> 4); |
1275 | mask = (u_int16_t) (1 << (index & 0xf)); |
1276 | af[port] |= mask; |
1277 | |
1278 | ETHER_NEXT_MULTI(step, enm); |
1279 | } |
1280 | } |
1281 | |
1282 | /* now program the chip with the addresses */ |
1283 | CS_WRITE_PACKET_PAGE(sc, PKTPG_LOG_ADDR + 0, af[0]); |
1284 | CS_WRITE_PACKET_PAGE(sc, PKTPG_LOG_ADDR + 2, af[1]); |
1285 | CS_WRITE_PACKET_PAGE(sc, PKTPG_LOG_ADDR + 4, af[2]); |
1286 | CS_WRITE_PACKET_PAGE(sc, PKTPG_LOG_ADDR + 6, af[3]); |
1287 | return; |
1288 | } |
1289 | |
1290 | u_int16_t |
1291 | cs_hash_index(char *addr) |
1292 | { |
1293 | uint32_t crc; |
1294 | uint16_t hash_code; |
1295 | |
1296 | crc = ether_crc32_le(addr, ETHER_ADDR_LEN); |
1297 | |
1298 | hash_code = crc >> 26; |
1299 | return (hash_code); |
1300 | } |
1301 | |
1302 | void |
1303 | cs_reset(struct cs_softc *sc) |
1304 | { |
1305 | |
1306 | /* Mark the interface as down */ |
1307 | sc->sc_ethercom.ec_if.if_flags &= ~IFF_RUNNING; |
1308 | |
1309 | /* Reset the chip */ |
1310 | cs_reset_chip(sc); |
1311 | } |
1312 | |
1313 | int |
1314 | cs_ioctl(struct ifnet *ifp, u_long cmd, void *data) |
1315 | { |
1316 | struct cs_softc *sc = ifp->if_softc; |
1317 | struct ifreq *ifr = data; |
1318 | int state; |
1319 | int result; |
1320 | |
1321 | state = splnet(); |
1322 | |
1323 | result = 0; /* only set if something goes wrong */ |
1324 | |
1325 | switch (cmd) { |
1326 | case SIOCGIFMEDIA: |
1327 | case SIOCSIFMEDIA: |
1328 | result = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd); |
1329 | break; |
1330 | |
1331 | default: |
1332 | result = ether_ioctl(ifp, cmd, data); |
1333 | if (result == ENETRESET) { |
1334 | if (ifp->if_flags & IFF_RUNNING) { |
1335 | /* |
1336 | * Multicast list has changed. Set the |
1337 | * hardware filter accordingly. |
1338 | */ |
1339 | cs_set_ladr_filt(sc, &sc->sc_ethercom); |
1340 | } |
1341 | result = 0; |
1342 | } |
1343 | break; |
1344 | } |
1345 | |
1346 | splx(state); |
1347 | |
1348 | return result; |
1349 | } |
1350 | |
1351 | int |
1352 | cs_mediachange(struct ifnet *ifp) |
1353 | { |
1354 | |
1355 | /* |
1356 | * Current media is already set up. Just reset the interface |
1357 | * to let the new value take hold. |
1358 | */ |
1359 | cs_init(ifp); |
1360 | return (0); |
1361 | } |
1362 | |
1363 | void |
1364 | cs_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) |
1365 | { |
1366 | struct cs_softc *sc = ifp->if_softc; |
1367 | |
1368 | /* |
1369 | * The currently selected media is always the active media. |
1370 | */ |
1371 | ifmr->ifm_active = sc->sc_media.ifm_cur->ifm_media; |
1372 | |
1373 | if (ifp->if_flags & IFF_UP) { |
1374 | /* Interface up, status is valid. */ |
1375 | ifmr->ifm_status = IFM_AVALID | |
1376 | (sc->sc_carrier ? IFM_ACTIVE : 0); |
1377 | } |
1378 | else ifmr->ifm_status = 0; |
1379 | } |
1380 | |
1381 | int |
1382 | cs_intr(void *arg) |
1383 | { |
1384 | struct cs_softc *sc = arg; |
1385 | u_int16_t Event; |
1386 | u_int16_t rndEvent; |
1387 | |
1388 | /*printf("cs_intr %p\n", sc);*/ |
1389 | /* Ignore any interrupts that happen while the chip is being reset */ |
1390 | if (sc->sc_resetting) { |
1391 | printf("%s: cs_intr: reset in progress\n" , |
1392 | device_xname(sc->sc_dev)); |
1393 | return 1; |
1394 | } |
1395 | |
1396 | /* Read an event from the Interrupt Status Queue */ |
1397 | if (sc->sc_memorymode) |
1398 | Event = CS_READ_PACKET_PAGE(sc, PKTPG_ISQ); |
1399 | else |
1400 | Event = CS_READ_PORT(sc, PORT_ISQ); |
1401 | |
1402 | if ((Event & REG_NUM_MASK) == 0 || Event == 0xffff) |
1403 | return 0; /* not ours */ |
1404 | |
1405 | rndEvent = Event; |
1406 | |
1407 | /* Process all the events in the Interrupt Status Queue */ |
1408 | while ((Event & REG_NUM_MASK) != 0 && Event != 0xffff) { |
1409 | /* Dispatch to an event handler based on the register number */ |
1410 | switch (Event & REG_NUM_MASK) { |
1411 | case REG_NUM_RX_EVENT: |
1412 | cs_receive_event(sc, Event); |
1413 | break; |
1414 | case REG_NUM_TX_EVENT: |
1415 | cs_transmit_event(sc, Event); |
1416 | break; |
1417 | case REG_NUM_BUF_EVENT: |
1418 | cs_buffer_event(sc, Event); |
1419 | break; |
1420 | case REG_NUM_TX_COL: |
1421 | case REG_NUM_RX_MISS: |
1422 | cs_counter_event(sc, Event); |
1423 | break; |
1424 | default: |
1425 | printf("%s: unknown interrupt event 0x%x\n" , |
1426 | device_xname(sc->sc_dev), Event); |
1427 | break; |
1428 | } |
1429 | |
1430 | /* Read another event from the Interrupt Status Queue */ |
1431 | if (sc->sc_memorymode) |
1432 | Event = CS_READ_PACKET_PAGE(sc, PKTPG_ISQ); |
1433 | else |
1434 | Event = CS_READ_PORT(sc, PORT_ISQ); |
1435 | } |
1436 | |
1437 | /* have handled the interrupt */ |
1438 | rnd_add_uint32(&sc->rnd_source, rndEvent); |
1439 | return 1; |
1440 | } |
1441 | |
1442 | void |
1443 | cs_counter_event(struct cs_softc *sc, u_int16_t cntEvent) |
1444 | { |
1445 | struct ifnet *ifp; |
1446 | u_int16_t errorCount; |
1447 | |
1448 | ifp = &sc->sc_ethercom.ec_if; |
1449 | |
1450 | switch (cntEvent & REG_NUM_MASK) { |
1451 | case REG_NUM_TX_COL: |
1452 | /* |
1453 | * the count should be read before an overflow occurs. |
1454 | */ |
1455 | errorCount = CS_READ_PACKET_PAGE(sc, PKTPG_TX_COL); |
1456 | /* |
1457 | * the tramsit event routine always checks the number of |
1458 | * collisions for any packet so we don't increment any |
1459 | * counters here, as they should already have been |
1460 | * considered. |
1461 | */ |
1462 | break; |
1463 | case REG_NUM_RX_MISS: |
1464 | /* |
1465 | * the count should be read before an overflow occurs. |
1466 | */ |
1467 | errorCount = CS_READ_PACKET_PAGE(sc, PKTPG_RX_MISS); |
1468 | /* |
1469 | * Increment the input error count, the first 6bits are the |
1470 | * register id. |
1471 | */ |
1472 | ifp->if_ierrors += ((errorCount & 0xffC0) >> 6); |
1473 | break; |
1474 | default: |
1475 | /* do nothing */ |
1476 | break; |
1477 | } |
1478 | } |
1479 | |
1480 | void |
1481 | cs_buffer_event(struct cs_softc *sc, u_int16_t bufEvent) |
1482 | { |
1483 | |
1484 | /* |
1485 | * multiple events can be in the buffer event register at one time so |
1486 | * a standard switch statement will not suffice, here every event |
1487 | * must be checked. |
1488 | */ |
1489 | |
1490 | /* |
1491 | * if 128 bits have been rxed by the time we get here, the dest event |
1492 | * will be cleared and 128 event will be set. |
1493 | */ |
1494 | if ((bufEvent & (BUF_EVENT_RX_DEST | BUF_EVENT_RX_128)) != 0) { |
1495 | cs_process_rx_early(sc); |
1496 | } |
1497 | |
1498 | if (bufEvent & BUF_EVENT_RX_DMA) { |
1499 | /* process the receive data */ |
1500 | if (sc->sc_dma_process_rx) |
1501 | (*sc->sc_dma_process_rx)(sc); |
1502 | else |
1503 | /* should panic? */ |
1504 | aprint_error_dev(sc->sc_dev, "unexpected DMA event\n" ); |
1505 | } |
1506 | |
1507 | if (bufEvent & BUF_EVENT_TX_UNDR) { |
1508 | #if 0 |
1509 | /* |
1510 | * This can happen occasionally, and it's not worth worrying |
1511 | * about. |
1512 | */ |
1513 | printf("%s: transmit underrun (%d -> %d)\n" , |
1514 | device_xname(sc->sc_dev), sc->sc_xe_ent, |
1515 | cs_xmit_early_table[sc->sc_xe_ent].worse); |
1516 | #endif |
1517 | sc->sc_xe_ent = cs_xmit_early_table[sc->sc_xe_ent].worse; |
1518 | sc->sc_xe_togo = |
1519 | cs_xmit_early_table[sc->sc_xe_ent].better_count; |
1520 | |
1521 | /* had an underrun, transmit is finished */ |
1522 | sc->sc_txbusy = FALSE; |
1523 | } |
1524 | |
1525 | if (bufEvent & BUF_EVENT_SW_INT) { |
1526 | printf("%s: software initiated interrupt\n" , |
1527 | device_xname(sc->sc_dev)); |
1528 | } |
1529 | } |
1530 | |
1531 | void |
1532 | cs_transmit_event(struct cs_softc *sc, u_int16_t txEvent) |
1533 | { |
1534 | struct ifnet *ifp = &sc->sc_ethercom.ec_if; |
1535 | |
1536 | /* If there were any errors transmitting this frame */ |
1537 | if (txEvent & (TX_EVENT_LOSS_CRS | TX_EVENT_SQE_ERR | TX_EVENT_OUT_WIN | |
1538 | TX_EVENT_JABBER | TX_EVENT_16_COLL)) { |
1539 | /* Increment the output error count */ |
1540 | ifp->if_oerrors++; |
1541 | |
1542 | /* Note carrier loss. */ |
1543 | if (txEvent & TX_EVENT_LOSS_CRS) |
1544 | sc->sc_carrier = 0; |
1545 | |
1546 | /* If debugging is enabled then log error messages */ |
1547 | if (ifp->if_flags & IFF_DEBUG) { |
1548 | if (txEvent & TX_EVENT_LOSS_CRS) { |
1549 | aprint_error_dev(sc->sc_dev, "lost carrier\n" ); |
1550 | } |
1551 | if (txEvent & TX_EVENT_SQE_ERR) { |
1552 | aprint_error_dev(sc->sc_dev, "SQE error\n" ); |
1553 | } |
1554 | if (txEvent & TX_EVENT_OUT_WIN) { |
1555 | aprint_error_dev(sc->sc_dev, |
1556 | "out-of-window collision\n" ); |
1557 | } |
1558 | if (txEvent & TX_EVENT_JABBER) { |
1559 | aprint_error_dev(sc->sc_dev, "jabber\n" ); |
1560 | } |
1561 | if (txEvent & TX_EVENT_16_COLL) { |
1562 | aprint_error_dev(sc->sc_dev, "16 collisions\n" ); |
1563 | } |
1564 | } |
1565 | } |
1566 | else { |
1567 | /* Transmission successful, carrier is up. */ |
1568 | sc->sc_carrier = 1; |
1569 | #ifdef SHARK |
1570 | ledNetActive(); |
1571 | #endif |
1572 | } |
1573 | |
1574 | /* Add the number of collisions for this frame */ |
1575 | if (txEvent & TX_EVENT_16_COLL) { |
1576 | ifp->if_collisions += 16; |
1577 | } else { |
1578 | ifp->if_collisions += ((txEvent & TX_EVENT_COLL_MASK) >> 11); |
1579 | } |
1580 | |
1581 | ifp->if_opackets++; |
1582 | |
1583 | /* Transmission is no longer in progress */ |
1584 | sc->sc_txbusy = FALSE; |
1585 | |
1586 | /* If there is more to transmit */ |
1587 | if (IFQ_IS_EMPTY(&ifp->if_snd) == 0) { |
1588 | /* Start the next transmission */ |
1589 | cs_start_output(ifp); |
1590 | } |
1591 | } |
1592 | |
1593 | void |
1594 | cs_print_rx_errors(struct cs_softc *sc, u_int16_t rxEvent) |
1595 | { |
1596 | |
1597 | if (rxEvent & RX_EVENT_RUNT) |
1598 | aprint_error_dev(sc->sc_dev, "runt\n" ); |
1599 | |
1600 | if (rxEvent & RX_EVENT_X_DATA) |
1601 | aprint_error_dev(sc->sc_dev, "extra data\n" ); |
1602 | |
1603 | if (rxEvent & RX_EVENT_CRC_ERR) { |
1604 | if (rxEvent & RX_EVENT_DRIBBLE) |
1605 | aprint_error_dev(sc->sc_dev, "alignment error\n" ); |
1606 | else |
1607 | aprint_error_dev(sc->sc_dev, "CRC error\n" ); |
1608 | } else { |
1609 | if (rxEvent & RX_EVENT_DRIBBLE) |
1610 | aprint_error_dev(sc->sc_dev, "dribble bits\n" ); |
1611 | } |
1612 | } |
1613 | |
1614 | void |
1615 | cs_receive_event(struct cs_softc *sc, u_int16_t rxEvent) |
1616 | { |
1617 | struct ifnet *ifp = &sc->sc_ethercom.ec_if; |
1618 | |
1619 | /* If the frame was not received OK */ |
1620 | if (!(rxEvent & RX_EVENT_RX_OK)) { |
1621 | /* Increment the input error count */ |
1622 | ifp->if_ierrors++; |
1623 | |
1624 | /* |
1625 | * If debugging is enabled then log error messages. |
1626 | */ |
1627 | if (ifp->if_flags & IFF_DEBUG) { |
1628 | if (rxEvent != REG_NUM_RX_EVENT) { |
1629 | cs_print_rx_errors(sc, rxEvent); |
1630 | |
1631 | /* |
1632 | * Must read the length of all received |
1633 | * frames |
1634 | */ |
1635 | CS_READ_PACKET_PAGE(sc, PKTPG_RX_LENGTH); |
1636 | |
1637 | /* Skip the received frame */ |
1638 | CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG, |
1639 | CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) | |
1640 | RX_CFG_SKIP); |
1641 | } else { |
1642 | aprint_error_dev(sc->sc_dev, "implied skip\n" ); |
1643 | } |
1644 | } |
1645 | } else { |
1646 | /* |
1647 | * process the received frame and pass it up to the upper |
1648 | * layers. |
1649 | */ |
1650 | cs_process_receive(sc); |
1651 | } |
1652 | } |
1653 | |
1654 | void |
1655 | cs_ether_input(struct cs_softc *sc, struct mbuf *m) |
1656 | { |
1657 | struct ifnet *ifp = &sc->sc_ethercom.ec_if; |
1658 | |
1659 | ifp->if_ipackets++; |
1660 | |
1661 | /* |
1662 | * Check if there's a BPF listener on this interface. |
1663 | * If so, hand off the raw packet to BPF. |
1664 | */ |
1665 | bpf_mtap(ifp, m); |
1666 | |
1667 | /* Pass the packet up. */ |
1668 | if_percpuq_enqueue(ifp->if_percpuq, m); |
1669 | } |
1670 | |
1671 | void |
1672 | cs_process_receive(struct cs_softc *sc) |
1673 | { |
1674 | struct ifnet *ifp; |
1675 | struct mbuf *m; |
1676 | int totlen; |
1677 | u_int16_t *pBuff, *pBuffLimit; |
1678 | int pad; |
1679 | unsigned int frameOffset = 0; /* XXX: gcc */ |
1680 | |
1681 | #ifdef SHARK |
1682 | ledNetActive(); |
1683 | #endif |
1684 | |
1685 | ifp = &sc->sc_ethercom.ec_if; |
1686 | |
1687 | /* Received a packet; carrier is up. */ |
1688 | sc->sc_carrier = 1; |
1689 | |
1690 | if (sc->sc_memorymode) { |
1691 | /* Initialize the frame offset */ |
1692 | frameOffset = PKTPG_RX_LENGTH; |
1693 | |
1694 | /* Get the length of the received frame */ |
1695 | totlen = CS_READ_PACKET_PAGE(sc, frameOffset); |
1696 | frameOffset += 2; |
1697 | } |
1698 | else { |
1699 | /* drop status */ |
1700 | CS_READ_PORT(sc, PORT_RXTX_DATA); |
1701 | |
1702 | /* Get the length of the received frame */ |
1703 | totlen = CS_READ_PORT(sc, PORT_RXTX_DATA); |
1704 | } |
1705 | |
1706 | if (totlen > ETHER_MAX_LEN) { |
1707 | aprint_error_dev(sc->sc_dev, "invalid packet length %d\n" , |
1708 | totlen); |
1709 | |
1710 | /* skip the received frame */ |
1711 | CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG, |
1712 | CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) | RX_CFG_SKIP); |
1713 | return; |
1714 | } |
1715 | |
1716 | MGETHDR(m, M_DONTWAIT, MT_DATA); |
1717 | if (m == 0) { |
1718 | aprint_error_dev(sc->sc_dev, |
1719 | "cs_process_receive: unable to allocate mbuf\n" ); |
1720 | ifp->if_ierrors++; |
1721 | /* |
1722 | * couldn't allocate an mbuf so things are not good, may as |
1723 | * well drop the packet I think. |
1724 | * |
1725 | * have already read the length so we should be right to skip |
1726 | * the packet. |
1727 | */ |
1728 | CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG, |
1729 | CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) | RX_CFG_SKIP); |
1730 | return; |
1731 | } |
1732 | m_set_rcvif(m, ifp); |
1733 | m->m_pkthdr.len = totlen; |
1734 | |
1735 | /* number of bytes to align ip header on word boundary for ipintr */ |
1736 | pad = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header); |
1737 | |
1738 | /* |
1739 | * alloc mbuf cluster if we need. |
1740 | * we need 1 byte spare because following |
1741 | * packet read loop can overrun. |
1742 | */ |
1743 | if (totlen + pad + 1 > MHLEN) { |
1744 | MCLGET(m, M_DONTWAIT); |
1745 | if ((m->m_flags & M_EXT) == 0) { |
1746 | /* couldn't allocate an mbuf cluster */ |
1747 | aprint_error_dev(sc->sc_dev, |
1748 | "cs_process_receive: " |
1749 | "unable to allocate a cluster\n" ); |
1750 | m_freem(m); |
1751 | |
1752 | /* skip the received frame */ |
1753 | CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG, |
1754 | CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) | RX_CFG_SKIP); |
1755 | return; |
1756 | } |
1757 | } |
1758 | |
1759 | /* align ip header on word boundary for ipintr */ |
1760 | m->m_data += pad; |
1761 | |
1762 | m->m_len = totlen; |
1763 | pBuff = mtod(m, u_int16_t *); |
1764 | |
1765 | /* now read the data from the chip */ |
1766 | if (sc->sc_memorymode) { |
1767 | pBuffLimit = pBuff + (totlen + 1) / 2; /* don't want to go over */ |
1768 | while (pBuff < pBuffLimit) { |
1769 | *pBuff++ = CS_READ_PACKET_PAGE(sc, frameOffset); |
1770 | frameOffset += 2; |
1771 | } |
1772 | } |
1773 | else { |
1774 | IO_READ_MULTI_2(sc, PORT_RXTX_DATA, pBuff, (totlen + 1)>>1); |
1775 | } |
1776 | |
1777 | cs_ether_input(sc, m); |
1778 | } |
1779 | |
1780 | void |
1781 | cs_process_rx_early(struct cs_softc *sc) |
1782 | { |
1783 | struct ifnet *ifp; |
1784 | struct mbuf *m; |
1785 | u_int16_t frameCount, oldFrameCount; |
1786 | u_int16_t rxEvent; |
1787 | u_int16_t *pBuff; |
1788 | int pad; |
1789 | unsigned int frameOffset; |
1790 | |
1791 | |
1792 | ifp = &sc->sc_ethercom.ec_if; |
1793 | |
1794 | /* Initialize the frame offset */ |
1795 | frameOffset = PKTPG_RX_FRAME; |
1796 | frameCount = 0; |
1797 | |
1798 | MGETHDR(m, M_DONTWAIT, MT_DATA); |
1799 | if (m == 0) { |
1800 | aprint_error_dev(sc->sc_dev, |
1801 | "cs_process_rx_early: unable to allocate mbuf\n" ); |
1802 | ifp->if_ierrors++; |
1803 | /* |
1804 | * couldn't allocate an mbuf so things are not good, may as |
1805 | * well drop the packet I think. |
1806 | * |
1807 | * have already read the length so we should be right to skip |
1808 | * the packet. |
1809 | */ |
1810 | CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG, |
1811 | CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) | RX_CFG_SKIP); |
1812 | return; |
1813 | } |
1814 | m_set_rcvif(m, ifp); |
1815 | /* |
1816 | * save processing by always using a mbuf cluster, guaranteed to fit |
1817 | * packet |
1818 | */ |
1819 | MCLGET(m, M_DONTWAIT); |
1820 | if ((m->m_flags & M_EXT) == 0) { |
1821 | /* couldn't allocate an mbuf cluster */ |
1822 | aprint_error_dev(sc->sc_dev, |
1823 | "cs_process_rx_early: unable to allocate a cluster\n" ); |
1824 | m_freem(m); |
1825 | /* skip the frame */ |
1826 | CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG, |
1827 | CS_READ_PACKET_PAGE(sc, PKTPG_RX_CFG) | RX_CFG_SKIP); |
1828 | return; |
1829 | } |
1830 | |
1831 | /* align ip header on word boundary for ipintr */ |
1832 | pad = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header); |
1833 | m->m_data += pad; |
1834 | |
1835 | /* set up the buffer pointer to point to the data area */ |
1836 | pBuff = mtod(m, u_int16_t *); |
1837 | |
1838 | /* |
1839 | * now read the frame byte counter until we have finished reading the |
1840 | * frame |
1841 | */ |
1842 | oldFrameCount = 0; |
1843 | frameCount = CS_READ_PACKET_PAGE(sc, PKTPG_FRAME_BYTE_COUNT); |
1844 | while ((frameCount != 0) && (frameCount < MCLBYTES)) { |
1845 | for (; oldFrameCount < frameCount; oldFrameCount += 2) { |
1846 | *pBuff++ = CS_READ_PACKET_PAGE(sc, frameOffset); |
1847 | frameOffset += 2; |
1848 | } |
1849 | |
1850 | /* read the new count from the chip */ |
1851 | frameCount = CS_READ_PACKET_PAGE(sc, PKTPG_FRAME_BYTE_COUNT); |
1852 | } |
1853 | |
1854 | /* update the mbuf counts */ |
1855 | m->m_len = oldFrameCount; |
1856 | m->m_pkthdr.len = oldFrameCount; |
1857 | |
1858 | /* now check the Rx Event register */ |
1859 | rxEvent = CS_READ_PACKET_PAGE(sc, PKTPG_RX_EVENT); |
1860 | |
1861 | if ((rxEvent & RX_EVENT_RX_OK) != 0) { |
1862 | /* |
1863 | * do an implied skip, it seems to be more reliable than a |
1864 | * forced skip. |
1865 | */ |
1866 | rxEvent = CS_READ_PACKET_PAGE(sc, PKTPG_RX_STATUS); |
1867 | rxEvent = CS_READ_PACKET_PAGE(sc, PKTPG_RX_LENGTH); |
1868 | |
1869 | /* |
1870 | * now read the RX_EVENT register to perform an implied skip. |
1871 | */ |
1872 | rxEvent = CS_READ_PACKET_PAGE(sc, PKTPG_RX_EVENT); |
1873 | |
1874 | cs_ether_input(sc, m); |
1875 | } else { |
1876 | m_freem(m); |
1877 | ifp->if_ierrors++; |
1878 | } |
1879 | } |
1880 | |
1881 | void |
1882 | cs_start_output(struct ifnet *ifp) |
1883 | { |
1884 | struct cs_softc *sc; |
1885 | struct mbuf *pMbuf; |
1886 | struct mbuf *pMbufChain; |
1887 | u_int16_t BusStatus; |
1888 | u_int16_t Length; |
1889 | int txLoop = 0; |
1890 | int dropout = 0; |
1891 | |
1892 | sc = ifp->if_softc; |
1893 | |
1894 | /* check that the interface is up and running */ |
1895 | if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) { |
1896 | return; |
1897 | } |
1898 | |
1899 | /* Don't interrupt a transmission in progress */ |
1900 | if (sc->sc_txbusy) { |
1901 | return; |
1902 | } |
1903 | |
1904 | /* this loop will only run through once if transmission is successful */ |
1905 | /* |
1906 | * While there are packets to transmit and a transmit is not in |
1907 | * progress |
1908 | */ |
1909 | while (sc->sc_txbusy == 0 && dropout == 0) { |
1910 | IFQ_DEQUEUE(&ifp->if_snd, pMbufChain); |
1911 | if (pMbufChain == NULL) |
1912 | break; |
1913 | |
1914 | /* |
1915 | * If BPF is listening on this interface, let it see the packet |
1916 | * before we commit it to the wire. |
1917 | */ |
1918 | bpf_mtap(ifp, pMbufChain); |
1919 | |
1920 | /* Find the total length of the data to transmit */ |
1921 | Length = 0; |
1922 | for (pMbuf = pMbufChain; pMbuf != NULL; pMbuf = pMbuf->m_next) |
1923 | Length += pMbuf->m_len; |
1924 | |
1925 | do { |
1926 | /* |
1927 | * Request that the transmit be started after all |
1928 | * data has been copied |
1929 | * |
1930 | * In IO mode must write to the IO port not the packet |
1931 | * page address |
1932 | * |
1933 | * If this is changed to start transmission after a |
1934 | * small amount of data has been copied you tend to |
1935 | * get packet missed errors i think because the ISA |
1936 | * bus is too slow. Or possibly the copy routine is |
1937 | * not streamlined enough. |
1938 | */ |
1939 | if (sc->sc_memorymode) { |
1940 | CS_WRITE_PACKET_PAGE(sc, PKTPG_TX_CMD, |
1941 | cs_xmit_early_table[sc->sc_xe_ent].txcmd); |
1942 | CS_WRITE_PACKET_PAGE(sc, PKTPG_TX_LENGTH, Length); |
1943 | } |
1944 | else { |
1945 | CS_WRITE_PORT(sc, PORT_TX_CMD, |
1946 | cs_xmit_early_table[sc->sc_xe_ent].txcmd); |
1947 | CS_WRITE_PORT(sc, PORT_TX_LENGTH, Length); |
1948 | } |
1949 | |
1950 | /* |
1951 | * Adjust early-transmit machinery. |
1952 | */ |
1953 | if (--sc->sc_xe_togo == 0) { |
1954 | sc->sc_xe_ent = |
1955 | cs_xmit_early_table[sc->sc_xe_ent].better; |
1956 | sc->sc_xe_togo = |
1957 | cs_xmit_early_table[sc->sc_xe_ent].better_count; |
1958 | } |
1959 | /* |
1960 | * Read the BusStatus register which indicates |
1961 | * success of the request |
1962 | */ |
1963 | BusStatus = CS_READ_PACKET_PAGE(sc, PKTPG_BUS_ST); |
1964 | |
1965 | /* |
1966 | * If there was an error in the transmit bid free the |
1967 | * mbuf and go on. This is presuming that mbuf is |
1968 | * corrupt. |
1969 | */ |
1970 | if (BusStatus & BUS_ST_TX_BID_ERR) { |
1971 | aprint_error_dev(sc->sc_dev, |
1972 | "transmit bid error (too big)" ); |
1973 | |
1974 | /* Discard the bad mbuf chain */ |
1975 | m_freem(pMbufChain); |
1976 | sc->sc_ethercom.ec_if.if_oerrors++; |
1977 | |
1978 | /* Loop up to transmit the next chain */ |
1979 | txLoop = 0; |
1980 | } else { |
1981 | if (BusStatus & BUS_ST_RDY4TXNOW) { |
1982 | /* |
1983 | * The chip is ready for transmission |
1984 | * now |
1985 | */ |
1986 | /* |
1987 | * Copy the frame to the chip to |
1988 | * start transmission |
1989 | */ |
1990 | cs_copy_tx_frame(sc, pMbufChain); |
1991 | |
1992 | /* Free the mbuf chain */ |
1993 | m_freem(pMbufChain); |
1994 | |
1995 | /* Transmission is now in progress */ |
1996 | sc->sc_txbusy = TRUE; |
1997 | txLoop = 0; |
1998 | } else { |
1999 | /* |
2000 | * if we get here we want to try |
2001 | * again with the same mbuf, until |
2002 | * the chip lets us transmit. |
2003 | */ |
2004 | txLoop++; |
2005 | if (txLoop > CS_OUTPUT_LOOP_MAX) { |
2006 | /* Free the mbuf chain */ |
2007 | m_freem(pMbufChain); |
2008 | /* |
2009 | * Transmission is not in |
2010 | * progress |
2011 | */ |
2012 | sc->sc_txbusy = FALSE; |
2013 | /* |
2014 | * Increment the output error |
2015 | * count |
2016 | */ |
2017 | ifp->if_oerrors++; |
2018 | /* |
2019 | * exit the routine and drop |
2020 | * the packet. |
2021 | */ |
2022 | txLoop = 0; |
2023 | dropout = 1; |
2024 | } |
2025 | } |
2026 | } |
2027 | } while (txLoop); |
2028 | } |
2029 | } |
2030 | |
2031 | void |
2032 | cs_copy_tx_frame(struct cs_softc *sc, struct mbuf *m0) |
2033 | { |
2034 | struct mbuf *m; |
2035 | int len, leftover, frameoff; |
2036 | u_int16_t dbuf; |
2037 | u_int8_t *p; |
2038 | #ifdef DIAGNOSTIC |
2039 | u_int8_t *lim; |
2040 | #endif |
2041 | |
2042 | /* Initialize frame pointer and data port address */ |
2043 | frameoff = PKTPG_TX_FRAME; |
2044 | |
2045 | /* start out with no leftover data */ |
2046 | leftover = 0; |
2047 | dbuf = 0; |
2048 | |
2049 | /* Process the chain of mbufs */ |
2050 | for (m = m0; m != NULL; m = m->m_next) { |
2051 | /* |
2052 | * Process all of the data in a single mbuf. |
2053 | */ |
2054 | p = mtod(m, u_int8_t *); |
2055 | len = m->m_len; |
2056 | #ifdef DIAGNOSTIC |
2057 | lim = p + len; |
2058 | #endif |
2059 | |
2060 | while (len > 0) { |
2061 | if (leftover) { |
2062 | /* |
2063 | * Data left over (from mbuf or realignment). |
2064 | * Buffer the next byte, and write it and |
2065 | * the leftover data out. |
2066 | */ |
2067 | dbuf |= *p++ << 8; |
2068 | len--; |
2069 | if (sc->sc_memorymode) { |
2070 | CS_WRITE_PACKET_PAGE(sc, frameoff, dbuf); |
2071 | frameoff += 2; |
2072 | } |
2073 | else { |
2074 | CS_WRITE_PORT(sc, PORT_RXTX_DATA, dbuf); |
2075 | } |
2076 | leftover = 0; |
2077 | } else if ((long) p & 1) { |
2078 | /* |
2079 | * Misaligned data. Buffer the next byte. |
2080 | */ |
2081 | dbuf = *p++; |
2082 | len--; |
2083 | leftover = 1; |
2084 | } else { |
2085 | /* |
2086 | * Aligned data. This is the case we like. |
2087 | * |
2088 | * Write-region out as much as we can, then |
2089 | * buffer the remaining byte (if any). |
2090 | */ |
2091 | leftover = len & 1; |
2092 | len &= ~1; |
2093 | if (sc->sc_memorymode) { |
2094 | MEM_WRITE_REGION_2(sc, frameoff, |
2095 | (u_int16_t *) p, len >> 1); |
2096 | frameoff += len; |
2097 | } |
2098 | else { |
2099 | IO_WRITE_MULTI_2(sc, |
2100 | PORT_RXTX_DATA, (u_int16_t *)p, len >> 1); |
2101 | } |
2102 | p += len; |
2103 | |
2104 | if (leftover) |
2105 | dbuf = *p++; |
2106 | len = 0; |
2107 | } |
2108 | } |
2109 | if (len < 0) |
2110 | panic("cs_copy_tx_frame: negative len" ); |
2111 | #ifdef DIAGNOSTIC |
2112 | if (p != lim) |
2113 | panic("cs_copy_tx_frame: p != lim" ); |
2114 | #endif |
2115 | } |
2116 | if (leftover) { |
2117 | if (sc->sc_memorymode) { |
2118 | CS_WRITE_PACKET_PAGE(sc, frameoff, dbuf); |
2119 | } |
2120 | else { |
2121 | CS_WRITE_PORT(sc, PORT_RXTX_DATA, dbuf); |
2122 | } |
2123 | } |
2124 | } |
2125 | |
2126 | static int |
2127 | cs_enable(struct cs_softc *sc) |
2128 | { |
2129 | |
2130 | if (CS_IS_ENABLED(sc) == 0) { |
2131 | if (sc->sc_enable != NULL) { |
2132 | int error; |
2133 | |
2134 | error = (*sc->sc_enable)(sc); |
2135 | if (error) |
2136 | return (error); |
2137 | } |
2138 | sc->sc_cfgflags |= CFGFLG_ENABLED; |
2139 | } |
2140 | |
2141 | return (0); |
2142 | } |
2143 | |
2144 | static void |
2145 | cs_disable(struct cs_softc *sc) |
2146 | { |
2147 | |
2148 | if (CS_IS_ENABLED(sc)) { |
2149 | if (sc->sc_disable != NULL) |
2150 | (*sc->sc_disable)(sc); |
2151 | |
2152 | sc->sc_cfgflags &= ~CFGFLG_ENABLED; |
2153 | } |
2154 | } |
2155 | |
2156 | static void |
2157 | cs_stop(struct ifnet *ifp, int disable) |
2158 | { |
2159 | struct cs_softc *sc = ifp->if_softc; |
2160 | |
2161 | CS_WRITE_PACKET_PAGE(sc, PKTPG_RX_CFG, 0); |
2162 | CS_WRITE_PACKET_PAGE(sc, PKTPG_TX_CFG, 0); |
2163 | CS_WRITE_PACKET_PAGE(sc, PKTPG_BUF_CFG, 0); |
2164 | CS_WRITE_PACKET_PAGE(sc, PKTPG_BUS_CTL, 0); |
2165 | |
2166 | if (disable) { |
2167 | cs_disable(sc); |
2168 | } |
2169 | |
2170 | ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); |
2171 | } |
2172 | |
2173 | int |
2174 | cs_activate(device_t self, enum devact act) |
2175 | { |
2176 | struct cs_softc *sc = device_private(self); |
2177 | |
2178 | switch (act) { |
2179 | case DVACT_DEACTIVATE: |
2180 | if_deactivate(&sc->sc_ethercom.ec_if); |
2181 | return 0; |
2182 | default: |
2183 | return EOPNOTSUPP; |
2184 | } |
2185 | } |
2186 | |