Deleted Added
full compact
if_xe.c (119418) if_xe.c (121099)
1/*-
1/*-
2 * Copyright (c) 1998, 1999 Scott Mitchell
2 * Copyright (c) 1998, 1999, 2003 Scott Mitchell
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright

--- 11 unchanged lines hidden (view full) ---

22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $Id: if_xe.c,v 1.20 1999/06/13 19:17:40 scott Exp $
27 */
28
29#include <sys/cdefs.h>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright

--- 11 unchanged lines hidden (view full) ---

22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $Id: if_xe.c,v 1.20 1999/06/13 19:17:40 scott Exp $
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: head/sys/dev/xe/if_xe.c 119418 2003-08-24 17:55:58Z obrien $");
30__FBSDID("$FreeBSD: head/sys/dev/xe/if_xe.c 121099 2003-10-14 22:51:35Z rsm $");
31
32/*
31
32/*
33 * XXX TODO XXX
34 *
35 * I've pushed this fairly far, but there are some things that need to be
36 * done here. I'm documenting them here in case I get destracted. -- imp
37 *
38 * xe_cem56fix -- need to figure out how to map the extra stuff.
39 */
40
41/*
42 * Portions of this software were derived from Werner Koch's xirc2ps driver
43 * for Linux under the terms of the following license (from v1.30 of the
44 * xirc2ps driver):
45 *
46 * Copyright (c) 1997 by Werner Koch (dd9jn)
47 *
48 * Redistribution and use in source and binary forms, with or without
49 * modification, are permitted provided that the following conditions

--- 44 unchanged lines hidden (view full) ---

94 * especially: Werner Koch, Duke Kamstra, Duncan Barclay, Jason George, Dru
95 * Nelson, Mike Kephart, Bill Rainey and Douglas Rand. Apologies if I've left
96 * out anyone who deserves a mention here.
97 *
98 * Special thanks to Ade Lovett for both hosting the mailing list and doing
99 * the CEM56/REM56 support code; and the FreeBSD UK Users' Group for hosting
100 * the web pages.
101 *
33 * Portions of this software were derived from Werner Koch's xirc2ps driver
34 * for Linux under the terms of the following license (from v1.30 of the
35 * xirc2ps driver):
36 *
37 * Copyright (c) 1997 by Werner Koch (dd9jn)
38 *
39 * Redistribution and use in source and binary forms, with or without
40 * modification, are permitted provided that the following conditions

--- 44 unchanged lines hidden (view full) ---

85 * especially: Werner Koch, Duke Kamstra, Duncan Barclay, Jason George, Dru
86 * Nelson, Mike Kephart, Bill Rainey and Douglas Rand. Apologies if I've left
87 * out anyone who deserves a mention here.
88 *
89 * Special thanks to Ade Lovett for both hosting the mailing list and doing
90 * the CEM56/REM56 support code; and the FreeBSD UK Users' Group for hosting
91 * the web pages.
92 *
102 * Contact points:
103 *
104 * Driver web page: http://ukug.uk.freebsd.org/~scott/xe_drv/
105 *
106 * Mailing list: http://www.lovett.com/lists/freebsd-xircom/
107 * or send "subscribe freebsd-xircom" to <majordomo@lovett.com>
108 *
109 * Author email: <scott@uk.freebsd.org>
93 * Author email: <scott@uk.freebsd.org>
94 * Driver web page: http://ukug.uk.freebsd.org/~scott/xe_drv/
110 */
111
112
113#include <sys/param.h>
114#include <sys/cdefs.h>
115#include <sys/errno.h>
116#include <sys/kernel.h>
117#include <sys/mbuf.h>

--- 36 unchanged lines hidden (view full) ---

154 * Media autonegotiation progress constants
155 */
156#define XE_AUTONEG_NONE 0 /* No autonegotiation in progress */
157#define XE_AUTONEG_WAITING 1 /* Waiting for transmitter to go idle */
158#define XE_AUTONEG_STARTED 2 /* Waiting for autonegotiation to complete */
159#define XE_AUTONEG_100TX 3 /* Trying to force 100baseTX link */
160#define XE_AUTONEG_FAIL 4 /* Autonegotiation failed */
161
95 */
96
97
98#include <sys/param.h>
99#include <sys/cdefs.h>
100#include <sys/errno.h>
101#include <sys/kernel.h>
102#include <sys/mbuf.h>

--- 36 unchanged lines hidden (view full) ---

