Deleted Added
full compact
if_arge.c (234859) if_arge.c (234862)
1/*-
2 * Copyright (c) 2009, Oleksandr Tymoshenko
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

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

21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2009, Oleksandr Tymoshenko
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

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

21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD: head/sys/mips/atheros/if_arge.c 234859 2012-05-01 04:35:53Z adrian $");
29__FBSDID("$FreeBSD: head/sys/mips/atheros/if_arge.c 234862 2012-05-01 06:18:30Z adrian $");
30
31/*
32 * AR71XX gigabit ethernet driver
33 */
34#ifdef HAVE_KERNEL_OPTION_HEADERS
35#include "opt_device_polling.h"
36#endif
37

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

69#include <sys/rman.h>
70
71#include <dev/mii/mii.h>
72#include <dev/mii/miivar.h>
73
74#include <dev/pci/pcireg.h>
75#include <dev/pci/pcivar.h>
76
30
31/*
32 * AR71XX gigabit ethernet driver
33 */
34#ifdef HAVE_KERNEL_OPTION_HEADERS
35#include "opt_device_polling.h"
36#endif
37

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

69#include <sys/rman.h>
70
71#include <dev/mii/mii.h>
72#include <dev/mii/miivar.h>
73
74#include <dev/pci/pcireg.h>
75#include <dev/pci/pcivar.h>
76
77#include "opt_arge.h"
78
79#if defined(ARGE_MDIO)
80#include <dev/etherswitch/mdio.h>
81#include <dev/etherswitch/miiproxy.h>
82#include "mdio_if.h"
83#endif
84
85
77MODULE_DEPEND(arge, ether, 1, 1, 1);
78MODULE_DEPEND(arge, miibus, 1, 1, 1);
86MODULE_DEPEND(arge, ether, 1, 1, 1);
87MODULE_DEPEND(arge, miibus, 1, 1, 1);
88MODULE_VERSION(arge, 1);
79
80#include "miibus_if.h"
81
82#include <mips/atheros/ar71xxreg.h>
83#include <mips/atheros/if_argevar.h>
84#include <mips/atheros/ar71xx_setup.h>
85#include <mips/atheros/ar71xx_cpudef.h>
86

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

133static int arge_suspend(device_t);
134
135static int arge_rx_locked(struct arge_softc *);
136static void arge_tx_locked(struct arge_softc *);
137static void arge_intr(void *);
138static int arge_intr_filter(void *);
139static void arge_tick(void *);
140
89
90#include "miibus_if.h"
91
92#include <mips/atheros/ar71xxreg.h>
93#include <mips/atheros/if_argevar.h>
94#include <mips/atheros/ar71xx_setup.h>
95#include <mips/atheros/ar71xx_cpudef.h>
96

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

143static int arge_suspend(device_t);
144
145static int arge_rx_locked(struct arge_softc *);
146static void arge_tx_locked(struct arge_softc *);
147static void arge_intr(void *);
148static int arge_intr_filter(void *);
149static void arge_tick(void *);
150
151static void arge_hinted_child(device_t bus, const char *dname, int dunit);
152
141/*
142 * ifmedia callbacks for multiPHY MAC
143 */
144void arge_multiphy_mediastatus(struct ifnet *, struct ifmediareq *);
145int arge_multiphy_mediachange(struct ifnet *);
146
147static void arge_dmamap_cb(void *, bus_dma_segment_t *, int, int);
148static int arge_dma_alloc(struct arge_softc *);

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

159 DEVMETHOD(device_resume, arge_resume),
160 DEVMETHOD(device_shutdown, arge_shutdown),
161
162 /* MII interface */
163 DEVMETHOD(miibus_readreg, arge_miibus_readreg),
164 DEVMETHOD(miibus_writereg, arge_miibus_writereg),
165 DEVMETHOD(miibus_statchg, arge_miibus_statchg),
166
153/*
154 * ifmedia callbacks for multiPHY MAC
155 */
156void arge_multiphy_mediastatus(struct ifnet *, struct ifmediareq *);
157int arge_multiphy_mediachange(struct ifnet *);
158
159static void arge_dmamap_cb(void *, bus_dma_segment_t *, int, int);
160static int arge_dma_alloc(struct arge_softc *);

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

