if_cpsw.c (277209) | if_cpsw.c (283276) |
---|---|
1/*- 2 * Copyright (c) 2012 Damjan Marion <dmarion@Freebsd.org> 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 --- 30 unchanged lines hidden (view full) --- 39 * the slivers and the Address Lookup Engine (ALE) that routes packets 40 * between the ports. 41 * 42 * This code was developed and tested on a BeagleBone with 43 * an AM335x SoC. 44 */ 45 46#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2012 Damjan Marion <dmarion@Freebsd.org> 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 --- 30 unchanged lines hidden (view full) --- 39 * the slivers and the Address Lookup Engine (ALE) that routes packets 40 * between the ports. 41 * 42 * This code was developed and tested on a BeagleBone with 43 * an AM335x SoC. 44 */ 45 46#include <sys/cdefs.h> |
47__FBSDID("$FreeBSD: head/sys/arm/ti/cpsw/if_cpsw.c 277209 2015-01-15 02:22:52Z bz $"); | 47__FBSDID("$FreeBSD: head/sys/arm/ti/cpsw/if_cpsw.c 283276 2015-05-22 03:16:18Z gonzo $"); |
48 49#include <sys/param.h> 50#include <sys/systm.h> 51#include <sys/endian.h> 52#include <sys/mbuf.h> 53#include <sys/lock.h> 54#include <sys/mutex.h> 55#include <sys/kernel.h> --- 134 unchanged lines hidden (view full) --- 190 191static devclass_t cpsw_devclass; 192 193DRIVER_MODULE(cpsw, simplebus, cpsw_driver, cpsw_devclass, 0, 0); 194DRIVER_MODULE(miibus, cpsw, miibus_driver, miibus_devclass, 0, 0); 195MODULE_DEPEND(cpsw, ether, 1, 1, 1); 196MODULE_DEPEND(cpsw, miibus, 1, 1, 1); 197 | 48 49#include <sys/param.h> 50#include <sys/systm.h> 51#include <sys/endian.h> 52#include <sys/mbuf.h> 53#include <sys/lock.h> 54#include <sys/mutex.h> 55#include <sys/kernel.h> --- 134 unchanged lines hidden (view full) --- 190 191static devclass_t cpsw_devclass; 192 193DRIVER_MODULE(cpsw, simplebus, cpsw_driver, cpsw_devclass, 0, 0); 194DRIVER_MODULE(miibus, cpsw, miibus_driver, miibus_devclass, 0, 0); 195MODULE_DEPEND(cpsw, ether, 1, 1, 1); 196MODULE_DEPEND(cpsw, miibus, 1, 1, 1); 197 |
198static struct resource_spec res_spec[] = { 199 { SYS_RES_MEMORY, 0, RF_ACTIVE }, | 198static struct resource_spec irq_res_spec[] = { |
200 { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE }, 201 { SYS_RES_IRQ, 1, RF_ACTIVE | RF_SHAREABLE }, 202 { SYS_RES_IRQ, 2, RF_ACTIVE | RF_SHAREABLE }, 203 { SYS_RES_IRQ, 3, RF_ACTIVE | RF_SHAREABLE }, 204 { -1, 0 } 205}; 206 207/* Number of entries here must match size of stats --- 109 unchanged lines hidden (view full) --- 317#define CPSW_GLOBAL_LOCK_ASSERT(sc) do { \ 318 CPSW_TX_LOCK_ASSERT(sc); \ 319 CPSW_RX_LOCK_ASSERT(sc); \ 320} while (0) 321 322/* 323 * Read/Write macros 324 */ | 199 { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE }, 200 { SYS_RES_IRQ, 1, RF_ACTIVE | RF_SHAREABLE }, 201 { SYS_RES_IRQ, 2, RF_ACTIVE | RF_SHAREABLE }, 202 { SYS_RES_IRQ, 3, RF_ACTIVE | RF_SHAREABLE }, 203 { -1, 0 } 204}; 205 206/* Number of entries here must match size of stats --- 109 unchanged lines hidden (view full) --- 316#define CPSW_GLOBAL_LOCK_ASSERT(sc) do { \ 317 CPSW_TX_LOCK_ASSERT(sc); \ 318 CPSW_RX_LOCK_ASSERT(sc); \ 319} while (0) 320 321/* 322 * Read/Write macros 323 */ |
325#define cpsw_read_4(sc, reg) bus_read_4(sc->res[0], reg) 326#define cpsw_write_4(sc, reg, val) bus_write_4(sc->res[0], reg, val) | 324#define cpsw_read_4(sc, reg) bus_read_4(sc->mem_res, reg) 325#define cpsw_write_4(sc, reg, val) bus_write_4(sc->mem_res, reg, val) |
327 328#define cpsw_cpdma_bd_offset(i) (CPSW_CPPI_RAM_OFFSET + ((i)*16)) 329 330#define cpsw_cpdma_bd_paddr(sc, slot) \ | 326 327#define cpsw_cpdma_bd_offset(i) (CPSW_CPPI_RAM_OFFSET + ((i)*16)) 328 329#define cpsw_cpdma_bd_paddr(sc, slot) \ |
331 BUS_SPACE_PHYSADDR(sc->res[0], slot->bd_offset) | 330 BUS_SPACE_PHYSADDR(sc->mem_res, slot->bd_offset) |
332#define cpsw_cpdma_read_bd(sc, slot, val) \ | 331#define cpsw_cpdma_read_bd(sc, slot, val) \ |
333 bus_read_region_4(sc->res[0], slot->bd_offset, (uint32_t *) val, 4) | 332 bus_read_region_4(sc->mem_res, slot->bd_offset, (uint32_t *) val, 4) |
334#define cpsw_cpdma_write_bd(sc, slot, val) \ | 333#define cpsw_cpdma_write_bd(sc, slot, val) \ |
335 bus_write_region_4(sc->res[0], slot->bd_offset, (uint32_t *) val, 4) | 334 bus_write_region_4(sc->mem_res, slot->bd_offset, (uint32_t *) val, 4) |
336#define cpsw_cpdma_write_bd_next(sc, slot, next_slot) \ 337 cpsw_write_4(sc, slot->bd_offset, cpsw_cpdma_bd_paddr(sc, next_slot)) 338#define cpsw_cpdma_read_bd_flags(sc, slot) \ | 335#define cpsw_cpdma_write_bd_next(sc, slot, next_slot) \ 336 cpsw_write_4(sc, slot->bd_offset, cpsw_cpdma_bd_paddr(sc, next_slot)) 337#define cpsw_cpdma_read_bd_flags(sc, slot) \ |
339 bus_read_2(sc->res[0], slot->bd_offset + 14) | 338 bus_read_2(sc->mem_res, slot->bd_offset + 14) |
340#define cpsw_write_hdp_slot(sc, queue, slot) \ 341 cpsw_write_4(sc, (queue)->hdp_offset, cpsw_cpdma_bd_paddr(sc, slot)) 342#define CP_OFFSET (CPSW_CPDMA_TX_CP(0) - CPSW_CPDMA_TX_HDP(0)) 343#define cpsw_read_cp(sc, queue) \ 344 cpsw_read_4(sc, (queue)->hdp_offset + CP_OFFSET) 345#define cpsw_write_cp(sc, queue, val) \ 346 cpsw_write_4(sc, (queue)->hdp_offset + CP_OFFSET, (val)) 347#define cpsw_write_cp_slot(sc, queue, slot) \ --- 196 unchanged lines hidden (view full) --- 544 545static int 546cpsw_attach(device_t dev) 547{ 548 bus_dma_segment_t segs[1]; 549 struct cpsw_softc *sc = device_get_softc(dev); 550 struct mii_softc *miisc; 551 struct ifnet *ifp; | 339#define cpsw_write_hdp_slot(sc, queue, slot) \ 340 cpsw_write_4(sc, (queue)->hdp_offset, cpsw_cpdma_bd_paddr(sc, slot)) 341#define CP_OFFSET (CPSW_CPDMA_TX_CP(0) - CPSW_CPDMA_TX_HDP(0)) 342#define cpsw_read_cp(sc, queue) \ 343 cpsw_read_4(sc, (queue)->hdp_offset + CP_OFFSET) 344#define cpsw_write_cp(sc, queue, val) \ 345 cpsw_write_4(sc, (queue)->hdp_offset + CP_OFFSET, (val)) 346#define cpsw_write_cp_slot(sc, queue, slot) \ --- 196 unchanged lines hidden (view full) --- 543 544static int 545cpsw_attach(device_t dev) 546{ 547 bus_dma_segment_t segs[1]; 548 struct cpsw_softc *sc = device_get_softc(dev); 549 struct mii_softc *miisc; 550 struct ifnet *ifp; |
552 void *phy_sc; 553 int error, phy, nsegs; | 551 int phy, nsegs, error; |
554 uint32_t reg; | 552 uint32_t reg; |
553 pcell_t phy_id[3]; 554 u_long mem_base, mem_size; 555 phandle_t child; 556 int len; |
|
555 556 CPSW_DEBUGF(("")); 557 558 getbinuptime(&sc->attach_uptime); 559 sc->dev = dev; 560 sc->node = ofw_bus_get_node(dev); 561 | 557 558 CPSW_DEBUGF(("")); 559 560 getbinuptime(&sc->attach_uptime); 561 sc->dev = dev; 562 sc->node = ofw_bus_get_node(dev); 563 |
562 /* Get phy address from fdt */ 563 if (fdt_get_phyaddr(sc->node, sc->dev, &phy, &phy_sc) != 0) { | 564 /* TODO: handle multiple slaves */ 565 phy = -1; 566 567 /* Find any slave with phy_id */ 568 for (child = OF_child(sc->node); child != 0; child = OF_peer(child)) { 569 len = OF_getproplen(child, "phy_id"); 570 if (len <= 0) 571 continue; 572 573 /* Get phy address from fdt */ 574 if (OF_getencprop(child, "phy_id", phy_id, len) <= 0) 575 continue; 576 577 phy = phy_id[1]; 578 /* TODO: get memory window for MDIO */ 579 580 break; 581 } 582 583 if (phy == -1) { |
564 device_printf(dev, "failed to get PHY address from FDT\n"); 565 return (ENXIO); 566 } | 584 device_printf(dev, "failed to get PHY address from FDT\n"); 585 return (ENXIO); 586 } |
587 588 mem_base = 0; 589 mem_size = 0; 590 591 if (fdt_regsize(sc->node, &mem_base, &mem_size) != 0) { 592 device_printf(sc->dev, "no regs property in cpsw node\n"); 593 return (ENXIO); 594 } 595 |
|
567 /* Initialize mutexes */ 568 mtx_init(&sc->tx.lock, device_get_nameunit(dev), 569 "cpsw TX lock", MTX_DEF); 570 mtx_init(&sc->rx.lock, device_get_nameunit(dev), 571 "cpsw RX lock", MTX_DEF); 572 | 596 /* Initialize mutexes */ 597 mtx_init(&sc->tx.lock, device_get_nameunit(dev), 598 "cpsw TX lock", MTX_DEF); 599 mtx_init(&sc->rx.lock, device_get_nameunit(dev), 600 "cpsw RX lock", MTX_DEF); 601 |
573 /* Allocate IO and IRQ resources */ 574 error = bus_alloc_resources(dev, res_spec, sc->res); | 602 /* Allocate IRQ resources */ 603 error = bus_alloc_resources(dev, irq_res_spec, sc->irq_res); |
575 if (error) { | 604 if (error) { |
576 device_printf(dev, "could not allocate resources\n"); | 605 device_printf(dev, "could not allocate IRQ resources\n"); |
577 cpsw_detach(dev); 578 return (ENXIO); 579 } 580 | 606 cpsw_detach(dev); 607 return (ENXIO); 608 } 609 |
610 sc->mem_rid = 0; 611 sc->mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, 612 &sc->mem_rid, mem_base, mem_base + CPSW_MEMWINDOW_SIZE -1, 613 CPSW_MEMWINDOW_SIZE, RF_ACTIVE); 614 if (sc->mem_res == NULL) { 615 device_printf(sc->dev, "failed to allocate memory resource\n"); 616 cpsw_detach(dev); 617 return (ENXIO); 618 } 619 |
|
581 reg = cpsw_read_4(sc, CPSW_SS_IDVER); 582 device_printf(dev, "CPSW SS Version %d.%d (%d)\n", (reg >> 8 & 0x7), 583 reg & 0xFF, (reg >> 11) & 0x1F); 584 585 cpsw_add_sysctls(sc); 586 587 /* Allocate a busdma tag and DMA safe memory for mbufs. */ 588 error = bus_dma_tag_create( --- 96 unchanged lines hidden (view full) --- 685 686 /* Tell the MAC where to find the PHY so autoneg works */ 687 miisc = LIST_FIRST(&sc->mii->mii_phys); 688 689 /* Select PHY and enable interrupts */ 690 cpsw_write_4(sc, MDIOUSERPHYSEL0, 1 << 6 | (miisc->mii_phy & 0x1F)); 691 692 /* Note: We don't use sc->res[3] (TX interrupt) */ | 620 reg = cpsw_read_4(sc, CPSW_SS_IDVER); 621 device_printf(dev, "CPSW SS Version %d.%d (%d)\n", (reg >> 8 & 0x7), 622 reg & 0xFF, (reg >> 11) & 0x1F); 623 624 cpsw_add_sysctls(sc); 625 626 /* Allocate a busdma tag and DMA safe memory for mbufs. */ 627 error = bus_dma_tag_create( --- 96 unchanged lines hidden (view full) --- 724 725 /* Tell the MAC where to find the PHY so autoneg works */ 726 miisc = LIST_FIRST(&sc->mii->mii_phys); 727 728 /* Select PHY and enable interrupts */ 729 cpsw_write_4(sc, MDIOUSERPHYSEL0, 1 << 6 | (miisc->mii_phy & 0x1F)); 730 731 /* Note: We don't use sc->res[3] (TX interrupt) */ |
693 if (cpsw_attach_interrupt(sc, sc->res[1], | 732 if (cpsw_attach_interrupt(sc, sc->irq_res[0], |
694 cpsw_intr_rx_thresh, "CPSW RX threshold interrupt") || | 733 cpsw_intr_rx_thresh, "CPSW RX threshold interrupt") || |
695 cpsw_attach_interrupt(sc, sc->res[2], | 734 cpsw_attach_interrupt(sc, sc->irq_res[1], |
696 cpsw_intr_rx, "CPSW RX interrupt") || | 735 cpsw_intr_rx, "CPSW RX interrupt") || |
697 cpsw_attach_interrupt(sc, sc->res[4], | 736 cpsw_attach_interrupt(sc, sc->irq_res[3], |
698 cpsw_intr_misc, "CPSW misc interrupt")) { 699 cpsw_detach(dev); 700 return (ENXIO); 701 } 702 703 ether_ifattach(ifp, sc->mac_addr); 704 callout_init(&sc->watchdog.callout, 0); 705 --- 50 unchanged lines hidden (view full) --- 756 if (sc->null_mbuf) 757 m_freem(sc->null_mbuf); 758 759 /* Free DMA tag */ 760 error = bus_dma_tag_destroy(sc->mbuf_dtag); 761 KASSERT(error == 0, ("Unable to destroy DMA tag")); 762 763 /* Free IO memory handler */ | 737 cpsw_intr_misc, "CPSW misc interrupt")) { 738 cpsw_detach(dev); 739 return (ENXIO); 740 } 741 742 ether_ifattach(ifp, sc->mac_addr); 743 callout_init(&sc->watchdog.callout, 0); 744 --- 50 unchanged lines hidden (view full) --- 795 if (sc->null_mbuf) 796 m_freem(sc->null_mbuf); 797 798 /* Free DMA tag */ 799 error = bus_dma_tag_destroy(sc->mbuf_dtag); 800 KASSERT(error == 0, ("Unable to destroy DMA tag")); 801 802 /* Free IO memory handler */ |
764 bus_release_resources(dev, res_spec, sc->res); | 803 bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem_res); 804 bus_release_resources(dev, irq_res_spec, sc->irq_res); |
765 766 if (sc->ifp != NULL) 767 if_free(sc->ifp); 768 769 /* Destroy mutexes */ 770 mtx_destroy(&sc->rx.lock); 771 mtx_destroy(&sc->tx.lock); 772 --- 1425 unchanged lines hidden --- | 805 806 if (sc->ifp != NULL) 807 if_free(sc->ifp); 808 809 /* Destroy mutexes */ 810 mtx_destroy(&sc->rx.lock); 811 mtx_destroy(&sc->tx.lock); 812 --- 1425 unchanged lines hidden --- |