139 * Media autonegotiation progress constants
140 */
141#define XE_AUTONEG_NONE 0 /* No autonegotiation in progress */
142#define XE_AUTONEG_WAITING 1 /* Waiting for transmitter to go idle */
143#define XE_AUTONEG_STARTED 2 /* Waiting for autonegotiation to complete */
144#define XE_AUTONEG_100TX 3 /* Trying to force 100baseTX link */
145#define XE_AUTONEG_FAIL 4 /* Autonegotiation failed */
146
147/*
148 * Multicast hashing CRC constants
149 */
150#define XE_CRC_POLY 0x04c11db6
162
163/*
164 * Prototypes start here
165 */
166static void xe_init (void *xscp);
167static void xe_start (struct ifnet *ifp);
168static int xe_ioctl (struct ifnet *ifp, u_long command, caddr_t data);
169static void xe_watchdog (struct ifnet *ifp);
170static int xe_media_change (struct ifnet *ifp);
171static void xe_media_status (struct ifnet *ifp, struct ifmediareq *mrp);
172static timeout_t xe_setmedia;
151
152/*
153 * Prototypes start here
154 */
155static void xe_init (void *xscp);
156static void xe_start (struct ifnet *ifp);
157static int xe_ioctl (struct ifnet *ifp, u_long command, caddr_t data);
158static void xe_watchdog (struct ifnet *ifp);
159static int xe_media_change (struct ifnet *ifp);
160static void xe_media_status (struct ifnet *ifp, struct ifmediareq *mrp);
161static timeout_t xe_setmedia;
173static void xe_hard_reset (struct xe_softc *scp);
174static void xe_soft_reset (struct xe_softc *scp);
162static void xe_reset (struct xe_softc *scp);
175static void xe_stop (struct xe_softc *scp);
176static void xe_enable_intr (struct xe_softc *scp);
177static void xe_disable_intr (struct xe_softc *scp);
163static void xe_stop (struct xe_softc *scp);
164static void xe_enable_intr (struct xe_softc *scp);
165static void xe_disable_intr (struct xe_softc *scp);
178static void xe_setmulti (struct xe_softc *scp);
179static void xe_setaddrs (struct xe_softc *scp);
166static void xe_set_multicast (struct xe_softc *scp);
167static void xe_set_addr (struct xe_softc *scp, u_int8_t* addr, unsigned idx);
168static void xe_set_hash (struct xe_softc *scp, u_int8_t* addr);
180static int xe_pio_write_packet (struct xe_softc *scp, struct mbuf *mbp);
169static int xe_pio_write_packet (struct xe_softc *scp, struct mbuf *mbp);
181static u_int32_t xe_compute_crc (u_int8_t *data, int len) __unused;
182static int xe_compute_hashbit (u_int32_t crc) __unused;
183
184/*
185 * MII functions
186 */
187static void xe_mii_sync (struct xe_softc *scp);
188static int xe_mii_init (struct xe_softc *scp);
189static void xe_mii_send (struct xe_softc *scp, u_int32_t bits, int cnt);
190static int xe_mii_readreg (struct xe_softc *scp, struct xe_mii_frame *frame);
191static int xe_mii_writereg (struct xe_softc *scp, struct xe_mii_frame *frame);
192static u_int16_t xe_phy_readreg (struct xe_softc *scp, u_int16_t reg);
193static void xe_phy_writereg (struct xe_softc *scp, u_int16_t reg, u_int16_t data);
194
170
171/*
172 * MII functions
173 */
174static void xe_mii_sync (struct xe_softc *scp);
175static int xe_mii_init (struct xe_softc *scp);
176static void xe_mii_send (struct xe_softc *scp, u_int32_t bits, int cnt);
177static int xe_mii_readreg (struct xe_softc *scp, struct xe_mii_frame *frame);
178static int xe_mii_writereg (struct xe_softc *scp, struct xe_mii_frame *frame);
179static u_int16_t xe_phy_readreg (struct xe_softc *scp, u_int16_t reg);
180static void xe_phy_writereg (struct xe_softc *scp, u_int16_t reg, u_int16_t data);
181
182
195/*
183/*
196 * Debug functions -- uncomment for VERY verbose dignostic information.
197 * Set to 1 for less verbose information
184 * Debug logging level (comment out for normal operation):
185 * 1 = Log more hardware details, xe_ioctl details
186 * 2 = Log most function calls, some (eg. multicast, MII) in detail
187 * 3 = Log everything, including all interrupts and packets sent
198 */
188 */
199/* #define XE_DEBUG 2 */
200#ifdef XE_DEBUG
189#define XE_DEBUG 0
190
191#if XE_DEBUG > 2
201#define XE_REG_DUMP(scp) xe_reg_dump((scp))
202#define XE_MII_DUMP(scp) xe_mii_dump((scp))
203static void xe_reg_dump (struct xe_softc *scp);
204static void xe_mii_dump (struct xe_softc *scp);
205#else
206#define XE_REG_DUMP(scp)
207#define XE_MII_DUMP(scp)
208#endif
209
192#define XE_REG_DUMP(scp) xe_reg_dump((scp))
193#define XE_MII_DUMP(scp) xe_mii_dump((scp))
194static void xe_reg_dump (struct xe_softc *scp);
195static void xe_mii_dump (struct xe_softc *scp);
196#else
197#define XE_REG_DUMP(scp)
198#define XE_MII_DUMP(scp)
199#endif
200
201
210/*
211 * Attach a device.
212 */
213int
214xe_attach (device_t dev)
215{
216 struct xe_softc *scp = device_get_softc(dev);
217
202/*
203 * Attach a device.
204 */
205int
206xe_attach (device_t dev)
207{
208 struct xe_softc *scp = device_get_softc(dev);
209
218#ifdef XE_DEBUG
210#if XE_DEBUG > 1
219 device_printf(dev, "attach\n");
220#endif
221
211 device_printf(dev, "attach\n");
212#endif
213
222 /* Fill in some private data */
214 /* Initialise stuff... */
215 scp->dev = dev;
223 scp->ifp = &scp->arpcom.ac_if;
224 scp->ifm = &scp->ifmedia;
216 scp->ifp = &scp->arpcom.ac_if;
217 scp->ifm = &scp->ifmedia;
225 scp->autoneg_status = 0;
218 scp->autoneg_status = XE_AUTONEG_NONE;
226
219
227 /* Hopefully safe to read this here */
228 XE_SELECT_PAGE(4);
229 scp->version = XE_INB(XE_BOV);
230
231 scp->dev = dev;
232 /* Initialise the ifnet structure */
233 if (!scp->ifp->if_name) {
234 scp->ifp->if_softc = scp;
235 scp->ifp->if_name = "xe";
236 scp->ifp->if_unit = device_get_unit(dev);
237 scp->ifp->if_timer = 0;
238 scp->ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST);
239 scp->ifp->if_linkmib = &scp->mibdata;
240 scp->ifp->if_linkmiblen = sizeof scp->mibdata;
241 scp->ifp->if_output = ether_output;
242 scp->ifp->if_start = xe_start;
243 scp->ifp->if_ioctl = xe_ioctl;
244 scp->ifp->if_watchdog = xe_watchdog;
245 scp->ifp->if_init = xe_init;
220 /* Initialise the ifnet structure */
221 if (!scp->ifp->if_name) {
222 scp->ifp->if_softc = scp;
223 scp->ifp->if_name = "xe";
224 scp->ifp->if_unit = device_get_unit(dev);
225 scp->ifp->if_timer = 0;
226 scp->ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST);
227 scp->ifp->if_linkmib = &scp->mibdata;
228 scp->ifp->if_linkmiblen = sizeof scp->mibdata;
229 scp->ifp->if_output = ether_output;
230 scp->ifp->if_start = xe_start;
231 scp->ifp->if_ioctl = xe_ioctl;
232 scp->ifp->if_watchdog = xe_watchdog;
233 scp->ifp->if_init = xe_init;
234 scp->ifp->if_baudrate = 100000000;
246 scp->ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
247 }
248
249 /* Initialise the ifmedia structure */
250 ifmedia_init(scp->ifm, 0, xe_media_change, xe_media_status);
251 callout_handle_init(&scp->chand);
252
235 scp->ifp->if_snd.ifq_maxlen = IFQ_MAXLEN;
236 }
237
238 /* Initialise the ifmedia structure */
239 ifmedia_init(scp->ifm, 0, xe_media_change, xe_media_status);
240 callout_handle_init(&scp->chand);
241
253 /*
254 * Fill in supported media types. Some cards _do_ support full duplex
255 * operation, but this driver doesn't, yet. Therefore we leave those modes
256 * out of the list. We support some form of autoselection in all cases.
257 */
242 /* Add supported media types */
258 if (scp->mohawk) {
259 ifmedia_add(scp->ifm, IFM_ETHER|IFM_100_TX, 0, NULL);
243 if (scp->mohawk) {
244 ifmedia_add(scp->ifm, IFM_ETHER|IFM_100_TX, 0, NULL);
260 ifmedia_add(scp->ifm, IFM_ETHER|IFM_10_T, 0, NULL);
245 ifmedia_add(scp->ifm, IFM_ETHER|IFM_10_T|IFM_FDX, 0, NULL);
246 ifmedia_add(scp->ifm, IFM_ETHER|IFM_10_T|IFM_HDX, 0, NULL);
261 }
247 }
262 else {
263 ifmedia_add(scp->ifm, IFM_ETHER|IFM_10_T, 0, NULL);
248 ifmedia_add(scp->ifm, IFM_ETHER|IFM_10_T, 0, NULL);
249 if (scp->ce2)
264 ifmedia_add(scp->ifm, IFM_ETHER|IFM_10_2, 0, NULL);
250 ifmedia_add(scp->ifm, IFM_ETHER|IFM_10_2, 0, NULL);
265 }
266 ifmedia_add(scp->ifm, IFM_ETHER|IFM_AUTO, 0, NULL);
267
268 /* Default is to autoselect best supported media type */
269 ifmedia_set(scp->ifm, IFM_ETHER|IFM_AUTO);
270
251 ifmedia_add(scp->ifm, IFM_ETHER|IFM_AUTO, 0, NULL);
252
253 /* Default is to autoselect best supported media type */
254 ifmedia_set(scp->ifm, IFM_ETHER|IFM_AUTO);
255
256 /* Get the hardware into a known state */
257 xe_reset(scp);
258
259 /* Get hardware version numbers */
260 XE_SELECT_PAGE(4);
261 scp->version = XE_INB(XE_BOV);
262 if (scp->mohawk)
263 scp->srev = (XE_INB(XE_BOV) & 0x70) >> 4;
264 else
265 scp->srev = (XE_INB(XE_BOV) & 0x30) >> 4;
266
271 /* Print some useful information */
267 /* Print some useful information */
272 device_printf(dev, "%s %s, bonding version %#x%s%s\n",
268 device_printf(dev, "%s %s, version 0x%02x/0x%02x%s%s\n",
273 scp->vendor,
274 scp->card_type,
275 scp->version,
269 scp->vendor,
270 scp->card_type,
271 scp->version,
272 scp->srev,
276 scp->mohawk ? ", 100Mbps capable" : "",
277 scp->modem ? ", with modem" : "");
273 scp->mohawk ? ", 100Mbps capable" : "",
274 scp->modem ? ", with modem" : "");
275#if XE_DEBUG > 0
278 if (scp->mohawk) {
279 XE_SELECT_PAGE(0x10);
276 if (scp->mohawk) {
277 XE_SELECT_PAGE(0x10);
280 device_printf(dev, "DingoID = %#x, RevisionID = %#x, VendorID = %#x\n",
278 device_printf(dev, "DingoID=0x%04x, RevisionID=0x%04x, VendorID=0x%04x\n",
281 XE_INW(XE_DINGOID),
282 XE_INW(XE_RevID),
283 XE_INW(XE_VendorID));
284 }
285 if (scp->ce2) {
286 XE_SELECT_PAGE(0x45);
279 XE_INW(XE_DINGOID),
280 XE_INW(XE_RevID),
281 XE_INW(XE_VendorID));
282 }
283 if (scp->ce2) {
284 XE_SELECT_PAGE(0x45);
287 device_printf(dev, "CE2 version = %#x\n", XE_INB(XE_REV));
285 device_printf(dev, "CE2 version = 0x%#02x\n", XE_INB(XE_REV));
288 }
286 }
289
290 /* Print MAC address */
287#endif
291 device_printf(dev, "Ethernet address %6D\n", scp->arpcom.ac_enaddr, ":");
292
293 /* Attach the interface */
294 ether_ifattach(scp->ifp, scp->arpcom.ac_enaddr);
295
296 /* Done */
297 return 0;
298}
299
300
301/*
288 device_printf(dev, "Ethernet address %6D\n", scp->arpcom.ac_enaddr, ":");
289
290 /* Attach the interface */
291 ether_ifattach(scp->ifp, scp->arpcom.ac_enaddr);
292
293 /* Done */
294 return 0;
295}
296
297
298/*
302 * Initialize device. Completes the reset procedure on the card and starts
303 * output. If there's an autonegotiation in progress we DON'T do anything;
304 * the media selection code will call us again when it's done.
299 * Complete hardware intitialisation and enable output. Exits without doing
300 * anything if there's no address assigned to the card, or if media selection
301 * is in progress (the latter implies we've already run this function).
305 */
306static void
307xe_init(void *xscp) {
308 struct xe_softc *scp = xscp;
302 */
303static void
304xe_init(void *xscp) {
305 struct xe_softc *scp = xscp;
306 unsigned i;
309 int s;
310
307 int s;
308
311#ifdef XE_DEBUG
309 if (TAILQ_EMPTY(&scp->ifp->if_addrhead)) return;
310
311 if (scp->autoneg_status != XE_AUTONEG_NONE) return;
312
313#if XE_DEBUG > 1
312 device_printf(scp->dev, "init\n");
313#endif
314
314 device_printf(scp->dev, "init\n");
315#endif
316
315 if (TAILQ_EMPTY(&scp->ifp->if_addrhead)) return;
317 s = splimp();
316
317 /* Reset transmitter flags */
318 scp->tx_queued = 0;
319 scp->tx_tpr = 0;
318
319 /* Reset transmitter flags */
320 scp->tx_queued = 0;
321 scp->tx_tpr = 0;
320 scp->tx_collisions = 0;
322 scp->tx_timeouts = 0;
323 scp->tx_thres = 64;
324 scp->tx_min = ETHER_MIN_LEN - ETHER_CRC_LEN;
321 scp->ifp->if_timer = 0;
322
325 scp->ifp->if_timer = 0;
326
323 s = splimp();
327 /* Soft reset the card */
328 XE_SELECT_PAGE(0);
329 XE_OUTB(XE_CR, XE_CR_SOFT_RESET);
330 DELAY(40000);
331 XE_OUTB(XE_CR, 0);
332 DELAY(40000);
324
333
334 if (scp->mohawk) {
335 /*
336 * set GP1 and GP2 as outputs (bits 2 & 3)
337 * set GP1 low to power on the ML6692 (bit 0)
338 * set GP2 high to power on the 10Mhz chip (bit 1)
339 */
340 XE_SELECT_PAGE(4);
341 XE_OUTB(XE_GPR0, XE_GPR0_GP2_SELECT|XE_GPR0_GP1_SELECT|XE_GPR0_GP2_OUT);
342 }
343
344 /* Shut off interrupts */
345 xe_disable_intr(scp);
346
347 /* Wait for everything to wake up */
348 DELAY(500000);
349
350 /* Check for PHY */
351 if (scp->mohawk)
352 scp->phy_ok = xe_mii_init(scp);
353
354 /* Disable 'source insertion' (not sure what that means) */
325 XE_SELECT_PAGE(0x42);
355 XE_SELECT_PAGE(0x42);
326 XE_OUTB(XE_SWC0, 0x20); /* Disable source insertion (WTF is that?) */
356 XE_OUTB(XE_SWC0, XE_SWC0_NO_SRC_INSERT);
327
357
328 /*
329 * Set the 'local memory dividing line' -- splits the 32K card memory into
330 * 8K for transmit buffers and 24K for receive. This is done automatically
331 * on newer revision cards.
332 */
358 /* Set 8K/24K Tx/Rx buffer split */
333 if (scp->srev != 1) {
334 XE_SELECT_PAGE(2);
335 XE_OUTW(XE_RBS, 0x2000);
336 }
337
359 if (scp->srev != 1) {
360 XE_SELECT_PAGE(2);
361 XE_OUTW(XE_RBS, 0x2000);
362 }
363
364 /* Enable early transmit mode on Mohawk/Dingo */
365 if (scp->mohawk) {
366 XE_SELECT_PAGE(0x03);
367 XE_OUTW(XE_TPT, scp->tx_thres);
368 XE_SELECT_PAGE(0x01);
369 XE_OUTB(XE_ECR, XE_INB(XE_ECR) | XE_ECR_EARLY_TX);
370 }
371
372 /* Put MAC address in first 'individual address' register */
373 XE_SELECT_PAGE(0x50);
374 for (i = 0; i < 6; i++)
375 XE_OUTB(0x08 + i, scp->arpcom.ac_enaddr[scp->mohawk ? 5 - i : i]);
376
338 /* Set up multicast addresses */
377 /* Set up multicast addresses */
339 xe_setmulti(scp);
378 xe_set_multicast(scp);
340
379
341 /* Fix the data offset register -- reset leaves it off-by-one */
380 /* Fix the receive data offset -- reset can leave it off-by-one */
342 XE_SELECT_PAGE(0);
343 XE_OUTW(XE_DO, 0x2000);
344
381 XE_SELECT_PAGE(0);
382 XE_OUTW(XE_DO, 0x2000);
383
345 /*
346 * Set MAC interrupt masks and clear status regs. The bit names are direct
347 * from the Linux code; I have no idea what most of them do.
348 */
349 XE_SELECT_PAGE(0x40); /* Bit 7..0 */
350 XE_OUTB(XE_RX0Msk, 0xff); /* ROK, RAB, rsv, RO, CRC, AE, PTL, MP */
351 XE_OUTB(XE_TX0Msk, 0xff); /* TOK, TAB, SQE, LL, TU, JAB, EXC, CRS */
352 XE_OUTB(XE_TX0Msk+1, 0xb0); /* rsv, rsv, PTD, EXT, rsv, rsv, rsv, rsv */
353 XE_OUTB(XE_RST0, 0x00); /* ROK, RAB, REN, RO, CRC, AE, PTL, MP */
354 XE_OUTB(XE_TXST0, 0x00); /* TOK, TAB, SQE, LL, TU, JAB, EXC, CRS */
355 XE_OUTB(XE_TXST1, 0x00); /* TEN, rsv, PTD, EXT, retry_counter:4 */
384 /* Set interrupt masks */
385 XE_SELECT_PAGE(1);
386 XE_OUTB(XE_IMR0, XE_IMR0_TX_PACKET | XE_IMR0_MAC_INTR | XE_IMR0_RX_PACKET);
356
387
357 /*
358 * Check for an in-progress autonegotiation. If one is active, just set
359 * IFF_RUNNING and return. The media selection code will call us again when
360 * it's done.
361 */
362 if (scp->autoneg_status) {
363 scp->ifp->if_flags |= IFF_RUNNING;
364 }
365 else {
366 /* Enable receiver, put MAC online */
367 XE_SELECT_PAGE(0x40);
368 XE_OUTB(XE_CMD0, XE_CMD0_RX_ENABLE|XE_CMD0_ONLINE);
388 /* Set MAC interrupt masks */
389 XE_SELECT_PAGE(0x40);
390 XE_OUTB(XE_RX0Msk,
391 ~(XE_RX0M_RX_OVERRUN | XE_RX0M_CRC_ERROR
392 | XE_RX0M_ALIGN_ERROR | XE_RX0M_LONG_PACKET));
393 XE_OUTB(XE_TX0Msk,
394 ~(XE_TX0M_SQE_FAIL | XE_TX0M_LATE_COLLISION | XE_TX0M_TX_UNDERRUN
395 | XE_TX0M_16_COLLISIONS | XE_TX0M_NO_CARRIER));
369
396
370 /* Set up IMR, enable interrupts */
371 xe_enable_intr(scp);
397 /* Clear MAC status registers */
398 XE_SELECT_PAGE(0x40);
399 XE_OUTB(XE_RST0, 0x00);
400 XE_OUTB(XE_TXST0, 0x00);
372
401
373 /* Attempt to start output */
374 scp->ifp->if_flags |= IFF_RUNNING;
375 scp->ifp->if_flags &= ~IFF_OACTIVE;
376 xe_start(scp->ifp);
377 }
402 /* Enable receiver and put MAC online */
403 XE_SELECT_PAGE(0x40);
404 XE_OUTB(XE_CMD0, XE_CMD0_RX_ENABLE|XE_CMD0_ONLINE);
378
405
406 /* Set up IMR, enable interrupts */
407 xe_enable_intr(scp);
408
409 /* Start media selection */
410 xe_setmedia(scp);
411
412 /* Enable output */
413 scp->ifp->if_flags |= IFF_RUNNING;
414 scp->ifp->if_flags &= ~IFF_OACTIVE;
415
379 (void)splx(s);
380}
381
382
383/*
416 (void)splx(s);
417}
418
419
420/*
384 * Start output on interface. We make two assumptions here:
385 * 1) that the current priority is set to splimp _before_ this code
386 * is called *and* is returned to the appropriate priority after
387 * return
388 * 2) that the IFF_OACTIVE flag is checked before this code is called
389 * (i.e. that the output part of the interface is idle)
421 * Start output on interface. Should be called at splimp() priority. Check
422 * that the output is idle (ie, IFF_OACTIVE is not set) before calling this
423 * function. If media selection is in progress we set IFF_OACTIVE ourselves
424 * and return immediately.
390 */
391static void
392xe_start(struct ifnet *ifp) {
393 struct xe_softc *scp = ifp->if_softc;
394 struct mbuf *mbp;
395
425 */
426static void
427xe_start(struct ifnet *ifp) {
428 struct xe_softc *scp = ifp->if_softc;
429 struct mbuf *mbp;
430
431 if (scp->autoneg_status != XE_AUTONEG_NONE) {
432 ifp->if_flags |= IFF_OACTIVE;
433 return;
434 }
435
436#if XE_DEBUG > 2
437 device_printf(scp->dev, "start\n");
438#endif
439
396 /*
397 * Loop while there are packets to be sent, and space to send them.
398 */
399 while (1) {
440 /*
441 * Loop while there are packets to be sent, and space to send them.
442 */
443 while (1) {
400 IF_DEQUEUE(&ifp->if_snd, mbp); /* Suck a packet off the send queue */
444 /* Suck a packet off the send queue */
445 IF_DEQUEUE(&ifp->if_snd, mbp);
401
402 if (mbp == NULL) {
403 /*
404 * We are using the !OACTIVE flag to indicate to the outside world that
405 * we can accept an additional packet rather than that the transmitter
406 * is _actually_ active. Indeed, the transmitter may be active, but if
407 * we haven't filled all the buffers with data then we still want to
408 * accept more.
409 */
410 ifp->if_flags &= ~IFF_OACTIVE;
411 return;
412 }
413
414 if (xe_pio_write_packet(scp, mbp) != 0) {
446
447 if (mbp == NULL) {
448 /*
449 * We are using the !OACTIVE flag to indicate to the outside world that
450 * we can accept an additional packet rather than that the transmitter
451 * is _actually_ active. Indeed, the transmitter may be active, but if
452 * we haven't filled all the buffers with data then we still want to
453 * accept more.
454 */
455 ifp->if_flags &= ~IFF_OACTIVE;
456 return;
457 }
458
459 if (xe_pio_write_packet(scp, mbp) != 0) {
415 IF_PREPEND(&ifp->if_snd, mbp); /* Push the packet back onto the queue */
460 /* Push the packet back onto the queue */
461 IF_PREPEND(&ifp->if_snd, mbp);
416 ifp->if_flags |= IFF_OACTIVE;
417 return;
418 }
419
420 /* Tap off here if there is a bpf listener */
421 BPF_MTAP(ifp, mbp);
422
462 ifp->if_flags |= IFF_OACTIVE;
463 return;
464 }
465
466 /* Tap off here if there is a bpf listener */
467 BPF_MTAP(ifp, mbp);
468
423 ifp->if_timer = 5; /* In case we don't hear from the card again */
469 /* In case we don't hear from the card again... */
470 ifp->if_timer = 5;
424 scp->tx_queued++;
425
426 m_freem(mbp);
427 }
428}
429
430
431/*

--- 6 unchanged lines hidden (view full) ---

438
439 scp = ifp->if_softc;
440 error = 0;
441
442 s = splimp();
443
444 switch (command) {
445
471 scp->tx_queued++;
472
473 m_freem(mbp);
474 }
475}
476
477
478/*

--- 6 unchanged lines hidden (view full) ---

485
486 scp = ifp->if_softc;
487 error = 0;
488
489 s = splimp();
490
491 switch (command) {
492
446 case SIOCSIFFLAGS:
493 case SIOCSIFFLAGS:
494#if XE_DEBUG > 1
495 device_printf(scp->dev, "ioctl: SIOCSIFFLAGS: 0x%04x\n", ifp->if_flags);
496#endif
447 /*
448 * If the interface is marked up and stopped, then start it. If it is
449 * marked down and running, then stop it.
450 */
451 if (ifp->if_flags & IFF_UP) {
452 if (!(ifp->if_flags & IFF_RUNNING)) {
497 /*
498 * If the interface is marked up and stopped, then start it. If it is
499 * marked down and running, then stop it.
500 */
501 if (ifp->if_flags & IFF_UP) {
502 if (!(ifp->if_flags & IFF_RUNNING)) {
453 xe_hard_reset(scp);
454 xe_setmedia(scp);
503 xe_reset(scp);
455 xe_init(scp);
456 }
457 }
458 else {
459 if (ifp->if_flags & IFF_RUNNING)
460 xe_stop(scp);
461 }
504 xe_init(scp);
505 }
506 }
507 else {
508 if (ifp->if_flags & IFF_RUNNING)
509 xe_stop(scp);
510 }
462 /* XXX: intentional fall-through ? */
463 case SIOCADDMULTI:
464 case SIOCDELMULTI:
511 /* FALL THROUGH (handle changes to PROMISC/ALLMULTI flags) */
512
513 case SIOCADDMULTI:
514 case SIOCDELMULTI:
515#if XE_DEBUG > 1
516 device_printf(scp->dev, "ioctl: SIOC{ADD,DEL}MULTI\n");
517#endif
465 /*
518 /*
466 * Multicast list has (maybe) changed; set the hardware filter
467 * accordingly. This also serves to deal with promiscuous mode if we have
468 * a BPF listener active.
519 * Multicast list has (maybe) changed; set the hardware filters
520 * accordingly.
469 */
521 */
470 xe_setmulti(scp);
522 xe_set_multicast(scp);
471 error = 0;
472 break;
473
523 error = 0;
524 break;
525
474 case SIOCSIFMEDIA:
475 case SIOCGIFMEDIA:
526 case SIOCSIFMEDIA:
527 case SIOCGIFMEDIA:
528#if XE_DEBUG > 1
529 device_printf(scp->dev, "ioctl: bounce to ifmedia_ioctl\n");
530#endif
476 /*
477 * Someone wants to get/set media options.
478 */
479 error = ifmedia_ioctl(ifp, (struct ifreq *)data, &scp->ifmedia, command);
480 break;
481
531 /*
532 * Someone wants to get/set media options.
533 */
534 error = ifmedia_ioctl(ifp, (struct ifreq *)data, &scp->ifmedia, command);
535 break;
536
482 default:
537 default:
538#if XE_DEBUG > 1
539 device_printf(scp->dev, "ioctl: bounce to ether_ioctl\n");
540#endif
483 error = ether_ioctl(ifp, command, data);
484 }
485
486 (void)splx(s);
487
488 return error;
489}
490

--- 16 unchanged lines hidden (view full) ---

507 * get your work done, don't buy a Xircom card. Or convince them to tell me
508 * how to do memory-mapped I/O :)
509 */
510static void
511xe_intr(void *xscp)
512{
513 struct xe_softc *scp = (struct xe_softc *) xscp;
514 struct ifnet *ifp;
541 error = ether_ioctl(ifp, command, data);
542 }
543
544 (void)splx(s);
545
546 return error;
547}
548