171 DEVMETHOD(device_resume, arge_resume),
172 DEVMETHOD(device_shutdown, arge_shutdown),
173
174 /* MII interface */
175 DEVMETHOD(miibus_readreg, arge_miibus_readreg),
176 DEVMETHOD(miibus_writereg, arge_miibus_writereg),
177 DEVMETHOD(miibus_statchg, arge_miibus_statchg),
178
179 /* bus interface */
180 DEVMETHOD(bus_add_child, device_add_child_ordered),
181 DEVMETHOD(bus_hinted_child, arge_hinted_child),
182
167 DEVMETHOD_END
168};
169
170static driver_t arge_driver = {
171 "arge",
172 arge_methods,
173 sizeof(struct arge_softc)
174};
175
176static devclass_t arge_devclass;
177
178DRIVER_MODULE(arge, nexus, arge_driver, arge_devclass, 0, 0);
179DRIVER_MODULE(miibus, arge, miibus_driver, miibus_devclass, 0, 0);
180
183 DEVMETHOD_END
184};
185
186static driver_t arge_driver = {
187 "arge",
188 arge_methods,
189 sizeof(struct arge_softc)
190};
191
192static devclass_t arge_devclass;
193
194DRIVER_MODULE(arge, nexus, arge_driver, arge_devclass, 0, 0);
195DRIVER_MODULE(miibus, arge, miibus_driver, miibus_devclass, 0, 0);
196
197#if defined(ARGE_MDIO)
198static int argemdio_probe(device_t);
199static int argemdio_attach(device_t);
200static int argemdio_detach(device_t);
201
181/*
202/*
203 * Declare an additional, separate driver for accessing the MDIO bus.
204 */
205static device_method_t argemdio_methods[] = {
206 /* Device interface */
207 DEVMETHOD(device_probe, argemdio_probe),
208 DEVMETHOD(device_attach, argemdio_attach),
209 DEVMETHOD(device_detach, argemdio_detach),
210
211 /* bus interface */
212 DEVMETHOD(bus_add_child, device_add_child_ordered),
213
214 /* MDIO access */
215 DEVMETHOD(mdio_readreg, arge_miibus_readreg),
216 DEVMETHOD(mdio_writereg, arge_miibus_writereg),
217};
218
219DEFINE_CLASS_0(argemdio, argemdio_driver, argemdio_methods,
220 sizeof(struct arge_softc));
221static devclass_t argemdio_devclass;
222
223DRIVER_MODULE(miiproxy, arge, miiproxy_driver, miiproxy_devclass, 0, 0);
224DRIVER_MODULE(argemdio, nexus, argemdio_driver, argemdio_devclass, 0, 0);
225DRIVER_MODULE(mdio, argemdio, mdio_driver, mdio_devclass, 0, 0);
226#endif
227
228/*
182 * RedBoot passes MAC address to entry point as environment
183 * variable. platfrom_start parses it and stores in this variable
184 */
185extern uint32_t ar711_base_mac[ETHER_ADDR_LEN];
186
187static struct mtx miibus_mtx;
188
189MTX_SYSINIT(miibus_mtx, &miibus_mtx, "arge mii lock", MTX_DEF);

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

232 CTLFLAG_RW, &sc->arge_cdata.arge_tx_prod, 0, "");
233 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "tx_cons",
234 CTLFLAG_RW, &sc->arge_cdata.arge_tx_cons, 0, "");
235 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "tx_cnt",
236 CTLFLAG_RW, &sc->arge_cdata.arge_tx_cnt, 0, "");
237#endif
238}
239
229 * RedBoot passes MAC address to entry point as environment
230 * variable. platfrom_start parses it and stores in this variable
231 */
232extern uint32_t ar711_base_mac[ETHER_ADDR_LEN];
233
234static struct mtx miibus_mtx;
235
236MTX_SYSINIT(miibus_mtx, &miibus_mtx, "arge mii lock", MTX_DEF);

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

