On 12/12/2015 01:15, Christian Lamparter wrote: > From: Chris R Blake <chrisrblak...@gmail.com> > > This patch adds support for Cisco's MR18. > Detailed instructions for the flashing the device can > be found in the OpenWrt forum thread: > <https://forum.openwrt.org/viewtopic.php?id=59248> > > Signed-off-by: Chris R Blake <chrisrblak...@gmail.com> > --- > in before complains about "not using the latest method". ;-) > (yes, this is because of r47874 - I'm not spamming the ML > just because of this.) > > Regards, > Christian
looks like you had to rebase quite often without actually being the cause ;) anyhow its now merged and i assume this patch obsoletes all previous still open ones ? > --- > target/linux/ar71xx/base-files/etc/board.d/01_leds | 4 + > .../linux/ar71xx/base-files/etc/board.d/02_network | 1 + > target/linux/ar71xx/base-files/etc/diag.sh | 3 + > .../etc/hotplug.d/firmware/10-ath9k-eeprom | 32 +++ > target/linux/ar71xx/base-files/lib/ar71xx.sh | 3 + > .../base-files/lib/preinit/05_set_iface_mac_ar71xx | 4 + > .../ar71xx/base-files/lib/upgrade/merakinand.sh | 137 ++++++++++ > .../ar71xx/base-files/lib/upgrade/platform.sh | 7 + > target/linux/ar71xx/config-4.1 | 1 + > .../ar71xx/files/arch/mips/ath79/Kconfig.openwrt | 11 + > target/linux/ar71xx/files/arch/mips/ath79/Makefile | 1 + > .../linux/ar71xx/files/arch/mips/ath79/mach-mr18.c | 297 > +++++++++++++++++++++ > .../linux/ar71xx/files/arch/mips/ath79/machtypes.h | 1 + > target/linux/ar71xx/image/Makefile | 21 ++ > target/linux/ar71xx/nand/config-default | 1 + > target/linux/ar71xx/nand/profiles/meraki.mk | 17 ++ > 16 files changed, 541 insertions(+) > create mode 100644 target/linux/ar71xx/base-files/lib/upgrade/merakinand.sh > create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-mr18.c > create mode 100644 target/linux/ar71xx/nand/profiles/meraki.mk > > diff --git a/target/linux/ar71xx/base-files/etc/board.d/01_leds > b/target/linux/ar71xx/base-files/etc/board.d/01_leds > index 33f8377..d4f226e 100755 > --- a/target/linux/ar71xx/base-files/etc/board.d/01_leds > +++ b/target/linux/ar71xx/base-files/etc/board.d/01_leds > @@ -283,6 +283,10 @@ mr16) > ucidef_set_led_wlan "wlan4" "WLAN4" "mr16:green:wifi4" "phy0tpt" > ;; > > +mr18) > + ucidef_set_led_netdev "wlan0" "WLAN0" "mr18:blue:tricolor0" "wlan0" > + ;; > + > mr600) > ucidef_set_led_wlan "wlan58" "WLAN58" "mr600:green:wlan58" "phy0tpt" > ;; > diff --git a/target/linux/ar71xx/base-files/etc/board.d/02_network > b/target/linux/ar71xx/base-files/etc/board.d/02_network > index 0e77e93..11c4341 100755 > --- a/target/linux/ar71xx/base-files/etc/board.d/02_network > +++ b/target/linux/ar71xx/base-files/etc/board.d/02_network > @@ -313,6 +313,7 @@ eap7660d |\ > el-mini |\ > loco-m-xw |\ > mr1750 |\ > +mr18 |\ > mr600 |\ > mr600v2 |\ > mr900 |\ > diff --git a/target/linux/ar71xx/base-files/etc/diag.sh > b/target/linux/ar71xx/base-files/etc/diag.sh > index 5b997e0..0e1df10 100644 > --- a/target/linux/ar71xx/base-files/etc/diag.sh > +++ b/target/linux/ar71xx/base-files/etc/diag.sh > @@ -152,6 +152,9 @@ get_status_led() { > mr16) > status_led="mr16:green:power" > ;; > + mr18) > + status_led="mr18:green:tricolor0" > + ;; > mr600) > status_led="mr600:orange:power" > ;; > diff --git > a/target/linux/ar71xx/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom > b/target/linux/ar71xx/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom > index 72f7858..f41c3de 100644 > --- a/target/linux/ar71xx/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom > +++ b/target/linux/ar71xx/base-files/etc/hotplug.d/firmware/10-ath9k-eeprom > @@ -54,6 +54,14 @@ board=$(ar71xx_board_name) > case "$FIRMWARE" in > "soc_wmac.eeprom") > case $board in > + mr18) > + if [ -n "$(nand_find_volume ubi0 caldata)" ]; then > + ath9k_ubi_eeprom_extract "caldata" 4096 2048 > + else > + ath9k_eeprom_extract "odm-caldata" 4096 2048 > + fi > + ath9k_patch_firmware_mac $(macaddr_add $(mtd_get_mac_binary_ubi > board-config 102) +1) > + ;; > r6100 | \ > wndr3700v4 | \ > wndr4300) > @@ -68,6 +76,14 @@ case "$FIRMWARE" in > > "pci_wmac0.eeprom") > case $board in > + mr18) > + if [ -n "$(nand_find_volume ubi0 caldata)" ]; then > + ath9k_ubi_eeprom_extract "caldata" 20480 2048 > + else > + ath9k_eeprom_extract "odm-caldata" 20480 2048 > + fi > + ath9k_patch_firmware_mac $(macaddr_add $(mtd_get_mac_binary_ubi > board-config 102) +2) > + ;; > wndr3700v4 | \ > wndr4300) > ath9k_eeprom_extract "caldata" 20480 2048 > @@ -78,4 +94,20 @@ case "$FIRMWARE" in > ;; > esac > ;; > + > +"pci_wmac1.eeprom") > + case $board in > + mr18) > + if [ -n "$(nand_find_volume ubi0 caldata)" ]; then > + ath9k_ubi_eeprom_extract "caldata" 36864 2048 > + else > + ath9k_eeprom_extract "odm-caldata" 36864 2048 > + fi > + ath9k_patch_firmware_mac $(macaddr_add $(mtd_get_mac_binary_ubi > board-config 102) +3) > + ;; > + *) > + ath9k_eeprom_die "board $board is not supported yet" > + ;; > + esac > + ;; > esac > diff --git a/target/linux/ar71xx/base-files/lib/ar71xx.sh > b/target/linux/ar71xx/base-files/lib/ar71xx.sh > index a112523..54e6166 100755 > --- a/target/linux/ar71xx/base-files/lib/ar71xx.sh > +++ b/target/linux/ar71xx/base-files/lib/ar71xx.sh > @@ -551,6 +551,9 @@ ar71xx_board_detect() { > *MR16) > name="mr16" > ;; > + *MR18) > + name="mr18" > + ;; > *MR600v2) > name="mr600v2" > ;; > diff --git > a/target/linux/ar71xx/base-files/lib/preinit/05_set_iface_mac_ar71xx > b/target/linux/ar71xx/base-files/lib/preinit/05_set_iface_mac_ar71xx > index 92b3765..a9f4bf5 100644 > --- a/target/linux/ar71xx/base-files/lib/preinit/05_set_iface_mac_ar71xx > +++ b/target/linux/ar71xx/base-files/lib/preinit/05_set_iface_mac_ar71xx > @@ -29,6 +29,10 @@ preinit_set_mac_address() { > dir-615-i1) > fetch_mac_from_mtd nvram sys_lan_mac sys_wan_mac > ;; > + mr18) > + mac_lan=$(mtd_get_mac_binary_ubi board-config 102) > + [ -n "$mac_lan" ] && ifconfig eth0 hw ether "$mac_lan" > + ;; > r6100) > mac_lan=$(mtd_get_mac_binary caldata 0) > [ -n "$mac_lan" ] && ifconfig eth1 hw ether "$mac_lan" > diff --git a/target/linux/ar71xx/base-files/lib/upgrade/merakinand.sh > b/target/linux/ar71xx/base-files/lib/upgrade/merakinand.sh > new file mode 100644 > index 0000000..fe78e9f > --- /dev/null > +++ b/target/linux/ar71xx/base-files/lib/upgrade/merakinand.sh > @@ -0,0 +1,137 @@ > +#!/bin/sh > +# > +# Copyright (C) 2015 Chris Blake <chrisrblak...@gmail.com> > +# > +# Custom upgrade script for Meraki NAND devices (ex. MR18) > +# Based on dir825.sh and stock nand functions > +# > +. /lib/ar71xx.sh > +. /lib/functions.sh > +. /lib/upgrade/nand.sh > + > +get_magic_at() { > + local mtddev=$1 > + local pos=$2 > + dd bs=1 count=2 skip=$pos if=$mtddev 2>/dev/null | hexdump -v -n 4 -e > '1/1 "%02x"' > +} > + > +mr18_is_caldata_valid() { > + local mtddev=$1 > + local magic > + > + magic=$(get_magic_at $mtddev 4096) > + [ "$magic" != "0202" ] && return 0 > + > + magic=$(get_magic_at $mtddev 20480) > + [ "$magic" != "0202" ] && return 0 > + > + magic=$(get_magic_at $mtddev 36864) > + [ "$magic" != "0202" ] && return 0 > + > + return 1 > +} > + > +merakinand_copy_caldata() { > + local cal_src=$1 > + local cal_dst=$2 > + local ubidev=$( nand_find_ubi $CI_UBIPART ) > + local board_name="$(cat /tmp/sysinfo/board_name)" > + local rootfs_size="$(ubinfo /dev/ubi0 -N rootfs_data | grep "Size" | > awk '{ print $6 }')" > + > + # Setup partitions using board name, in case of future platforms > + case "$board_name" in > + "mr18") > + # Src is MTD > + mtd_src=$(find_mtd_chardev $cal_src) > + [ -n "$mtd_src" ] || { > + echo "no mtd device found for partition $cal_src" > + exit 1 > + } > + > + # Dest is UBI > + # TODO: possibly add create (hard to do when rootfs_data is > expanded & mounted) > + # Would need to be done from ramdisk > + mtd_dst="$(nand_find_volume $ubidev $cal_dst)" > + [ -n "$mtd_dst" ] || { > + echo "no ubi device found for partition $cal_dst" > + exit 1 > + } > + > + mr18_is_caldata_valid "$mtd_src" && { > + echo "no valid calibration data found in $cal_src" > + exit 1 > + } > + > + mr18_is_caldata_valid "/dev/$mtd_dst" && { > + echo "Copying calibration data from $cal_src to > $cal_dst..." > + dd if="$mtd_src" of=/tmp/caldata.tmp 2>/dev/null > + ubiupdatevol "/dev/$mtd_dst" /tmp/caldata.tmp > + rm /tmp/caldata.tmp > + sync > + } > + return 0 > + ;; > + *) > + echo "Unsupported device $board_name"; > + return 1 > + ;; > + esac > +} > + > +merakinand_do_kernel_check() { > + local board_name="$1" > + local tar_file="$2" > + local image_magic_word=`(tar xf $tar_file sysupgrade-$board_name/kernel > -O 2>/dev/null | dd bs=1 count=4 skip=0 2>/dev/null | hexdump -v -n 4 -e '1/1 > "%02x"')` > + > + # What is our kernel magic string? > + case "$board_name" in > + "mr18") > + [ "$image_magic_word" == "8e73ed8a" ] && { > + echo "pass" && return 0 > + } > + ;; > + esac > + > + exit 1 > +} > + > +merakinand_do_platform_check() { > + local board_name="$1" > + local tar_file="$2" > + local control_length=`(tar xf $tar_file sysupgrade-$board_name/CONTROL > -O | wc -c) 2> /dev/null` > + local file_type="$(identify_tar $2 sysupgrade-$board_name/root)" > + local kernel_magic="$(merakinand_do_kernel_check $1 $2)" > + > + case "$board_name" in > + "mr18") > + [ "$control_length" = 0 -o "$file_type" != "squashfs" -o > "$kernel_magic" != "pass" ] && { > + echo "Invalid sysupgrade file for $board_name" > + return 1 > + } > + ;; > + *) > + echo "Unsupported device $board_name"; > + return 1 > + ;; > + esac > + > + return 0 > +} > + > +merakinand_do_upgrade() { > + local tar_file="$1" > + local board_name="$(cat /tmp/sysinfo/board_name)" > + > + # Do we need to do any platform tweaks? > + case "$board_name" in > + "mr18") > + # Check and create UBI caldata if it's invalid > + merakinand_copy_caldata "odm-caldata" "caldata" > + nand_do_upgrade $1 > + ;; > + *) > + echo "Unsupported device $board_name"; > + exit 1 > + ;; > + esac > +} > diff --git a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh > b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh > index 5ec4499..bb64ef8 100755 > --- a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh > +++ b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh > @@ -434,6 +434,10 @@ platform_check_image() { > } > return 0 > ;; > + mr18) > + merakinand_do_platform_check $board $1 > + return $?; > + ;; > nbg6716 | \ > r6100 | \ > wndr3700v4 | \ > @@ -494,6 +498,9 @@ platform_pre_upgrade() { > wndr4300 ) > nand_do_upgrade "$1" > ;; > + mr18) > + merakinand_do_upgrade "$1" > + ;; > esac > } > > diff --git a/target/linux/ar71xx/config-4.1 b/target/linux/ar71xx/config-4.1 > index e21581d..0e8b4a4 100644 > --- a/target/linux/ar71xx/config-4.1 > +++ b/target/linux/ar71xx/config-4.1 > @@ -91,6 +91,7 @@ CONFIG_ATH79_MACH_MC_MAC1200R=y > CONFIG_ATH79_MACH_MR12=y > CONFIG_ATH79_MACH_MR16=y > CONFIG_ATH79_MACH_MR1750=y > +CONFIG_ATH79_MACH_MR18=y > CONFIG_ATH79_MACH_MR600=y > CONFIG_ATH79_MACH_MR900=y > CONFIG_ATH79_MACH_MYNET_N600=y > diff --git a/target/linux/ar71xx/files/arch/mips/ath79/Kconfig.openwrt > b/target/linux/ar71xx/files/arch/mips/ath79/Kconfig.openwrt > index 43ffa70..2b62d89 100644 > --- a/target/linux/ar71xx/files/arch/mips/ath79/Kconfig.openwrt > +++ b/target/linux/ar71xx/files/arch/mips/ath79/Kconfig.openwrt > @@ -853,6 +853,17 @@ config ATH79_MACH_MR16 > select ATH79_DEV_M25P80 > select ATH79_DEV_WMAC > > +config ATH79_MACH_MR18 > + bool "Meraki MR18 board support" > + select SOC_QCA955X > + select ATH79_DEV_AP9X_PCI if PCI > + select ATH79_DEV_ETH > + select ATH79_DEV_GPIO_BUTTONS > + select ATH79_DEV_LEDS_GPIO > + select ATH79_DEV_NFC > + select ATH79_DEV_WMAC > + select LEDS_NU801 > + > config ATH79_MACH_MR600 > bool "OpenMesh MR600 board support" > select SOC_AR934X > diff --git a/target/linux/ar71xx/files/arch/mips/ath79/Makefile > b/target/linux/ar71xx/files/arch/mips/ath79/Makefile > index b001876..f9c5b8f 100644 > --- a/target/linux/ar71xx/files/arch/mips/ath79/Makefile > +++ b/target/linux/ar71xx/files/arch/mips/ath79/Makefile > @@ -98,6 +98,7 @@ obj-$(CONFIG_ATH79_MACH_HORNET_UB) += mach-hornet-ub.o > obj-$(CONFIG_ATH79_MACH_MC_MAC1200R) += mach-mc-mac1200r.o > obj-$(CONFIG_ATH79_MACH_MR12) += mach-mr12.o > obj-$(CONFIG_ATH79_MACH_MR16) += mach-mr16.o > +obj-$(CONFIG_ATH79_MACH_MR18) += mach-mr18.o > obj-$(CONFIG_ATH79_MACH_MR1750) += mach-mr1750.o > obj-$(CONFIG_ATH79_MACH_MR600) += mach-mr600.o > obj-$(CONFIG_ATH79_MACH_MR900) += mach-mr900.o > diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-mr18.c > b/target/linux/ar71xx/files/arch/mips/ath79/mach-mr18.c > new file mode 100644 > index 0000000..a24cb3f > --- /dev/null > +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-mr18.c > @@ -0,0 +1,297 @@ > +/* > + * Cisco Meraki MR18 board support > + * > + * Copyright (C) 2015 Chris Blake <chrisrblak...@gmail.com> > + * Copyright (C) 2015 Christian Lamparter <chunk...@googlemail.com> > + * Copyright (C) 2015 Thomas Hebb <tommyh...@gmail.com> > + * > + * Based on Cisco Meraki GPL Release r23-20150601 MR18 Device Config > + * > + * This program is free software; you can redistribute it and/or modify it > + * under the terms of the GNU General Public License version 2 as published > + * by the Free Software Foundation. > + */ > +#include <linux/platform_device.h> > +#include <linux/ath9k_platform.h> > +#include <linux/platform/ar934x_nfc.h> > +#include <linux/platform_data/phy-at803x.h> > + > +#include <asm/mach-ath79/ath79.h> > +#include <asm/mach-ath79/ar71xx_regs.h> > + > +#include <linux/leds-nu801.h> > +#include <linux/pci.h> > + > +#include "common.h" > +#include "dev-eth.h" > +#include "pci.h" > +#include "dev-gpio-buttons.h" > +#include "dev-leds-gpio.h" > +#include "dev-nfc.h" > +#include "dev-wmac.h" > +#include "machtypes.h" > + > +#define MR18_GPIO_LED_POWER_WHITE 18 > +#define MR18_GPIO_LED_POWER_ORANGE 21 > + > +#define MR18_GPIO_BTN_RESET 17 > +#define MR18_KEYS_POLL_INTERVAL 20 /* msecs */ > +#define MR18_KEYS_DEBOUNCE_INTERVAL (3 * MR18_KEYS_POLL_INTERVAL) > + > +#define MR18_WAN_PHYADDR 3 > + > +/* used for eth calibration */ > +#define MR18_OTP_BASE (AR71XX_APB_BASE + 0x130000) > +#define MR18_OTP_SIZE (0x2000) /* just a guess */ > +#define MR18_OTP_MEM_0_REG (0x0000) > +#define MR18_OTP_INTF2_REG (0x1008) > +#define MR18_OTP_STATUS0_REG (0x1018) > +#define MR18_OTP_STATUS0_EFUSE_VALID BIT(2) > + > +#define MR18_OTP_STATUS1_REG (0x101c) > +#define MR18_OTP_LDO_CTRL_REG (0x1024) > +#define MR18_OTP_LDO_STATUS_REG (0x102c) > +#define MR18_OTP_LDO_STATUS_POWER_ON BIT(0) > + > +static struct gpio_led MR18_leds_gpio[] __initdata = { > + { > + .name = "mr18:white:power", > + .gpio = MR18_GPIO_LED_POWER_WHITE, > + .active_low = 1, > + }, { > + .name = "mr18:orange:power", > + .gpio = MR18_GPIO_LED_POWER_ORANGE, > + .active_low = 0, > + }, > +}; > + > +static struct gpio_keys_button MR18_gpio_keys[] __initdata = { > + { > + .desc = "reset", > + .type = EV_KEY, > + .code = KEY_RESTART, > + .debounce_interval = MR18_KEYS_DEBOUNCE_INTERVAL, > + .gpio = MR18_GPIO_BTN_RESET, > + .active_low = 1, > + }, > +}; > + > +static struct led_nu801_template tricolor_led_template = { > + .device_name = "mr18", > + .name = "tricolor", > + .num_leds = 1, > + .cki = 11, > + .sdi = 12, > + .lei = -1, > + .ndelay = 500, > + .init_brightness = { > + LED_OFF, > + LED_OFF, > + LED_OFF, > + }, > + .default_trigger = "none", > + .led_colors = { "red", "green", "blue" }, > +}; > + > +static struct led_nu801_platform_data tricolor_led_data = { > + .num_controllers = 1, > + .template = &tricolor_led_template, > +}; > + > +static struct platform_device tricolor_leds = { > + .name = "leds-nu801", > + .id = -1, > + .dev.platform_data = &tricolor_led_data, > +}; > + > +static int mr18_extract_sgmii_res_cal(void) > +{ > + void __iomem *base; > + unsigned int reversed_sgmii_value; > + > + unsigned int otp_value, otp_per_val, rbias_per, read_data; > + unsigned int rbias_pos_or_neg; > + unsigned int sgmii_res_cal_value; > + int res_cal_val; > + > + base = ioremap_nocache(MR18_OTP_BASE, MR18_OTP_SIZE); > + if (!base) > + return -EIO; > + > + __raw_writel(0x7d, base + MR18_OTP_INTF2_REG); > + __raw_writel(0x00, base + MR18_OTP_LDO_CTRL_REG); > + > + while (__raw_readl(base + MR18_OTP_LDO_STATUS_REG) & > + MR18_OTP_LDO_STATUS_POWER_ON); > + > + __raw_readl(base + MR18_OTP_MEM_0_REG + 4); > + > + while (!(__raw_readl(base + MR18_OTP_STATUS0_REG) & > + MR18_OTP_STATUS0_EFUSE_VALID)); > + > + read_data = __raw_readl(base + MR18_OTP_STATUS1_REG); > + > + iounmap(base); > + > + if (!(read_data & 0x1fff)) > + return -ENODEV; > + > + if (read_data & 0x00001000) > + otp_value = (read_data & 0xfc0) >> 6; > + else > + otp_value = read_data & 0x3f; > + > + if (otp_value > 31) { > + otp_per_val = 63 - otp_value; > + rbias_pos_or_neg = 1; > + } else { > + otp_per_val = otp_value; > + rbias_pos_or_neg = 0; > + } > + > + rbias_per = otp_per_val * 15; > + > + if (rbias_pos_or_neg == 1) > + res_cal_val = (rbias_per + 34) / 21; > + else if (rbias_per > 34) > + res_cal_val = -((rbias_per - 34) / 21); > + else > + res_cal_val = (34 - rbias_per) / 21; > + > + sgmii_res_cal_value = (8 + res_cal_val) & 0xf; > + > + reversed_sgmii_value = (sgmii_res_cal_value & 8) >> 3; > + reversed_sgmii_value |= (sgmii_res_cal_value & 4) >> 1; > + reversed_sgmii_value |= (sgmii_res_cal_value & 2) << 1; > + reversed_sgmii_value |= (sgmii_res_cal_value & 1) << 3; > + printk(KERN_INFO "SGMII cal value = 0x%x\n", reversed_sgmii_value); > + return reversed_sgmii_value; > +} > + > +#define QCA955X_PLL_ETH_SGMII_SERDES_REG 0x004c > +#define QCA955X_PLL_ETH_SGMII_SERDES_LOCK_DETECT BIT(2) > +#define QCA955X_PLL_ETH_SGMII_SERDES_PLL_REFCLK BIT(1) > +#define QCA955X_PLL_ETH_SGMII_SERDES_EN_PLL BIT(0) > + > +#define QCA955X_GMAC_REG_SGMII_SERDES 0x0018 > +#define QCA955X_SGMII_SERDES_RES_CALIBRATION BIT(23) > +#define QCA955X_SGMII_SERDES_RES_CALIBRATION_MASK 0xf > +#define QCA955X_SGMII_SERDES_RES_CALIBRATION_SHIFT 23 > +#define QCA955X_SGMII_SERDES_LOCK_DETECT_STATUS BIT(15) > + > +static void mr18_setup_qca955x_eth_serdes_cal(unsigned int sgmii_value) > +{ > + void __iomem *ethbase, *pllbase; > + u32 t; > + > + ethbase = ioremap_nocache(QCA955X_GMAC_BASE, QCA955X_GMAC_SIZE); > + pllbase = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); > + > + /* To Check the locking of the SGMII PLL */ > + t = __raw_readl(ethbase + QCA955X_GMAC_REG_SGMII_SERDES); > + t &= ~(QCA955X_SGMII_SERDES_RES_CALIBRATION_MASK << > + QCA955X_SGMII_SERDES_RES_CALIBRATION_SHIFT); > + t |= (sgmii_value & QCA955X_SGMII_SERDES_RES_CALIBRATION_MASK) << > + QCA955X_SGMII_SERDES_RES_CALIBRATION_SHIFT; > + __raw_writel(t, ethbase + QCA955X_GMAC_REG_SGMII_SERDES); > + > + __raw_writel(QCA955X_PLL_ETH_SGMII_SERDES_LOCK_DETECT | > + QCA955X_PLL_ETH_SGMII_SERDES_PLL_REFCLK | > + QCA955X_PLL_ETH_SGMII_SERDES_EN_PLL, > + pllbase + QCA955X_PLL_ETH_SGMII_SERDES_REG); > + > + ath79_device_reset_clear(QCA955X_RESET_SGMII_ANALOG); > + ath79_device_reset_clear(QCA955X_RESET_SGMII); > + > + while (!(__raw_readl(ethbase + QCA955X_GMAC_REG_SGMII_SERDES) & > + QCA955X_SGMII_SERDES_LOCK_DETECT_STATUS)); > + > + iounmap(ethbase); > + iounmap(pllbase); > +} > + > +static struct ath9k_platform_data pci_main_wifi_data = { > + .led_pin = -1, > +}; > +static struct ath9k_platform_data pci_scan_wifi_data = { > + .led_pin = -1, > +}; > + > +static int mr18_dual_pci_plat_dev_init(struct pci_dev *dev) > +{ > + /* The PCIE devices are attached to different busses but they > + * both share the same slot number. Checking the PCI_SLOT vals > + * does not work. > + */ > + switch (dev->bus->number) { > + case 0: > + dev->dev.platform_data = &pci_main_wifi_data; > + break; > + case 1: > + dev->dev.platform_data = &pci_scan_wifi_data; > + break; > + } > + > + return 0; > +} > + > +static void __init mr18_setup(void) > +{ > + int res; > + > + /* NAND */ > + ath79_nfc_set_ecc_mode(AR934X_NFC_ECC_SOFT_BCH); > + ath79_register_nfc(); > + > + /* even though, the PHY is connected via RGMII, > + * the SGMII/SERDES PLLs need to be calibrated and locked. > + * Or else, the PHY won't be working for this platfrom. > + * > + * Figuring this out took such a long time, that we want to > + * point this quirk out, before someone wants to remove it. > + */ > + res = mr18_extract_sgmii_res_cal(); > + if (res >= 0) { > + /* Setup SoC Eth Config */ > + ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN | > + (3 << QCA955X_ETH_CFG_RXD_DELAY_SHIFT) | > + (3 << QCA955X_ETH_CFG_RDV_DELAY_SHIFT)); > + > + /* MDIO Interface */ > + ath79_register_mdio(0, 0x0); > + > + mr18_setup_qca955x_eth_serdes_cal(res); > + > + /* GMAC0 is connected to an Atheros AR8035-A */ > + ath79_init_mac(ath79_eth0_data.mac_addr, NULL, 0); > + ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; > + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII; > + ath79_eth0_data.phy_mask = BIT(MR18_WAN_PHYADDR); > + ath79_eth0_pll_data.pll_1000 = 0xa6000000; > + ath79_eth0_pll_data.pll_100 = 0xa0000101; > + ath79_eth0_pll_data.pll_10 = 0x80001313; > + ath79_register_eth(0); > + } else { > + printk(KERN_ERR "failed to read EFUSE for ethernet cal\n"); > + } > + > + /* LEDs and Buttons */ > + platform_device_register(&tricolor_leds); > + ath79_register_leds_gpio(-1, ARRAY_SIZE(MR18_leds_gpio), > + MR18_leds_gpio); > + ath79_register_gpio_keys_polled(-1, MR18_KEYS_POLL_INTERVAL, > + ARRAY_SIZE(MR18_gpio_keys), > + MR18_gpio_keys); > + > + /* Clear RTC reset (Needed by SoC WiFi) */ > + ath79_device_reset_clear(QCA955X_RESET_RTC); > + > + /* WiFi */ > + ath79_register_wmac_simple(); > + > + pci_main_wifi_data.eeprom_name = "pci_wmac0.eeprom"; > + pci_scan_wifi_data.eeprom_name = "pci_wmac1.eeprom"; > + ath79_pci_set_plat_dev_init(mr18_dual_pci_plat_dev_init); > + ath79_register_pci(); > +} > +MIPS_MACHINE(ATH79_MACH_MR18, "MR18", "Meraki MR18", mr18_setup); > diff --git a/target/linux/ar71xx/files/arch/mips/ath79/machtypes.h > b/target/linux/ar71xx/files/arch/mips/ath79/machtypes.h > index 550d927..2ea772d 100644 > --- a/target/linux/ar71xx/files/arch/mips/ath79/machtypes.h > +++ b/target/linux/ar71xx/files/arch/mips/ath79/machtypes.h > @@ -87,6 +87,7 @@ enum ath79_mach_type { > ATH79_MACH_HORNET_UB, /* ALFA Networks Hornet-UB */ > ATH79_MACH_MR12, /* Cisco Meraki MR12 */ > ATH79_MACH_MR16, /* Cisco Meraki MR16 */ > + ATH79_MACH_MR18, /* Cisco Meraki MR18 */ > ATH79_MACH_MR1750, /* OpenMesh MR1750 */ > ATH79_MACH_MR600V2, /* OpenMesh MR600v2 */ > ATH79_MACH_MR600, /* OpenMesh MR600 */ > diff --git a/target/linux/ar71xx/image/Makefile > b/target/linux/ar71xx/image/Makefile > index 78be345..e197ed3 100644 > --- a/target/linux/ar71xx/image/Makefile > +++ b/target/linux/ar71xx/image/Makefile > @@ -1986,6 +1986,14 @@ Image/Build/CyberTANLZMA/buildkernel=$(call > MkuImageLzma,$(2),$(3) $(4)) > Image/Build/CyberTANLZMA=$(call > Image/Build/CyberTAN,$(1),$(2),$(3),$(4),$(5)) > > > +define Build/MerakiNAND > + -$(STAGING_DIR_HOST)/bin/mkmerakifw \ > + -B $(BOARDNAME) -s \ > + -i $@ \ > + -o $@.new > + @mv $@.new $@ > +endef > + > Image/Build/Netgear/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) > $(4),,-M $(5)) > > define Image/Build/Netgear/buildkernel > @@ -2426,6 +2434,19 @@ $(eval $(call MultiProfile,Madwifi,EAP7660D WP543)) > endif # ifeq ($(SUBTARGET),generic) > > ifeq ($(SUBTARGET),nand) > + > +define Device/mr18 > + BOARDNAME = MR18 > + BLOCKSIZE := 64k > + CONSOLE = ttyS0,115200 > + MTDPARTS = > ar934x-nfc:512k(nandloader)ro,8M(kernel),8M(recovery),113664k(ubi),128k@130944k(odm-caldata)ro > + IMAGES := sysupgrade.tar > + KERNEL := kernel-bin | patch-cmdline | MerakiNAND > + KERNEL_INITRAMFS := kernel-bin | patch-cmdline | MerakiNAND > + IMAGE/sysupgrade.tar := sysupgrade-nand > +endef > +TARGET_DEVICES += mr18 > + > $(eval $(call > SingleProfile,NetgearNAND,64k,WNDR3700V4,wndr3700v4,WNDR3700_V4,ttyS0,115200,$$(wndr4300_mtdlayout),0x33373033,WNDR3700v4,"",-H > 29763948+128+128,wndr4300)) > $(eval $(call > SingleProfile,NetgearNAND,64k,WNDR4300V1,wndr4300,WNDR4300,ttyS0,115200,$$(wndr4300_mtdlayout),0x33373033,WNDR4300,"",-H > 29763948+0+128+128+2x2+3x3,wndr4300)) > $(eval $(call > SingleProfile,NetgearNAND,64k,R6100,r6100,R6100,ttyS0,115200,$$(r6100_mtdlayout),0x36303030,R6100,"",-H > 29764434+0+128+128+2x2+2x2,wndr4300)) > diff --git a/target/linux/ar71xx/nand/config-default > b/target/linux/ar71xx/nand/config-default > index 50b6dbe..05f52af 100644 > --- a/target/linux/ar71xx/nand/config-default > +++ b/target/linux/ar71xx/nand/config-default > @@ -91,6 +91,7 @@ CONFIG_MTD_NAND=y > CONFIG_MTD_NAND_AR934X=y > CONFIG_MTD_NAND_AR934X_HW_ECC=y > CONFIG_MTD_NAND_ECC=y > +CONFIG_MTD_NAND_ECC_BCH=y > # CONFIG_MTD_REDBOOT_PARTS is not set > # CONFIG_MTD_SM_COMMON is not set > # CONFIG_MTD_SPLIT_SEAMA_FW is not set > diff --git a/target/linux/ar71xx/nand/profiles/meraki.mk > b/target/linux/ar71xx/nand/profiles/meraki.mk > new file mode 100644 > index 0000000..2c848c9 > --- /dev/null > +++ b/target/linux/ar71xx/nand/profiles/meraki.mk > @@ -0,0 +1,17 @@ > +# > +# Copyright (C) 2014-2015 Chris Blake (chrisrblak...@gmail.com) > +# > +# This is free software, licensed under the GNU General Public License v2. > +# See /LICENSE for more information. > +# > + > +define Profile/MR18 > + NAME:=Meraki MR18 > + PACKAGES:=kmod-spi-gpio kmod-ath9k > +endef > + > +define Profile/MR18/description > + Package set optimized for the Cisco Meraki MR18 Access Point. > +endef > + > +$(eval $(call Profile,MR18)) > _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel