imx6: drop support for kernel 3.18

Signed-off-by: Luka Perkov <luka@openwrt.org>

SVN-Revision: 47509
v19.07.3_mercusys_ac12_duma
Luka Perkov 9 years ago
parent 03401fed5e
commit 5f3d29f4e6

@ -1,369 +0,0 @@
CONFIG_AHCI_IMX=y
CONFIG_ALIGNMENT_TRAP=y
CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
CONFIG_ARCH_HAS_RESET_CONTROLLER=y
CONFIG_ARCH_HAS_SG_CHAIN=y
CONFIG_ARCH_HAS_TICK_BROADCAST=y
CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
CONFIG_ARCH_MULTIPLATFORM=y
# CONFIG_ARCH_MULTI_CPU_AUTO is not set
CONFIG_ARCH_MULTI_V6_V7=y
CONFIG_ARCH_MULTI_V7=y
CONFIG_ARCH_MXC=y
CONFIG_ARCH_NR_GPIO=0
CONFIG_ARCH_REQUIRE_GPIOLIB=y
# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
CONFIG_ARCH_SUPPORTS_UPROBES=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARCH_USE_BUILTIN_BSWAP=y
CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
CONFIG_ARM=y
# CONFIG_ARM_CPU_SUSPEND is not set
CONFIG_ARM_ERRATA_754322=y
CONFIG_ARM_ERRATA_764369=y
CONFIG_ARM_ERRATA_775420=y
CONFIG_ARM_GIC=y
CONFIG_ARM_HAS_SG_CHAIN=y
CONFIG_ARM_IMX6Q_CPUFREQ=y
# CONFIG_ARM_KIRKWOOD_CPUFREQ is not set
CONFIG_ARM_L1_CACHE_SHIFT=6
CONFIG_ARM_L1_CACHE_SHIFT_6=y
# CONFIG_ARM_LPAE is not set
CONFIG_ARM_PATCH_PHYS_VIRT=y
CONFIG_ARM_THUMB=y
# CONFIG_ARM_THUMBEE is not set
CONFIG_ARM_VIRT_EXT=y
CONFIG_ATA=y
CONFIG_ATAGS=y
# CONFIG_ATA_SFF is not set
CONFIG_AUTO_ZRELADDR=y
# CONFIG_CACHE_L2X0 is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_CLKDEV_LOOKUP=y
CONFIG_CLKSRC_MMIO=y
CONFIG_CLKSRC_OF=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_COMMON_CLK=y
CONFIG_CPUFREQ_DT=y
CONFIG_CPU_32v6K=y
CONFIG_CPU_32v7=y
CONFIG_CPU_ABRT_EV7=y
# CONFIG_CPU_BPREDICT_DISABLE is not set
CONFIG_CPU_CACHE_V7=y
CONFIG_CPU_CACHE_VIPT=y
CONFIG_CPU_COPY_V6=y
CONFIG_CPU_CP15=y
CONFIG_CPU_CP15_MMU=y
CONFIG_CPU_FREQ=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
CONFIG_CPU_FREQ_GOV_COMMON=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_STAT=y
CONFIG_CPU_FREQ_STAT_DETAILS=y
CONFIG_CPU_HAS_ASID=y
# CONFIG_CPU_ICACHE_DISABLE is not set
CONFIG_CPU_PABRT_V7=y
CONFIG_CPU_RMAP=y
CONFIG_CPU_TLB_V7=y
CONFIG_CPU_V7=y
CONFIG_CRC16=y
CONFIG_CRYPTO_CRC32C=y
CONFIG_CRYPTO_DEFLATE=y
CONFIG_CRYPTO_HASH=y
CONFIG_CRYPTO_HASH2=y
CONFIG_CRYPTO_LZO=y
CONFIG_CRYPTO_SHA1_ARM_NEON=y
CONFIG_CRYPTO_SHA512_ARM_NEON=y
CONFIG_CRYPTO_XZ=y
CONFIG_DCACHE_WORD_ACCESS=y
CONFIG_DEBUG_IMX_UART_PORT=1
CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
# CONFIG_DEBUG_UART_8250 is not set
# CONFIG_DEBUG_UART_PL01X is not set
# CONFIG_DEBUG_USER is not set
CONFIG_DECOMPRESS_BZIP2=y
CONFIG_DECOMPRESS_GZIP=y
CONFIG_DECOMPRESS_LZO=y
CONFIG_DECOMPRESS_XZ=y
CONFIG_DMADEVICES=y
CONFIG_DMA_ENGINE=y
CONFIG_DMA_OF=y
CONFIG_DTC=y
# CONFIG_DW_DMAC_CORE is not set
# CONFIG_DW_DMAC_PCI is not set
# CONFIG_EMAC_ROCKCHIP is not set
CONFIG_EXT4_FS=y
CONFIG_EXT4_FS_POSIX_ACL=y
CONFIG_EXT4_FS_SECURITY=y
CONFIG_FEC=y
CONFIG_FRAME_POINTER=y
CONFIG_FS_MBCACHE=y
CONFIG_FS_POSIX_ACL=y
CONFIG_GENERIC_ALLOCATOR=y
CONFIG_GENERIC_BUG=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_GENERIC_IDLE_POLL_SETUP=y
CONFIG_GENERIC_IO=y
CONFIG_GENERIC_IRQ_CHIP=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_SCHED_CLOCK=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GENERIC_STRNCPY_FROM_USER=y
CONFIG_GENERIC_STRNLEN_USER=y
CONFIG_GLOB=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_DEVRES=y
CONFIG_GPIO_GENERIC=y
CONFIG_GPIO_MXC=y
# CONFIG_GPIO_SYSCON is not set
CONFIG_GPIO_SYSFS=y
CONFIG_HANDLE_DOMAIN_IRQ=y
CONFIG_HARDIRQS_SW_RESEND=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT_MAP=y
# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
CONFIG_HAVE_ARCH_AUDITSYSCALL=y
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_HAVE_ARCH_PFN_VALID=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
CONFIG_HAVE_ARM_SCU=y
CONFIG_HAVE_ARM_TWD=y
# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
CONFIG_HAVE_BPF_JIT=y
CONFIG_HAVE_CC_STACKPROTECTOR=y
CONFIG_HAVE_CLK=y
CONFIG_HAVE_CLK_PREPARE=y
CONFIG_HAVE_CONTEXT_TRACKING=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_HAVE_DMA_API_DEBUG=y
CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_DMA_CONTIGUOUS=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_HAVE_HW_BREAKPOINT=y
CONFIG_HAVE_IDE=y
CONFIG_HAVE_IMX_ANATOP=y
CONFIG_HAVE_IMX_GPC=y
CONFIG_HAVE_IMX_MMDC=y
CONFIG_HAVE_IMX_SRC=y
CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
CONFIG_HAVE_KERNEL_GZIP=y
CONFIG_HAVE_KERNEL_LZ4=y
CONFIG_HAVE_KERNEL_LZMA=y
CONFIG_HAVE_KERNEL_LZO=y
CONFIG_HAVE_KERNEL_XZ=y
CONFIG_HAVE_MEMBLOCK=y
CONFIG_HAVE_NET_DSA=y
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_HAVE_PERF_REGS=y
CONFIG_HAVE_PERF_USER_STACK_DUMP=y
CONFIG_HAVE_PROC_CPU=y
CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
CONFIG_HAVE_SMP=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HAVE_UID16=y
CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
CONFIG_HZ_FIXED=0
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_IMX=y
CONFIG_IMX2_WDT=y
CONFIG_IMX_DMA=y
CONFIG_IMX_SDMA=y
# CONFIG_IMX_WEIM is not set
CONFIG_INITRAMFS_SOURCE=""
CONFIG_IOMMU_HELPER=y
CONFIG_IRQCHIP=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_IRQ_WORK=y
CONFIG_JBD=y
CONFIG_JBD2=y
# CONFIG_LEDS_REGULATOR is not set
# CONFIG_LEDS_SYSCON is not set
CONFIG_LIBFDT=y
CONFIG_LZO_COMPRESS=y
CONFIG_LZO_DECOMPRESS=y
CONFIG_MDIO_BOARDINFO=y
CONFIG_MFD_SYSCON=y
CONFIG_MIGHT_HAVE_CACHE_L2X0=y
CONFIG_MIGHT_HAVE_PCI=y
CONFIG_MMC=y
CONFIG_MMC_BLOCK=y
# CONFIG_MMC_MXC is not set
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_ESDHC_IMX=y
CONFIG_MMC_SDHCI_IO_ACCESSORS=y
# CONFIG_MMC_SDHCI_PCI is not set
CONFIG_MMC_SDHCI_PLTFM=y
# CONFIG_MMC_TIFM_SD is not set
CONFIG_MODULES_USE_ELF_REL=y
CONFIG_MTD_M25P80=y
CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_ECC=y
CONFIG_MTD_NAND_GPMI_NAND=y
# CONFIG_MTD_PHYSMAP_OF is not set
CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_BEB_LIMIT=20
# CONFIG_MTD_UBI_BLOCK is not set
# CONFIG_MTD_UBI_FASTMAP is not set
# CONFIG_MTD_UBI_GLUEBI is not set
CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MULTI_IRQ_HANDLER=y
CONFIG_MUTEX_SPIN_ON_OWNER=y
# CONFIG_MX3_IPU is not set
# CONFIG_MXC_DEBUG_BOARD is not set
CONFIG_MXS_DMA=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEON=y
CONFIG_NET_FLOW_LIMIT=y
CONFIG_NET_PTP_CLASSIFY=y
CONFIG_NLS=y
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NO_BOOTMEM=y
CONFIG_NO_HZ_COMMON=y
CONFIG_NO_HZ_IDLE=y
CONFIG_NR_CPUS=4
CONFIG_OF=y
CONFIG_OF_ADDRESS=y
CONFIG_OF_ADDRESS_PCI=y
CONFIG_OF_EARLY_FLATTREE=y
CONFIG_OF_FLATTREE=y
CONFIG_OF_GPIO=y
CONFIG_OF_IRQ=y
CONFIG_OF_MDIO=y
CONFIG_OF_MTD=y
CONFIG_OF_NET=y
CONFIG_OF_PCI=y
CONFIG_OF_PCI_IRQ=y
CONFIG_OF_RESERVED_MEM=y
CONFIG_OLD_SIGACTION=y
CONFIG_OLD_SIGSUSPEND3=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_PAGE_OFFSET=0x80000000
CONFIG_PCI=y
CONFIG_PCIEAER=y
CONFIG_PCIEPORTBUS=y
CONFIG_PCIE_DW=y
CONFIG_PCI_DOMAINS=y
CONFIG_PCI_IMX6=y
CONFIG_PERF_EVENTS=y
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PHYLIB=y
CONFIG_PINCTRL=y
CONFIG_PINCTRL_IMX=y
CONFIG_PINCTRL_IMX6Q=y
CONFIG_PINCTRL_IMX6SL=y
# CONFIG_PINCTRL_SINGLE is not set
CONFIG_PM_OPP=y
CONFIG_PPS=y
# CONFIG_PREEMPT_RCU is not set
CONFIG_PTP_1588_CLOCK=y
CONFIG_RAS=y
CONFIG_RATIONAL=y
CONFIG_RCU_STALL_COMMON=y
CONFIG_RD_BZIP2=y
CONFIG_RD_GZIP=y
CONFIG_RD_LZO=y
CONFIG_RD_XZ=y
CONFIG_REGMAP=y
CONFIG_REGMAP_I2C=y
CONFIG_REGMAP_MMIO=y
CONFIG_REGMAP_SPI=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_ANATOP=y
# CONFIG_REGULATOR_DEBUG is not set
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_PFUZE100=y
# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
CONFIG_RFS_ACCEL=y
CONFIG_RPS=y
CONFIG_RTC_CLASS=y
# CONFIG_RTC_DRV_IMXDI is not set
# CONFIG_RTC_DRV_MXC is not set
CONFIG_RWSEM_SPIN_ON_OWNER=y
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
CONFIG_SATA_AHCI_PLATFORM=y
CONFIG_SCHED_HRTICK=y
CONFIG_SCSI=y
CONFIG_SERIAL_IMX=y
CONFIG_SERIAL_IMX_CONSOLE=y
CONFIG_SMP=y
CONFIG_SMP_ON_UP=y
CONFIG_SOC_BUS=y
# CONFIG_SOC_IMX50 is not set
# CONFIG_SOC_IMX51 is not set
# CONFIG_SOC_IMX53 is not set
CONFIG_SOC_IMX6=y
CONFIG_SOC_IMX6Q=y
CONFIG_SOC_IMX6SL=y
# CONFIG_SOC_IMX6SX is not set
# CONFIG_SOC_VF610 is not set
CONFIG_SPARSE_IRQ=y
CONFIG_SPI=y
CONFIG_SPI_BITBANG=y
CONFIG_SPI_IMX=y
CONFIG_SPI_MASTER=y
CONFIG_SRAM=y
CONFIG_STMP_DEVICE=y
CONFIG_STOP_MACHINE=y
CONFIG_SWIOTLB=y
CONFIG_SWP_EMULATE=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
# CONFIG_THUMB2_KERNEL is not set
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_TREE_RCU=y
CONFIG_UBIFS_FS=y
CONFIG_UBIFS_FS_ADVANCED_COMPR=y
CONFIG_UBIFS_FS_LZO=y
CONFIG_UBIFS_FS_XZ=y
CONFIG_UBIFS_FS_ZLIB=y
CONFIG_UID16=y
CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
# CONFIG_USB_MXS_PHY is not set
CONFIG_USB_SUPPORT=y
CONFIG_USE_OF=y
CONFIG_VECTORS_BASE=0xffff0000
CONFIG_VFP=y
CONFIG_VFPv3=y
CONFIG_VMSPLIT_2G=y
# CONFIG_VMSPLIT_3G is not set
CONFIG_WATCHDOG_CORE=y
# CONFIG_XEN is not set
CONFIG_XPS=y
CONFIG_XZ_DEC_ARM=y
CONFIG_XZ_DEC_BCJ=y
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZLIB_DEFLATE=y
CONFIG_ZLIB_INFLATE=y
CONFIG_ZONE_DMA_FLAG=0