279 CTLFLAG_RW, &sc->arge_cdata.arge_tx_prod, 0, "");
280 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "tx_cons",
281 CTLFLAG_RW, &sc->arge_cdata.arge_tx_cons, 0, "");
282 SYSCTL_ADD_UINT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "tx_cnt",
283 CTLFLAG_RW, &sc->arge_cdata.arge_tx_cnt, 0, "");
284#endif
285}
286
287static void
288arge_reset_mac(struct arge_softc *sc)
289{
290 uint32_t reg;
291
292 /* Step 1. Soft-reset MAC */
293 ARGE_SET_BITS(sc, AR71XX_MAC_CFG1, MAC_CFG1_SOFT_RESET);
294 DELAY(20);
295
296 /* Step 2. Punt the MAC core from the central reset register */
297 ar71xx_device_stop(sc->arge_mac_unit == 0 ? RST_RESET_GE0_MAC :
298 RST_RESET_GE1_MAC);
299 DELAY(100);
300 ar71xx_device_start(sc->arge_mac_unit == 0 ? RST_RESET_GE0_MAC :
301 RST_RESET_GE1_MAC);
302
303 /* Step 3. Reconfigure MAC block */
304 ARGE_WRITE(sc, AR71XX_MAC_CFG1,
305 MAC_CFG1_SYNC_RX | MAC_CFG1_RX_ENABLE |
306 MAC_CFG1_SYNC_TX | MAC_CFG1_TX_ENABLE);
307
308 reg = ARGE_READ(sc, AR71XX_MAC_CFG2);
309 reg |= MAC_CFG2_ENABLE_PADCRC | MAC_CFG2_LENGTH_FIELD ;
310 ARGE_WRITE(sc, AR71XX_MAC_CFG2, reg);
311
312 ARGE_WRITE(sc, AR71XX_MAC_MAX_FRAME_LEN, 1536);
313}
314
315static void
316arge_reset_miibus(struct arge_softc *sc)
317{
318
319 /* Reset MII bus */
320 ARGE_WRITE(sc, AR71XX_MAC_MII_CFG, MAC_MII_CFG_RESET);
321 DELAY(100);
322 ARGE_WRITE(sc, AR71XX_MAC_MII_CFG, MAC_MII_CFG_CLOCK_DIV_28);
323 DELAY(100);
324}
325
240static int
241arge_attach(device_t dev)
242{
326static int
327arge_attach(device_t dev)
328{
243 uint8_t eaddr[ETHER_ADDR_LEN];
244 struct ifnet *ifp;
245 struct arge_softc *sc;
329 struct ifnet *ifp;
330 struct arge_softc *sc;
246 int error = 0, rid, phymask;
247 uint32_t reg, rnd;
248 int is_base_mac_empty, i, phys_total;
331 int error = 0, rid;
332 uint32_t rnd;
333 int is_base_mac_empty, i;
249 uint32_t hint;
250 long eeprom_mac_addr = 0;
251
252 sc = device_get_softc(dev);
253 sc->arge_dev = dev;
254 sc->arge_mac_unit = device_get_unit(dev);
255
256 /*

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

275 }
276
277 KASSERT(((sc->arge_mac_unit == 0) || (sc->arge_mac_unit == 1)),
278 ("if_arge: Only MAC0 and MAC1 supported"));
279
280 /*
281 * Get which PHY of 5 available we should use for this unit
282 */
334 uint32_t hint;
335 long eeprom_mac_addr = 0;
336
337 sc = device_get_softc(dev);
338 sc->arge_dev = dev;
339 sc->arge_mac_unit = device_get_unit(dev);
340
341 /*

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

360 }
361
362 KASSERT(((sc->arge_mac_unit == 0) || (sc->arge_mac_unit == 1)),
363 ("if_arge: Only MAC0 and MAC1 supported"));
364
365 /*
366 * Get which PHY of 5 available we should use for this unit
367 */
283 if (resource_int_value(device_get_name(dev), device_get_unit(dev),
284 "phymask", &phymask) != 0) {
368 if (resource_int_value(device_get_name(dev), device_get_unit(dev),
369 "phymask", &sc->arge_phymask) != 0) {
285 /*
286 * Use port 4 (WAN) for GE0. For any other port use
287 * its PHY the same as its unit number
288 */
289 if (sc->arge_mac_unit == 0)
370 /*
371 * Use port 4 (WAN) for GE0. For any other port use
372 * its PHY the same as its unit number
373 */
374 if (sc->arge_mac_unit == 0)
290 phymask = (1 << 4);
375 sc->arge_phymask = (1 << 4);
291 else
292 /* Use all phys up to 4 */
376 else
377 /* Use all phys up to 4 */
293 phymask = (1 << 4) - 1;
378 sc->arge_phymask = (1 << 4) - 1;
294
379
295 device_printf(dev, "No PHY specified, using mask %d\n",
296 phymask);
380 device_printf(dev, "No PHY specified, using mask %d\n", sc->arge_phymask);
297 }
298
299 /*
300 * Get default media & duplex mode, by default its Base100T
301 * and full duplex
302 */
303 if (resource_int_value(device_get_name(dev), device_get_unit(dev),
304 "media", &hint) != 0)

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

313 "fduplex", &hint) != 0)
314 hint = 1;
315
316 if (hint)
317 sc->arge_duplex_mode = IFM_FDX;
318 else
319 sc->arge_duplex_mode = 0;
320
381 }
382
383 /*
384 * Get default media & duplex mode, by default its Base100T
385 * and full duplex
386 */
387 if (resource_int_value(device_get_name(dev), device_get_unit(dev),
388 "media", &hint) != 0)

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

