From 4becc7dbbd3e8543d4b4f55f033197c4bdda1152 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 29 May 2016 14:28:16 +0200 Subject: [PATCH] Backport fixes for the WNR2200 --- ...xx-Send-power-to-USB-port-on-WNR2200.patch | 41 +++ ...71xx-WNR2200-fix-for-random-WLAN-MAC.patch | 86 ++++++ ...able-control-of-all-LEDs-and-buttons.patch | 251 ++++++++++++++++++ 3 files changed, 378 insertions(+) create mode 100644 patches/openwrt/0087-ar71xx-Send-power-to-USB-port-on-WNR2200.patch create mode 100644 patches/openwrt/0088-ar71xx-WNR2200-fix-for-random-WLAN-MAC.patch create mode 100644 patches/openwrt/0089-ar71xx-WNR2200-enable-control-of-all-LEDs-and-buttons.patch diff --git a/patches/openwrt/0087-ar71xx-Send-power-to-USB-port-on-WNR2200.patch b/patches/openwrt/0087-ar71xx-Send-power-to-USB-port-on-WNR2200.patch new file mode 100644 index 00000000..42906fc8 --- /dev/null +++ b/patches/openwrt/0087-ar71xx-Send-power-to-USB-port-on-WNR2200.patch @@ -0,0 +1,41 @@ +From: Matthias Schiffer +Date: Sun, 29 May 2016 11:37:08 +0200 +Subject: ar71xx: Send power to USB port on WNR2200 + +This patch fixes ticket #15267 by enabling power on the +WNR2200's USB port. At present, the USB port on the WNR2200 +is non-functional due to it not receiving power. + +This patch defines an additional GPIO pin, but none of the +current GPIO definitions have been modified. + +Signed-off-by: Riley Baird + +Backport of r47236 + +diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2200.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2200.c +index 0087cac..5d23f21 100644 +--- a/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2200.c ++++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2200.c +@@ -36,7 +36,7 @@ + #define WNR2200_GPIO_LED_LAN4_GREEN 16 + #define WNR2200_GPIO_LED_PWR_AMBER 21 + #define WNR2200_GPIO_LED_PWR_GREEN 22 +- ++#define WNR2200_GPIO_USB_5V 4 + #define WNR2200_GPIO_USB_POWER 24 + + #define WNR2200_KEYS_POLL_INTERVAL 20 /* msecs */ +@@ -128,9 +128,9 @@ static void __init wnr2200_setup(void) + wnr2200_leds_gpio); + + /* enable power for the USB port */ +- gpio_request_one(WNR2200_GPIO_USB_POWER, +- GPIOF_OUT_INIT_HIGH | GPIOF_EXPORT_DIR_FIXED, +- "USB power"); ++ ap9x_pci_setup_wmac_gpio(0, ++ BIT(WNR2200_GPIO_USB_5V), ++ BIT(WNR2200_GPIO_USB_5V)); + + ath79_register_usb(); + } diff --git a/patches/openwrt/0088-ar71xx-WNR2200-fix-for-random-WLAN-MAC.patch b/patches/openwrt/0088-ar71xx-WNR2200-fix-for-random-WLAN-MAC.patch new file mode 100644 index 00000000..b2fb55c1 --- /dev/null +++ b/patches/openwrt/0088-ar71xx-WNR2200-fix-for-random-WLAN-MAC.patch @@ -0,0 +1,86 @@ +From: Matthias Schiffer +Date: Sun, 29 May 2016 11:45:14 +0200 +Subject: ar71xx: WNR2200: fix for random WLAN MAC + +Fix for invalid/random/duplicate WLAN MAC address in WNR2200. +Permanent platform MAC is calculated and assigned during system startup. +WLAN MAC follows wired Ethernet interface addresses. + +Signed-off-by: Michal Cieslakiewicz + +Backport of r49100 + +diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2200.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2200.c +index 5d23f21..37ffc4c 100644 +--- a/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2200.c ++++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2200.c +@@ -12,6 +12,7 @@ + + #include + #include ++#include /* for max() macro */ + + #include + +@@ -45,6 +46,7 @@ + #define WNR2200_MAC0_OFFSET 0 + #define WNR2200_MAC1_OFFSET 6 + #define WNR2200_PCIE_CALDATA_OFFSET 0x1000 ++#define WNR2200_WMAC_OFFSET 0x108c /* wireless MAC is inside ART */ + + static struct gpio_led wnr2200_leds_gpio[] __initdata = { + { +@@ -102,9 +104,40 @@ static struct gpio_led wnr2200_leds_gpio[] __initdata = { + } + }; + ++/* ++ * For WNR2200 ART flash area used for WLAN MAC is usually empty (0xff) ++ * so ath9k driver uses random MAC instead each time module is loaded. ++ * OpenWrt's original fix was to copy eth1 address to WLAN interface. ++ * New solution does not duplicate hardware addresses and is taken from ++ * WNR2000v3 code. It assigns permanent WLAN MAC equal to ethN's MAC ++ * plus 1, so network interfaces get sequential addresses. ++ * If ART wireless MAC address field has been filled by user, use it. ++ */ ++static void __init wnr2200_get_wmac(u8 *wmac_gen_addr, int mac0_art_offset, ++ int mac1_art_offset, int wmac_art_offset) ++{ ++ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); ++ u8 *eth0_mac_addr = (u8 *) (art + mac0_art_offset); ++ u8 *eth1_mac_addr = (u8 *) (art + mac1_art_offset); ++ u8 *wlan_mac_addr = (u8 *) (art + wmac_art_offset); ++ ++ /* only 0xff if all bits are set - address is invalid, empty area */ ++ if ((wlan_mac_addr[0] & wlan_mac_addr[1] & wlan_mac_addr[2] & ++ wlan_mac_addr[3] & wlan_mac_addr[4] & wlan_mac_addr[5]) == 0xff) { ++ memcpy(wmac_gen_addr, eth0_mac_addr, 5); ++ wmac_gen_addr[5] = max(eth0_mac_addr[5], eth1_mac_addr[5]) + 1; ++ ++ /* Avoid potential conflict in case max(0xff,0x00)+1==0x00 */ ++ if (!wmac_gen_addr[5]) ++ wmac_gen_addr[5] = 1; ++ } else ++ memcpy(wmac_gen_addr, wlan_mac_addr, 6); ++} ++ + static void __init wnr2200_setup(void) + { + u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); ++ u8 wlan_mac_addr[6]; + + ath79_register_mdio(0, 0x0); + +@@ -121,8 +154,10 @@ static void __init wnr2200_setup(void) + ath79_register_eth(1); + + ath79_register_m25p80(NULL); +- ap91_pci_init(art + WNR2200_PCIE_CALDATA_OFFSET, +- art + WNR2200_MAC1_OFFSET); ++ ++ wnr2200_get_wmac(wlan_mac_addr, WNR2200_MAC0_OFFSET, ++ WNR2200_MAC1_OFFSET, WNR2200_WMAC_OFFSET); ++ ap91_pci_init(art + WNR2200_PCIE_CALDATA_OFFSET, wlan_mac_addr); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(wnr2200_leds_gpio), + wnr2200_leds_gpio); diff --git a/patches/openwrt/0089-ar71xx-WNR2200-enable-control-of-all-LEDs-and-buttons.patch b/patches/openwrt/0089-ar71xx-WNR2200-enable-control-of-all-LEDs-and-buttons.patch new file mode 100644 index 00000000..853104ce --- /dev/null +++ b/patches/openwrt/0089-ar71xx-WNR2200-enable-control-of-all-LEDs-and-buttons.patch @@ -0,0 +1,251 @@ +From: Matthias Schiffer +Date: Sun, 29 May 2016 11:50:03 +0200 +Subject: ar71xx: WNR2200: enable control of all LEDs and buttons + +This patch provides full GPIO support for WNR2200 (LEDs and buttons). +It exposes all LEDs to operating system, including Ethernet ones. + +Signed-off-by: Michal Cieslakiewicz + +Backport of r49101 + +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 9a768cd..ae17853 100644 +--- a/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds ++++ b/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds +@@ -590,6 +590,21 @@ wnr2000-v4) + ucidef_set_led_usbdev "usb" "USB" "netgear:amber:status" "1-1" + ;; + ++wnr2200) ++ ucidef_set_led_netdev "wan-amber" "WAN (amber)" "netgear:amber:wan" "eth0" ++ ucidef_set_led_default "wan-green" "WAN (green)" "netgear:green:wan" "0" ++ ucidef_set_led_netdev "wlan" "WLAN" "netgear:blue:wlan" "wlan0" ++ ucidef_set_led_switch "lan1green" "LAN1 (green)" "netgear:green:lan1" "switch0" "0x02" "0x04" ++ ucidef_set_led_switch "lan2green" "LAN2 (green)" "netgear:green:lan2" "switch0" "0x04" "0x04" ++ ucidef_set_led_switch "lan3green" "LAN3 (green)" "netgear:green:lan3" "switch0" "0x08" "0x04" ++ ucidef_set_led_switch "lan4green" "LAN4 (green)" "netgear:green:lan4" "switch0" "0x10" "0x04" ++ ucidef_set_led_switch "lan1amber" "LAN1 (amber)" "netgear:amber:lan1" "switch0" "0x02" "0x02" ++ ucidef_set_led_switch "lan2amber" "LAN2 (amber)" "netgear:amber:lan2" "switch0" "0x04" "0x02" ++ ucidef_set_led_switch "lan3amber" "LAN3 (amber)" "netgear:amber:lan3" "switch0" "0x08" "0x02" ++ ucidef_set_led_switch "lan4amber" "LAN4 (amber)" "netgear:amber:lan4" "switch0" "0x10" "0x02" ++ ucidef_set_led_usbdev "usb" "USB" "netgear:green:usb" "1-1" ++ ;; ++ + wpn824n) + ucidef_set_led_netdev "wan-amber" "WAN (amber)" "netgear:amber:wan" "eth0" + ucidef_set_led_wlan "wlan" "WLAN" "netgear:blue:wlan" "phy0tpt" +diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2200.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2200.c +index 37ffc4c..258d254 100644 +--- a/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2200.c ++++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-wnr2200.c +@@ -15,6 +15,8 @@ + #include /* for max() macro */ + + #include ++#include /* needed to disable switch LEDs */ ++#include "common.h" /* needed to disable switch LEDs */ + + #include "dev-ap9x-pci.h" + #include "dev-eth.h" +@@ -24,21 +26,28 @@ + #include "dev-usb.h" + #include "machtypes.h" + ++/* WNR2200 - connected through AR7241 */ + #define WNR2200_GPIO_LED_LAN2_AMBER 0 + #define WNR2200_GPIO_LED_LAN4_AMBER 1 +-#define WNR2200_GPIO_LED_WPS 5 +-#define WNR2200_GPIO_LED_WAN_GREEN 7 +-#define WNR2200_GPIO_LED_USB 8 ++#define WNR2200_GPIO_LED_LAN1_AMBER 6 /* AR724X_GPIO_FUNC_JTAG_DISABLE */ ++#define WNR2200_GPIO_LED_WPS_GREEN 7 /* AR724X_GPIO_FUNC_JTAG_DISABLE */ ++#define WNR2200_GPIO_LED_USB_GREEN 8 /* AR724X_GPIO_FUNC_JTAG_DISABLE */ + #define WNR2200_GPIO_LED_LAN3_AMBER 11 + #define WNR2200_GPIO_LED_WAN_AMBER 12 +-#define WNR2200_GPIO_LED_LAN1_GREEN 13 +-#define WNR2200_GPIO_LED_LAN2_GREEN 14 +-#define WNR2200_GPIO_LED_LAN3_GREEN 15 +-#define WNR2200_GPIO_LED_LAN4_GREEN 16 +-#define WNR2200_GPIO_LED_PWR_AMBER 21 +-#define WNR2200_GPIO_LED_PWR_GREEN 22 +-#define WNR2200_GPIO_USB_5V 4 +-#define WNR2200_GPIO_USB_POWER 24 ++#define WNR2200_GPIO_LED_LAN1_GREEN 13 /* AR724X_..._ETH_SWITCH_LED0 */ ++#define WNR2200_GPIO_LED_LAN2_GREEN 14 /* AR724X_..._ETH_SWITCH_LED1 */ ++#define WNR2200_GPIO_LED_LAN3_GREEN 15 /* AR724X_..._ETH_SWITCH_LED2 */ ++#define WNR2200_GPIO_LED_LAN4_GREEN 16 /* AR724X_..._ETH_SWITCH_LED3 */ ++#define WNR2200_GPIO_LED_WAN_GREEN 17 /* AR724X_..._ETH_SWITCH_LED4 */ ++ ++/* WNR2200 - connected through AR9287 */ ++#define WNR2200_GPIO_WMAC_LED_WLAN_BLUE 0 ++#define WNR2200_GPIO_WMAC_LED_TEST_AMBER 1 ++#define WNR2200_GPIO_WMAC_LED_POWER_GREEN 2 ++#define WNR2200_GPIO_WMAC_BTN_RFKILL 3 ++#define WNR2200_GPIO_WMAC_USB_5V 4 ++#define WNR2200_GPIO_WMAC_BTN_WPS 5 ++#define WNR2200_GPIO_WMAC_BTN_RESET 6 + + #define WNR2200_KEYS_POLL_INTERVAL 20 /* msecs */ + #define WNR2200_KEYS_DEBOUNCE_INTERVAL (3 * WNR2200_KEYS_POLL_INTERVAL) +@@ -50,30 +59,22 @@ + + static struct gpio_led wnr2200_leds_gpio[] __initdata = { + { +- .name = "netgear:amber:lan2", +- .gpio = WNR2200_GPIO_LED_LAN2_AMBER, +- .active_low = 1, +- }, { +- .name = "netgear:amber:lan4", +- .gpio = WNR2200_GPIO_LED_LAN4_AMBER, +- .active_low = 1, +- }, { +- .name = "netgear:green:wps", +- .gpio = WNR2200_GPIO_LED_WPS, +- .active_low = 1, +- }, { +- .name = "netgear:green:wan", +- .gpio = WNR2200_GPIO_LED_WAN_GREEN, ++ .name = "netgear:amber:lan1", ++ .gpio = WNR2200_GPIO_LED_LAN1_AMBER, + .active_low = 1, + }, { +- .name = "netgear:green:usb", +- .gpio = WNR2200_GPIO_LED_USB, ++ .name = "netgear:amber:lan2", ++ .gpio = WNR2200_GPIO_LED_LAN2_AMBER, + .active_low = 1, + }, { + .name = "netgear:amber:lan3", + .gpio = WNR2200_GPIO_LED_LAN3_AMBER, + .active_low = 1, + }, { ++ .name = "netgear:amber:lan4", ++ .gpio = WNR2200_GPIO_LED_LAN4_AMBER, ++ .active_low = 1, ++ }, { + .name = "netgear:amber:wan", + .gpio = WNR2200_GPIO_LED_WAN_AMBER, + .active_low = 1, +@@ -94,12 +95,56 @@ static struct gpio_led wnr2200_leds_gpio[] __initdata = { + .gpio = WNR2200_GPIO_LED_LAN4_GREEN, + .active_low = 1, + }, { +- .name = "netgear:amber:power", +- .gpio = WNR2200_GPIO_LED_PWR_AMBER, ++ .name = "netgear:green:usb", ++ .gpio = WNR2200_GPIO_LED_USB_GREEN, ++ .active_low = 1, ++ }, { ++ .name = "netgear:green:wan", ++ .gpio = WNR2200_GPIO_LED_WAN_GREEN, ++ .active_low = 1, ++ }, { ++ .name = "netgear:green:wps", ++ .gpio = WNR2200_GPIO_LED_WPS_GREEN, ++ .active_low = 1, ++ } ++}; ++ ++static const char *wnr2200_wmac_led_name = "netgear:blue:wlan"; ++ ++static struct gpio_led wnr2200_wmac_leds_gpio[] = { ++ { ++ .name = "netgear:amber:test", ++ .gpio = WNR2200_GPIO_WMAC_LED_TEST_AMBER, + .active_low = 1, + }, { + .name = "netgear:green:power", +- .gpio = WNR2200_GPIO_LED_PWR_GREEN, ++ .gpio = WNR2200_GPIO_WMAC_LED_POWER_GREEN, ++ .active_low = 1, ++ .default_state = LEDS_GPIO_DEFSTATE_ON, ++ } ++}; ++ ++static struct gpio_keys_button wnr2200_wmac_keys_gpio[] = { ++ { ++ .desc = "reset", ++ .type = EV_KEY, ++ .code = KEY_RESTART, ++ .debounce_interval = WNR2200_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WNR2200_GPIO_WMAC_BTN_RESET, ++ .active_low = 1, ++ }, { ++ .desc = "rfkill", ++ .type = EV_KEY, ++ .code = KEY_RFKILL, ++ .debounce_interval = WNR2200_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WNR2200_GPIO_WMAC_BTN_RFKILL, ++ .active_low = 1, ++ }, { ++ .desc = "wps", ++ .type = EV_KEY, ++ .code = KEY_WPS_BUTTON, ++ .debounce_interval = WNR2200_KEYS_DEBOUNCE_INTERVAL, ++ .gpio = WNR2200_GPIO_WMAC_BTN_WPS, + .active_low = 1, + } + }; +@@ -139,14 +184,32 @@ static void __init wnr2200_setup(void) + u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); + u8 wlan_mac_addr[6]; + ++ /* ++ * Disable JTAG to use all AR724X GPIO LEDs. Disable CLKs. ++ * Allow OS to control all link LEDs. ++ */ ++ ath79_gpio_function_setup(AR724X_GPIO_FUNC_JTAG_DISABLE | ++ AR724X_GPIO_FUNC_UART_EN, ++ AR724X_GPIO_FUNC_CLK_OBS1_EN | ++ AR724X_GPIO_FUNC_CLK_OBS2_EN | ++ AR724X_GPIO_FUNC_CLK_OBS3_EN | ++ AR724X_GPIO_FUNC_CLK_OBS4_EN | ++ AR724X_GPIO_FUNC_CLK_OBS5_EN | ++ AR724X_GPIO_FUNC_GE0_MII_CLK_EN | ++ AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN | ++ AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN | ++ AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN | ++ AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN | ++ AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN); ++ + ath79_register_mdio(0, 0x0); + +- ath79_init_mac(ath79_eth0_data.mac_addr, art+WNR2200_MAC0_OFFSET, 0); ++ ath79_init_mac(ath79_eth0_data.mac_addr, art + WNR2200_MAC0_OFFSET, 0); + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ath79_eth0_data.speed = SPEED_100; + ath79_eth0_data.duplex = DUPLEX_FULL; + +- ath79_init_mac(ath79_eth1_data.mac_addr, art+WNR2200_MAC1_OFFSET, 0); ++ ath79_init_mac(ath79_eth1_data.mac_addr, art + WNR2200_MAC1_OFFSET, 0); + ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; + ath79_eth1_data.phy_mask = 0x10; + +@@ -160,12 +223,22 @@ static void __init wnr2200_setup(void) + ap91_pci_init(art + WNR2200_PCIE_CALDATA_OFFSET, wlan_mac_addr); + + ath79_register_leds_gpio(-1, ARRAY_SIZE(wnr2200_leds_gpio), +- wnr2200_leds_gpio); ++ wnr2200_leds_gpio); ++ ++ ap9x_pci_setup_wmac_led_pin(0, WNR2200_GPIO_WMAC_LED_WLAN_BLUE); ++ ap9x_pci_setup_wmac_led_name(0, wnr2200_wmac_led_name); ++ ++ ap9x_pci_setup_wmac_leds(0, wnr2200_wmac_leds_gpio, ++ ARRAY_SIZE(wnr2200_wmac_leds_gpio)); ++ ++ /* All 3 buttons are connected to wireless chip */ ++ ap9x_pci_setup_wmac_btns(0, wnr2200_wmac_keys_gpio, ++ ARRAY_SIZE(wnr2200_wmac_keys_gpio), ++ WNR2200_KEYS_POLL_INTERVAL); + + /* enable power for the USB port */ +- ap9x_pci_setup_wmac_gpio(0, +- BIT(WNR2200_GPIO_USB_5V), +- BIT(WNR2200_GPIO_USB_5V)); ++ ap9x_pci_setup_wmac_gpio(0, BIT(WNR2200_GPIO_WMAC_USB_5V), ++ BIT(WNR2200_GPIO_WMAC_USB_5V)); + + ath79_register_usb(); + }