@ -1,11 +0,0 @@
--- a/arch/arm/boot/dts/imx6dl-wandboard.dts
+++ b/arch/arm/boot/dts/imx6dl-wandboard.dts
@@ -19,4 +19,8 @@
memory {
reg = <0x10000000 0x40000000>;
};
+
+ chosen {
+ bootargs = "console=ttymxc0,115200";
+ };
};

@ -1,33 +0,0 @@
commit e84634dc6c7f3f6af9b8ef1fb36f0d85c476ab95
Author: Tim Harvey <tharvey@gateworks.com>
Date: Thu Feb 27 01:02:23 2014 -0800
PCI: designware: add ability for custom swizzle
Add the ability for a platform driver to provide a platform-specific
swizzle function.
Signed-off-by: Tim Harvey <tharvey@gateworks.com>
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -492,6 +492,9 @@ int dw_pcie_host_init(struct pcie_port *
if (pp->ops->host_init)
pp->ops->host_init(pp);
+ if (pp->swizzle)
+ dw_pci.swizzle = pp->swizzle;
+
dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
/* program correct class for RC */
--- a/drivers/pci/host/pcie-designware.h
+++ b/drivers/pci/host/pcie-designware.h
@@ -53,6 +53,7 @@ struct pcie_port {
struct irq_domain *irq_domain;
unsigned long msi_data;
DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS);
+ u8 (*swizzle)(struct pci_dev *, u8 *);
};
struct pcie_host_ops {

@ -1,81 +0,0 @@
commit 2c0d0491438433a1f327f2e754c7b6b55fec51c4
Author: Tim Harvey <tharvey@gateworks.com>
Date: Thu Feb 27 00:59:53 2014 -0800
PCI: imx6: ventana: fixup for IRQ mismapping
The TI XIO2001 PCIe-to-PCI bridge used on several Ventana expansion boards
has its slot-to-bridge IRQ mapping reversed from the PCI specification:
INTA->INTD
INTB->INTC
INTC->INTB
INTD->INTA
Implement a custom swizzle function that does a fixup on the interrupt for
devices on a TI XIO2001 bridge.
Signed-off-by: Tim Harvey <tharvey@gateworks.com>
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -553,6 +553,39 @@ static int __init imx6_add_pcie_port(str
return 0;
}
+/* TI XIO2001 PCIe-to-PCI bridge on GW16082 exp card has IRQs reversed */
+u8 ventana_swizzle(struct pci_dev *dev, u8 *pin)
+{
+ u8 i = 0;
+ struct pci_dev *pdev = dev;
+
+ /* count number of TI XIO2001 bridges on bus */
+ while (!pci_is_root_bus(pdev->bus)) {
+ if (pdev->bus && pdev->bus->self &&
+ (pdev->bus->self->vendor == PCI_VENDOR_ID_TI) &&
+ (pdev->bus->self->device == PCI_DEVICE_ID_TI_XIO2001)) {
+ i++;
+ }
+ pdev = pdev->bus->self;
+ }
+ while (!pci_is_root_bus(dev->bus)) {
+ /* if we are directly downstream from 1st TI XIO2001 bridge */
+ if (dev->bus && dev->bus->self &&
+ (dev->bus->self->vendor == PCI_VENDOR_ID_TI) &&
+ (dev->bus->self->device == PCI_DEVICE_ID_TI_XIO2001)) {
+ if (--i == 0) {
+ /* swap IRQs and swizzle backwards */
+ *pin = (15 - PCI_SLOT(dev->devfn)) + 1;
+ dev = dev->bus->self;
+ continue;
+ }
+ }
+ *pin = pci_swizzle_interrupt_pin(dev, *pin);
+ dev = dev->bus->self;
+ }
+ return PCI_SLOT(dev->devfn);
+}
+
static int __init imx6_pcie_probe(struct platform_device *pdev)
{
struct imx6_pcie *imx6_pcie;
@@ -618,6 +651,9 @@ static int __init imx6_pcie_probe(struct
return PTR_ERR(imx6_pcie->iomuxc_gpr);
}
+ if (of_machine_is_compatible("gw,ventana"))
+ pp->swizzle = ventana_swizzle;
+
ret = imx6_add_pcie_port(pp, pdev);
if (ret < 0)
return ret;
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -827,6 +827,7 @@
#define PCI_DEVICE_ID_TI_XX12 0x8039
#define PCI_DEVICE_ID_TI_XX12_FM 0x803b
#define PCI_DEVICE_ID_TI_XIO2000A 0x8231
+#define PCI_DEVICE_ID_TI_XIO2001 0x8240
#define PCI_DEVICE_ID_TI_1130 0xac12
#define PCI_DEVICE_ID_TI_1031 0xac13
#define PCI_DEVICE_ID_TI_1131 0xac15

@ -1,129 +0,0 @@
Author: Tim Harvey <tharvey@gateworks.com>
Date: Thu May 15 00:12:26 2014 -0700
net: igb: add i210/i211 support for phy read/write
The i210/i211 uses the MDICNFG register for the phy address instead of the
MDIC register.
Signed-off-by: Tim Harvey <tharvey@gateworks.com>
--- a/drivers/net/ethernet/intel/igb/e1000_phy.c
+++ b/drivers/net/ethernet/intel/igb/e1000_phy.c
@@ -135,7 +135,7 @@ out:
s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
{
struct e1000_phy_info *phy = &hw->phy;
- u32 i, mdic = 0;
+ u32 i, mdicnfg, mdic = 0;
s32 ret_val = 0;
if (offset > MAX_PHY_REG_ADDRESS) {
@@ -148,11 +148,25 @@ s32 igb_read_phy_reg_mdic(struct e1000_h
* Control register. The MAC will take care of interfacing with the
* PHY to retrieve the desired data.
*/
- mdic = ((offset << E1000_MDIC_REG_SHIFT) |
- (phy->addr << E1000_MDIC_PHY_SHIFT) |
- (E1000_MDIC_OP_READ));
+ switch (hw->mac.type) {
+ case e1000_i210:
+ case e1000_i211:
+ mdicnfg = rd32(E1000_MDICNFG);
+ mdicnfg &= ~(E1000_MDICNFG_PHY_MASK);
+ mdicnfg |= (phy->addr << E1000_MDICNFG_PHY_SHIFT);
+ wr32(E1000_MDICNFG, mdicnfg);
+ mdic = ((offset << E1000_MDIC_REG_SHIFT) |
+ (E1000_MDIC_OP_READ));
+ break;
+ default:
+ mdic = ((offset << E1000_MDIC_REG_SHIFT) |
+ (phy->addr << E1000_MDIC_PHY_SHIFT) |
+ (E1000_MDIC_OP_READ));
+ break;
+ }
wr32(E1000_MDIC, mdic);
+ wrfl();
/* Poll the ready bit to see if the MDI read completed
* Increasing the time out as testing showed failures with
@@ -177,6 +191,18 @@ s32 igb_read_phy_reg_mdic(struct e1000_h
*data = (u16) mdic;
out:
+ switch (hw->mac.type) {
+ /* restore MDICNFG to have phy's addr */
+ case e1000_i210:
+ case e1000_i211:
+ mdicnfg = rd32(E1000_MDICNFG);
+ mdicnfg &= ~(E1000_MDICNFG_PHY_MASK);
+ mdicnfg |= (hw->phy.addr << E1000_MDICNFG_PHY_SHIFT);
+ wr32(E1000_MDICNFG, mdicnfg);
+ break;
+ default:
+ break;
+ }
return ret_val;
}
@@ -191,7 +217,7 @@ out:
s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
{
struct e1000_phy_info *phy = &hw->phy;
- u32 i, mdic = 0;
+ u32 i, mdicnfg, mdic = 0;
s32 ret_val = 0;
if (offset > MAX_PHY_REG_ADDRESS) {
@@ -204,12 +230,27 @@ s32 igb_write_phy_reg_mdic(struct e1000_
* Control register. The MAC will take care of interfacing with the
* PHY to retrieve the desired data.
*/
- mdic = (((u32)data) |
- (offset << E1000_MDIC_REG_SHIFT) |
- (phy->addr << E1000_MDIC_PHY_SHIFT) |
- (E1000_MDIC_OP_WRITE));
+ switch (hw->mac.type) {
+ case e1000_i210:
+ case e1000_i211:
+ mdicnfg = rd32(E1000_MDICNFG);
+ mdicnfg &= ~(E1000_MDICNFG_PHY_MASK);
+ mdicnfg |= (phy->addr << E1000_MDICNFG_PHY_SHIFT);
+ wr32(E1000_MDICNFG, mdicnfg);
+ mdic = (((u32)data) |
+ (offset << E1000_MDIC_REG_SHIFT) |
+ (E1000_MDIC_OP_WRITE));
+ break;
+ default:
+ mdic = (((u32)data) |
+ (offset << E1000_MDIC_REG_SHIFT) |
+ (phy->addr << E1000_MDIC_PHY_SHIFT) |
+ (E1000_MDIC_OP_WRITE));
+ break;
+ }
wr32(E1000_MDIC, mdic);
+ wrfl();
/* Poll the ready bit to see if the MDI read completed
* Increasing the time out as testing showed failures with
@@ -233,6 +274,18 @@ s32 igb_write_phy_reg_mdic(struct e1000_
}
out:
+ switch (hw->mac.type) {
+ /* restore MDICNFG to have phy's addr */
+ case e1000_i210:
+ case e1000_i211:
+ mdicnfg = rd32(E1000_MDICNFG);
+ mdicnfg &= ~(E1000_MDICNFG_PHY_MASK);
+ mdicnfg |= (hw->phy.addr << E1000_MDICNFG_PHY_SHIFT);
+ wr32(E1000_MDICNFG, mdicnfg);
+ break;
+ default:
+ break;
+ }
return ret_val;
}

@ -1,260 +0,0 @@
From 16df7dc5901c1cb2a40f6adbd0d9423768ed8210 Mon Sep 17 00:00:00 2001
From: Tim Harvey <tharvey@gateworks.com>
Date: Thu, 15 May 2014 00:29:18 -0700
Subject: [PATCH] net: igb: add phy read/write functions that accept phy addr
Add igb_write_reg_gs40g/igb_read_reg_gs40g that can be passed a phy address.
The existing igb_write_phy_reg_gs40g/igb_read_phy_reg_gs40g become wrappers
to this function.
Signed-off-by: Tim Harvey <tharvey@gateworks.com>
---
drivers/net/ethernet/intel/igb/e1000_82575.c | 4 +-
drivers/net/ethernet/intel/igb/e1000_phy.c | 74 +++++++++++++++++++---------
drivers/net/ethernet/intel/igb/e1000_phy.h | 6 ++-
3 files changed, 58 insertions(+), 26 deletions(-)
--- a/drivers/net/ethernet/intel/igb/e1000_82575.c
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.c
@@ -2129,7 +2129,7 @@ static s32 igb_read_phy_reg_82580(struct
if (ret_val)
goto out;
- ret_val = igb_read_phy_reg_mdic(hw, offset, data);
+ ret_val = igb_read_phy_reg_mdic(hw, hw->phy.addr, offset, data);
hw->phy.ops.release(hw);
@@ -2154,7 +2154,7 @@ static s32 igb_write_phy_reg_82580(struc
if (ret_val)
goto out;
- ret_val = igb_write_phy_reg_mdic(hw, offset, data);
+ ret_val = igb_write_phy_reg_mdic(hw, hw->phy.addr, offset, data);
hw->phy.ops.release(hw);
--- a/drivers/net/ethernet/intel/igb/e1000_phy.c
+++ b/drivers/net/ethernet/intel/igb/e1000_phy.c
@@ -132,9 +132,8 @@ out:
* Reads the MDI control regsiter in the PHY at offset and stores the
* information read to data.
**/
-s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
+s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u8 addr, u32 offset, u16 *data)
{
- struct e1000_phy_info *phy = &hw->phy;
u32 i, mdicnfg, mdic = 0;
s32 ret_val = 0;
@@ -153,14 +152,14 @@ s32 igb_read_phy_reg_mdic(struct e1000_h
case e1000_i211:
mdicnfg = rd32(E1000_MDICNFG);
mdicnfg &= ~(E1000_MDICNFG_PHY_MASK);
- mdicnfg |= (phy->addr << E1000_MDICNFG_PHY_SHIFT);
+ mdicnfg |= (addr << E1000_MDICNFG_PHY_SHIFT);
wr32(E1000_MDICNFG, mdicnfg);
mdic = ((offset << E1000_MDIC_REG_SHIFT) |
(E1000_MDIC_OP_READ));
break;
default:
mdic = ((offset << E1000_MDIC_REG_SHIFT) |
- (phy->addr << E1000_MDIC_PHY_SHIFT) |
+ (addr << E1000_MDIC_PHY_SHIFT) |
(E1000_MDIC_OP_READ));
break;
}
@@ -214,9 +213,8 @@ out:
*
* Writes data to MDI control register in the PHY at offset.
**/
-s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
+s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u8 addr, u32 offset, u16 data)
{
- struct e1000_phy_info *phy = &hw->phy;
u32 i, mdicnfg, mdic = 0;
s32 ret_val = 0;
@@ -235,7 +233,7 @@ s32 igb_write_phy_reg_mdic(struct e1000_
case e1000_i211:
mdicnfg = rd32(E1000_MDICNFG);
mdicnfg &= ~(E1000_MDICNFG_PHY_MASK);
- mdicnfg |= (phy->addr << E1000_MDICNFG_PHY_SHIFT);
+ mdicnfg |= (addr << E1000_MDICNFG_PHY_SHIFT);
wr32(E1000_MDICNFG, mdicnfg);
mdic = (((u32)data) |
(offset << E1000_MDIC_REG_SHIFT) |
@@ -244,7 +242,7 @@ s32 igb_write_phy_reg_mdic(struct e1000_
default:
mdic = (((u32)data) |
(offset << E1000_MDIC_REG_SHIFT) |
- (phy->addr << E1000_MDIC_PHY_SHIFT) |
+ (addr << E1000_MDIC_PHY_SHIFT) |
(E1000_MDIC_OP_WRITE));
break;
}
@@ -464,7 +462,7 @@ s32 igb_read_phy_reg_igp(struct e1000_hw
goto out;
if (offset > MAX_PHY_MULTI_PAGE_REG) {
- ret_val = igb_write_phy_reg_mdic(hw,
+ ret_val = igb_write_phy_reg_mdic(hw, hw->phy.addr,
IGP01E1000_PHY_PAGE_SELECT,
(u16)offset);
if (ret_val) {
@@ -473,8 +471,8 @@ s32 igb_read_phy_reg_igp(struct e1000_hw
}
}
- ret_val = igb_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
- data);
+ ret_val = igb_read_phy_reg_mdic(hw, hw->phy.addr,
+ MAX_PHY_REG_ADDRESS & offset, data);
hw->phy.ops.release(hw);
@@ -503,7 +501,7 @@ s32 igb_write_phy_reg_igp(struct e1000_h
goto out;
if (offset > MAX_PHY_MULTI_PAGE_REG) {
- ret_val = igb_write_phy_reg_mdic(hw,
+ ret_val = igb_write_phy_reg_mdic(hw, hw->phy.addr,
IGP01E1000_PHY_PAGE_SELECT,
(u16)offset);
if (ret_val) {
@@ -512,8 +510,8 @@ s32 igb_write_phy_reg_igp(struct e1000_h
}
}
- ret_val = igb_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
- data);
+ ret_val = igb_write_phy_reg_mdic(hw, hw->phy.addr,
+ MAX_PHY_REG_ADDRESS & offset, data);
hw->phy.ops.release(hw);
@@ -2464,8 +2462,9 @@ out:
}
/**
- * igb_write_phy_reg_gs40g - Write GS40G PHY register
+ * igb_write_reg_gs40g - Write GS40G PHY register
* @hw: pointer to the HW structure
+ * @addr: phy address to write to
* @offset: lower half is register offset to write to
* upper half is page to use.
* @data: data to write at register offset
@@ -2473,7 +2472,7 @@ out:
* Acquires semaphore, if necessary, then writes the data to PHY register
* at the offset. Release any acquired semaphores before exiting.
**/
-s32 igb_write_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 data)
+s32 igb_write_reg_gs40g(struct e1000_hw *hw, u8 addr, u32 offset, u16 data)
{
s32 ret_val;
u16 page = offset >> GS40G_PAGE_SHIFT;
@@ -2483,10 +2482,10 @@ s32 igb_write_phy_reg_gs40g(struct e1000
if (ret_val)
return ret_val;
- ret_val = igb_write_phy_reg_mdic(hw, GS40G_PAGE_SELECT, page);
+ ret_val = igb_write_phy_reg_mdic(hw, addr, GS40G_PAGE_SELECT, page);
if (ret_val)
goto release;
- ret_val = igb_write_phy_reg_mdic(hw, offset, data);
+ ret_val = igb_write_phy_reg_mdic(hw, addr, offset, data);
release:
hw->phy.ops.release(hw);
@@ -2494,8 +2493,24 @@ release:
}
/**
- * igb_read_phy_reg_gs40g - Read GS40G PHY register
+ * igb_write_phy_reg_gs40g - Write GS40G PHY register
+ * @hw: pointer to the HW structure
+ * @offset: lower half is register offset to write to
+ * upper half is page to use.
+ * @data: data to write at register offset
+ *
+ * Acquires semaphore, if necessary, then writes the data to PHY register
+ * at the offset. Release any acquired semaphores before exiting.
+ **/
+s32 igb_write_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 data)
+{
+ return igb_write_reg_gs40g(hw, hw->phy.addr, offset, data);
+}
+
+/**
+ * igb_read_reg_gs40g - Read GS40G PHY register
* @hw: pointer to the HW structure
+ * @addr: phy address to read from
* @offset: lower half is register offset to read to
* upper half is page to use.
* @data: data to read at register offset
@@ -2503,7 +2518,7 @@ release:
* Acquires semaphore, if necessary, then reads the data in the PHY register
* at the offset. Release any acquired semaphores before exiting.
**/
-s32 igb_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data)
+s32 igb_read_reg_gs40g(struct e1000_hw *hw, u8 addr, u32 offset, u16 *data)
{
s32 ret_val;
u16 page = offset >> GS40G_PAGE_SHIFT;
@@ -2513,10 +2528,10 @@ s32 igb_read_phy_reg_gs40g(struct e1000_
if (ret_val)
return ret_val;
- ret_val = igb_write_phy_reg_mdic(hw, GS40G_PAGE_SELECT, page);
+ ret_val = igb_write_phy_reg_mdic(hw, addr, GS40G_PAGE_SELECT, page);
if (ret_val)
goto release;
- ret_val = igb_read_phy_reg_mdic(hw, offset, data);
+ ret_val = igb_read_phy_reg_mdic(hw, addr, offset, data);
release:
hw->phy.ops.release(hw);
@@ -2524,6 +2539,21 @@ release:
}
/**
+ * igb_read_phy_reg_gs40g - Read GS40G PHY register
+ * @hw: pointer to the HW structure
+ * @offset: lower half is register offset to read to
+ * upper half is page to use.
+ * @data: data to read at register offset
+ *
+ * Acquires semaphore, if necessary, then reads the data in the PHY register
+ * at the offset. Release any acquired semaphores before exiting.
+ **/
+s32 igb_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+ return igb_read_reg_gs40g(hw, hw->phy.addr, offset, data);
+}
+
+/**
* igb_set_master_slave_mode - Setup PHY for Master/slave mode
* @hw: pointer to the HW structure
*
--- a/drivers/net/ethernet/intel/igb/e1000_phy.h
+++ b/drivers/net/ethernet/intel/igb/e1000_phy.h
@@ -61,8 +61,8 @@ s32 igb_phy_has_link(struct e1000_hw *h
void igb_power_up_phy_copper(struct e1000_hw *hw);
void igb_power_down_phy_copper(struct e1000_hw *hw);
s32 igb_phy_init_script_igp3(struct e1000_hw *hw);
-s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
-s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
+s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u8 addr, u32 offset, u16 *data);
+s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u8 addr, u32 offset, u16 data);
s32 igb_read_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 *data);
s32 igb_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data);
s32 igb_read_sfp_data_byte(struct e1000_hw *hw, u16 offset, u8 *data);
@@ -72,6 +72,8 @@ s32 igb_phy_force_speed_duplex_82580(st
s32 igb_get_cable_length_82580(struct e1000_hw *hw);
s32 igb_read_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 *data);
s32 igb_write_phy_reg_gs40g(struct e1000_hw *hw, u32 offset, u16 data);
+s32 igb_read_reg_gs40g(struct e1000_hw *hw, u8 addr, u32 offset, u16 *data);
+s32 igb_write_reg_gs40g(struct e1000_hw *hw, u8 addr, u32 offset, u16 data);
s32 igb_check_polarity_m88(struct e1000_hw *hw);
/* IGP01E1000 Specific Registers */

@ -1,308 +0,0 @@
From 03855caf93f7332a3f320228ba1a0e7baae8a749 Mon Sep 17 00:00:00 2001
From: Tim Harvey <tharvey@gateworks.com>
Date: Thu, 15 May 2014 12:36:23 -0700
Subject: [PATCH] net: igb: register mii_bus for SerDes w/ external phy
If an i210 is configured for 1000BASE-BX link_mode and has an external phy
specified, then register an mii bus using the external phy address as
a mask.
An i210 hooked to an external standard phy will be configured with a link_mo
of SGMII in which case phy ops will be configured and used internall in the
igb driver for link status. However, in certain cases one might be using a
backplane SerDes connection to something that talks on the mdio bus but is
not a standard phy, such as a switch. In this case by registering an mdio
bus a phy driver can manage the device.
Signed-off-by: Tim Harvey <tharvey@gateworks.com>
---
drivers/net/ethernet/intel/igb/e1000_82575.c | 15 +++
drivers/net/ethernet/intel/igb/e1000_hw.h | 7 ++
drivers/net/ethernet/intel/igb/igb_main.c | 168 ++++++++++++++++++++++++++-
3 files changed, 185 insertions(+), 5 deletions(-)
--- a/drivers/net/ethernet/intel/igb/e1000_82575.c
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.c
@@ -598,13 +598,25 @@ static s32 igb_get_invariants_82575(stru
switch (link_mode) {
case E1000_CTRL_EXT_LINK_MODE_1000BASE_KX:
hw->phy.media_type = e1000_media_type_internal_serdes;
+ if (igb_sgmii_uses_mdio_82575(hw)) {
+ u32 mdicnfg = rd32(E1000_MDICNFG);
+ mdicnfg &= E1000_MDICNFG_PHY_MASK;
+ hw->phy.addr = mdicnfg >> E1000_MDICNFG_PHY_SHIFT;
+ hw_dbg("1000BASE_KX w/ external MDIO device at 0x%x\n",
+ hw->phy.addr);
+ } else {
+ hw_dbg("1000BASE_KX");
+ }
break;
case E1000_CTRL_EXT_LINK_MODE_SGMII:
/* Get phy control interface type set (MDIO vs. I2C)*/
if (igb_sgmii_uses_mdio_82575(hw)) {
hw->phy.media_type = e1000_media_type_copper;
dev_spec->sgmii_active = true;
+ hw_dbg("SGMII with external MDIO PHY");
break;
+ } else {
+ hw_dbg("SGMII with external I2C PHY");
}
/* fall through for I2C based SGMII */
case E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES:
@@ -621,8 +633,11 @@ static s32 igb_get_invariants_82575(stru
hw->phy.media_type = e1000_media_type_copper;
dev_spec->sgmii_active = true;
}
+ hw_dbg("SERDES with external SFP");
break;
+ } else {
+ hw_dbg("SERDES");
}
/* do not change link mode for 100BaseFX */
--- a/drivers/net/ethernet/intel/igb/e1000_hw.h
+++ b/drivers/net/ethernet/intel/igb/e1000_hw.h
@@ -27,6 +27,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/netdevice.h>
+#include <linux/phy.h>
#include "e1000_regs.h"
#include "e1000_defines.h"
@@ -543,6 +544,12 @@ struct e1000_hw {
struct e1000_mbx_info mbx;
struct e1000_host_mng_dhcp_cookie mng_cookie;
+#ifdef CONFIG_PHYLIB
+ /* Phylib and MDIO interface */
+ struct mii_bus *mii_bus;
+ struct phy_device *phy_dev;
+ phy_interface_t phy_interface;
+#endif
union {
struct e1000_dev_spec_82575 _82575;
} dev_spec;
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -41,6 +41,7 @@
#include <linux/if_vlan.h>
#include <linux/pci.h>
#include <linux/pci-aspm.h>
+#include <linux/phy.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/ip.h>
@@ -2237,6 +2238,126 @@ static s32 igb_init_i2c(struct igb_adapt
return status;
}
+
+#ifdef CONFIG_PHYLIB
+/*
+ * MMIO/PHYdev support
+ */
+
+static int igb_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
+{
+ struct e1000_hw *hw = bus->priv;
+ u16 out;
+ int err;
+
+ err = igb_read_reg_gs40g(hw, mii_id, regnum, &out);
+ if (err)
+ return err;
+ return out;
+}
+
+static int igb_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
+ u16 val)
+{
+ struct e1000_hw *hw = bus->priv;
+
+ return igb_write_reg_gs40g(hw, mii_id, regnum, val);
+}
+
+static int igb_enet_mdio_reset(struct mii_bus *bus)
+{
+ udelay(300);
+ return 0;
+}
+
+static void igb_enet_mii_link(struct net_device *netdev)
+{
+}
+
+/* Probe the mdio bus for phys and connect them */
+static int igb_enet_mii_probe(struct net_device *netdev)
+{
+ struct igb_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+ struct phy_device *phy_dev = NULL;
+ int phy_id;
+
+ /* check for attached phy */
+ for (phy_id = 0; (phy_id < PHY_MAX_ADDR); phy_id++) {
+ if (hw->mii_bus->phy_map[phy_id]) {
+ phy_dev = hw->mii_bus->phy_map[phy_id];
+ break;
+ }
+ }
+ if (!phy_dev) {
+ netdev_err(netdev, "no PHY found\n");
+ return -ENODEV;
+ }
+
+ hw->phy_interface = PHY_INTERFACE_MODE_RGMII;
+ phy_dev = phy_connect(netdev, dev_name(&phy_dev->dev),
+ igb_enet_mii_link, hw->phy_interface);
+ if (IS_ERR(phy_dev)) {
+ netdev_err(netdev, "could not attach to PHY\n");
+ return PTR_ERR(phy_dev);
+ }
+
+ hw->phy_dev = phy_dev;
+ netdev_info(netdev, "igb PHY driver [%s] (mii_bus:phy_addr=%s)\n",
+ hw->phy_dev->drv->name, dev_name(&hw->phy_dev->dev));
+
+ return 0;
+}
+
+/* Create and register mdio bus */
+static int igb_enet_mii_init(struct pci_dev *pdev)
+{
+ struct mii_bus *mii_bus;
+ struct net_device *netdev = pci_get_drvdata(pdev);
+ struct igb_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
+ int err;
+
+ mii_bus = mdiobus_alloc();
+ if (mii_bus == NULL) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
+ mii_bus->name = "igb_enet_mii_bus";
+ mii_bus->read = igb_enet_mdio_read;
+ mii_bus->write = igb_enet_mdio_write;
+ mii_bus->reset = igb_enet_mdio_reset;
+ snprintf(mii_bus->id, MII_BUS_ID_SIZE, "%s-%x",
+ pci_name(pdev), hw->device_id + 1);
+ mii_bus->priv = hw;
+ mii_bus->parent = &pdev->dev;
+ mii_bus->phy_mask = ~(1 << hw->phy.addr);
+
+ err = mdiobus_register(mii_bus);
+ if (err) {
+ printk(KERN_ERR "failed to register mii_bus: %d\n", err);
+ goto err_out_free_mdiobus;
+ }
+ hw->mii_bus = mii_bus;
+
+ return 0;
+
+err_out_free_mdiobus:
+ mdiobus_free(mii_bus);
+err_out:
+ return err;
+}
+
+static void igb_enet_mii_remove(struct e1000_hw *hw)
+{
+ if (hw->mii_bus) {
+ mdiobus_unregister(hw->mii_bus);
+ mdiobus_free(hw->mii_bus);
+ }
+}
+#endif /* CONFIG_PHYLIB */
+
/**
* igb_probe - Device Initialization Routine
* @pdev: PCI device information struct
@@ -2659,6 +2780,13 @@ static int igb_probe(struct pci_dev *pde
}
}
pm_runtime_put_noidle(&pdev->dev);
+
+#ifdef CONFIG_PHYLIB
+ /* create and register the mdio bus if using ext phy */
+ if (rd32(E1000_MDICNFG) & E1000_MDICNFG_EXT_MDIO)
+ igb_enet_mii_init(pdev);
+#endif
+
return 0;
err_register:
@@ -2802,6 +2930,10 @@ static void igb_remove(struct pci_dev *p
struct e1000_hw *hw = &adapter->hw;
pm_runtime_get_noresume(&pdev->dev);
+#ifdef CONFIG_PHYLIB
+ if (rd32(E1000_MDICNFG) & E1000_MDICNFG_EXT_MDIO)
+ igb_enet_mii_remove(hw);
+#endif
#ifdef CONFIG_IGB_HWMON
igb_sysfs_exit(adapter);
#endif
@@ -3115,6 +3247,12 @@ static int __igb_open(struct net_device
if (!resuming)
pm_runtime_put(&pdev->dev);
+#ifdef CONFIG_PHYLIB
+ /* Probe and connect to PHY if using ext phy */
+ if (rd32(E1000_MDICNFG) & E1000_MDICNFG_EXT_MDIO)
+ igb_enet_mii_probe(netdev);
+#endif
+
/* start the watchdog. */
hw->mac.get_link_status = 1;
schedule_work(&adapter->watchdog_task);
@@ -7111,21 +7249,41 @@ void igb_alloc_rx_buffers(struct igb_rin
static int igb_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
{
struct igb_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
struct mii_ioctl_data *data = if_mii(ifr);
- if (adapter->hw.phy.media_type != e1000_media_type_copper)
+ if (adapter->hw.phy.media_type != e1000_media_type_copper &&
+ !(rd32(E1000_MDICNFG) & E1000_MDICNFG_EXT_MDIO))
return -EOPNOTSUPP;
switch (cmd) {
case SIOCGMIIPHY:
- data->phy_id = adapter->hw.phy.addr;
+ data->phy_id = hw->phy.addr;
break;
case SIOCGMIIREG:
- if (igb_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
- &data->val_out))
- return -EIO;
+ if (hw->mac.type == e1000_i210 || hw->mac.type == e1000_i211) {
+ if (igb_read_reg_gs40g(&adapter->hw, data->phy_id,
+ data->reg_num & 0x1F,
+ &data->val_out))
+ return -EIO;
+ } else {
+ if (igb_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
+ &data->val_out))
+ return -EIO;
+ }
break;
case SIOCSMIIREG:
+ if (hw->mac.type == e1000_i210 || hw->mac.type == e1000_i211) {
+ if (igb_write_reg_gs40g(hw, data->phy_id,
+ data->reg_num & 0x1F,
+ data->val_in))
+ return -EIO;
+ } else {
+ if (igb_write_phy_reg(hw, data->reg_num & 0x1F,
+ data->val_in))
+ return -EIO;
+ }
+ break;
default:
return -EOPNOTSUPP;
}

@ -1,27 +0,0 @@
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -292,6 +292,14 @@ endif # RTL8366_SMI
source "drivers/net/phy/b53/Kconfig"
+config GATEWORKS_GW16083
+ tristate "Gateworks GW16083 Ethernet Expansion Mezzanine"
+ ---help---
+ The Gateworks GW16083 Ethernet Expansion Mezzanine connects to a
+ Gateworks Ventana baseboard and provides a 7-port GbE managed
+ Ethernet switch with 4 dedicated GbE RJ45 ports, and 2 Gbe/SFP
+ ports"
+
endif # PHYLIB
config MICREL_KS8995MA
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -40,6 +40,7 @@ obj-$(CONFIG_NATIONAL_PHY) += national.o
obj-$(CONFIG_DP83640_PHY) += dp83640.o
obj-$(CONFIG_STE10XP) += ste10Xp.o
obj-$(CONFIG_MICREL_PHY) += micrel.o
+obj-$(CONFIG_GATEWORKS_GW16083) += gw16083.o
obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o
obj-$(CONFIG_MICREL_KS8995MA) += spi_ks8995.o
obj-$(CONFIG_AT803X_PHY) += at803x.o

@ -1,56 +0,0 @@
--- a/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw51xx.dtsi
@@ -89,6 +89,11 @@
enable-active-high;
};
};
+
+ gw16083: gw16083@52 {
+ compatible = "gateworks,gw16083";
+ reg = <0x52>;
+ };
};
&fec {
--- a/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw52xx.dtsi
@@ -266,6 +266,11 @@
};
};
};
+
+ gw16083: gw16083@52 {
+ compatible = "gateworks,gw16083";
+ reg = <0x52>;
+ };
};
&pcie {
--- a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
@@ -267,6 +267,11 @@
};
};
};
+
+ gw16083: gw16083@52 {
+ compatible = "gateworks,gw16083";
+ reg = <0x52>;
+ };
};
&pcie {
--- a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
@@ -308,6 +308,11 @@
};
};
};
+
+ gw16083: gw16083@52 {
+ compatible = "gateworks,gw16083";
+ reg = <0x52>;
+ };
};
&i2c3 {

@ -1,110 +0,0 @@
From 840202d23892baaff74be11ec71c3ffc6ad6298e Mon Sep 17 00:00:00 2001
From: Tim Harvey <tharvey@gateworks.com>
Date: Tue, 20 Jan 2015 08:46:55 -0800
Subject: [PATCH] ARM: dts: imx6 ventana: Add PCI nodes for on-board PCI
devices
If the PCI nodes are defined, drivers can access information from the DT.
For example, the sky2 enet driver can obtain the mac address configured
from the bootloader (which is applied to the DT node with the ethernet1 alias).
Signed-off-by: Tim Harvey <tharvey@gateworks.com>
---
arch/arm/boot/dts/imx6qdl-gw53xx.dtsi | 38 +++++++++++++++++++++++++++++++++--
arch/arm/boot/dts/imx6qdl-gw54xx.dtsi | 38 +++++++++++++++++++++++++++++++++--
2 files changed, 72 insertions(+), 4 deletions(-)
--- a/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw53xx.dtsi
@@ -280,8 +280,42 @@
reset-gpio = <&gpio1 29 GPIO_ACTIVE_LOW>;
status = "okay";
- eth1: sky2@8 { /* MAC/PHY on bus 8 */
- compatible = "marvell,sky2";
+ pcie@0,0 {
+ /* 00:00.0 0604: 16c3:abcd root host-bridge */
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ reg = <0x0 0 0 0 0>;
+
+ pcie@0,0 {
+ /* 01:00.0 0604: 10b5:8609 PEX switch bridge */
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ reg = <0x0 0 0 0 0>;
+
+ /*
+ * GigE PCI dev node needs to be defined so that enet
+ * driver can use it to obtain its boot-loader
+ * specified MAC
+ */
+ pcie@4,0 {
+ /* 02:04.0 0604: 10b5:8609: PEX port bridge */
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ reg = <0x2000 0 0 0 0>;
+
+ eth1: pci@0,0 {
+ /* 04:00.0 0200: 11ab:4380: GigE */
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ reg = <0x0 0 0 0 0>;
+ compatible = "marvell,sky2";
+ };
+ };
+ };
};
};
--- a/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
+++ b/arch/arm/boot/dts/imx6qdl-gw54xx.dtsi
@@ -369,8 +369,42 @@
reset-gpio = <&gpio1 29 GPIO_ACTIVE_LOW>;
status = "okay";
- eth1: sky2@8 { /* MAC/PHY on bus 8 */
- compatible = "marvell,sky2";
+ pcie@0,0 {
+ /* 00:00.0 0604: 16c3:abcd root host-bridge */
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ reg = <0x0 0 0 0 0>;
+
+ pcie@0,0 {
+ /* 01:00.0 0604: 10b5:8609 PEX switch bridge */
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ reg = <0x0 0 0 0 0>;
+
+ /*
+ * GigE PCI dev node needs to be defined so that enet
+ * driver can use it to obtain its boot-loader
+ * specified MAC
+ */
+ pcie@8,0 {
+ /* 02:08.0 0604: 10b5:8609: PEX port bridge */
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ reg = <0x4000 0 0 0 0>;
+
+ eth1: pci@0,0 {
+ /* 08:00.0 0200: 11ab:4380: GigE */
+ #address-cells = <3>;
+ #size-cells = <2>;
+ device_type = "pci";
+ reg = <0x0 0 0 0 0>;
+ compatible = "marvell,sky2";
+ };
+ };
+ };
};
};
Loading…
Cancel
Save