397 "fduplex", &hint) != 0)
398 hint = 1;
399
400 if (hint)
401 sc->arge_duplex_mode = IFM_FDX;
402 else
403 sc->arge_duplex_mode = 0;
404
321 sc->arge_phymask = phymask;
322
323 mtx_init(&sc->arge_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
324 MTX_DEF);
325 callout_init_mtx(&sc->arge_stat_callout, &sc->arge_mtx, 0);
326 TASK_INIT(&sc->arge_link_task, 0, arge_link_task, sc);
327
328 /* Map control/status registers. */
329 sc->arge_rid = 0;
405 mtx_init(&sc->arge_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
406 MTX_DEF);
407 callout_init_mtx(&sc->arge_stat_callout, &sc->arge_mtx, 0);
408 TASK_INIT(&sc->arge_link_task, 0, arge_link_task, sc);
409
410 /* Map control/status registers. */
411 sc->arge_rid = 0;
330 sc->arge_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
331 &sc->arge_rid, RF_ACTIVE);
412 sc->arge_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
413 &sc->arge_rid, RF_ACTIVE | RF_SHAREABLE);
332
333 if (sc->arge_res == NULL) {
334 device_printf(dev, "couldn't map memory\n");
335 error = ENXIO;
336 goto fail;
337 }
338
339 /* Allocate interrupts */

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

