Deleted Added
full compact
if_stge.c (226173) if_stge.c (226995)
1/* $NetBSD: if_stge.c,v 1.32 2005/12/11 12:22:49 christos Exp $ */
2
3/*-
4 * Copyright (c) 2001 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe.

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

30 */
31
32/*
33 * Device driver for the Sundance Tech. TC9021 10/100/1000
34 * Ethernet controller.
35 */
36
37#include <sys/cdefs.h>
1/* $NetBSD: if_stge.c,v 1.32 2005/12/11 12:22:49 christos Exp $ */
2
3/*-
4 * Copyright (c) 2001 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe.

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

30 */
31
32/*
33 * Device driver for the Sundance Tech. TC9021 10/100/1000
34 * Ethernet controller.
35 */
36
37#include <sys/cdefs.h>
38__FBSDID("$FreeBSD: head/sys/dev/stge/if_stge.c 226173 2011-10-09 20:27:20Z marius $");
38__FBSDID("$FreeBSD: head/sys/dev/stge/if_stge.c 226995 2011-11-01 16:13:59Z marius $");
39
40#ifdef HAVE_KERNEL_OPTION_HEADERS
41#include "opt_device_polling.h"
42#endif
43
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/endian.h>

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

62#include <net/if_vlan_var.h>
63
64#include <machine/bus.h>
65#include <machine/resource.h>
66#include <sys/bus.h>
67#include <sys/rman.h>
68
69#include <dev/mii/mii.h>
39
40#ifdef HAVE_KERNEL_OPTION_HEADERS
41#include "opt_device_polling.h"
42#endif
43
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/endian.h>

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