--- 16 unchanged lines hidden (view full) ---

565 * get your work done, don't buy a Xircom card. Or convince them to tell me
566 * how to do memory-mapped I/O :)
567 */
568static void
569xe_intr(void *xscp)
570{
571 struct xe_softc *scp = (struct xe_softc *) xscp;
572 struct ifnet *ifp;
515 u_int16_t rx_bytes, rxs, txs;
516 u_int8_t psr, isr, esr, rsr;
573 u_int8_t psr, isr, esr, rsr, rst0, txst0, txst1, coll;
517
518 ifp = &scp->arpcom.ac_if;
574
575 ifp = &scp->arpcom.ac_if;
519 rx_bytes = 0; /* Bytes received on this interrupt */
520
576
521 if (scp->mohawk) {
522 XE_OUTB(XE_CR, 0); /* Disable interrupts */
523 }
577 /* Disable interrupts */
578 if (scp->mohawk)
579 XE_OUTB(XE_CR, 0);
524
580
525 psr = XE_INB(XE_PR); /* Stash the current register page */
581 /* Cache current register page */
582 psr = XE_INB(XE_PR);
526
583
527 /*
528 * Read ISR to see what caused this interrupt. Note that this clears the
529 * ISR on CE2 type cards.
530 */
531 if ((isr = XE_INB(XE_ISR)) && isr != 0xff) {
584 /* Read ISR to see what caused this interrupt */
585 while ((isr = XE_INB(XE_ISR)) != 0) {
532
586
533 esr = XE_INB(XE_ESR); /* Read the other status registers */
587 /* 0xff might mean the card is no longer around */
588 if (isr == 0xff) {
589#if XE_DEBUG > 2
590 device_printf(scp->dev, "intr: interrupt received for missing card?\n");
591#endif
592 break;
593 }
594
595 /* Read other status registers */
534 XE_SELECT_PAGE(0x40);
596 XE_SELECT_PAGE(0x40);
535 rxs = XE_INB(XE_RST0);
536 XE_OUTB(XE_RST0, ~rxs & 0xff);
537 txs = XE_INB(XE_TXST0);
538 txs |= XE_INB(XE_TXST1) << 8;
597 rst0 = XE_INB(XE_RST0);
598 XE_OUTB(XE_RST0, 0);
599 txst0 = XE_INB(XE_TXST0);
600 txst1 = XE_INB(XE_TXST1);
601 coll = txst1 & XE_TXST1_RETRY_COUNT;
539 XE_OUTB(XE_TXST0, 0);
540 XE_OUTB(XE_TXST1, 0);
541 XE_SELECT_PAGE(0);
542
543#if XE_DEBUG > 2
602 XE_OUTB(XE_TXST0, 0);
603 XE_OUTB(XE_TXST1, 0);
604 XE_SELECT_PAGE(0);
605
606#if XE_DEBUG > 2
544 printf("xe%d: ISR=%#2.2x ESR=%#2.2x RST=%#2.2x TXST=%#4.4x\n", unit, isr, esr, rxs, txs);
607 device_printf(scp->dev, "intr: ISR=0x%02x, RST=0x%02x, TXT=0x%02x%02x, COLL=0x%01x\n", isr, rst0, txst1, txst0, coll);
545#endif
546
608#endif
609
547 /*
548 * Handle transmit interrupts
549 */
610 /* Handle transmitted packet(s) */
550 if (isr & XE_ISR_TX_PACKET) {
611 if (isr & XE_ISR_TX_PACKET) {
551 u_int8_t new_tpr, sent;
552
553 if ((new_tpr = XE_INB(XE_TPR)) < scp->tx_tpr) /* Update packet count */
554 sent = (0xff - scp->tx_tpr) + new_tpr; /* TPR rolled over */
555 else
556 sent = new_tpr - scp->tx_tpr;
612 u_int8_t tpr, sent;
557
613
558 if (sent > 0) { /* Packets sent since last interrupt */
559 scp->tx_tpr = new_tpr;
614 /* Update packet count, accounting for rollover */
615 tpr = XE_INB(XE_TPR);
616 sent = -scp->tx_tpr + tpr;
617
618 /* Update statistics if we actually sent anything */
619 if (sent > 0) {
620 scp->tx_tpr = tpr;
560 scp->tx_queued -= sent;
561 ifp->if_opackets += sent;
621 scp->tx_queued -= sent;
622 ifp->if_opackets += sent;
562 ifp->if_collisions += scp->tx_collisions;
623 ifp->if_collisions += coll;
563
564 /*
624
625 /*
565 * Collision stats are a PITA. If multiples frames have been sent, we
566 * distribute any outstanding collision count equally amongst them.
567 * However, if we're missing interrupts we're quite likely to also
568 * miss some collisions; thus the total count will be off anyway.
569 * Likewise, if we miss a frame dropped due to excessive collisions
570 * any outstanding collisions count will be held against the next
571 * frame to be successfully sent. Hopefully it averages out in the
572 * end!
573 * XXX - This will screw up if tx_collisions/sent > 14. FIX IT!
626 * According to the Xircom manual, Dingo will sometimes manage to
627 * transmit a packet with triggering an interrupt. If this happens,
628 * we have sent > 1 and the collision count only reflects collisions
629 * on the last packet sent (the one that triggered the interrupt).
630 * Collision stats might therefore be a bit low, but there doesn't
631 * seem to be anything we can do about that.
574 */
632 */
575 switch (scp->tx_collisions) {
576 case 0:
633
634 switch (coll) {
635 case 0:
577 break;
636 break;
578 case 1:
637 case 1:
579 scp->mibdata.dot3StatsSingleCollisionFrames++;
580 scp->mibdata.dot3StatsCollFrequencies[0]++;
581 break;
638 scp->mibdata.dot3StatsSingleCollisionFrames++;
639 scp->mibdata.dot3StatsCollFrequencies[0]++;
640 break;
582 default:
583 if (sent == 1) {
584 scp->mibdata.dot3StatsMultipleCollisionFrames++;
585 scp->mibdata.dot3StatsCollFrequencies[scp->tx_collisions-1]++;
586 }
587 else { /* Distribute across multiple frames */
588 scp->mibdata.dot3StatsMultipleCollisionFrames += sent;
589 scp->mibdata.
590 dot3StatsCollFrequencies[scp->tx_collisions/sent] += sent - scp->tx_collisions%sent;
591 scp->mibdata.
592 dot3StatsCollFrequencies[scp->tx_collisions/sent + 1] += scp->tx_collisions%sent;
593 }
641 default:
642 scp->mibdata.dot3StatsMultipleCollisionFrames++;
643 scp->mibdata.dot3StatsCollFrequencies[coll-1]++;
594 }
644 }
595 scp->tx_collisions = 0;
596 }
597 ifp->if_timer = 0;
598 ifp->if_flags &= ~IFF_OACTIVE;
599 }
645 }
646 ifp->if_timer = 0;
647 ifp->if_flags &= ~IFF_OACTIVE;
648 }
600 if (txs & 0x0002) { /* Excessive collisions (packet dropped) */
601 ifp->if_collisions += 16;
602 ifp->if_oerrors++;
603 scp->tx_collisions = 0;
604 scp->mibdata.dot3StatsExcessiveCollisions++;
605 scp->mibdata.dot3StatsMultipleCollisionFrames++;
606 scp->mibdata.dot3StatsCollFrequencies[15]++;
607 XE_OUTB(XE_CR, XE_CR_RESTART_TX);
608 }
609 if (txs & 0x0040) /* Transmit aborted -- probably collisions */
610 scp->tx_collisions++;
611
649
650 /* Handle most MAC interrupts */
651 if (isr & XE_ISR_MAC_INTR) {
612
652
613 /*
614 * Handle receive interrupts
615 */
653#if 0
654 /* Carrier sense lost -- only in 10Mbit HDX mode */
655 if (txst0 & XE_TXST0_NO_CARRIER || !(txst1 & XE_TXST1_LINK_STATUS)) {
656 /* XXX - Need to update media status here */
657 device_printf(scp->dev, "no carrier\n");
658 ifp->if_oerrors++;
659 scp->mibdata.dot3StatsCarrierSenseErrors++;
660 }
661#endif
662 /* Excessive collisions -- try sending again */
663 if (txst0 & XE_TXST0_16_COLLISIONS) {
664 ifp->if_collisions += 16;
665 ifp->if_oerrors++;
666 scp->mibdata.dot3StatsExcessiveCollisions++;
667 scp->mibdata.dot3StatsMultipleCollisionFrames++;
668 scp->mibdata.dot3StatsCollFrequencies[15]++;
669 XE_OUTB(XE_CR, XE_CR_RESTART_TX);
670 }
671 /* Transmit underrun -- increase early transmit threshold */
672 if (txst0 & XE_TXST0_TX_UNDERRUN && scp->mohawk) {
673 device_printf(scp->dev, "transmit underrun");
674 if (scp->tx_thres < ETHER_MAX_LEN) {
675 if ((scp->tx_thres += 64) > ETHER_MAX_LEN)
676 scp->tx_thres = ETHER_MAX_LEN;
677 printf(": increasing transmit threshold to %u", scp->tx_thres);
678 XE_SELECT_PAGE(0x3);
679 XE_OUTW(XE_TPT, scp->tx_thres);
680 XE_SELECT_PAGE(0x0);
681 }
682 printf("\n");
683 ifp->if_oerrors++;
684 scp->mibdata.dot3StatsInternalMacTransmitErrors++;
685 }
686 /* Late collision -- just complain about it */
687 if (txst0 & XE_TXST0_LATE_COLLISION) {
688 device_printf(scp->dev, "late collision\n");
689 ifp->if_oerrors++;
690 scp->mibdata.dot3StatsLateCollisions++;
691 }
692 /* SQE test failure -- just complain about it */
693 if (txst0 & XE_TXST0_SQE_FAIL) {
694 device_printf(scp->dev, "SQE test failure\n");
695 ifp->if_oerrors++;
696 scp->mibdata.dot3StatsSQETestErrors++;
697 }
698 /* Packet too long -- what happens to these */
699 if (rst0 & XE_RST0_LONG_PACKET) {
700 device_printf(scp->dev, "received giant packet\n");
701 ifp->if_ierrors++;
702 scp->mibdata.dot3StatsFrameTooLongs++;
703 }
704 /* CRC error -- packet dropped */
705 if (rst0 & XE_RST0_CRC_ERROR) {
706 device_printf(scp->dev, "CRC error\n");
707 ifp->if_ierrors++;
708 scp->mibdata.dot3StatsFCSErrors++;
709 }
710 }
711
712 /* Handle received packet(s) */
616 while ((esr = XE_INB(XE_ESR)) & XE_ESR_FULL_PACKET_RX) {
713 while ((esr = XE_INB(XE_ESR)) & XE_ESR_FULL_PACKET_RX) {
714 rsr = XE_INB(XE_RSR);
617
715
618 if ((rsr = XE_INB(XE_RSR)) & XE_RSR_RX_OK) {
716#if XE_DEBUG > 2
717 device_printf(scp->dev, "intr: ESR=0x%02x, RSR=0x%02x\n", esr, rsr);
718#endif
719
720 /* Make sure packet is a good one */
721 if (rsr & XE_RSR_RX_OK) {
619 struct ether_header *ehp;
620 struct mbuf *mbp;
621 u_int16_t len;
622
722 struct ether_header *ehp;
723 struct mbuf *mbp;
724 u_int16_t len;
725
623 len = XE_INW(XE_RBC);
726 len = XE_INW(XE_RBC) - ETHER_CRC_LEN;
624
727
625 if (len == 0)
728#if XE_DEBUG > 2
729 device_printf(scp->dev, "intr: receive length = %d\n", len);
730#endif
731
732 if (len == 0) {
733 ifp->if_iqdrops++;
626 continue;
734 continue;
735 }
627
736
628#if 0
629 /*
737 /*
630 * Limit the amount of time we spend in this loop, dropping packets if
631 * necessary. The Linux code does this with considerably more
632 * finesse, adjusting the threshold dynamically.
738 * Allocate mbuf to hold received packet. If the mbuf header isn't
739 * big enough, we attach an mbuf cluster to hold the packet. Note the
740 * +=2 to align the packet data on a 32-bit boundary, and the +3 to
741 * allow for the possibility of reading one more byte than the actual
742 * packet length (we always read 16-bit words).
743 * XXX - Surely there's a better way to do this alignment?
633 */
744 */
634 if ((rx_bytes += len) > 22000) {
745 MGETHDR(mbp, M_DONTWAIT, MT_DATA);
746 if (mbp == NULL) {
635 ifp->if_iqdrops++;
747 ifp->if_iqdrops++;
636 scp->mibData.dot3StatsMissedFrames++;
637 XE_OUTW(XE_DO, 0x8000);
638 continue;
639 }
748 continue;
749 }
640#endif
641
750
642 if (len & 0x01)
643 len++;
644
645 MGETHDR(mbp, M_DONTWAIT, MT_DATA); /* Allocate a header mbuf */
646 if (mbp != NULL) {
647 mbp->m_pkthdr.rcvif = ifp;
648 mbp->m_pkthdr.len = mbp->m_len = len;
649
650 /*
651 * If the mbuf header isn't big enough for the packet, attach an
652 * mbuf cluster to hold it. The +2 is to allow for the nasty little
653 * alignment hack below.
654 */
655 if (len + 2 > MHLEN) {
656 MCLGET(mbp, M_DONTWAIT);
657 if ((mbp->m_flags & M_EXT) == 0) {
658 m_freem(mbp);
659 mbp = NULL;
660 }
751 if (len + 3 > MHLEN) {
752 MCLGET(mbp, M_DONTWAIT);
753 if ((mbp->m_flags & M_EXT) == 0) {
754 m_freem(mbp);
755 ifp->if_iqdrops++;
756 continue;
661 }
662 }
663
757 }
758 }
759
664 if (mbp != NULL) {
665 /*
666 * The Ethernet header is 14 bytes long; thus the actual packet data
667 * won't be 32-bit aligned when it's dumped into the mbuf. We
668 * offset everything by 2 bytes to fix this. Apparently the
669 * alignment is important for NFS, damn its eyes.
670 */
671 mbp->m_data += 2;
672 ehp = mtod(mbp, struct ether_header *);
760 mbp->m_data += 2;
761 ehp = mtod(mbp, struct ether_header *);
673
762
674 /*
675 * Now get the packet, including the Ethernet header and trailer (?)
676 * We use programmed I/O, because we don't know how to do shared
677 * memory with these cards. So yes, it's real slow, and heavy on
678 * the interrupts (CPU on my P150 maxed out at ~950KBps incoming).
679 */
680 if (scp->srev == 0) { /* Workaround a bug in old cards */
681 u_short rhs;
763 /*
764 * Now get the packet in PIO mode, including the Ethernet header but
765 * omitting the trailing CRC.
766 */
682
767
683 XE_SELECT_PAGE(5);
684 rhs = XE_INW(XE_RHSA);
685 XE_SELECT_PAGE(0);
768 /*
769 * Work around a bug in CE2 cards. There seems to be a problem with
770 * duplicated and extraneous bytes in the receive buffer, but without
771 * any real documentation for the CE2 it's hard to tell for sure.
772 * XXX - Needs testing on CE2 hardware
773 */
774 if (scp->srev == 0) {
775 u_short rhs;
686
776
687 rhs += 3; /* Skip control info */
777 XE_SELECT_PAGE(5);
778 rhs = XE_INW(XE_RHSA);
779 XE_SELECT_PAGE(0);
688
780
689 if (rhs >= 0x8000)
690 rhs = 0;
781 rhs += 3; /* Skip control info */
691
782
692 if (rhs + len > 0x8000) {
693 int i;
783 if (rhs >= 0x8000)
784 rhs = 0;
694
785
695 /*
696 * XXX - This i-- seems very wrong, but it's what the Linux guys
697 * XXX - do. Need someone with an old CE2 to test this for me.
698 * XXX - 99/3/28: Changed the first i-- to an i++, maybe that'll
699 * XXX - fix it? It seems as though the previous version would
700 * XXX - have caused an infinite loop (what, another one?).
701 */
702 for (i = 0; i < len; i++, rhs++) {
703 ((char *)ehp)[i] = XE_INB(XE_EDP);
704 if (rhs == 0x8000) {
705 rhs = 0;
706 i--;
707 }
786 if (rhs + len > 0x8000) {
787 int i;
788
789 for (i = 0; i < len; i++, rhs++) {
790 ((char *)ehp)[i] = XE_INB(XE_EDP);
791 if (rhs == 0x8000) {
792 rhs = 0;
793 i--;
708 }
709 }
794 }
795 }
710 else
711 bus_space_read_multi_2(scp->bst, scp->bsh, XE_EDP,
712 (u_int16_t *) ehp, len >> 1);
713 }
714 else
715 bus_space_read_multi_2(scp->bst, scp->bsh, XE_EDP,
796 }
797 else
798 bus_space_read_multi_2(scp->bst, scp->bsh, XE_EDP,
716 (u_int16_t *) ehp, len >> 1);
717
718 /* Deliver packet to upper layers */
719 if (mbp != NULL) {
720 mbp->m_flags |= M_HASFCS; /* FCS is included in our
721 * packet */
722 mbp->m_pkthdr.len = mbp->m_len = len;
723 (*ifp->if_input)(ifp, mbp); /* Send the packet on its way */
724 ifp->if_ipackets++; /* Success! */
725 }
726 XE_OUTW(XE_DO, 0x8000); /* skip_rx_packet command */
799 (u_int16_t *) ehp, (len + 1) >> 1);
727 }
800 }
801 else
802 bus_space_read_multi_2(scp->bst, scp->bsh, XE_EDP,
803 (u_int16_t *) ehp, (len + 1) >> 1);
804
805 /* Deliver packet to upper layers */
806 mbp->m_pkthdr.rcvif = ifp;
807 mbp->m_pkthdr.len = mbp->m_len = len;
808 (*ifp->if_input)(ifp, mbp);
809 ifp->if_ipackets++;
728 }
810 }
729 else if (rsr & XE_RSR_LONG_PACKET) { /* Packet length >1518 bytes */
730 scp->mibdata.dot3StatsFrameTooLongs++;
731 ifp->if_ierrors++;
732 }
733 else if (rsr & XE_RSR_CRC_ERROR) { /* Bad checksum on packet */
734 scp->mibdata.dot3StatsFCSErrors++;
735 ifp->if_ierrors++;
736 }
737 else if (rsr & XE_RSR_ALIGN_ERROR) { /* Packet alignment error */
811
812 /* Packet alignment error -- drop packet */
813 else if (rsr & XE_RSR_ALIGN_ERROR) {
814 device_printf(scp->dev, "alignment error\n");
738 scp->mibdata.dot3StatsAlignmentErrors++;
739 ifp->if_ierrors++;
740 }
815 scp->mibdata.dot3StatsAlignmentErrors++;
816 ifp->if_ierrors++;
817 }
818
819 /* Skip to next packet, if there is one */
820 XE_OUTW(XE_DO, 0x8000);
741 }
821 }
742 if (rxs & 0x10) { /* Receiver overrun */
743 scp->mibdata.dot3StatsInternalMacReceiveErrors++;
822
823 /* Clear receiver overruns now we have some free buffer space */
824 if (rst0 & XE_RST0_RX_OVERRUN) {
825#if XE_DEBUG > 0
826 device_printf(scp->dev, "receive overrun\n");
827#endif
744 ifp->if_ierrors++;
828 ifp->if_ierrors++;
829 scp->mibdata.dot3StatsInternalMacReceiveErrors++;
745 XE_OUTB(XE_CR, XE_CR_CLEAR_OVERRUN);
746 }
747 }
748
830 XE_OUTB(XE_CR, XE_CR_CLEAR_OVERRUN);
831 }
832 }
833
749 XE_SELECT_PAGE(psr); /* Restore saved page */
750 XE_OUTB(XE_CR, XE_CR_ENABLE_INTR); /* Re-enable interrupts */
834 /* Restore saved page */
835 XE_SELECT_PAGE(psr);
751
836
752 /* Could force an int here, instead of dropping packets? */
753 /* XE_OUTB(XE_CR, XE_CR_ENABLE_INTR|XE_CE_FORCE_INTR); */
837 /* Re-enable interrupts */
838 XE_OUTB(XE_CR, XE_CR_ENABLE_INTR);
754
755 return;
756}
757
758
759/*
760 * Device timeout/watchdog routine. Called automatically if we queue a packet
761 * for transmission but don't get an interrupt within a specified timeout
762 * (usually 5 seconds). When this happens we assume the worst and reset the
763 * card.
764 */
765static void
766xe_watchdog(struct ifnet *ifp) {
767 struct xe_softc *scp = ifp->if_softc;
768
839
840 return;
841}
842
843
844/*
845 * Device timeout/watchdog routine. Called automatically if we queue a packet
846 * for transmission but don't get an interrupt within a specified timeout
847 * (usually 5 seconds). When this happens we assume the worst and reset the
848 * card.
849 */
850static void
851xe_watchdog(struct ifnet *ifp) {
852 struct xe_softc *scp = ifp->if_softc;
853
769 device_printf(scp->dev, "watchdog timeout; resetting card\n");
854 device_printf(scp->dev, "watchdog timeout: resetting card\n");
770 scp->tx_timeouts++;
771 ifp->if_oerrors += scp->tx_queued;
772 xe_stop(scp);
855 scp->tx_timeouts++;
856 ifp->if_oerrors += scp->tx_queued;
857 xe_stop(scp);
773 xe_hard_reset(scp);
774 xe_setmedia(scp);
858 xe_reset(scp);
775 xe_init(scp);
776}
777
778
779/*
780 * Change media selection.
781 */
782static int
783xe_media_change(struct ifnet *ifp) {
784 struct xe_softc *scp = ifp->if_softc;
785
859 xe_init(scp);
860}
861
862
863/*
864 * Change media selection.
865 */
866static int
867xe_media_change(struct ifnet *ifp) {
868 struct xe_softc *scp = ifp->if_softc;
869
786#ifdef XE_DEBUG
870#if XE_DEBUG > 1
787 if_printf(ifp, "media_change\n");
788#endif
789
790 if (IFM_TYPE(scp->ifm->ifm_media) != IFM_ETHER)
791 return(EINVAL);
792
793 /*
794 * Some card/media combos aren't always possible -- filter those out here.

--- 9 unchanged lines hidden (view full) ---

804
805
806/*
807 * Return current media selection.
808 */
809static void
810xe_media_status(struct ifnet *ifp, struct ifmediareq *mrp) {
811
871 if_printf(ifp, "media_change\n");
872#endif
873
874 if (IFM_TYPE(scp->ifm->ifm_media) != IFM_ETHER)
875 return(EINVAL);
876
877 /*
878 * Some card/media combos aren't always possible -- filter those out here.

--- 9 unchanged lines hidden (view full) ---

888
889
890/*
891 * Return current media selection.
892 */
893static void
894xe_media_status(struct ifnet *ifp, struct ifmediareq *mrp) {
895
812#ifdef XE_DEBUG
896#if XE_DEBUG > 1
813 if_printf(ifp, "media_status\n");
814#endif
815
897 if_printf(ifp, "media_status\n");
898#endif
899
900 /* XXX - This is clearly wrong. Will fix once I have CE2 working */
901 mrp->ifm_status = IFM_AVALID | IFM_ACTIVE;
816 mrp->ifm_active = ((struct xe_softc *)ifp->if_softc)->media;
817
818 return;
819}
820
821
822/*
823 * Select active media.
824 */
825static void xe_setmedia(void *xscp) {
826 struct xe_softc *scp = xscp;
827 u_int16_t bmcr, bmsr, anar, lpar;
828
902 mrp->ifm_active = ((struct xe_softc *)ifp->if_softc)->media;
903
904 return;
905}
906
907
908/*
909 * Select active media.
910 */
911static void xe_setmedia(void *xscp) {
912 struct xe_softc *scp = xscp;
913 u_int16_t bmcr, bmsr, anar, lpar;
914
829#ifdef XE_DEBUG
915#if XE_DEBUG > 1
830 device_printf(scp->dev, "setmedia\n");
831#endif
832
833 /* Cancel any pending timeout */
834 untimeout(xe_setmedia, scp, scp->chand);
835 xe_disable_intr(scp);
836
837 /* Select media */

--- 29 unchanged lines hidden (view full) ---

867 * Select 10baseT
868 * ELSE
869 * Select 10baseT or 10base2, whichever is connected
870 * ENDIF
871 * ENDIF
872 */
873 switch (scp->autoneg_status) {
874
916 device_printf(scp->dev, "setmedia\n");
917#endif
918
919 /* Cancel any pending timeout */
920 untimeout(xe_setmedia, scp, scp->chand);
921 xe_disable_intr(scp);
922
923 /* Select media */

--- 29 unchanged lines hidden (view full) ---

953 * Select 10baseT
954 * ELSE
955 * Select 10baseT or 10base2, whichever is connected
956 * ENDIF
957 * ENDIF
958 */
959 switch (scp->autoneg_status) {
960
875 case XE_AUTONEG_NONE:
961 case XE_AUTONEG_NONE:
876#if XE_DEBUG > 1
877 device_printf(scp->dev, "Waiting for idle transmitter\n");
878#endif
879 scp->arpcom.ac_if.if_flags |= IFF_OACTIVE;
880 scp->autoneg_status = XE_AUTONEG_WAITING;
962#if XE_DEBUG > 1
963 device_printf(scp->dev, "Waiting for idle transmitter\n");
964#endif
965 scp->arpcom.ac_if.if_flags |= IFF_OACTIVE;
966 scp->autoneg_status = XE_AUTONEG_WAITING;
881 scp->chand = timeout(xe_setmedia, scp, hz * 2);
882 return;
967 /* FALL THROUGH */
883
968
884 case XE_AUTONEG_WAITING:
885 xe_soft_reset(scp);
969 case XE_AUTONEG_WAITING:
970 if (scp->tx_queued != 0) {
971 scp->chand = timeout(xe_setmedia, scp, hz/2);
972 return;
973 }
886 if (scp->phy_ok) {
887#if XE_DEBUG > 1
888 device_printf(scp->dev, "Starting autonegotiation\n");
889#endif
890 bmcr = xe_phy_readreg(scp, PHY_BMCR);
891 bmcr &= ~(PHY_BMCR_AUTONEGENBL);
892 xe_phy_writereg(scp, PHY_BMCR, bmcr);
893 anar = xe_phy_readreg(scp, PHY_ANAR);
894 anar &= ~(PHY_ANAR_100BT4|PHY_ANAR_100BTXFULL|PHY_ANAR_10BTFULL);
895 anar |= PHY_ANAR_100BTXHALF|PHY_ANAR_10BTHALF;
896 xe_phy_writereg(scp, PHY_ANAR, anar);
897 bmcr |= PHY_BMCR_AUTONEGENBL|PHY_BMCR_AUTONEGRSTR;
898 xe_phy_writereg(scp, PHY_BMCR, bmcr);
899 scp->autoneg_status = XE_AUTONEG_STARTED;
974 if (scp->phy_ok) {
975#if XE_DEBUG > 1
976 device_printf(scp->dev, "Starting autonegotiation\n");
977#endif
978 bmcr = xe_phy_readreg(scp, PHY_BMCR);
979 bmcr &= ~(PHY_BMCR_AUTONEGENBL);
980 xe_phy_writereg(scp, PHY_BMCR, bmcr);
981 anar = xe_phy_readreg(scp, PHY_ANAR);
982 anar &= ~(PHY_ANAR_100BT4|PHY_ANAR_100BTXFULL|PHY_ANAR_10BTFULL);
983 anar |= PHY_ANAR_100BTXHALF|PHY_ANAR_10BTHALF;
984 xe_phy_writereg(scp, PHY_ANAR, anar);
985 bmcr |= PHY_BMCR_AUTONEGENBL|PHY_BMCR_AUTONEGRSTR;
986 xe_phy_writereg(scp, PHY_BMCR, bmcr);
987 scp->autoneg_status = XE_AUTONEG_STARTED;
900 scp->chand = timeout(xe_setmedia, scp, hz * 7/2);
988 scp->chand = timeout(xe_setmedia, scp, hz * 7/2);
901 return;
902 }
903 else {
904 scp->autoneg_status = XE_AUTONEG_FAIL;
905 }
906 break;
907
908 case XE_AUTONEG_STARTED:

--- 38 unchanged lines hidden (view full) ---

947 /*scp->autoneg_status = XE_AUTONEG_FAIL;*/
948 }
949 }
950 else {
951#if XE_DEBUG > 1
952 device_printf(scp->dev, "Autonegotiation failed; trying 100baseTX\n");
953#endif
954 XE_MII_DUMP(scp);
989 return;
990 }
991 else {
992 scp->autoneg_status = XE_AUTONEG_FAIL;
993 }
994 break;
995
996 case XE_AUTONEG_STARTED:

--- 38 unchanged lines hidden (view full) ---

1035 /*scp->autoneg_status = XE_AUTONEG_FAIL;*/
1036 }
1037 }
1038 else {
1039#if XE_DEBUG > 1
1040 device_printf(scp->dev, "Autonegotiation failed; trying 100baseTX\n");
1041#endif
1042 XE_MII_DUMP(scp);
955 xe_soft_reset(scp);
956 if (scp->phy_ok) {
957 xe_phy_writereg(scp, PHY_BMCR, PHY_BMCR_SPEEDSEL);
958 scp->autoneg_status = XE_AUTONEG_100TX;
959 scp->chand = timeout(xe_setmedia, scp, hz * 3);
960 return;
961 }
962 else {
963 scp->autoneg_status = XE_AUTONEG_FAIL;

--- 58 unchanged lines hidden (view full) ---

1022
1023
1024 /*
1025 * If a specific media has been requested, we just reset the card and
1026 * select it (one small exception -- if 100baseTX is requested by there is
1027 * no PHY, we fall back to 10baseT operation).
1028 */
1029 case IFM_100_TX: /* Force 100baseTX */
1043 if (scp->phy_ok) {
1044 xe_phy_writereg(scp, PHY_BMCR, PHY_BMCR_SPEEDSEL);
1045 scp->autoneg_status = XE_AUTONEG_100TX;
1046 scp->chand = timeout(xe_setmedia, scp, hz * 3);
1047 return;
1048 }
1049 else {
1050 scp->autoneg_status = XE_AUTONEG_FAIL;

--- 58 unchanged lines hidden (view full) ---

1109
1110
1111 /*
1112 * If a specific media has been requested, we just reset the card and
1113 * select it (one small exception -- if 100baseTX is requested by there is
1114 * no PHY, we fall back to 10baseT operation).
1115 */
1116 case IFM_100_TX: /* Force 100baseTX */
1030 xe_soft_reset(scp);
1031 if (scp->phy_ok) {
1032#if XE_DEBUG > 1
1033 device_printf(scp->dev, "Selecting 100baseTX\n");
1034#endif
1035 XE_SELECT_PAGE(0x42);
1036 XE_OUTB(XE_SWC1, 0);
1037 xe_phy_writereg(scp, PHY_BMCR, PHY_BMCR_SPEEDSEL);
1038 XE_SELECT_PAGE(2);
1039 XE_OUTB(XE_MSR, XE_INB(XE_MSR) | 0x08);
1040 scp->media |= IFM_100_TX;
1041 break;
1042 }
1043 /* FALLTHROUGH */
1044
1045 case IFM_10_T: /* Force 10baseT */
1117 if (scp->phy_ok) {
1118#if XE_DEBUG > 1
1119 device_printf(scp->dev, "Selecting 100baseTX\n");
1120#endif
1121 XE_SELECT_PAGE(0x42);
1122 XE_OUTB(XE_SWC1, 0);
1123 xe_phy_writereg(scp, PHY_BMCR, PHY_BMCR_SPEEDSEL);
1124 XE_SELECT_PAGE(2);
1125 XE_OUTB(XE_MSR, XE_INB(XE_MSR) | 0x08);
1126 scp->media |= IFM_100_TX;
1127 break;
1128 }
1129 /* FALLTHROUGH */
1130
1131 case IFM_10_T: /* Force 10baseT */
1046 xe_soft_reset(scp);
1047#if XE_DEBUG > 1
1048 device_printf(scp->dev, "Selecting 10baseT\n");
1049#endif
1050 if (scp->phy_ok) {
1051 xe_phy_writereg(scp, PHY_BMCR, 0x0000);
1052 XE_SELECT_PAGE(2);
1053 XE_OUTB(XE_MSR, XE_INB(XE_MSR) & ~0x08); /* Disable PHY */
1054 }
1055 XE_SELECT_PAGE(0x42);
1056 XE_OUTB(XE_SWC1, 0x80);
1057 scp->media |= IFM_10_T;
1058 break;
1059
1060 case IFM_10_2:
1132#if XE_DEBUG > 1
1133 device_printf(scp->dev, "Selecting 10baseT\n");
1134#endif
1135 if (scp->phy_ok) {
1136 xe_phy_writereg(scp, PHY_BMCR, 0x0000);
1137 XE_SELECT_PAGE(2);
1138 XE_OUTB(XE_MSR, XE_INB(XE_MSR) & ~0x08); /* Disable PHY */
1139 }
1140 XE_SELECT_PAGE(0x42);
1141 XE_OUTB(XE_SWC1, 0x80);
1142 scp->media |= IFM_10_T;
1143 break;
1144
1145 case IFM_10_2:
1061 xe_soft_reset(scp);
1062#if XE_DEBUG > 1
1063 device_printf(scp->dev, "Selecting 10base2\n");
1064#endif
1065 XE_SELECT_PAGE(0x42);
1066 XE_OUTB(XE_SWC1, 0xc0);
1067 scp->media |= IFM_10_2;
1068 break;
1069 }

--- 16 unchanged lines hidden (view full) ---

1086 break;
1087
1088 case IFM_10_2:
1089 XE_OUTB(XE_LED, 0x3a);
1090 break;
1091 }
1092
1093 /* Restart output? */
1146#if XE_DEBUG > 1
1147 device_printf(scp->dev, "Selecting 10base2\n");
1148#endif
1149 XE_SELECT_PAGE(0x42);
1150 XE_OUTB(XE_SWC1, 0xc0);
1151 scp->media |= IFM_10_2;
1152 break;
1153 }

--- 16 unchanged lines hidden (view full) ---

1170 break;
1171
1172 case IFM_10_2:
1173 XE_OUTB(XE_LED, 0x3a);
1174 break;
1175 }
1176
1177 /* Restart output? */
1178 xe_enable_intr(scp);
1094 scp->ifp->if_flags &= ~IFF_OACTIVE;
1179 scp->ifp->if_flags &= ~IFF_OACTIVE;
1095 xe_init(scp);
1180 xe_start(scp->ifp);
1096}
1097
1098
1099/*
1100 * Hard reset (power cycle) the card.
1101 */
1102static void
1181}
1182
1183
1184/*
1185 * Hard reset (power cycle) the card.
1186 */
1187static void
1103xe_hard_reset(struct xe_softc *scp) {
1188xe_reset(struct xe_softc *scp) {
1104 int s;
1105
1189 int s;
1190
1106#ifdef XE_DEBUG
1107 device_printf(scp->dev, "hard_reset\n");
1191#if XE_DEBUG > 1
1192 device_printf(scp->dev, "reset\n");
1108#endif
1109
1110 s = splimp();
1111
1193#endif
1194
1195 s = splimp();
1196
1112 /*
1113 * Power cycle the card.
1114 */
1197 /* Power down */
1115 XE_SELECT_PAGE(4);
1198 XE_SELECT_PAGE(4);
1116 XE_OUTB(XE_GPR1, 0); /* Power off */
1199 XE_OUTB(XE_GPR1, 0);
1117 DELAY(40000);
1118
1200 DELAY(40000);
1201
1202 /* Power up again */
1119 if (scp->mohawk)
1203 if (scp->mohawk)
1120 XE_OUTB(XE_GPR1, 1); /* And back on again */
1204 XE_OUTB(XE_GPR1, XE_GPR1_POWER_DOWN);
1121 else
1205 else
1122 XE_OUTB(XE_GPR1, 5); /* Also set AIC bit, whatever that is */
1123 DELAY(40000);
1124 XE_SELECT_PAGE(0);
1206 XE_OUTB(XE_GPR1, XE_GPR1_POWER_DOWN|XE_GPR1_AIC);
1125
1207
1126 (void)splx(s);
1127}
1128
1129
1130/*
1131 * Soft reset the card. Also makes sure that the ML6692 and 10Mbit controller
1132 * are powered up, sets the silicon revision number in softc, disables
1133 * interrupts and checks for the prescence of a 100Mbit PHY. This should
1134 * leave us in a position where we can access the PHY and do media
1135 * selection. The function imposes a 0.5s delay while the hardware powers up.
1136 */
1137static void
1138xe_soft_reset(struct xe_softc *scp) {
1139 int s;
1140
1141#ifdef XE_DEBUG
1142 device_printf(scp->dev, "soft_reset\n");
1143#endif
1144
1145 s = splimp();
1146
1147 /*
1148 * Reset the card, (again).
1149 */
1150 XE_SELECT_PAGE(0);
1151 XE_OUTB(XE_CR, XE_CR_SOFT_RESET);
1152 DELAY(40000);
1208 DELAY(40000);
1153 XE_OUTB(XE_CR, 0);
1154 DELAY(40000);
1155
1156 if (scp->mohawk) {
1157 /*
1158 * set GP1 and GP2 as outputs (bits 2 & 3)
1159 * set GP1 low to power on the ML6692 (bit 0)
1160 * set GP2 high to power on the 10Mhz chip (bit 1)
1161 */
1162 XE_SELECT_PAGE(4);
1163 XE_OUTB(XE_GPR0, 0x0e);
1164 }
1165
1166 /*
1167 * Wait for everything to wake up.
1168 */
1169 DELAY(500000);
1170
1171 /*
1172 * Get silicon revision number.
1173 */
1174 XE_SELECT_PAGE(4);
1175 if (scp->mohawk)
1176 scp->srev = (XE_INB(XE_BOV) & 0x70) >> 4;
1177 else
1178 scp->srev = (XE_INB(XE_BOV) & 0x30) >> 4;
1179#ifdef XE_DEBUG
1180 device_printf(scp->dev, "silicon revision = %d\n", scp->srev);
1181#endif
1182
1183 /*
1184 * Shut off interrupts.
1185 */
1186 xe_disable_intr(scp);
1187
1188 /*
1189 * Check for PHY.
1190 */
1191 if (scp->mohawk) {
1192 scp->phy_ok = xe_mii_init(scp);
1193 }
1194
1195 XE_SELECT_PAGE(0);
1196
1197 (void)splx(s);
1198}
1199
1200
1201/*
1202 * Take interface offline. This is done by powering down the device, which I
1203 * assume means just shutting down the transceiver and Ethernet logic. This
1204 * requires a _hard_ reset to recover from, as we need to power up again.
1205 */
1206static void
1207xe_stop(struct xe_softc *scp) {
1208 int s;
1209
1209 XE_SELECT_PAGE(0);
1210
1211 (void)splx(s);
1212}
1213
1214
1215/*
1216 * Take interface offline. This is done by powering down the device, which I
1217 * assume means just shutting down the transceiver and Ethernet logic. This
1218 * requires a _hard_ reset to recover from, as we need to power up again.
1219 */
1220static void
1221xe_stop(struct xe_softc *scp) {
1222 int s;
1223
1210#ifdef XE_DEBUG
1224#if XE_DEBUG > 1
1211 device_printf(scp->dev, "stop\n");
1212#endif
1213
1214 s = splimp();
1215
1216 /*
1217 * Shut off interrupts.
1218 */
1219 xe_disable_intr(scp);
1220
1221 /*
1222 * Power down.
1223 */
1224 XE_SELECT_PAGE(4);
1225 XE_OUTB(XE_GPR1, 0);
1226 XE_SELECT_PAGE(0);
1225 device_printf(scp->dev, "stop\n");
1226#endif
1227
1228 s = splimp();
1229
1230 /*
1231 * Shut off interrupts.
1232 */
1233 xe_disable_intr(scp);
1234
1235 /*
1236 * Power down.
1237 */
1238 XE_SELECT_PAGE(4);
1239 XE_OUTB(XE_GPR1, 0);
1240 XE_SELECT_PAGE(0);
1241 if (scp->mohawk) {
1242 /*
1243 * set GP1 and GP2 as outputs (bits 2 & 3)
1244 * set GP1 high to power on the ML6692 (bit 0)
1245 * set GP2 low to power on the 10Mhz chip (bit 1)
1246 */
1247 XE_SELECT_PAGE(4);
1248 XE_OUTB(XE_GPR0, XE_GPR0_GP2_SELECT|XE_GPR0_GP1_SELECT|XE_GPR0_GP1_OUT);
1249 }
1227
1228 /*
1229 * ~IFF_RUNNING == interface down.
1230 */
1231 scp->ifp->if_flags &= ~IFF_RUNNING;
1232 scp->ifp->if_flags &= ~IFF_OACTIVE;
1233 scp->ifp->if_timer = 0;
1234
1235 (void)splx(s);
1236}
1237
1238
1239/*
1250
1251 /*
1252 * ~IFF_RUNNING == interface down.
1253 */
1254 scp->ifp->if_flags &= ~IFF_RUNNING;
1255 scp->ifp->if_flags &= ~IFF_OACTIVE;
1256 scp->ifp->if_timer = 0;
1257
1258 (void)splx(s);
1259}
1260
1261
1262/*
1240 * Enable Ethernet interrupts from the card.
1263 * Enable interrupts from the card.
1241 */
1242static void
1243xe_enable_intr(struct xe_softc *scp) {
1264 */
1265static void
1266xe_enable_intr(struct xe_softc *scp) {
1244#ifdef XE_DEBUG
1267
1268#if XE_DEBUG > 1
1245 device_printf(scp->dev, "enable_intr\n");
1246#endif
1247
1269 device_printf(scp->dev, "enable_intr\n");
1270#endif
1271
1248 XE_SELECT_PAGE(1);
1249 XE_OUTB(XE_IMR0, 0xff); /* Unmask everything */
1250 XE_OUTB(XE_IMR1, 0x01); /* Unmask TX underrun detection */
1251 DELAY(1);
1252
1253 XE_SELECT_PAGE(0);
1254 XE_OUTB(XE_CR, XE_CR_ENABLE_INTR); /* Enable interrupts */
1255 if (scp->modem && !scp->dingo) { /* This bit is just magic */
1256 if (!(XE_INB(0x10) & 0x01)) {
1257 XE_OUTB(0x10, 0x11); /* Unmask master int enable bit */
1258 }
1259 }
1260}
1261
1262
1263/*
1272 XE_SELECT_PAGE(0);
1273 XE_OUTB(XE_CR, XE_CR_ENABLE_INTR); /* Enable interrupts */
1274 if (scp->modem && !scp->dingo) { /* This bit is just magic */
1275 if (!(XE_INB(0x10) & 0x01)) {
1276 XE_OUTB(0x10, 0x11); /* Unmask master int enable bit */
1277 }
1278 }
1279}
1280
1281
1282/*
1264 * Disable all Ethernet interrupts from the card.
1283 * Disable interrupts from the card.
1265 */
1266static void
1267xe_disable_intr(struct xe_softc *scp) {
1284 */
1285static void
1286xe_disable_intr(struct xe_softc *scp) {
1268#ifdef XE_DEBUG
1287
1288#if XE_DEBUG > 1
1269 device_printf(scp->dev, "disable_intr\n");
1270#endif
1271
1272 XE_SELECT_PAGE(0);
1273 XE_OUTB(XE_CR, 0); /* Disable interrupts */
1289 device_printf(scp->dev, "disable_intr\n");
1290#endif
1291
1292 XE_SELECT_PAGE(0);
1293 XE_OUTB(XE_CR, 0); /* Disable interrupts */
1274 if (scp->modem && !scp->dingo) { /* More magic (does this work?) */
1294 if (scp->modem && !scp->dingo) { /* More magic */
1275 XE_OUTB(0x10, 0x10); /* Mask the master int enable bit */
1276 }
1295 XE_OUTB(0x10, 0x10); /* Mask the master int enable bit */
1296 }
1277
1278 XE_SELECT_PAGE(1);
1279 XE_OUTB(XE_IMR0, 0); /* Forbid all interrupts */
1280 XE_OUTB(XE_IMR1, 0);
1281 XE_SELECT_PAGE(0);
1282}
1283
1284
1285/*
1297}
1298
1299
1300/*
1286 * Set up multicast filter and promiscuous mode
1301 * Set up multicast filter and promiscuous modes.
1287 */
1288static void
1302 */
1303static void
1289xe_setmulti(struct xe_softc *scp) {
1304xe_set_multicast(struct xe_softc *scp) {
1290 struct ifnet *ifp;
1291 struct ifmultiaddr *maddr;
1305 struct ifnet *ifp;
1306 struct ifmultiaddr *maddr;
1292 int count;
1307 unsigned count, i;
1293
1308
1309#if XE_DEBUG > 1
1310 device_printf(scp->dev, "set_multicast\n");
1311#endif
1312
1294 ifp = &scp->arpcom.ac_if;
1313 ifp = &scp->arpcom.ac_if;
1295 maddr = TAILQ_FIRST(&ifp->if_multiaddrs);
1314 XE_SELECT_PAGE(0x42);
1296
1315
1297 /* Get length of multicast list */
1298 for (count = 0; maddr != NULL; maddr = TAILQ_NEXT(maddr, ifma_link), count++);
1316 /* Handle PROMISC flag */
1317 if (ifp->if_flags & IFF_PROMISC) {
1318 XE_OUTB(XE_SWC1, XE_INB(XE_SWC1) | XE_SWC1_PROMISCUOUS);
1319 return;
1320 }
1321 else
1322 XE_OUTB(XE_SWC1, XE_INB(XE_SWC1) & ~XE_SWC1_PROMISCUOUS);
1299
1323
1300 if ((ifp->if_flags & IFF_PROMISC) || (ifp->if_flags & IFF_ALLMULTI) || (count > 9)) {
1301 /*
1302 * Go into promiscuous mode if either of the PROMISC or ALLMULTI flags are
1303 * set, or if we have been asked to deal with more than 9 multicast
1304 * addresses. To do this: set MPE and PME in SWC1
1305 */
1306 XE_SELECT_PAGE(0x42);
1307 XE_OUTB(XE_SWC1, 0x06);
1324 /* Handle ALLMULTI flag */
1325 if (ifp->if_flags & IFF_ALLMULTI) {
1326 XE_OUTB(XE_SWC1, XE_INB(XE_SWC1) | XE_SWC1_ALLMULTI);
1327 return;
1308 }
1328 }
1309 else if ((ifp->if_flags & IFF_MULTICAST) && (count > 0)) {
1310 /*
1311 * Program the filters for up to 9 addresses
1312 */
1329 else
1330 XE_OUTB(XE_SWC1, XE_INB(XE_SWC1) & ~XE_SWC1_ALLMULTI);
1331
1332 /* Iterate over multicast address list */
1333 count = 0;
1334#if __FreeBSD_version < 500000
1335 LIST_FOREACH(maddr, &ifp->if_multiaddrs, ifma_link) {
1336#else
1337 TAILQ_FOREACH(maddr, &ifp->if_multiaddrs, ifma_link) {
1338#endif
1339 if (maddr->ifma_addr->sa_family != AF_LINK)
1340 continue;
1341
1342 count++;
1343
1344 if (count < 10)
1345 /* First 9 use Individual Addresses for exact matching */
1346 xe_set_addr(scp, LLADDR((struct sockaddr_dl *)maddr->ifma_addr), count);
1347 else
1348 if (scp->mohawk)
1349 /* Use hash filter on Mohawk and Dingo */
1350 xe_set_hash(scp, LLADDR((struct sockaddr_dl *)maddr->ifma_addr));
1351 else
1352 /* Nowhere else to put them on CE2 */
1353 break;
1354 }
1355
1356#if XE_DEBUG > 1
1357 device_printf(scp->dev, "set_multicast: count = %u\n", count);
1358#endif
1359
1360 /* Now do some cleanup and enable multicast handling as needed */
1361 if (count == 0) {
1362 /* Disable all multicast handling */
1313 XE_SELECT_PAGE(0x42);
1363 XE_SELECT_PAGE(0x42);
1314 XE_OUTB(XE_SWC1, 0x01);
1315 XE_SELECT_PAGE(0x40);
1316 XE_OUTB(XE_CMD0, XE_CMD0_OFFLINE);
1317 /*xe_reg_dump(scp);*/
1318 xe_setaddrs(scp);
1319 /*xe_reg_dump(scp);*/
1320 XE_SELECT_PAGE(0x40);
1321 XE_OUTB(XE_CMD0, XE_CMD0_RX_ENABLE|XE_CMD0_ONLINE);
1364 XE_OUTB(XE_SWC1, XE_INB(XE_SWC1) & ~(XE_SWC1_IA_ENABLE|XE_SWC1_ALLMULTI));
1365 if (scp->mohawk) {
1366 XE_SELECT_PAGE(0x02);
1367 XE_OUTB(XE_MSR, XE_INB(XE_MSR) & ~XE_MSR_HASH_TABLE);
1368 }
1322 }
1369 }
1323 else {
1324 /*
1325 * No multicast operation (default)
1326 */
1370 else if (count < 10) {
1371 /* Full in any unused Individual Addresses with our MAC address */
1372 for (i = count + 1; i < 10; i++)
1373 xe_set_addr(scp, (u_int8_t *)(&scp->arpcom.ac_enaddr), i);
1374 /* Enable Individual Address matching only */
1327 XE_SELECT_PAGE(0x42);
1375 XE_SELECT_PAGE(0x42);
1328 XE_OUTB(XE_SWC1, 0);
1376 XE_OUTB(XE_SWC1, (XE_INB(XE_SWC1) & ~XE_SWC1_ALLMULTI) | XE_SWC1_IA_ENABLE);
1377 if (scp->mohawk) {
1378 XE_SELECT_PAGE(0x02);
1379 XE_OUTB(XE_MSR, XE_INB(XE_MSR) & ~XE_MSR_HASH_TABLE);
1380 }
1381 }
1382 else {
1383 if (scp->mohawk) {
1384 /* Check whether hash table is full */
1385 XE_SELECT_PAGE(0x58);
1386 for (i = 0x08; i < 0x10; i++)
1387 if (XE_INB(i) != 0xff)
1388 break;
1389 if (i == 0x10) {
1390 /* Hash table full - enable promiscuous multicast matching */
1391 XE_SELECT_PAGE(0x42);
1392 XE_OUTB(XE_SWC1, (XE_INB(XE_SWC1) & ~XE_SWC1_IA_ENABLE) | XE_SWC1_ALLMULTI);
1393 XE_SELECT_PAGE(0x02);
1394 XE_OUTB(XE_MSR, XE_INB(XE_MSR) & ~XE_MSR_HASH_TABLE);
1395 }
1396 else {
1397 /* Enable hash table and Individual Address matching */
1398 XE_SELECT_PAGE(0x42);
1399 XE_OUTB(XE_SWC1, (XE_INB(XE_SWC1) & ~XE_SWC1_ALLMULTI) | XE_SWC1_IA_ENABLE);
1400 XE_SELECT_PAGE(0x02);
1401 XE_OUTB(XE_MSR, XE_INB(XE_MSR) | XE_MSR_HASH_TABLE);
1402 }
1403 }
1404 else {
1405 /* Enable promiscuous multicast matching */
1406 XE_SELECT_PAGE(0x42);
1407 XE_OUTB(XE_SWC1, (XE_INB(XE_SWC1) & ~XE_SWC1_IA_ENABLE) | XE_SWC1_ALLMULTI);
1408 }
1329 }
1409 }
1410
1330 XE_SELECT_PAGE(0);
1331}
1332
1333
1334/*
1411 XE_SELECT_PAGE(0);
1412}
1413
1414
1415/*
1335 * Set up all on-chip addresses (for multicast). AFAICS, there are 10
1336 * of these things; the first is our MAC address, the other 9 are mcast
1337 * addresses, padded with the MAC address if there aren't enough.
1338 * XXX - This doesn't work right, but I'm not sure why yet. We seem to be
1339 * XXX - doing much the same as the Linux code, which is weird enough that
1340 * XXX - it's probably right (despite my earlier comments to the contrary).
1416 * Copy the Ethernet multicast address in addr to the on-chip registers for
1417 * Individual Address idx. Assumes that addr is really a multicast address
1418 * and that idx > 0 (slot 0 is always used for the card MAC address).
1341 */
1342static void
1419 */
1420static void
1343xe_setaddrs(struct xe_softc *scp) {
1344 struct ifmultiaddr *maddr;
1345 u_int8_t *addr;
1346 u_int8_t page, slot, byte, i;
1421xe_set_addr(struct xe_softc *scp, u_int8_t* addr, unsigned idx) {
1422 u_int8_t page, reg;
1423 unsigned i;
1347
1424
1348 maddr = TAILQ_FIRST(&scp->arpcom.ac_if.if_multiaddrs);
1425 /*
1426 * Individual Addresses are stored in registers 8-F of pages 0x50-0x57. IA1
1427 * therefore starts at register 0xE on page 0x50. The expressions below
1428 * compute the starting page and register for any IA index > 0.
1429 */
1430 --idx;
1431 page = 0x50 + idx%4 + idx/4*3;
1432 reg = 0x0e - 2 * (idx%4);
1349
1433
1350 XE_SELECT_PAGE(page = 0x50);
1434#if XE_DEBUG > 1
1435 device_printf(scp->dev, "set_addr: idx = %u, page = 0x%02x, reg = 0x%02x\n",
1436 idx+1, page, reg);
1437#endif
1351
1438
1352 for (slot = 0, byte = 8; slot < 10; slot++) {
1353
1354 if (slot == 0)
1355 addr = (u_int8_t *)(&scp->arpcom.ac_enaddr);
1356 else {
1357 while (maddr != NULL && maddr->ifma_addr->sa_family != AF_LINK)
1358 maddr = TAILQ_NEXT(maddr, ifma_link);
1359 if (maddr != NULL)
1360 addr = LLADDR((struct sockaddr_dl *)maddr->ifma_addr);
1361 else
1362 addr = (u_int8_t *)(&scp->arpcom.ac_enaddr);
1439 /*
1440 * Copy the IA bytes. Note that the byte order is reversed for Mohawk and
1441 * Dingo wrt. CE2 hardware.
1442 */
1443 XE_SELECT_PAGE(page);
1444 for (i = 0; i < 6; i++) {
1445#if XE_DEBUG > 1
1446 if (i > 0)
1447 printf(":%02x", addr[i]);
1448 else
1449 device_printf(scp->dev, "set_addr: %02x", addr[0]);
1450#endif
1451 XE_OUTB(reg, addr[scp->mohawk ? 5 - i : i]);
1452 if (++reg == 0x10) {
1453 reg = 0x08;
1454 XE_SELECT_PAGE(++page);
1363 }
1455 }
1364
1365 for (i = 0; i < 6; i++, byte++) {
1366#if XE_DEBUG > 2
1367 if (i)
1368 printf(":%x", addr[i]);
1369 else
1370 device_printf(scp->dev, "individual addresses %d: %x", slot, addr[0]);
1456 }
1457#if XE_DEBUG > 1
1458 printf("\n");
1371#endif
1459#endif
1460}
1372
1461
1373 if (byte > 15) {
1374 page++;
1375 byte = 8;
1376 XE_SELECT_PAGE(page);
1377 }
1378
1462
1379 if (scp->mohawk)
1380 XE_OUTB(byte, addr[5 - i]);
1463/*
1464 * Set the appropriate bit in the multicast hash table for the supplied
1465 * Ethernet multicast address addr. Assumes that addr is really a multicast
1466 * address.
1467 */
1468static void
1469xe_set_hash(struct xe_softc* scp, u_int8_t* addr) {
1470 u_int32_t crc = 0xffffffff;
1471 u_int8_t bit, byte, crc31, idx;
1472 unsigned i, j;
1473
1474 /* Compute CRC of the address -- standard Ethernet CRC function */
1475 for (i = 0; i < 6; i++) {
1476 byte = addr[i];
1477 for (j = 1; j <= 8; j++) {
1478 if (crc & 0x80000000)
1479 crc31 = 0x01;
1381 else
1480 else
1382 XE_OUTB(byte, addr[i]);
1481 crc31 = 0;
1482 bit = crc31 ^ (byte & 0x01);
1483 crc <<= 1;
1484 byte >>= 1;
1485 if (bit)
1486 crc = (crc ^ XE_CRC_POLY)|1;
1383 }
1487 }
1384#if XE_DEBUG > 2
1385 printf("\n");
1488 }
1489
1490#if XE_DEBUG > 1
1491 device_printf(scp->dev, "set_hash: CRC = 0x%08x\n", crc);
1386#endif
1492#endif
1493
1494 /* Hash table index = 6 msbs of CRC, reversed */
1495 for (i = 0, idx = 0; i < 6; i++) {
1496 idx >>= 1;
1497 if (crc & 0x80000000) {
1498 idx |= 0x20;
1499 }
1500 crc <<= 1;
1387 }
1388
1501 }
1502
1389 XE_SELECT_PAGE(0);
1503 /* Top 3 bits of idx give register - 8, bottom 3 give bit within register */
1504 byte = idx >> 3 | 0x08;
1505 bit = 0x01 << (idx & 0x07);
1506
1507#if XE_DEBUG > 1
1508 device_printf(scp->dev, "set_hash: idx = 0x%02x, byte = 0x%02x, bit = 0x%02x\n", idx, byte, bit);
1509#endif
1510
1511 XE_SELECT_PAGE(0x58);
1512 XE_OUTB(byte, XE_INB(byte) | bit);
1390}
1391
1392
1393/*
1394 * Write an outgoing packet to the card using programmed I/O.
1395 */
1396static int
1397xe_pio_write_packet(struct xe_softc *scp, struct mbuf *mbp) {
1513}
1514
1515
1516/*
1517 * Write an outgoing packet to the card using programmed I/O.
1518 */
1519static int
1520xe_pio_write_packet(struct xe_softc *scp, struct mbuf *mbp) {
1398 struct mbuf *mbp2;
1399 u_int16_t len, pad, free;
1521 unsigned len, pad;
1522 unsigned char wantbyte;
1400 u_int8_t *data;
1523 u_int8_t *data;
1401 u_int8_t savebyte[2], wantbyte;
1524 u_int8_t savebyte[2];
1402
1403 /* Get total packet length */
1525
1526 /* Get total packet length */
1404 for (len = 0, mbp2 = mbp; mbp2 != NULL; len += mbp2->m_len, mbp2 = mbp2->m_next);
1527 if (mbp->m_flags & M_PKTHDR)
1528 len = mbp->m_pkthdr.len;
1529 else {
1530 struct mbuf* mbp2 = mbp;
1531 for (len = 0; mbp2 != NULL; len += mbp2->m_len, mbp2 = mbp2->m_next);
1532 }
1405
1533
1534#if XE_DEBUG > 2
1535 device_printf(scp->dev, "pio_write_packet: len = %u\n", len);
1536#endif
1537
1406 /* Packets < minimum length may need to be padded out */
1407 pad = 0;
1538 /* Packets < minimum length may need to be padded out */
1539 pad = 0;
1408 if (len < ETHER_MIN_LEN - ETHER_CRC_LEN) {
1409 pad = (ETHER_MIN_LEN - ETHER_CRC_LEN - len + 1) >> 1;
1410 len = ETHER_MIN_LEN - ETHER_CRC_LEN;
1540 if (len < scp->tx_min) {
1541 pad = scp->tx_min - len;
1542 len = scp->tx_min;
1411 }
1412
1413 /* Check transmit buffer space */
1414 XE_SELECT_PAGE(0);
1543 }
1544
1545 /* Check transmit buffer space */
1546 XE_SELECT_PAGE(0);
1415 XE_OUTW(XE_TRS, len+2);
1416 free = XE_INW(XE_TSO);
1417 free &= 0x7fff;
1418 if (free <= len + 2)
1547 XE_OUTW(XE_TRS, len+2); /* Only effective on rev. 1 CE2 cards */
1548 if ((XE_INW(XE_TSO) & 0x7fff) <= len + 2)
1419 return 1;
1420
1421 /* Send packet length to card */
1422 XE_OUTW(XE_EDP, len);
1423
1424 /*
1425 * Write packet to card using PIO (code stolen from the ed driver)
1426 */

--- 6 unchanged lines hidden (view full) ---

1433 savebyte[1] = *data;
1434 XE_OUTW(XE_EDP, *(u_short *)savebyte);
1435 data++;
1436 len--;
1437 wantbyte = 0;
1438 }
1439 if (len > 1) { /* Output contiguous words */
1440 bus_space_write_multi_2(scp->bst, scp->bsh, XE_EDP, (u_int16_t *) data,
1549 return 1;
1550
1551 /* Send packet length to card */
1552 XE_OUTW(XE_EDP, len);
1553
1554 /*
1555 * Write packet to card using PIO (code stolen from the ed driver)
1556 */

--- 6 unchanged lines hidden (view full) ---

1563 savebyte[1] = *data;
1564 XE_OUTW(XE_EDP, *(u_short *)savebyte);
1565 data++;
1566 len--;
1567 wantbyte = 0;
1568 }
1569 if (len > 1) { /* Output contiguous words */
1570 bus_space_write_multi_2(scp->bst, scp->bsh, XE_EDP, (u_int16_t *) data,
1441 len >> 1);
1571 len >> 1);
1442 data += len & ~1;
1443 len &= 1;
1444 }
1445 if (len == 1) { /* Save last byte, if necessary */
1446 savebyte[0] = *data;
1447 wantbyte = 1;
1448 }
1449 }
1450 mbp = mbp->m_next;
1451 }
1572 data += len & ~1;
1573 len &= 1;
1574 }
1575 if (len == 1) { /* Save last byte, if necessary */
1576 savebyte[0] = *data;
1577 wantbyte = 1;
1578 }
1579 }
1580 mbp = mbp->m_next;
1581 }
1452 if (wantbyte) /* Last byte for odd-length packets */
1453 XE_OUTW(XE_EDP, *(u_short *)savebyte);
1454
1455 /*
1582
1583 /*
1456 * For CE3 cards, just tell 'em to send -- apparently the card will pad out
1457 * short packets with random cruft. Otherwise, write nonsense words to fill
1458 * out the packet. I guess it is then sent automatically (?)
1584 * Send last byte of odd-length packets
1459 */
1585 */
1586 if (wantbyte)
1587 XE_OUTB(XE_EDP, savebyte[0]);
1588
1589 /*
1590 * Can just tell CE3 cards to send; short packets will be padded out with
1591 * random cruft automatically. For CE2, manually pad the packet with
1592 * garbage; it will be sent when the required number or bytes have been
1593 * delivered to the card.
1594 */
1460 if (scp->mohawk)
1595 if (scp->mohawk)
1461 XE_OUTB(XE_CR, XE_CR_TX_PACKET|XE_CR_ENABLE_INTR);
1462 else
1596 XE_OUTB(XE_CR, XE_CR_TX_PACKET | XE_CR_RESTART_TX | XE_CR_ENABLE_INTR);
1597 else if (pad > 0) {
1598 if (pad & 0x01)
1599 XE_OUTB(XE_EDP, 0xaa);
1600 pad >>= 1;
1463 while (pad > 0) {
1464 XE_OUTW(XE_EDP, 0xdead);
1465 pad--;
1466 }
1601 while (pad > 0) {
1602 XE_OUTW(XE_EDP, 0xdead);
1603 pad--;
1604 }
1605 }
1467
1468 return 0;
1469}
1470
1606
1607 return 0;
1608}
1609
1471/*
1472 * Compute the 32-bit Ethernet CRC for the given buffer.
1473 */
1474static u_int32_t
1475xe_compute_crc(u_int8_t *data, int len) {
1476 u_int32_t crc = 0xffffffff;
1477 u_int32_t poly = 0x04c11db6;
1478 u_int8_t current, crc31, bit;
1479 int i, k;
1480
1610
1481 for (i = 0; i < len; i++) {
1482 current = data[i];
1483 for (k = 1; k <= 8; k++) {
1484 if (crc & 0x80000000) {
1485 crc31 = 0x01;
1486 }
1487 else {
1488 crc31 = 0;
1489 }
1490 bit = crc31 ^ (current & 0x01);
1491 crc <<= 1;
1492 current >>= 1;
1493 if (bit) {
1494 crc = (crc ^ poly)|1;
1495 }
1496 }
1497 }
1498 return crc;
1499}
1500
1611
1501
1502/*
1503 * Convert a CRC into an index into the multicast hash table. What we do is
1504 * take the most-significant 6 bits of the CRC, reverse them, and use that as
1505 * the bit number in the hash table. Bits 5:3 of the result give the byte
1506 * within the table (0-7); bits 2:0 give the bit number within that byte (also
1507 * 0-7), ie. the number of shifts needed to get it into the lsb position.
1508 */
1509static int
1510xe_compute_hashbit(u_int32_t crc) {
1511 u_int8_t hashbit = 0;
1512 int i;
1513
1514 for (i = 0; i < 6; i++) {
1515 hashbit >>= 1;
1516 if (crc & 0x80000000) {
1517 hashbit &= 0x80;
1518 }
1519 crc <<= 1;
1520 }
1521 return (hashbit >> 2);
1522}
1523
1524
1525
1526/**************************************************************
1527 * *
1528 * M I I F U N C T I O N S *
1529 * *
1530 **************************************************************/
1531
1532/*
1533 * Alternative MII/PHY handling code adapted from the xl driver. It doesn't

--- 249 unchanged lines hidden (view full) ---

1783 frame.mii_regaddr = reg;
1784 frame.mii_data = data;
1785 xe_mii_writereg(scp, &frame);
1786
1787 return;
1788}
1789
1790
1612/**************************************************************
1613 * *
1614 * M I I F U N C T I O N S *
1615 * *
1616 **************************************************************/
1617
1618/*
1619 * Alternative MII/PHY handling code adapted from the xl driver. It doesn't

--- 249 unchanged lines hidden (view full) ---

1869 frame.mii_regaddr = reg;
1870 frame.mii_data = data;
1871 xe_mii_writereg(scp, &frame);
1872
1873 return;
1874}
1875
1876
1791#ifdef XE_DEBUG
1877#if XE_DEBUG > 2
1792/*
1793 * A bit of debugging code.
1794 */
1795static void
1796xe_mii_dump(struct xe_softc *scp) {
1797 int i, s;
1798
1799 s = splimp();

--- 48 unchanged lines hidden (view full) ---

1848 (void)splx(s);
1849}
1850#endif
1851
1852int
1853xe_activate(device_t dev)
1854{
1855 struct xe_softc *sc = device_get_softc(dev);
1878/*
1879 * A bit of debugging code.
1880 */
1881static void
1882xe_mii_dump(struct xe_softc *scp) {
1883 int i, s;
1884
1885 s = splimp();

--- 48 unchanged lines hidden (view full) ---

1934 (void)splx(s);
1935}
1936#endif
1937
1938int
1939xe_activate(device_t dev)
1940{
1941 struct xe_softc *sc = device_get_softc(dev);
1856 int start, err;
1942 int start, err, i;
1857
1943
1858 if (!sc->dingo) {
1944#if XE_DEBUG > 1
1945 device_printf(dev, "activate\n");
1946#endif
1947
1948 if (!sc->modem) {
1859 sc->port_rid = 0; /* 0 is managed by pccard */
1860 sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT,
1861 &sc->port_rid, 0, ~0, 16, RF_ACTIVE);
1949 sc->port_rid = 0; /* 0 is managed by pccard */
1950 sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT,
1951 &sc->port_rid, 0, ~0, 16, RF_ACTIVE);
1862 } else {
1952 }
1953 else if (sc->dingo) {
1863 /*
1864 * Find a 16 byte aligned ioport for the card.
1865 */
1866#if XE_DEBUG > 0
1867 device_printf(dev, "Finding an aligned port for RealPort\n");
1868#endif /* XE_DEBUG */
1869 sc->port_rid = 1; /* 0 is managed by pccard */
1870 start = 0x100;

--- 4 unchanged lines hidden (view full) ---

1875 if (sc->port_res == 0)
1876 break; /* we failed */
1877 if ((rman_get_start(sc->port_res) & 0xf) == 0)
1878 break; /* good */
1879 bus_release_resource(dev, SYS_RES_IOPORT, sc->port_rid,
1880 sc->port_res);
1881 start = (rman_get_start(sc->port_res) + 15) & ~0xf;
1882 } while (1);
1954 /*
1955 * Find a 16 byte aligned ioport for the card.
1956 */
1957#if XE_DEBUG > 0
1958 device_printf(dev, "Finding an aligned port for RealPort\n");
1959#endif /* XE_DEBUG */
1960 sc->port_rid = 1; /* 0 is managed by pccard */
1961 start = 0x100;

--- 4 unchanged lines hidden (view full) ---

1966 if (sc->port_res == 0)
1967 break; /* we failed */
1968 if ((rman_get_start(sc->port_res) & 0xf) == 0)
1969 break; /* good */
1970 bus_release_resource(dev, SYS_RES_IOPORT, sc->port_rid,
1971 sc->port_res);
1972 start = (rman_get_start(sc->port_res) + 15) & ~0xf;
1973 } while (1);
1974#if XE_DEBUG > 1
1975 device_printf(dev, "RealPort port 0x%0lx, size 0x%0lx\n",
1976 bus_get_resource_start(dev, SYS_RES_IOPORT, sc->port_rid),
1977 bus_get_resource_count(dev, SYS_RES_IOPORT, sc->port_rid));
1978#endif /* XE_DEBUG */
1979 }
1980 else if (sc->ce2) {
1981 /*
1982 * Find contiguous I/O port for the Ethernet function on CEM2 and
1983 * CEM3 cards. We allocate window 0 wherever pccard has decided
1984 * it should be, then find an available window adjacent to it for
1985 * the second function. Not sure that both windows are actually
1986 * needed.
1987 */
1988#if XE_DEBUG > 0
1989 device_printf(dev, "Finding I/O port for CEM2/CEM3\n");
1990#endif
1991 sc->ce2_port_rid = 0; /* 0 is managed by pccard */
1992 sc->ce2_port_res = bus_alloc_resource(dev, SYS_RES_IOPORT,
1993 &sc->ce2_port_rid, 0, ~0,
1994 8, RF_ACTIVE);
1995 if (!sc->ce2_port_res) {
1996#if XE_DEBUG > 0
1997 device_printf(dev, "Cannot allocate I/O port for modem\n");
1998#endif
1999 return ENOMEM;
2000 }
2001
2002 sc->port_rid = 1;
2003 start = bus_get_resource_start(dev, SYS_RES_IOPORT,
2004 sc->ce2_port_rid);
2005 for (i = 0; i < 2; i++) {
2006 start += (i == 0 ? 8 : -24);
2007 sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT,
2008 &sc->port_rid, start,
2009 start + 18, 18, RF_ACTIVE);
2010 if (sc->port_res == 0)
2011 continue; /* Failed, try again if possible */
2012 if (bus_get_resource_start(dev, SYS_RES_IOPORT,
2013 sc->port_rid) == start)
2014 break; /* Success! */
2015
2016 bus_release_resource(dev, SYS_RES_IOPORT, sc->port_rid,
2017 sc->port_res);
2018 sc->port_res = 0;
2019 }
1883#if XE_DEBUG > 2
2020#if XE_DEBUG > 2
1884 device_printf(dev, "port 0x%0lx, size 0x%0lx\n",
2021 device_printf(dev, "CEM2/CEM3 port 0x%0lx, size 0x%0lx\n",
1885 bus_get_resource_start(dev, SYS_RES_IOPORT, sc->port_rid),
1886 bus_get_resource_count(dev, SYS_RES_IOPORT, sc->port_rid));
1887#endif /* XE_DEBUG */
1888 }
2022 bus_get_resource_start(dev, SYS_RES_IOPORT, sc->port_rid),
2023 bus_get_resource_count(dev, SYS_RES_IOPORT, sc->port_rid));
2024#endif /* XE_DEBUG */
2025 }
2026
1889 if (!sc->port_res) {
1890#if XE_DEBUG > 0
1891 device_printf(dev, "Cannot allocate ioport\n");
1892#endif
1893 return ENOMEM;
1894 }
1895
1896 sc->irq_rid = 0;

