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} |