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

Reply via email to