--- 17 unchanged lines hidden (view full) ---

1914 return (0);
1915}
1916
1917void
1918xe_deactivate(device_t dev)
1919{
1920 struct xe_softc *sc = device_get_softc(dev);
1921
2027 if (!sc->port_res) {
2028#if XE_DEBUG > 0
2029 device_printf(dev, "Cannot allocate ioport\n");
2030#endif
2031 return ENOMEM;
2032 }
2033
2034 sc->irq_rid = 0;

--- 17 unchanged lines hidden (view full) ---

2052 return (0);
2053}
2054
2055void
2056xe_deactivate(device_t dev)
2057{
2058 struct xe_softc *sc = device_get_softc(dev);
2059
2060#if XE_DEBUG > 1
2061 device_printf(dev, "deactivate\n");
2062#endif
2063 xe_disable_intr(sc);
2064
1922 if (sc->intrhand)
1923 bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
1924 sc->intrhand = 0;
1925 if (sc->port_res)
1926 bus_release_resource(dev, SYS_RES_IOPORT, sc->port_rid,
1927 sc->port_res);
1928 sc->port_res = 0;
2065 if (sc->intrhand)
2066 bus_teardown_intr(dev, sc->irq_res, sc->intrhand);
2067 sc->intrhand = 0;
2068 if (sc->port_res)
2069 bus_release_resource(dev, SYS_RES_IOPORT, sc->port_rid,
2070 sc->port_res);
2071 sc->port_res = 0;
2072 if (sc->ce2_port_res)
2073 bus_release_resource(dev, SYS_RES_IOPORT, sc->ce2_port_rid,
2074 sc->ce2_port_res);
2075 sc->ce2_port_res = 0;
1929 if (sc->irq_res)
1930 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid,
1931 sc->irq_res);
1932 sc->irq_res = 0;
1933 return;
1934}
2076 if (sc->irq_res)
2077 bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid,
2078 sc->irq_res);
2079 sc->irq_res = 0;
2080 return;
2081}