ar71xx: add support for Cisco's MR18
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 <chrisrblake93@gmail.com> SVN-Revision: 47878
This commit is contained in:
parent
9e5044926b
commit
abc84551c0
@ -283,6 +283,10 @@ mr16)
|
|||||||
ucidef_set_led_wlan "wlan4" "WLAN4" "mr16:green:wifi4" "phy0tpt"
|
ucidef_set_led_wlan "wlan4" "WLAN4" "mr16:green:wifi4" "phy0tpt"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
mr18)
|
||||||
|
ucidef_set_led_netdev "wlan0" "WLAN0" "mr18:blue:tricolor0" "wlan0"
|
||||||
|
;;
|
||||||
|
|
||||||
mr600)
|
mr600)
|
||||||
ucidef_set_led_wlan "wlan58" "WLAN58" "mr600:green:wlan58" "phy0tpt"
|
ucidef_set_led_wlan "wlan58" "WLAN58" "mr600:green:wlan58" "phy0tpt"
|
||||||
;;
|
;;
|
||||||
|
@ -313,6 +313,7 @@ eap7660d |\
|
|||||||
el-mini |\
|
el-mini |\
|
||||||
loco-m-xw |\
|
loco-m-xw |\
|
||||||
mr1750 |\
|
mr1750 |\
|
||||||
|
mr18 |\
|
||||||
mr600 |\
|
mr600 |\
|
||||||
mr600v2 |\
|
mr600v2 |\
|
||||||
mr900 |\
|
mr900 |\
|
||||||
|
@ -152,6 +152,9 @@ get_status_led() {
|
|||||||
mr16)
|
mr16)
|
||||||
status_led="mr16:green:power"
|
status_led="mr16:green:power"
|
||||||
;;
|
;;
|
||||||
|
mr18)
|
||||||
|
status_led="mr18:green:tricolor0"
|
||||||
|
;;
|
||||||
mr600)
|
mr600)
|
||||||
status_led="mr600:orange:power"
|
status_led="mr600:orange:power"
|
||||||
;;
|
;;
|
||||||
|
@ -38,6 +38,14 @@ board=$(ar71xx_board_name)
|
|||||||
case "$FIRMWARE" in
|
case "$FIRMWARE" in
|
||||||
"soc_wmac.eeprom")
|
"soc_wmac.eeprom")
|
||||||
case $board in
|
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 | \
|
r6100 | \
|
||||||
wndr3700v4 | \
|
wndr3700v4 | \
|
||||||
wndr4300)
|
wndr4300)
|
||||||
@ -52,6 +60,14 @@ case "$FIRMWARE" in
|
|||||||
|
|
||||||
"pci_wmac0.eeprom")
|
"pci_wmac0.eeprom")
|
||||||
case $board in
|
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 | \
|
wndr3700v4 | \
|
||||||
wndr4300)
|
wndr4300)
|
||||||
ath9k_eeprom_extract "caldata" 20480 2048
|
ath9k_eeprom_extract "caldata" 20480 2048
|
||||||
@ -62,4 +78,20 @@ case "$FIRMWARE" in
|
|||||||
;;
|
;;
|
||||||
esac
|
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
|
esac
|
||||||
|
@ -551,6 +551,9 @@ ar71xx_board_detect() {
|
|||||||
*MR16)
|
*MR16)
|
||||||
name="mr16"
|
name="mr16"
|
||||||
;;
|
;;
|
||||||
|
*MR18)
|
||||||
|
name="mr18"
|
||||||
|
;;
|
||||||
*MR600v2)
|
*MR600v2)
|
||||||
name="mr600v2"
|
name="mr600v2"
|
||||||
;;
|
;;
|
||||||
|
@ -29,6 +29,10 @@ preinit_set_mac_address() {
|
|||||||
dir-615-i1)
|
dir-615-i1)
|
||||||
fetch_mac_from_mtd nvram sys_lan_mac sys_wan_mac
|
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)
|
r6100)
|
||||||
mac_lan=$(mtd_get_mac_binary caldata 0)
|
mac_lan=$(mtd_get_mac_binary caldata 0)
|
||||||
[ -n "$mac_lan" ] && ifconfig eth1 hw ether "$mac_lan"
|
[ -n "$mac_lan" ] && ifconfig eth1 hw ether "$mac_lan"
|
||||||
|
137
target/linux/ar71xx/base-files/lib/upgrade/merakinand.sh
Normal file
137
target/linux/ar71xx/base-files/lib/upgrade/merakinand.sh
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Copyright (C) 2015 Chris Blake <chrisrblake93@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
|
||||||
|
}
|
@ -434,6 +434,10 @@ platform_check_image() {
|
|||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
;;
|
;;
|
||||||
|
mr18)
|
||||||
|
merakinand_do_platform_check $board $1
|
||||||
|
return $?;
|
||||||
|
;;
|
||||||
nbg6716 | \
|
nbg6716 | \
|
||||||
r6100 | \
|
r6100 | \
|
||||||
wndr3700v4 | \
|
wndr3700v4 | \
|
||||||
@ -494,6 +498,9 @@ platform_pre_upgrade() {
|
|||||||
wndr4300 )
|
wndr4300 )
|
||||||
nand_do_upgrade "$1"
|
nand_do_upgrade "$1"
|
||||||
;;
|
;;
|
||||||
|
mr18)
|
||||||
|
merakinand_do_upgrade "$1"
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,6 +91,7 @@ CONFIG_ATH79_MACH_MC_MAC1200R=y
|
|||||||
CONFIG_ATH79_MACH_MR12=y
|
CONFIG_ATH79_MACH_MR12=y
|
||||||
CONFIG_ATH79_MACH_MR16=y
|
CONFIG_ATH79_MACH_MR16=y
|
||||||
CONFIG_ATH79_MACH_MR1750=y
|
CONFIG_ATH79_MACH_MR1750=y
|
||||||
|
CONFIG_ATH79_MACH_MR18=y
|
||||||
CONFIG_ATH79_MACH_MR600=y
|
CONFIG_ATH79_MACH_MR600=y
|
||||||
CONFIG_ATH79_MACH_MR900=y
|
CONFIG_ATH79_MACH_MR900=y
|
||||||
CONFIG_ATH79_MACH_MYNET_N600=y
|
CONFIG_ATH79_MACH_MYNET_N600=y
|
||||||
|
@ -853,6 +853,17 @@ config ATH79_MACH_MR16
|
|||||||
select ATH79_DEV_M25P80
|
select ATH79_DEV_M25P80
|
||||||
select ATH79_DEV_WMAC
|
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
|
config ATH79_MACH_MR600
|
||||||
bool "OpenMesh MR600 board support"
|
bool "OpenMesh MR600 board support"
|
||||||
select SOC_AR934X
|
select SOC_AR934X
|
||||||
|
@ -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_MC_MAC1200R) += mach-mc-mac1200r.o
|
||||||
obj-$(CONFIG_ATH79_MACH_MR12) += mach-mr12.o
|
obj-$(CONFIG_ATH79_MACH_MR12) += mach-mr12.o
|
||||||
obj-$(CONFIG_ATH79_MACH_MR16) += mach-mr16.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_MR1750) += mach-mr1750.o
|
||||||
obj-$(CONFIG_ATH79_MACH_MR600) += mach-mr600.o
|
obj-$(CONFIG_ATH79_MACH_MR600) += mach-mr600.o
|
||||||
obj-$(CONFIG_ATH79_MACH_MR900) += mach-mr900.o
|
obj-$(CONFIG_ATH79_MACH_MR900) += mach-mr900.o
|
||||||
|
297
target/linux/ar71xx/files/arch/mips/ath79/mach-mr18.c
Normal file
297
target/linux/ar71xx/files/arch/mips/ath79/mach-mr18.c
Normal file
@ -0,0 +1,297 @@
|
|||||||
|
/*
|
||||||
|
* Cisco Meraki MR18 board support
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 Chris Blake <chrisrblake93@gmail.com>
|
||||||
|
* Copyright (C) 2015 Christian Lamparter <chunkeey@googlemail.com>
|
||||||
|
* Copyright (C) 2015 Thomas Hebb <tommyhebb@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);
|
@ -87,6 +87,7 @@ enum ath79_mach_type {
|
|||||||
ATH79_MACH_HORNET_UB, /* ALFA Networks Hornet-UB */
|
ATH79_MACH_HORNET_UB, /* ALFA Networks Hornet-UB */
|
||||||
ATH79_MACH_MR12, /* Cisco Meraki MR12 */
|
ATH79_MACH_MR12, /* Cisco Meraki MR12 */
|
||||||
ATH79_MACH_MR16, /* Cisco Meraki MR16 */
|
ATH79_MACH_MR16, /* Cisco Meraki MR16 */
|
||||||
|
ATH79_MACH_MR18, /* Cisco Meraki MR18 */
|
||||||
ATH79_MACH_MR1750, /* OpenMesh MR1750 */
|
ATH79_MACH_MR1750, /* OpenMesh MR1750 */
|
||||||
ATH79_MACH_MR600V2, /* OpenMesh MR600v2 */
|
ATH79_MACH_MR600V2, /* OpenMesh MR600v2 */
|
||||||
ATH79_MACH_MR600, /* OpenMesh MR600 */
|
ATH79_MACH_MR600, /* OpenMesh MR600 */
|
||||||
|
@ -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))
|
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))
|
Image/Build/Netgear/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(4),,-M $(5))
|
||||||
|
|
||||||
define Image/Build/Netgear/buildkernel
|
define Image/Build/Netgear/buildkernel
|
||||||
@ -2426,6 +2434,19 @@ $(eval $(call MultiProfile,Madwifi,EAP7660D WP543))
|
|||||||
endif # ifeq ($(SUBTARGET),generic)
|
endif # ifeq ($(SUBTARGET),generic)
|
||||||
|
|
||||||
ifeq ($(SUBTARGET),nand)
|
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,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,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))
|
$(eval $(call SingleProfile,NetgearNAND,64k,R6100,r6100,R6100,ttyS0,115200,$$(r6100_mtdlayout),0x36303030,R6100,"",-H 29764434+0+128+128+2x2+2x2,wndr4300))
|
||||||
|
@ -91,6 +91,7 @@ CONFIG_MTD_NAND=y
|
|||||||
CONFIG_MTD_NAND_AR934X=y
|
CONFIG_MTD_NAND_AR934X=y
|
||||||
CONFIG_MTD_NAND_AR934X_HW_ECC=y
|
CONFIG_MTD_NAND_AR934X_HW_ECC=y
|
||||||
CONFIG_MTD_NAND_ECC=y
|
CONFIG_MTD_NAND_ECC=y
|
||||||
|
CONFIG_MTD_NAND_ECC_BCH=y
|
||||||
# CONFIG_MTD_REDBOOT_PARTS is not set
|
# CONFIG_MTD_REDBOOT_PARTS is not set
|
||||||
# CONFIG_MTD_SM_COMMON is not set
|
# CONFIG_MTD_SM_COMMON is not set
|
||||||
# CONFIG_MTD_SPLIT_SEAMA_FW is not set
|
# CONFIG_MTD_SPLIT_SEAMA_FW is not set
|
||||||
|
17
target/linux/ar71xx/nand/profiles/meraki.mk
Normal file
17
target/linux/ar71xx/nand/profiles/meraki.mk
Normal file
@ -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))
|
Loading…
Reference in New Issue
Block a user