371
372 ifp->if_capenable = ifp->if_capabilities;
373#ifdef DEVICE_POLLING
374 ifp->if_capabilities |= IFCAP_POLLING;
375#endif
376
377 is_base_mac_empty = 1;
378 for (i = 0; i < ETHER_ADDR_LEN; i++) {
414
415 if (sc->arge_res == NULL) {
416 device_printf(dev, "couldn't map memory\n");
417 error = ENXIO;
418 goto fail;
419 }
420
421 /* Allocate interrupts */

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

453
454 ifp->if_capenable = ifp->if_capabilities;
455#ifdef DEVICE_POLLING
456 ifp->if_capabilities |= IFCAP_POLLING;
457#endif
458
459 is_base_mac_empty = 1;
460 for (i = 0; i < ETHER_ADDR_LEN; i++) {
379 eaddr[i] = ar711_base_mac[i] & 0xff;
380 if (eaddr[i] != 0)
461 sc->arge_eaddr[i] = ar711_base_mac[i] & 0xff;
462 if (sc->arge_eaddr[i] != 0)
381 is_base_mac_empty = 0;
382 }
383
384 if (is_base_mac_empty) {
385 /*
386 * No MAC address configured. Generate the random one.
387 */
388 if (bootverbose)
389 device_printf(dev,
390 "Generating random ethernet address.\n");
391
392 rnd = arc4random();
463 is_base_mac_empty = 0;
464 }
465
466 if (is_base_mac_empty) {
467 /*
468 * No MAC address configured. Generate the random one.
469 */
470 if (bootverbose)
471 device_printf(dev,
472 "Generating random ethernet address.\n");
473
474 rnd = arc4random();
393 eaddr[0] = 'b';
394 eaddr[1] = 's';
395 eaddr[2] = 'd';
396 eaddr[3] = (rnd >> 24) & 0xff;
397 eaddr[4] = (rnd >> 16) & 0xff;
398 eaddr[5] = (rnd >> 8) & 0xff;
475 sc->arge_eaddr[0] = 'b';
476 sc->arge_eaddr[1] = 's';
477 sc->arge_eaddr[2] = 'd';
478 sc->arge_eaddr[3] = (rnd >> 24) & 0xff;
479 sc->arge_eaddr[4] = (rnd >> 16) & 0xff;
480 sc->arge_eaddr[5] = (rnd >> 8) & 0xff;
399 }
481 }
400
401 if (sc->arge_mac_unit != 0)
482 if (sc->arge_mac_unit != 0)
402 eaddr[5] += sc->arge_mac_unit;
483 sc->arge_eaddr[5] += sc->arge_mac_unit;
403
404 if (arge_dma_alloc(sc) != 0) {
405 error = ENXIO;
406 goto fail;
407 }
408
484
485 if (arge_dma_alloc(sc) != 0) {
486 error = ENXIO;
487 goto fail;
488 }
489
490 /*
491 * Don't do this for the MDIO bus case - it's already done
492 * as part of the MDIO bus attachment.
493 */
494#if !defined(ARGE_MDIO)
409 /* Initialize the MAC block */
495 /* Initialize the MAC block */
496 arge_reset_mac(sc);
497 arge_reset_miibus(sc);
498#endif
410
499
411 /* Step 1. Soft-reset MAC */
412 ARGE_SET_BITS(sc, AR71XX_MAC_CFG1, MAC_CFG1_SOFT_RESET);
413 DELAY(20);
414
415 /* Step 2. Punt the MAC core from the central reset register */
416 ar71xx_device_stop(sc->arge_mac_unit == 0 ? RST_RESET_GE0_MAC :
417 RST_RESET_GE1_MAC);
418 DELAY(100);
419 ar71xx_device_start(sc->arge_mac_unit == 0 ? RST_RESET_GE0_MAC :
420 RST_RESET_GE1_MAC);
421
422 /* Step 3. Reconfigure MAC block */
423 ARGE_WRITE(sc, AR71XX_MAC_CFG1,
424 MAC_CFG1_SYNC_RX | MAC_CFG1_RX_ENABLE |
425 MAC_CFG1_SYNC_TX | MAC_CFG1_TX_ENABLE);
426
427 reg = ARGE_READ(sc, AR71XX_MAC_CFG2);
428 reg |= MAC_CFG2_ENABLE_PADCRC | MAC_CFG2_LENGTH_FIELD ;
429 ARGE_WRITE(sc, AR71XX_MAC_CFG2, reg);
430
431 ARGE_WRITE(sc, AR71XX_MAC_MAX_FRAME_LEN, 1536);
432
433 /* Reset MII bus */
434 ARGE_WRITE(sc, AR71XX_MAC_MII_CFG, MAC_MII_CFG_RESET);
435 DELAY(100);
436 ARGE_WRITE(sc, AR71XX_MAC_MII_CFG, MAC_MII_CFG_CLOCK_DIV_28);
437 DELAY(100);
438
439 /*
440 * Set all Ethernet address registers to the same initial values
441 * set all four addresses to 66-88-aa-cc-dd-ee
442 */
500 /*
501 * Set all Ethernet address registers to the same initial values
502 * set all four addresses to 66-88-aa-cc-dd-ee
503 */
443 ARGE_WRITE(sc, AR71XX_MAC_STA_ADDR1,
444 (eaddr[2] << 24) | (eaddr[3] << 16) | (eaddr[4] << 8) | eaddr[5]);
445 ARGE_WRITE(sc, AR71XX_MAC_STA_ADDR2, (eaddr[0] << 8) | eaddr[1]);
504 ARGE_WRITE(sc, AR71XX_MAC_STA_ADDR1, (sc->arge_eaddr[2] << 24)
505 | (sc->arge_eaddr[3] << 16) | (sc->arge_eaddr[4] << 8)
506 | sc->arge_eaddr[5]);
507 ARGE_WRITE(sc, AR71XX_MAC_STA_ADDR2, (sc->arge_eaddr[0] << 8)
508 | sc->arge_eaddr[1]);
446
447 ARGE_WRITE(sc, AR71XX_MAC_FIFO_CFG0,
448 FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT);
449
450 switch (ar71xx_soc) {
451 case AR71XX_SOC_AR7240:
452 case AR71XX_SOC_AR7241:
453 case AR71XX_SOC_AR7242:

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

460 }
461
462 ARGE_WRITE(sc, AR71XX_MAC_FIFO_RX_FILTMATCH,
463 FIFO_RX_FILTMATCH_DEFAULT);
464
465 ARGE_WRITE(sc, AR71XX_MAC_FIFO_RX_FILTMASK,
466 FIFO_RX_FILTMASK_DEFAULT);
467
509
510 ARGE_WRITE(sc, AR71XX_MAC_FIFO_CFG0,
511 FIFO_CFG0_ALL << FIFO_CFG0_ENABLE_SHIFT);
512
513 switch (ar71xx_soc) {
514 case AR71XX_SOC_AR7240:
515 case AR71XX_SOC_AR7241:
516 case AR71XX_SOC_AR7242:

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

523 }
524
525 ARGE_WRITE(sc, AR71XX_MAC_FIFO_RX_FILTMATCH,
526 FIFO_RX_FILTMATCH_DEFAULT);
527
528 ARGE_WRITE(sc, AR71XX_MAC_FIFO_RX_FILTMASK,
529 FIFO_RX_FILTMASK_DEFAULT);
530
468 /*
469 * Check if we have single-PHY MAC or multi-PHY
470 */
471 phys_total = 0;
472 for (i = 0; i < ARGE_NPHY; i++)
473 if (phymask & (1 << i))
474 phys_total ++;
531#if defined(ARGE_MDIO)
532 sc->arge_miiproxy = mii_attach_proxy(sc->arge_dev);
533#endif
475
534
476 if (phys_total == 0) {
477 error = EINVAL;
478 goto fail;
479 }
480
481 if (phys_total == 1) {
482 /* Do MII setup. */
483 error = mii_attach(dev, &sc->arge_miibus, ifp,
484 arge_ifmedia_upd, arge_ifmedia_sts, BMSR_DEFCAPMASK,
485 MII_PHY_ANY, MII_OFFSET_ANY, 0);
486 if (error != 0) {
487 device_printf(dev, "attaching PHYs failed\n");
488 goto fail;
535 device_printf(sc->arge_dev, "finishing attachment, phymask %04x"
536 ", proxy %s \n", sc->arge_phymask, sc->arge_miiproxy == NULL ?
537 "null" : "set");
538 for (i = 0; i < ARGE_NPHY; i++) {
539 if (((1 << i) & sc->arge_phymask) != 0) {
540 error = mii_attach(sc->arge_miiproxy != NULL ?
541 sc->arge_miiproxy : sc->arge_dev,
542 &sc->arge_miibus, sc->arge_ifp,
543 arge_ifmedia_upd, arge_ifmedia_sts,
544 BMSR_DEFCAPMASK, i, MII_OFFSET_ANY, 0);
545 if (error != 0) {
546 device_printf(sc->arge_dev, "unable to attach"
547 " PHY %d: %d\n", i, error);
548 goto fail;
549 }
489 }
490 }
550 }
551 }
491 else {
492 ifmedia_init(&sc->arge_ifmedia, 0,
552 if (sc->arge_miibus == NULL) {
553 /* no PHY, so use hard-coded values */
554 ifmedia_init(&sc->arge_ifmedia, 0,
493 arge_multiphy_mediachange,
494 arge_multiphy_mediastatus);
495 ifmedia_add(&sc->arge_ifmedia,
496 IFM_ETHER | sc->arge_media_type | sc->arge_duplex_mode,
497 0, NULL);
498 ifmedia_set(&sc->arge_ifmedia,
499 IFM_ETHER | sc->arge_media_type | sc->arge_duplex_mode);
500 arge_set_pll(sc, sc->arge_media_type, sc->arge_duplex_mode);
501 }
502
503 /* Call MI attach routine. */
555 arge_multiphy_mediachange,
556 arge_multiphy_mediastatus);
557 ifmedia_add(&sc->arge_ifmedia,
558 IFM_ETHER | sc->arge_media_type | sc->arge_duplex_mode,
559 0, NULL);
560 ifmedia_set(&sc->arge_ifmedia,
561 IFM_ETHER | sc->arge_media_type | sc->arge_duplex_mode);
562 arge_set_pll(sc, sc->arge_media_type, sc->arge_duplex_mode);
563 }
564
565 /* Call MI attach routine. */
504 ether_ifattach(ifp, eaddr);
566 ether_ifattach(sc->arge_ifp, sc->arge_eaddr);
505
506 /* Hook interrupt last to avoid having to lock softc */
567
568 /* Hook interrupt last to avoid having to lock softc */
507 error = bus_setup_intr(dev, sc->arge_irq, INTR_TYPE_NET | INTR_MPSAFE,
569 error = bus_setup_intr(sc->arge_dev, sc->arge_irq, INTR_TYPE_NET | INTR_MPSAFE,
508 arge_intr_filter, arge_intr, sc, &sc->arge_intrhand);
509
510 if (error) {
570 arge_intr_filter, arge_intr, sc, &sc->arge_intrhand);
571
572 if (error) {
511 device_printf(dev, "couldn't set up irq\n");
512 ether_ifdetach(ifp);
573 device_printf(sc->arge_dev, "couldn't set up irq\n");
574 ether_ifdetach(sc->arge_ifp);
513 goto fail;
514 }
515
516 /* setup sysctl variables */
575 goto fail;
576 }
577
578 /* setup sysctl variables */
517 arge_attach_sysctl(dev);
579 arge_attach_sysctl(sc->arge_dev);
518
519fail:
580
581fail:
520 if (error)
582 if (error)
521 arge_detach(dev);
522
523 return (error);
524}
525
526static int
527arge_detach(device_t dev)
528{

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

545 ARGE_UNLOCK(sc);
546 taskqueue_drain(taskqueue_swi, &sc->arge_link_task);
547 ether_ifdetach(ifp);
548 }
549
550 if (sc->arge_miibus)
551 device_delete_child(dev, sc->arge_miibus);
552
583 arge_detach(dev);
584
585 return (error);
586}
587
588static int
589arge_detach(device_t dev)
590{

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

607 ARGE_UNLOCK(sc);
608 taskqueue_drain(taskqueue_swi, &sc->arge_link_task);
609 ether_ifdetach(ifp);
610 }
611
612 if (sc->arge_miibus)
613 device_delete_child(dev, sc->arge_miibus);
614
615 if (sc->arge_miiproxy)
616 device_delete_child(dev, sc->arge_miiproxy);
617
553 bus_generic_detach(dev);
554
555 if (sc->arge_intrhand)
556 bus_teardown_intr(dev, sc->arge_irq, sc->arge_intrhand);
557
558 if (sc->arge_res)
559 bus_release_resource(dev, SYS_RES_MEMORY, sc->arge_rid,
560 sc->arge_res);

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

