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