From patchwork Thu Sep 17 15:27:27 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Lamparter X-Patchwork-Id: 518915 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from arrakis.dune.hu (arrakis.dune.hu [78.24.191.176]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id DEEC1141567 for ; Fri, 18 Sep 2015 01:30:20 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=googlemail.com header.i=@googlemail.com header.b=ATzPtp51; dkim-atps=neutral Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id ED812289C79; Thu, 17 Sep 2015 17:27:19 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on arrakis.dune.hu X-Spam-Level: X-Spam-Status: No, score=-1.5 required=5.0 tests=BAYES_00,FREEMAIL_FROM, T_DKIM_INVALID autolearn=unavailable version=3.3.2 Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id 74E98284DDB for ; Thu, 17 Sep 2015 17:26:53 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 CL_IP_EQ_HELO_IP=-2 (check from: .googlemail. - helo: .mail-wi0-f176.google. - helo-domain: .google.) FROM/MX_MATCHES_HELO(DOMAIN)=-2; rate: -8.5 Received: from mail-wi0-f176.google.com (mail-wi0-f176.google.com [209.85.212.176]) by arrakis.dune.hu (Postfix) with ESMTPS for ; Thu, 17 Sep 2015 17:26:47 +0200 (CEST) Received: by wicgb1 with SMTP id gb1so122962680wic.1 for ; Thu, 17 Sep 2015 08:27:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20120113; h=from:to:cc:subject:date:message-id:user-agent:mime-version :content-transfer-encoding:content-type; bh=XUvcEaFSm9yZBL2OLa9O7m7P/FEwxWF21cKJp+BJbZo=; b=ATzPtp51NTwoZrboqJkDoxMLJQwhDyUiJ1116wiXiyQGvTleIDJoyRHoEB+SQcqi9/ 0MAlsCvgQs+CxZQ8KFlIzVUYyqGF4SeBMz4Ufr69W+N6a2n7XyZUjSzqGXIX2yqh+Nym Q/12OhsFpWxu73VQOf4EsWOnvaYY/9sUImmDNelJ4NMKaMOG4ubjoLfDhwgfDd4IbHNM xllAkm8U2mpcEe4hVSAIC2chLxM5JoAHIXXybSy/qXwtGdRtrkNMwjjXAp7BWTBV7sJc 1GRkzBHmJyUmBD3vefZ6HuHyoPfe8kP6znRTbODHR3Bb+vIUADwc74M7I1NLkj1Gy8PJ qkAA== X-Received: by 10.180.96.164 with SMTP id dt4mr32250478wib.53.1442503648902; Thu, 17 Sep 2015 08:27:28 -0700 (PDT) Received: from debian64.daheim (pD9F8873C.dip0.t-ipconnect.de. [217.248.135.60]) by smtp.googlemail.com with ESMTPSA id bi6sm3967598wjc.25.2015.09.17.08.27.27 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 17 Sep 2015 08:27:28 -0700 (PDT) From: Chris R Blake X-Google-Original-From: Chris R Blake Received: from localhost.daheim ([127.0.0.1] helo=debian64.localnet) by debian64.daheim with esmtps (TLS1.0:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.86) (envelope-from ) id 1Zcb5r-00088I-Du; Thu, 17 Sep 2015 17:27:27 +0200 To: openwrt-devel@lists.openwrt.org Date: Thu, 17 Sep 2015 17:27:27 +0200 Message-ID: <1574370.QZ0ctRuMxh@debian64> User-Agent: KMail/4.14.2 (Linux/4.3.0-rc1-wl+; KDE/4.14.10; x86_64; ; ) MIME-Version: 1.0 Subject: [OpenWrt-Devel] [RFC 5/5] ar71xx: add support for Cisco's MR18 X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: openwrt-devel-bounces@lists.openwrt.org Sender: "openwrt-devel" From: Chris R Blake This patch adds support for Cisco's MR18. Detailed instructions for the flashing the device can be found in the OpenWrt forum thread: Signed-off-by: Chris R Blake --- package/base-files/files/lib/functions/system.sh | 17 ++ target/linux/ar71xx/base-files/etc/diag.sh | 3 + .../etc/hotplug.d/firmware/10-ath9k-eeprom | 39 +++- .../ar71xx/base-files/etc/uci-defaults/01_leds | 4 + .../ar71xx/base-files/etc/uci-defaults/02_network | 1 + 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 | 136 +++++++++++ .../ar71xx/base-files/lib/upgrade/platform.sh | 4 + target/linux/ar71xx/config-4.1 | 1 + .../linux/ar71xx/files/arch/mips/ath79/mach-mr18.c | 254 +++++++++++++++++++++ target/linux/ar71xx/image/Makefile | 34 +++ target/linux/ar71xx/nand/config-default | 1 + target/linux/ar71xx/nand/profiles/meraki.mk | 17 ++ .../817-MIPS-ath79-add-meraki-mr18-support.patch | 41 ++++ 15 files changed, 558 insertions(+), 1 deletion(-) 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 create mode 100644 target/linux/ar71xx/patches-4.1/817-MIPS-ath79-add-meraki-mr18-support.patch diff --git a/package/base-files/files/lib/functions/system.sh b/package/base-files/files/lib/functions/system.sh index 8d75a5a..2f5d063 100644 --- a/package/base-files/files/lib/functions/system.sh +++ b/package/base-files/files/lib/functions/system.sh @@ -41,6 +41,23 @@ mtd_get_mac_binary() { dd bs=1 skip=$offset count=6 if=$part 2>/dev/null | hexdump -v -n 6 -e '5/1 "%02x:" 1/1 "%02x"' } +mtd_get_mac_binary_ubi() { + local mtdname="$1" + local offset="$2" + + . /lib/upgrade/nand.sh + + local ubidev=$(nand_find_ubi $CI_UBIPART) + local part="$(nand_find_volume $ubidev $mtdname)" + + if [ -z "$part" ]; then + echo "mtd_get_mac_binary: ubi partition $mtdname not found!" >&2 + return + fi + + dd bs=1 skip=$offset count=6 if=/dev/$part 2>/dev/null | hexdump -v -n 6 -e '5/1 "%02x:" 1/1 "%02x"' +} + mtd_get_part_size() { local part_name=$1 local first dev size erasesize name diff --git a/target/linux/ar71xx/base-files/etc/diag.sh b/target/linux/ar71xx/base-files/etc/diag.sh index cfba6b4..d6cc23f 100644 --- a/target/linux/ar71xx/base-files/etc/diag.sh +++ b/target/linux/ar71xx/base-files/etc/diag.sh @@ -144,6 +144,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 b5f0588..381ff55 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 @@ -9,11 +9,14 @@ ath9k_eeprom_extract() { local part=$1 local offset=$2 local count=$3 + local ubidev=$(nand_find_ubi $CI_UBIPART) local mtd mtd=$(find_mtd_chardev $part) [ -n "$mtd" ] || \ - ath9k_eeprom_die "no mtd device found for partition $part" + mtd="/dev/$(nand_find_volume $ubidev $part)" + [ -n "$mtd" ] || \ + ath9k_eeprom_die "no mtd device found for partition $part" dd if=$mtd of=/lib/firmware/$FIRMWARE bs=1 skip=$offset count=$count 2>/dev/null || \ ath9k_eeprom_die "failed to extract from $mtd" @@ -29,15 +32,25 @@ ath9k_patch_firmware_mac() { [ -e /lib/firmware/$FIRMWARE ] && exit 0 + . /lib/ar71xx.sh . /lib/functions.sh . /lib/functions/system.sh +. /lib/upgrade/nand.sh board=$(ar71xx_board_name) case "$FIRMWARE" in "soc_wmac.eeprom") case $board in + mr18) + if [ -n "$(nand_find_volume ubi0 caldata)" ]; then + ath9k_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) @@ -52,6 +65,14 @@ case "$FIRMWARE" in "pci_wmac0.eeprom") case $board in + mr18) + if [ -n "$(nand_find_volume ubi0 caldata)" ]; then + ath9k_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 @@ -62,4 +83,20 @@ case "$FIRMWARE" in ;; esac ;; + +"pci_wmac1.eeprom") + case $board in + mr18) + if [ -n "$(nand_find_volume ubi0 caldata)" ]; then + ath9k_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/etc/uci-defaults/01_leds b/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds index fac4751..dcf4aa5 100644 --- a/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds +++ b/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds @@ -260,6 +260,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/uci-defaults/02_network b/target/linux/ar71xx/base-files/etc/uci-defaults/02_network index 880953c..2be8d68 100644 --- a/target/linux/ar71xx/base-files/etc/uci-defaults/02_network +++ b/target/linux/ar71xx/base-files/etc/uci-defaults/02_network @@ -347,6 +347,7 @@ eap7660d |\ el-mini |\ loco-m-xw |\ mr1750 |\ +mr18 |\ mr600 |\ mr600v2 |\ mr900 |\ diff --git a/target/linux/ar71xx/base-files/lib/ar71xx.sh b/target/linux/ar71xx/base-files/lib/ar71xx.sh index efb3d16..ed20e16 100755 --- a/target/linux/ar71xx/base-files/lib/ar71xx.sh +++ b/target/linux/ar71xx/base-files/lib/ar71xx.sh @@ -520,6 +520,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..0069127 --- /dev/null +++ b/target/linux/ar71xx/base-files/lib/upgrade/merakinand.sh @@ -0,0 +1,136 @@ +#!/bin/sh +# +# Copyright (C) 2015 Chris Blake +# +# 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 + # To:Do possibly add create (hard to do when rootfs_data is expanded) + mtd_dst="/dev/$(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 "$mtd_dst" && { + echo "Copying calibration data from $cal_src to $cal_dst..." + dd if="$mtd_src" of=/tmp/caldata.tmp 2>/dev/null + ubiupdatevol "$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 cad8b43..0ca2257 100755 --- a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh +++ b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh @@ -424,6 +424,10 @@ platform_check_image() { } return 0 ;; + mr18) + merakinand_do_platform_check $board $1 + return $?; + ;; nbg6716 | \ r6100 | \ wndr3700v4 | \ diff --git a/target/linux/ar71xx/config-4.1 b/target/linux/ar71xx/config-4.1 index 51f2f2f..8fff692 100644 --- a/target/linux/ar71xx/config-4.1 +++ b/target/linux/ar71xx/config-4.1 @@ -84,6 +84,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/mach-mr18.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-mr18.c new file mode 100644 index 0000000..1ce5c83 --- /dev/null +++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-mr18.c @@ -0,0 +1,254 @@ +/* + * Cisco Meraki MR18 board support + * + * Copyright (C) 2015 Chris Blake + * Copyright (C) 2015 Christian Lamparter + * Copyright (C) 2015 Thomas Hebb + * + * 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 +#include +#include +#include + +#include +#include + +#include +#include + +#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; +} + +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); + ath79_setup_qca955x_eth_rx_delay(3, 3); + + /* MDIO Interface */ + ath79_register_mdio(0, 0x0); + + ath79_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/image/Makefile b/target/linux/ar71xx/image/Makefile index b00846f..f18aa05 100644 --- a/target/linux/ar71xx/image/Makefile +++ b/target/linux/ar71xx/image/Makefile @@ -1273,6 +1273,7 @@ dragino2_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,16000k(firmware),64k(config)ro hiwifi_hc6361_mtdlayout=mtdparts=spi0.0:64k(u-boot)ro,64k(bdinfo)ro,1280k(kernel),14848k(rootfs),64k(backup)ro,64k(art)ro,16128k@0x20000(firmware) mr12_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,256k(u-boot-env)ro,13440k(rootfs),2304k(kernel),128k(art)ro,15744k@0x80000(firmware) mr16_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,256k(u-boot-env)ro,13440k(rootfs),2304k(kernel),128k(art)ro,15744k@0x80000(firmware) +mr18_mtdlayout=mtdparts=ar934x-nfc:512k(nandloader)ro,8M(kernel),8M(recovery),113664k(ubi),128k@130944k(odm-caldata)ro pb92_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,2752k(rootfs),896k(kernel),64k(nvram),64k(art)ro,3648k@0x50000(firmware) planex_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,7744k(firmware),128k(art)ro ubntxm_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,7552k(firmware),256k(cfg)ro,64k(EEPROM)ro @@ -1877,6 +1878,37 @@ Image/Build/CyberTANLZMA/buildkernel=$(call MkuImageLzma,$(2),$(3) $(4)) Image/Build/CyberTANLZMA=$(call Image/Build/CyberTAN,$(1),$(2),$(3),$(4),$(5)) +define Image/Build/MerakiNAND/initramfs + $(eval kernelsize=$(call mtdpartsize,kernel,$(4))) + $(call PatchKernel,$(2),$(3) $(4),"-initramfs") + -$(STAGING_DIR_HOST)/bin/mkmerakifw \ + -B $(2) -s \ + -i $(KDIR_TMP)/vmlinux-initramfs-$(2) \ + -o $(KDIR_TMP)/vmlinux-initramfs-$(2)-patched + $(CP) $(KDIR_TMP)/vmlinux-initramfs-$(2)-patched $(BIN_DIR)/$(IMG_PREFIX)-$(2)-initramfs.bin +endef + +define Image/Build/MerakiNAND/buildkernel + $(eval kernelsize=$(call mtdpartsize,kernel,$(4))) + $(call PatchKernel,$(2),$(3) $(4),"") + -$(STAGING_DIR_HOST)/bin/mkmerakifw \ + -B $(2) -s \ + -i $(KDIR_TMP)/vmlinux-$(2) \ + -o $(KDIR_TMP)/vmlinux-$(2)-patched + $(CP) $(KDIR_TMP)/vmlinux-$(2)-patched $(BIN_DIR)/$(IMG_PREFIX)-$(2)-kernel.bin + +endef + +define Image/Build/MerakiNAND + $(eval fwsize=$(call mtdpartsize,firmware,$(4))) + $(eval rootsize=$(call mtdpartsize,rootfs,$(4))) + $(eval kernsize=$(call mtdpartsize,kernel,$(4))) + dd if=$(KDIR)/root.$(1) \ + of=$(call imgname,$(1),$(2)-rootfs).bin bs=128k conv=sync; \ + $(call Image/Build/SysupgradeNAND,$(2),squashfs,$(KDIR_TMP)/vmlinux-$(2)-patched) +endef + + Image/Build/Netgear/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4),,-M $(5)) define Image/Build/Netgear/buildkernel @@ -2323,6 +2355,8 @@ $(eval $(call MultiProfile,Madwifi,EAP7660D WP543)) endif # ifeq ($(SUBTARGET),generic) ifeq ($(SUBTARGET),nand) +$(eval $(call SingleProfile,MerakiNAND,64k,MR18,mr18,MR18,ttyS0,115200,$$(mr18_mtdlayout))) + $(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 (chrisrblake93@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)) diff --git a/target/linux/ar71xx/patches-4.1/817-MIPS-ath79-add-meraki-mr18-support.patch b/target/linux/ar71xx/patches-4.1/817-MIPS-ath79-add-meraki-mr18-support.patch new file mode 100644 index 0000000..a36075a --- /dev/null +++ b/target/linux/ar71xx/patches-4.1/817-MIPS-ath79-add-meraki-mr18-support.patch @@ -0,0 +1,41 @@ +--- a/arch/mips/ath79/Kconfig ++++ b/arch/mips/ath79/Kconfig +@@ -824,6 +824,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 + +--- a/arch/mips/ath79/Makefile ++++ b/arch/mips/ath79/Makefile +@@ -91,6 +91,7 @@ obj-$(CONFIG_ATH79_MACH_HORNET_UB) += ma + 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 +--- a/arch/mips/ath79/machtypes.h ++++ b/arch/mips/ath79/machtypes.h +@@ -80,6 +80,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 */