62#include <net/if_vlan_var.h>
63
64#include <machine/bus.h>
65#include <machine/resource.h>
66#include <sys/bus.h>
67#include <sys/rman.h>
68
69#include <dev/mii/mii.h>
70#include <dev/mii/mii_bitbang.h>
70#include <dev/mii/miivar.h>
71
72#include <dev/pci/pcireg.h>
73#include <dev/pci/pcivar.h>
74
75#include <dev/stge/if_stgereg.h>
76
77#define STGE_CSUM_FEATURES (CSUM_IP | CSUM_TCP | CSUM_UDP)
78
79MODULE_DEPEND(stge, pci, 1, 1, 1);
80MODULE_DEPEND(stge, ether, 1, 1, 1);
81MODULE_DEPEND(stge, miibus, 1, 1, 1);
82
83/* "device miibus" required. See GENERIC if you get errors here. */
84#include "miibus_if.h"
85
86/*
87 * Devices supported by this driver.
88 */
71#include <dev/mii/miivar.h>
72
73#include <dev/pci/pcireg.h>
74#include <dev/pci/pcivar.h>
75
76#include <dev/stge/if_stgereg.h>
77
78#define STGE_CSUM_FEATURES (CSUM_IP | CSUM_TCP | CSUM_UDP)
79
80MODULE_DEPEND(stge, pci, 1, 1, 1);
81MODULE_DEPEND(stge, ether, 1, 1, 1);
82MODULE_DEPEND(stge, miibus, 1, 1, 1);
83
84/* "device miibus" required. See GENERIC if you get errors here. */
85#include "miibus_if.h"
86
87/*
88 * Devices supported by this driver.
89 */
89static struct stge_product {
90static const struct stge_product {
90 uint16_t stge_vendorid;
91 uint16_t stge_deviceid;
92 const char *stge_name;
91 uint16_t stge_vendorid;
92 uint16_t stge_deviceid;
93 const char *stge_name;
93} stge_products[] = {
94} const stge_products[] = {
94 { VENDOR_SUNDANCETI, DEVICEID_SUNDANCETI_ST1023,
95 "Sundance ST-1023 Gigabit Ethernet" },
96
97 { VENDOR_SUNDANCETI, DEVICEID_SUNDANCETI_ST2021,
98 "Sundance ST-2021 Gigabit Ethernet" },
99
100 { VENDOR_TAMARACK, DEVICEID_TAMARACK_TC9021,
101 "Tamarack TC9021 Gigabit Ethernet" },

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

155static void stge_txeof(struct stge_softc *);
156static int stge_rxeof(struct stge_softc *);
157static __inline void stge_discard_rxbuf(struct stge_softc *, int);
158static int stge_newbuf(struct stge_softc *, int);
159#ifndef __NO_STRICT_ALIGNMENT
160static __inline struct mbuf *stge_fixup_rx(struct stge_softc *, struct mbuf *);
161#endif
162
95 { VENDOR_SUNDANCETI, DEVICEID_SUNDANCETI_ST1023,
96 "Sundance ST-1023 Gigabit Ethernet" },
97
98 { VENDOR_SUNDANCETI, DEVICEID_SUNDANCETI_ST2021,
99 "Sundance ST-2021 Gigabit Ethernet" },
100
101 { VENDOR_TAMARACK, DEVICEID_TAMARACK_TC9021,
102 "Tamarack TC9021 Gigabit Ethernet" },

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

156static void stge_txeof(struct stge_softc *);
157static int stge_rxeof(struct stge_softc *);
158static __inline void stge_discard_rxbuf(struct stge_softc *, int);
159static int stge_newbuf(struct stge_softc *, int);
160#ifndef __NO_STRICT_ALIGNMENT
161static __inline struct mbuf *stge_fixup_rx(struct stge_softc *, struct mbuf *);
162#endif
163
163static void stge_mii_sync(struct stge_softc *);
164static void stge_mii_send(struct stge_softc *, uint32_t, int);
165static int stge_mii_readreg(struct stge_softc *, struct stge_mii_frame *);
166static int stge_mii_writereg(struct stge_softc *, struct stge_mii_frame *);
167static int stge_miibus_readreg(device_t, int, int);
168static int stge_miibus_writereg(device_t, int, int, int);
169static void stge_miibus_statchg(device_t);
170static int stge_mediachange(struct ifnet *);
171static void stge_mediastatus(struct ifnet *, struct ifmediareq *);
172
173static void stge_dmamap_cb(void *, bus_dma_segment_t *, int, int);
174static int stge_dma_alloc(struct stge_softc *);

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

180static int stge_poll(struct ifnet *, enum poll_cmd, int);
181#endif
182
183static void stge_setwol(struct stge_softc *);
184static int sysctl_int_range(SYSCTL_HANDLER_ARGS, int, int);
185static int sysctl_hw_stge_rxint_nframe(SYSCTL_HANDLER_ARGS);
186static int sysctl_hw_stge_rxint_dmawait(SYSCTL_HANDLER_ARGS);
187
164static int stge_miibus_readreg(device_t, int, int);
165static int stge_miibus_writereg(device_t, int, int, int);
166static void stge_miibus_statchg(device_t);
167static int stge_mediachange(struct ifnet *);
168static void stge_mediastatus(struct ifnet *, struct ifmediareq *);
169
170static void stge_dmamap_cb(void *, bus_dma_segment_t *, int, int);
171static int stge_dma_alloc(struct stge_softc *);

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

177static int stge_poll(struct ifnet *, enum poll_cmd, int);
178#endif
179
180static void stge_setwol(struct stge_softc *);
181static int sysctl_int_range(SYSCTL_HANDLER_ARGS, int, int);
182static int sysctl_hw_stge_rxint_nframe(SYSCTL_HANDLER_ARGS);
183static int sysctl_hw_stge_rxint_dmawait(SYSCTL_HANDLER_ARGS);
184
185/*
186 * MII bit-bang glue
187 */
188static uint32_t stge_mii_bitbang_read(device_t);
189static void stge_mii_bitbang_write(device_t, uint32_t);
190
191static const struct mii_bitbang_ops stge_mii_bitbang_ops = {
192 stge_mii_bitbang_read,
193 stge_mii_bitbang_write,
194 {
195 PC_MgmtData, /* MII_BIT_MDO */
196 PC_MgmtData, /* MII_BIT_MDI */
197 PC_MgmtClk, /* MII_BIT_MDC */
198 PC_MgmtDir, /* MII_BIT_DIR_HOST_PHY */
199 0, /* MII_BIT_DIR_PHY_HOST */
200 }
201};
202
188static device_method_t stge_methods[] = {
189 /* Device interface */
190 DEVMETHOD(device_probe, stge_probe),
191 DEVMETHOD(device_attach, stge_attach),
192 DEVMETHOD(device_detach, stge_detach),
193 DEVMETHOD(device_shutdown, stge_shutdown),
194 DEVMETHOD(device_suspend, stge_suspend),
195 DEVMETHOD(device_resume, stge_resume),

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

220};
221
222static struct resource_spec stge_res_spec_mem[] = {
223 { SYS_RES_MEMORY, PCIR_BAR(1), RF_ACTIVE },
224 { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE },
225 { -1, 0, 0 }
226};
227
203static device_method_t stge_methods[] = {
204 /* Device interface */
205 DEVMETHOD(device_probe, stge_probe),
206 DEVMETHOD(device_attach, stge_attach),
207 DEVMETHOD(device_detach, stge_detach),
208 DEVMETHOD(device_shutdown, stge_shutdown),
209 DEVMETHOD(device_suspend, stge_suspend),
210 DEVMETHOD(device_resume, stge_resume),

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

235};
236
237static struct resource_spec stge_res_spec_mem[] = {
238 { SYS_RES_MEMORY, PCIR_BAR(1), RF_ACTIVE },
239 { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE },
240 { -1, 0, 0 }
241};
242
228#define MII_SET(x) \
229 CSR_WRITE_1(sc, STGE_PhyCtrl, CSR_READ_1(sc, STGE_PhyCtrl) | (x))
230#define MII_CLR(x) \
231 CSR_WRITE_1(sc, STGE_PhyCtrl, CSR_READ_1(sc, STGE_PhyCtrl) & ~(x))
232
233/*
243/*
234 * Sync the PHYs by setting data bit and strobing the clock 32 times.
244 * stge_mii_bitbang_read: [mii bit-bang interface function]
245 *
246 * Read the MII serial port for the MII bit-bang module.
235 */
247 */
236static void
237stge_mii_sync(struct stge_softc *sc)
248static uint32_t
249stge_mii_bitbang_read(device_t dev)
238{
250{
239 int i;
251 struct stge_softc *sc;
252 uint32_t val;
240
253
241 MII_SET(PC_MgmtDir | PC_MgmtData);
254 sc = device_get_softc(dev);
242
255
243 for (i = 0; i < 32; i++) {
244 MII_SET(PC_MgmtClk);
245 DELAY(1);
246 MII_CLR(PC_MgmtClk);
247 DELAY(1);
248 }
256 val = CSR_READ_1(sc, STGE_PhyCtrl);
257 CSR_BARRIER(sc, STGE_PhyCtrl, 1,
258 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
259 return (val);
249}
250
251/*
260}
261
262/*
252 * Clock a series of bits through the MII.
263 * stge_mii_bitbang_write: [mii big-bang interface function]
264 *
265 * Write the MII serial port for the MII bit-bang module.
253 */
254static void
266 */
267static void
255stge_mii_send(struct stge_softc *sc, uint32_t bits, int cnt)
268stge_mii_bitbang_write(device_t dev, uint32_t val)
256{
269{
257 int i;
270 struct stge_softc *sc;
258
271
259 MII_CLR(PC_MgmtClk);
272 sc = device_get_softc(dev);
260
273
261 for (i = (0x1 << (cnt - 1)); i; i >>= 1) {
262 if (bits & i)
263 MII_SET(PC_MgmtData);
264 else
265 MII_CLR(PC_MgmtData);
266 DELAY(1);
267 MII_CLR(PC_MgmtClk);
268 DELAY(1);
269 MII_SET(PC_MgmtClk);
270 }
274 CSR_WRITE_1(sc, STGE_PhyCtrl, val);
275 CSR_BARRIER(sc, STGE_PhyCtrl, 1,
276 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
271}
272
273/*
277}
278
279/*
274 * Read an PHY register through the MII.
275 */
276static int
277stge_mii_readreg(struct stge_softc *sc, struct stge_mii_frame *frame)
278{
279 int i, ack;
280
281 /*
282 * Set up frame for RX.
283 */
284 frame->mii_stdelim = STGE_MII_STARTDELIM;
285 frame->mii_opcode = STGE_MII_READOP;
286 frame->mii_turnaround = 0;
287 frame->mii_data = 0;
288
289 CSR_WRITE_1(sc, STGE_PhyCtrl, 0 | sc->sc_PhyCtrl);
290 /*
291 * Turn on data xmit.
292 */
293 MII_SET(PC_MgmtDir);
294
295 stge_mii_sync(sc);
296
297 /*
298 * Send command/address info.
299 */
300 stge_mii_send(sc, frame->mii_stdelim, 2);
301 stge_mii_send(sc, frame->mii_opcode, 2);
302 stge_mii_send(sc, frame->mii_phyaddr, 5);
303 stge_mii_send(sc, frame->mii_regaddr, 5);
304
305 /* Turn off xmit. */
306 MII_CLR(PC_MgmtDir);
307
308 /* Idle bit */
309 MII_CLR((PC_MgmtClk | PC_MgmtData));
310 DELAY(1);
311 MII_SET(PC_MgmtClk);
312 DELAY(1);
313
314 /* Check for ack */
315 MII_CLR(PC_MgmtClk);
316 DELAY(1);
317 ack = CSR_READ_1(sc, STGE_PhyCtrl) & PC_MgmtData;
318 MII_SET(PC_MgmtClk);
319 DELAY(1);
320
321 /*
322 * Now try reading data bits. If the ack failed, we still
323 * need to clock through 16 cycles to keep the PHY(s) in sync.
324 */
325 if (ack) {
326 for(i = 0; i < 16; i++) {
327 MII_CLR(PC_MgmtClk);
328 DELAY(1);
329 MII_SET(PC_MgmtClk);
330 DELAY(1);
331 }
332 goto fail;
333 }
334
335 for (i = 0x8000; i; i >>= 1) {
336 MII_CLR(PC_MgmtClk);
337 DELAY(1);
338 if (!ack) {
339 if (CSR_READ_1(sc, STGE_PhyCtrl) & PC_MgmtData)
340 frame->mii_data |= i;
341 DELAY(1);
342 }
343 MII_SET(PC_MgmtClk);
344 DELAY(1);
345 }
346
347fail:
348 MII_CLR(PC_MgmtClk);
349 DELAY(1);
350 MII_SET(PC_MgmtClk);
351 DELAY(1);
352
353 if (ack)
354 return(1);
355 return(0);
356}
357
358/*
359 * Write to a PHY register through the MII.
360 */
361static int
362stge_mii_writereg(struct stge_softc *sc, struct stge_mii_frame *frame)
363{
364
365 /*
366 * Set up frame for TX.
367 */
368 frame->mii_stdelim = STGE_MII_STARTDELIM;
369 frame->mii_opcode = STGE_MII_WRITEOP;
370 frame->mii_turnaround = STGE_MII_TURNAROUND;
371
372 /*
373 * Turn on data output.
374 */
375 MII_SET(PC_MgmtDir);
376
377 stge_mii_sync(sc);
378
379 stge_mii_send(sc, frame->mii_stdelim, 2);
380 stge_mii_send(sc, frame->mii_opcode, 2);
381 stge_mii_send(sc, frame->mii_phyaddr, 5);
382 stge_mii_send(sc, frame->mii_regaddr, 5);
383 stge_mii_send(sc, frame->mii_turnaround, 2);
384 stge_mii_send(sc, frame->mii_data, 16);
385
386 /* Idle bit. */
387 MII_SET(PC_MgmtClk);
388 DELAY(1);
389 MII_CLR(PC_MgmtClk);
390 DELAY(1);
391
392 /*
393 * Turn off xmit.
394 */
395 MII_CLR(PC_MgmtDir);
396
397 return(0);
398}
399
400/*
401 * sc_miibus_readreg: [mii interface function]
402 *
403 * Read a PHY register on the MII of the TC9021.
404 */
405static int
406stge_miibus_readreg(device_t dev, int phy, int reg)
407{
408 struct stge_softc *sc;
280 * sc_miibus_readreg: [mii interface function]
281 *
282 * Read a PHY register on the MII of the TC9021.
283 */
284static int
285stge_miibus_readreg(device_t dev, int phy, int reg)
286{
287 struct stge_softc *sc;
409 struct stge_mii_frame frame;
410 int error;
288 int error, val;
411
412 sc = device_get_softc(dev);
413
414 if (reg == STGE_PhyCtrl) {
415 /* XXX allow ip1000phy read STGE_PhyCtrl register. */
416 STGE_MII_LOCK(sc);
417 error = CSR_READ_1(sc, STGE_PhyCtrl);
418 STGE_MII_UNLOCK(sc);
419 return (error);
420 }
289
290 sc = device_get_softc(dev);
291
292 if (reg == STGE_PhyCtrl) {
293 /* XXX allow ip1000phy read STGE_PhyCtrl register. */
294 STGE_MII_LOCK(sc);
295 error = CSR_READ_1(sc, STGE_PhyCtrl);
296 STGE_MII_UNLOCK(sc);
297 return (error);
298 }
421 bzero(&frame, sizeof(frame));
422 frame.mii_phyaddr = phy;
423 frame.mii_regaddr = reg;
424
425 STGE_MII_LOCK(sc);
299
300 STGE_MII_LOCK(sc);
426 error = stge_mii_readreg(sc, &frame);
301 val = mii_bitbang_readreg(dev, &stge_mii_bitbang_ops, phy, reg);
427 STGE_MII_UNLOCK(sc);
302 STGE_MII_UNLOCK(sc);
428
429 if (error != 0) {
430 /* Don't show errors for PHY probe request */
431 if (reg != 1)
432 device_printf(sc->sc_dev, "phy read fail\n");
433 return (0);
434 }
435 return (frame.mii_data);
303 return (val);
436}
437
438/*
439 * stge_miibus_writereg: [mii interface function]
440 *
441 * Write a PHY register on the MII of the TC9021.
442 */
443static int
444stge_miibus_writereg(device_t dev, int phy, int reg, int val)
445{
446 struct stge_softc *sc;
304}
305
306/*
307 * stge_miibus_writereg: [mii interface function]
308 *
309 * Write a PHY register on the MII of the TC9021.
310 */
311static int
312stge_miibus_writereg(device_t dev, int phy, int reg, int val)
313{
314 struct stge_softc *sc;
447 struct stge_mii_frame frame;
448 int error;
449
450 sc = device_get_softc(dev);
451
315
316 sc = device_get_softc(dev);
317
452 bzero(&frame, sizeof(frame));
453 frame.mii_phyaddr = phy;
454 frame.mii_regaddr = reg;
455 frame.mii_data = val;
456
457 STGE_MII_LOCK(sc);
318 STGE_MII_LOCK(sc);
458 error = stge_mii_writereg(sc, &frame);
319 mii_bitbang_writereg(dev, &stge_mii_bitbang_ops, phy, reg, val);
459 STGE_MII_UNLOCK(sc);
320 STGE_MII_UNLOCK(sc);
460
461 if (error != 0)
462 device_printf(sc->sc_dev, "phy write fail\n");
463 return (0);
464}
465
466/*
467 * stge_miibus_statchg: [mii interface function]
468 *
469 * Callback from MII layer when media changes.
470 */

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

545 device_printf(sc->sc_dev, "EEPROM read timed out\n");
546 *data = CSR_READ_2(sc, STGE_EepromData);
547}
548
549
550static int
551stge_probe(device_t dev)
552{
321 return (0);
322}
323
324/*
325 * stge_miibus_statchg: [mii interface function]
326 *
327 * Callback from MII layer when media changes.
328 */

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

403 device_printf(sc->sc_dev, "EEPROM read timed out\n");
404 *data = CSR_READ_2(sc, STGE_EepromData);
405}
406
407
408static int
409stge_probe(device_t dev)
410{
553 struct stge_product *sp;
411 const struct stge_product *sp;
554 int i;
555 uint16_t vendor, devid;
556
557 vendor = pci_get_vendor(dev);
558 devid = pci_get_device(dev);
559 sp = stge_products;
560 for (i = 0; i < sizeof(stge_products)/sizeof(stge_products[0]);
561 i++, sp++) {

--- 2188 unchanged lines hidden ---
412 int i;
413 uint16_t vendor, devid;
414
415 vendor = pci_get_vendor(dev);
416 devid = pci_get_device(dev);
417 sp = stge_products;
418 for (i = 0; i < sizeof(stge_products)/sizeof(stge_products[0]);
419 i++, sp++) {

--- 2188 unchanged lines hidden ---