595
596 ARGE_LOCK(sc);
597 arge_stop(sc);
598 ARGE_UNLOCK(sc);
599
600 return (0);
601}
602
618 bus_generic_detach(dev);
619
620 if (sc->arge_intrhand)
621 bus_teardown_intr(dev, sc->arge_irq, sc->arge_intrhand);
622
623 if (sc->arge_res)
624 bus_release_resource(dev, SYS_RES_MEMORY, sc->arge_rid,
625 sc->arge_res);

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

660
661 ARGE_LOCK(sc);
662 arge_stop(sc);
663 ARGE_UNLOCK(sc);
664
665 return (0);
666}
667
668static void
669arge_hinted_child(device_t bus, const char *dname, int dunit)
670{
671 BUS_ADD_CHILD(bus, 0, dname, dunit);
672 device_printf(bus, "hinted child %s%d\n", dname, dunit);
673}
674
603static int
604arge_miibus_readreg(device_t dev, int phy, int reg)
605{
606 struct arge_softc * sc = device_get_softc(dev);
607 int i, result;
608 uint32_t addr = (phy << MAC_MII_PHY_ADDR_SHIFT)
609 | (reg & MAC_MII_REG_MASK);
610
675static int
676arge_miibus_readreg(device_t dev, int phy, int reg)
677{
678 struct arge_softc * sc = device_get_softc(dev);
679 int i, result;
680 uint32_t addr = (phy << MAC_MII_PHY_ADDR_SHIFT)
681 | (reg & MAC_MII_REG_MASK);
682
611 if ((sc->arge_phymask & (1 << phy)) == 0)
612 return (0);
613
614 mtx_lock(&miibus_mtx);
683 mtx_lock(&miibus_mtx);
615 ARGE_MII_WRITE(AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE);
616 ARGE_MII_WRITE(AR71XX_MAC_MII_ADDR, addr);
617 ARGE_MII_WRITE(AR71XX_MAC_MII_CMD, MAC_MII_CMD_READ);
684 ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE);
685 ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_ADDR, addr);
686 ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_READ);
618
619 i = ARGE_MII_TIMEOUT;
687
688 i = ARGE_MII_TIMEOUT;
620 while ((ARGE_MII_READ(AR71XX_MAC_MII_INDICATOR) &
689 while ((ARGE_MDIO_READ(sc, AR71XX_MAC_MII_INDICATOR) &
621 MAC_MII_INDICATOR_BUSY) && (i--))
622 DELAY(5);
623
624 if (i < 0) {
625 mtx_unlock(&miibus_mtx);
626 ARGEDEBUG(sc, ARGE_DBG_MII, "%s timedout\n", __func__);
627 /* XXX: return ERRNO istead? */
628 return (-1);
629 }
630
690 MAC_MII_INDICATOR_BUSY) && (i--))
691 DELAY(5);
692
693 if (i < 0) {
694 mtx_unlock(&miibus_mtx);
695 ARGEDEBUG(sc, ARGE_DBG_MII, "%s timedout\n", __func__);
696 /* XXX: return ERRNO istead? */
697 return (-1);
698 }
699
631 result = ARGE_MII_READ(AR71XX_MAC_MII_STATUS) & MAC_MII_STATUS_MASK;
632 ARGE_MII_WRITE(AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE);
700 result = ARGE_MDIO_READ(sc, AR71XX_MAC_MII_STATUS) & MAC_MII_STATUS_MASK;
701 ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_CMD, MAC_MII_CMD_WRITE);
633 mtx_unlock(&miibus_mtx);
634
635 ARGEDEBUG(sc, ARGE_DBG_MII,
636 "%s: phy=%d, reg=%02x, value[%08x]=%04x\n",
637 __func__, phy, reg, addr, result);
638
639 return (result);
640}
641
642static int
643arge_miibus_writereg(device_t dev, int phy, int reg, int data)
644{
645 struct arge_softc * sc = device_get_softc(dev);
646 int i;
647 uint32_t addr =
648 (phy << MAC_MII_PHY_ADDR_SHIFT) | (reg & MAC_MII_REG_MASK);
649
702 mtx_unlock(&miibus_mtx);
703
704 ARGEDEBUG(sc, ARGE_DBG_MII,
705 "%s: phy=%d, reg=%02x, value[%08x]=%04x\n",
706 __func__, phy, reg, addr, result);
707
708 return (result);
709}
710
711static int
712arge_miibus_writereg(device_t dev, int phy, int reg, int data)
713{
714 struct arge_softc * sc = device_get_softc(dev);
715 int i;
716 uint32_t addr =
717 (phy << MAC_MII_PHY_ADDR_SHIFT) | (reg & MAC_MII_REG_MASK);
718
719 ARGEDEBUG(sc, ARGE_DBG_MII, "%s: phy=%d, reg=%02x, value=%04x\n", __func__,
720 phy, reg, data);
650
721
651 if ((sc->arge_phymask & (1 << phy)) == 0)
652 return (-1);
653
654 ARGEDEBUG(sc, ARGE_DBG_MII, "%s: phy=%d, reg=%02x, value=%04x\n",
655 __func__, phy, reg, data);
656
657 mtx_lock(&miibus_mtx);
722 mtx_lock(&miibus_mtx);
658 ARGE_MII_WRITE(AR71XX_MAC_MII_ADDR, addr);
659 ARGE_MII_WRITE(AR71XX_MAC_MII_CONTROL, data);
723 ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_ADDR, addr);
724 ARGE_MDIO_WRITE(sc, AR71XX_MAC_MII_CONTROL, data);
660
661 i = ARGE_MII_TIMEOUT;
725
726 i = ARGE_MII_TIMEOUT;
662 while ((ARGE_MII_READ(AR71XX_MAC_MII_INDICATOR) &
727 while ((ARGE_MDIO_READ(sc, AR71XX_MAC_MII_INDICATOR) &
663 MAC_MII_INDICATOR_BUSY) && (i--))
664 DELAY(5);
665
666 mtx_unlock(&miibus_mtx);
667
668 if (i < 0) {
669 ARGEDEBUG(sc, ARGE_DBG_MII, "%s timedout\n", __func__);
670 /* XXX: return ERRNO istead? */

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

724
725static void
726arge_set_pll(struct arge_softc *sc, int media, int duplex)
727{
728 uint32_t cfg, ifcontrol, rx_filtmask;
729 uint32_t fifo_tx;
730 int if_speed;
731
728 MAC_MII_INDICATOR_BUSY) && (i--))
729 DELAY(5);
730
731 mtx_unlock(&miibus_mtx);
732
733 if (i < 0) {
734 ARGEDEBUG(sc, ARGE_DBG_MII, "%s timedout\n", __func__);
735 /* XXX: return ERRNO istead? */

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

789
790static void
791arge_set_pll(struct arge_softc *sc, int media, int duplex)
792{
793 uint32_t cfg, ifcontrol, rx_filtmask;
794 uint32_t fifo_tx;
795 int if_speed;
796
797 ARGEDEBUG(sc, ARGE_DBG_MII, "set_pll(%04x, %s)\n", media,
798 duplex == IFM_FDX ? "full" : "half");
732 cfg = ARGE_READ(sc, AR71XX_MAC_CFG2);
733 cfg &= ~(MAC_CFG2_IFACE_MODE_1000
734 | MAC_CFG2_IFACE_MODE_10_100
735 | MAC_CFG2_FULL_DUPLEX);
736
737 if (duplex == IFM_FDX)
738 cfg |= MAC_CFG2_FULL_DUPLEX;
739

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

1987{
1988 struct arge_softc *sc = ifp->if_softc;
1989
1990 ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE;
1991 ifmr->ifm_active = IFM_ETHER | sc->arge_media_type |
1992 sc->arge_duplex_mode;
1993}
1994
799 cfg = ARGE_READ(sc, AR71XX_MAC_CFG2);
800 cfg &= ~(MAC_CFG2_IFACE_MODE_1000
801 | MAC_CFG2_IFACE_MODE_10_100
802 | MAC_CFG2_FULL_DUPLEX);
803
804 if (duplex == IFM_FDX)
805 cfg |= MAC_CFG2_FULL_DUPLEX;
806

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

2054{
2055 struct arge_softc *sc = ifp->if_softc;
2056
2057 ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE;
2058 ifmr->ifm_active = IFM_ETHER | sc->arge_media_type |
2059 sc->arge_duplex_mode;
2060}
2061
2062#if defined(ARGE_MDIO)
2063static int
2064argemdio_probe(device_t dev)
2065{
2066 device_set_desc(dev, "Atheros AR71xx built-in ethernet interface, MDIO controller");
2067 return (0);
2068}
2069
2070static int
2071argemdio_attach(device_t dev)
2072{
2073 struct arge_softc *sc;
2074 int error = 0;
2075
2076 sc = device_get_softc(dev);
2077 sc->arge_dev = dev;
2078 sc->arge_mac_unit = device_get_unit(dev);
2079 sc->arge_rid = 0;
2080 sc->arge_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
2081 &sc->arge_rid, RF_ACTIVE | RF_SHAREABLE);
2082 if (sc->arge_res == NULL) {
2083 device_printf(dev, "couldn't map memory\n");
2084 error = ENXIO;
2085 goto fail;
2086 }
2087
2088 /* Reset MAC - required for AR71xx MDIO to successfully occur */
2089 arge_reset_mac(sc);
2090 /* Reset MII bus */
2091 arge_reset_miibus(sc);
2092
2093 bus_generic_probe(dev);
2094 bus_enumerate_hinted_children(dev);
2095 error = bus_generic_attach(dev);
2096fail:
2097 return (error);
2098}
2099
2100static int
2101argemdio_detach(device_t dev)
2102{
2103 return (0);
2104}
2105
2106#endif