From 62a519f4a9fa104d4dec54bae465d695a5b1ee54 Mon Sep 17 00:00:00 2001
From: Konstantin Kuzov <master.nosferatu@gmail.com>
Date: Fri, 31 Aug 2018 10:13:52 +0300
Subject: [PATCH 2/4] ar71xx: add support for D-Link DIR-632 A1

Also enable second mdio bus with internal switch for AR7242 in ag71xx.
It is required for this board's wan to function properly.

Hardware specification:
CPU: AR7242
RAM: 32MB
Storage: 8MB
Switch: RTL8309G
Switch2: S26, internal
Ethernet: 9 x 100Mb
USB: 1 x 2.0
WiSoC: AR9287

Signed-off-by: Konstantin Kuzov <master.nosferatu@gmail.com>
---
 .../ar71xx/base-files/etc/board.d/01_leds     |   5 +
 .../ar71xx/base-files/etc/board.d/02_network  |   7 +
 target/linux/ar71xx/base-files/etc/diag.sh    |   1 +
 .../uci-defaults/03_network-switchX-migration |   1 +
 target/linux/ar71xx/base-files/lib/ar71xx.sh  |   3 +
 .../ar71xx/base-files/lib/upgrade/platform.sh |   1 +
 target/linux/ar71xx/config-4.14               |   1 +
 target/linux/ar71xx/config-4.9                |   1 +
 .../files/arch/mips/ath79/Kconfig.openwrt     |  11 ++
 .../ar71xx/files/arch/mips/ath79/Makefile     |   1 +
 .../ar71xx/files/arch/mips/ath79/dev-eth.c    |  16 +-
 .../files/arch/mips/ath79/mach-dir-632-a1.c   | 180 ++++++++++++++++++
 .../ar71xx/files/arch/mips/ath79/machtypes.h  |   1 +
 .../ethernet/atheros/ag71xx/ag71xx_ar7240.c   |   2 +-
 target/linux/ar71xx/generic/config-default    |   1 +
 .../ar71xx/image/generic-legacy-devices.mk    |   6 +
 target/linux/ar71xx/image/legacy.mk           |   7 +
 17 files changed, 239 insertions(+), 6 deletions(-)
 create mode 100644 target/linux/ar71xx/files/arch/mips/ath79/mach-dir-632-a1.c

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 af480cb001..e26e47d154 100755
--- a/target/linux/ar71xx/base-files/etc/board.d/01_leds
+++ b/target/linux/ar71xx/base-files/etc/board.d/01_leds
@@ -340,6 +340,11 @@ dir-615-c1)
 	ucidef_set_led_netdev "wan" "WAN" "d-link:green:wan" "eth1"
 	ucidef_set_led_wlan "wlan" "WLAN" "d-link:green:wlan" "phy0tpt"
 	;;
+dir-632-a1)
+	ucidef_set_led_usbdev "usb" "USB" "d-link:green:usb" "1-1"
+	ucidef_set_led_netdev "wan" "WAN" "d-link:green:wan" "eth1"
+	ucidef_set_led_wlan "wlan" "WLAN" "d-link:green:wireless" "phy0tpt"
+	;;
 dir-825-b1|\
 dir-825-c1)
 	ucidef_set_led_usbdev "usb" "USB" "d-link:blue:usb" "1-1"
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 7f209fbcac..4d6dd98833 100755
--- a/target/linux/ar71xx/base-files/etc/board.d/02_network
+++ b/target/linux/ar71xx/base-files/etc/board.d/02_network
@@ -61,6 +61,13 @@ ar71xx_setup_interfaces()
 		ucidef_add_switch "switch0" \
 			"0@eth0" "1:lan:4" "2:lan:3" "3:lan:2" "4:lan:1"
 		;;
+	dir-632-a1)
+		ucidef_set_interfaces_lan_wan "eth0.1" "eth1.1"
+		ucidef_add_switch "switch0" \
+			"8@eth0" "0:lan" "1:lan" "2:lan" "3:lan" "4:lan" "5:lan" "6:lan" "7:lan"
+		ucidef_add_switch "switch1" \
+			"0@eth1" "1:wan"
+		;;
 	alfa-ap120c|\
 	all0305|\
 	antminer-s1|\
diff --git a/target/linux/ar71xx/base-files/etc/diag.sh b/target/linux/ar71xx/base-files/etc/diag.sh
index fafdcce8f7..2bc0d8c8ce 100644
--- a/target/linux/ar71xx/base-files/etc/diag.sh
+++ b/target/linux/ar71xx/base-files/etc/diag.sh
@@ -177,6 +177,7 @@ get_status_led() {
 	dir-600-a1|\
 	dir-615-e1|\
 	dir-615-i1|\
+	dir-632-a1|\
 	dir-615-e4)
 		status_led="d-link:green:power"
 		;;
diff --git a/target/linux/ar71xx/base-files/etc/uci-defaults/03_network-switchX-migration b/target/linux/ar71xx/base-files/etc/uci-defaults/03_network-switchX-migration
index 0388fb6dc9..00c1f96e32 100644
--- a/target/linux/ar71xx/base-files/etc/uci-defaults/03_network-switchX-migration
+++ b/target/linux/ar71xx/base-files/etc/uci-defaults/03_network-switchX-migration
@@ -85,6 +85,7 @@ rb-450)
 	;;
 
 db120|\
+dir-632-a1|\
 rb-2011il|\
 rb-2011ils|\
 rb-2011l|\
diff --git a/target/linux/ar71xx/base-files/lib/ar71xx.sh b/target/linux/ar71xx/base-files/lib/ar71xx.sh
index 05f497fcbf..4e9afe7f50 100755
--- a/target/linux/ar71xx/base-files/lib/ar71xx.sh
+++ b/target/linux/ar71xx/base-files/lib/ar71xx.sh
@@ -640,6 +640,9 @@ ar71xx_board_detect() {
 	*"DIR-615 rev. I1")
 		name="dir-615-i1"
 		;;
+	*"DIR-632 rev. A1")
+		name="dir-632-a1"
+		;;
 	*"DIR-825 rev. B1")
 		name="dir-825-b1"
 		;;
diff --git a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh
index 3068aa4235..7e276ef0f3 100755
--- a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh
+++ b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh
@@ -242,6 +242,7 @@ platform_check_image() {
 	dir-615-e1|\
 	dir-615-e4|\
 	dir-615-i1|\
+	dir-632-a1|\
 	dir-825-c1|\
 	dir-835-a1|\
 	dlan-hotspot|\
diff --git a/target/linux/ar71xx/config-4.14 b/target/linux/ar71xx/config-4.14
index 254262bb71..6ce9ed57ff 100644
--- a/target/linux/ar71xx/config-4.14
+++ b/target/linux/ar71xx/config-4.14
@@ -89,6 +89,7 @@ CONFIG_ATH79=y
 # CONFIG_ATH79_MACH_DIR_600_A1 is not set
 # CONFIG_ATH79_MACH_DIR_615_C1 is not set
 # CONFIG_ATH79_MACH_DIR_615_I1 is not set
+# CONFIG_ATH79_MACH_DIR_632_A1 is not set
 # CONFIG_ATH79_MACH_DIR_825_B1 is not set
 # CONFIG_ATH79_MACH_DIR_825_C1 is not set
 # CONFIG_ATH79_MACH_DIR_869_A1 is not set
diff --git a/target/linux/ar71xx/config-4.9 b/target/linux/ar71xx/config-4.9
index a9cfb9e9ff..ae7995e7ee 100644
--- a/target/linux/ar71xx/config-4.9
+++ b/target/linux/ar71xx/config-4.9
@@ -89,6 +89,7 @@ CONFIG_ATH79=y
 # CONFIG_ATH79_MACH_DIR_600_A1 is not set
 # CONFIG_ATH79_MACH_DIR_615_C1 is not set
 # CONFIG_ATH79_MACH_DIR_615_I1 is not set
+# CONFIG_ATH79_MACH_DIR_632_A1 is not set
 # CONFIG_ATH79_MACH_DIR_825_B1 is not set
 # CONFIG_ATH79_MACH_DIR_825_C1 is not set
 # CONFIG_ATH79_MACH_DIR_869_A1 is not set
diff --git a/target/linux/ar71xx/files/arch/mips/ath79/Kconfig.openwrt b/target/linux/ar71xx/files/arch/mips/ath79/Kconfig.openwrt
index f60825a6dd..b47b4a9077 100644
--- a/target/linux/ar71xx/files/arch/mips/ath79/Kconfig.openwrt
+++ b/target/linux/ar71xx/files/arch/mips/ath79/Kconfig.openwrt
@@ -570,6 +570,17 @@ config ATH79_MACH_DIR_615_I1
 	select ATH79_DEV_M25P80
 	select ATH79_DEV_WMAC
 
+config ATH79_MACH_DIR_632_A1
+	bool "D-Link DIR-632 A1 support"
+	select SOC_AR724X
+	select ATH79_DEV_AP9X_PCI if PCI
+	select ATH79_DEV_ETH
+	select ATH79_DEV_GPIO_BUTTONS
+	select ATH79_DEV_LEDS_GPIO
+	select ATH79_DEV_M25P80
+	select ATH79_DEV_USB
+	select ATH79_NVRAM
+
 config ATH79_MACH_DIR_825_B1
 	bool "D-Link DIR-825 rev. B1 board support"
 	select SOC_AR71XX
diff --git a/target/linux/ar71xx/files/arch/mips/ath79/Makefile b/target/linux/ar71xx/files/arch/mips/ath79/Makefile
index 0a2fc9c17d..42342547d6 100644
--- a/target/linux/ar71xx/files/arch/mips/ath79/Makefile
+++ b/target/linux/ar71xx/files/arch/mips/ath79/Makefile
@@ -100,6 +100,7 @@ obj-$(CONFIG_ATH79_MACH_DIR_505_A1)		+= mach-dir-505-a1.o
 obj-$(CONFIG_ATH79_MACH_DIR_600_A1)		+= mach-dir-600-a1.o
 obj-$(CONFIG_ATH79_MACH_DIR_615_C1)		+= mach-dir-615-c1.o
 obj-$(CONFIG_ATH79_MACH_DIR_615_I1)		+= mach-dir-615-i1.o
+obj-$(CONFIG_ATH79_MACH_DIR_632_A1)		+= mach-dir-632-a1.o
 obj-$(CONFIG_ATH79_MACH_DIR_825_B1)		+= mach-dir-825-b1.o
 obj-$(CONFIG_ATH79_MACH_DIR_825_C1)		+= mach-dir-825-c1.o
 obj-$(CONFIG_ATH79_MACH_DIR_869_A1)		+= mach-dir-869-a1.o
diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c b/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c
index 1e230bce61..97a8b36be0 100644
--- a/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c
+++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c
@@ -182,6 +182,7 @@ void __init ath79_register_mdio(unsigned int id, u32 phy_mask)
 	if (ath79_soc == ATH79_SOC_AR9341 ||
 	    ath79_soc == ATH79_SOC_AR9342 ||
 	    ath79_soc == ATH79_SOC_AR9344 ||
+	    ath79_soc == ATH79_SOC_AR7242 ||
 	    ath79_soc == ATH79_SOC_QCA9556 ||
 	    ath79_soc == ATH79_SOC_QCA9558 ||
 	    ath79_soc == ATH79_SOC_QCA956X)
@@ -204,6 +205,11 @@ void __init ath79_register_mdio(unsigned int id, u32 phy_mask)
 		mdio_data = &ath79_mdio1_data;
 		break;
 
+	case ATH79_SOC_AR7242:
+		ath79_set_pll(AR71XX_PLL_REG_SEC_CONFIG,
+			       AR7242_PLL_REG_ETH0_INT_CLOCK, 0x62000000,
+			       AR71XX_ETH0_PLL_SHIFT);
+		/* fall through */
 	case ATH79_SOC_AR9341:
 	case ATH79_SOC_AR9342:
 	case ATH79_SOC_AR9344:
@@ -219,11 +225,6 @@ void __init ath79_register_mdio(unsigned int id, u32 phy_mask)
 		}
 		break;
 
-	case ATH79_SOC_AR7242:
-		ath79_set_pll(AR71XX_PLL_REG_SEC_CONFIG,
-			       AR7242_PLL_REG_ETH0_INT_CLOCK, 0x62000000,
-			       AR71XX_ETH0_PLL_SHIFT);
-		/* fall through */
 	default:
 		mdio_dev = &ath79_mdio0_device;
 		mdio_data = &ath79_mdio0_data;
@@ -240,6 +241,11 @@ void __init ath79_register_mdio(unsigned int id, u32 phy_mask)
 		mdio_data->builtin_switch = 1;
 		break;
 
+	case ATH79_SOC_AR7242:
+		if (id == 1)
+			mdio_data->builtin_switch = 1;
+		break;
+
 	case ATH79_SOC_AR9330:
 		mdio_data->is_ar9330 = 1;
 		/* fall through */
diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-632-a1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-632-a1.c
new file mode 100644
index 0000000000..b49f087afe
--- /dev/null
+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-632-a1.c
@@ -0,0 +1,180 @@
+/*
+ *  D-Link DIR-632 rev. A1 board support
+ *
+ *  Copyright (C) 2017 Konstantin Kuzov <master.nosferatu@gmail.com>
+ *
+ *  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/pci.h>
+#include <linux/platform_device.h>
+#include <linux/phy.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+
+#include <linux/ar8216_platform.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/irq.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+
+#include <linux/platform_data/phy-at803x.h>
+
+#include "common.h"
+#include "dev-ap9x-pci.h"
+#include "dev-eth.h"
+#include "dev-gpio-buttons.h"
+#include "dev-leds-gpio.h"
+#include "dev-m25p80.h"
+#include "dev-wmac.h"
+#include "dev-usb.h"
+#include "machtypes.h"
+#include "nvram.h"
+
+#define DIR_632_A1_GPIO_LED_WPS			0
+#define DIR_632_A1_GPIO_LED_POWER_AMBER		1
+#define DIR_632_A1_GPIO_LED_POWER_GREEN		6
+#define DIR_632_A1_GPIO_LED_WAN_AMBER		7
+#define DIR_632_A1_GPIO_LED_WAN_GREEN		17
+
+#define DIR_632_A1_GPIO_LED_USB			11
+#define DIR_632_A1_GPIO_LED_WLAN		0
+
+#define DIR_632_A1_GPIO_BTN_RESET		8
+#define DIR_632_A1_GPIO_BTN_WPS			12
+
+#define DIR_632_A1_KEYS_POLL_INTERVAL		20	/* msecs */
+#define DIR_632_A1_KEYS_DEBOUNCE_INTERVAL (3 * DIR_632_A1_KEYS_POLL_INTERVAL)
+
+#define DIR_632_A1_NVRAM_ADDR			0x1ffe0000
+#define DIR_632_A1_NVRAM_SIZE			0x10000
+
+#define DIR_632_A1_MAC_ADDR			0x1ffb0000
+#define DIR_632_A1_ART_ADDR			0x1fff0000
+#define DIR_632_A1_EEPROM_ADDR			0x1fff1000
+
+#define DIR_632_A1_MAC0_OFFSET			0
+#define DIR_632_A1_MAC1_OFFSET			6
+
+#define DIR_632A1_LAN_PHYMASK			BIT(8)
+#define DIR_632A1_WAN_PHYMASK			BIT(0)
+
+#define AR724X_GPIO_FUNCTION_PCIEPHY_TST_EN	BIT(16)
+#define AR724X_GPIO_FUNCTION_CLK_OBS6_ENABLE	BIT(20)
+
+static struct gpio_led dir_632_a1_leds_gpio[] __initdata = {
+	{
+		.name		= "d-link:green:power",
+		.gpio		= DIR_632_A1_GPIO_LED_POWER_GREEN,
+	}, {
+		.name		= "d-link:amber:power",
+		.gpio		= DIR_632_A1_GPIO_LED_POWER_AMBER,
+	}, {
+		.name		= "d-link:amber:wan",
+		.gpio		= DIR_632_A1_GPIO_LED_WAN_AMBER,
+	}, {
+		.name		= "d-link:green:wan",
+		.gpio		= DIR_632_A1_GPIO_LED_WAN_GREEN,
+		.active_low	= 1,
+	}, {
+		.name		= "d-link:blue:wps",
+		.gpio		= DIR_632_A1_GPIO_LED_WPS,
+		.active_low	= 1,
+	}, {
+		.name           = "d-link:green:usb",
+		.gpio           = DIR_632_A1_GPIO_LED_USB,
+		.active_low     = 1,
+	}
+};
+
+static struct gpio_keys_button dir_632_a1_gpio_keys[] __initdata = {
+	{
+		.desc		= "reset",
+		.type		= EV_KEY,
+		.code		= KEY_RESTART,
+		.debounce_interval = DIR_632_A1_KEYS_DEBOUNCE_INTERVAL,
+		.gpio		= DIR_632_A1_GPIO_BTN_RESET,
+		.active_low	= 1,
+	}, {
+		.desc		= "wps",
+		.type		= EV_KEY,
+		.code		= KEY_WPS_BUTTON,
+		.debounce_interval = DIR_632_A1_KEYS_DEBOUNCE_INTERVAL,
+		.gpio		= DIR_632_A1_GPIO_BTN_WPS,
+		.active_low	= 1,
+	}
+};
+
+static struct flash_platform_data dir_632_a1_flash_data = {
+	.type = "mx25l6405d",
+};
+
+static void __init dir_632_a1_setup(void)
+{
+	const char *nvram = (char *) KSEG1ADDR(DIR_632_A1_NVRAM_ADDR);
+	u8 *ee = (u8*)KSEG1ADDR(DIR_632_A1_EEPROM_ADDR);
+	u8 *art = (u8*)KSEG1ADDR(DIR_632_A1_ART_ADDR);
+	u8 *mac = (u8*)KSEG1ADDR(DIR_632_A1_MAC_ADDR);
+	u8 mac_buff[6];
+
+	ath79_register_m25p80(&dir_632_a1_flash_data);
+
+	/* Make LEDs on GPIO6/7 work */
+	ath79_gpio_function_enable(AR724X_GPIO_FUNC_JTAG_DISABLE);
+
+	ath79_gpio_function_disable(
+				    AR71XX_GPIO_FUNC_STEREO_EN |
+				    AR724X_GPIO_FUNCTION_CLK_OBS6_ENABLE |
+				    AR724X_GPIO_FUNC_UART_RTS_CTS_EN |
+				    AR724X_GPIO_FUNCTION_PCIEPHY_TST_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_leds_gpio(-1, ARRAY_SIZE(dir_632_a1_leds_gpio),
+				 dir_632_a1_leds_gpio);
+
+	ath79_register_gpio_keys_polled(-1, DIR_632_A1_KEYS_POLL_INTERVAL,
+					ARRAY_SIZE(dir_632_a1_gpio_keys),
+					dir_632_a1_gpio_keys);
+
+	if (ath79_nvram_parse_mac_addr(nvram, DIR_632_A1_NVRAM_SIZE,
+				       "ath0_hwaddr=", mac_buff) == 0) {
+		mac = mac_buff;
+		pr_info("dir_632_a1_setup(): NVRAM ath0_hwaddr=%pM", mac);
+	}
+
+	ath79_register_mdio(0, ~(DIR_632A1_LAN_PHYMASK));
+	ath79_register_mdio(1, ~(DIR_632A1_WAN_PHYMASK));
+
+	ath79_switch_data.phy4_mii_en = 1;
+	ath79_switch_data.phy_poll_mask |= DIR_632A1_LAN_PHYMASK;
+
+	ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0);
+	ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev;
+	ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
+	ath79_eth0_data.phy_mask = DIR_632A1_LAN_PHYMASK;
+	ath79_eth0_data.speed = SPEED_100;
+	ath79_eth0_data.duplex = DUPLEX_FULL;
+	ath79_register_eth(0);
+
+	ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1);
+	ath79_eth1_data.mii_bus_dev = &ath79_mdio1_device.dev;
+	ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII;
+	ath79_eth1_data.phy_mask = DIR_632A1_WAN_PHYMASK;
+	ath79_eth1_data.switch_data = &ath79_switch_data;
+	ath79_register_eth(1);
+
+	ath79_register_usb();
+
+	ap9x_pci_setup_wmac_led_pin(0, DIR_632_A1_GPIO_LED_WLAN);
+	ap91_pci_init(ee, art);
+}
+
+MIPS_MACHINE(ATH79_MACH_DIR_632_A1, "DIR-632-A1", "D-Link DIR-632 rev. A1",
+	     dir_632_a1_setup);
+
diff --git a/target/linux/ar71xx/files/arch/mips/ath79/machtypes.h b/target/linux/ar71xx/files/arch/mips/ath79/machtypes.h
index 987e80bb1f..2d65a62b78 100644
--- a/target/linux/ar71xx/files/arch/mips/ath79/machtypes.h
+++ b/target/linux/ar71xx/files/arch/mips/ath79/machtypes.h
@@ -93,6 +93,7 @@ enum ath79_mach_type {
 	ATH79_MACH_DIR_615_E1,			/* D-Link DIR-615 rev. E1 */
 	ATH79_MACH_DIR_615_E4,			/* D-Link DIR-615 rev. E4 */
 	ATH79_MACH_DIR_615_I1,			/* D-Link DIR-615 rev. I1 */
+	ATH79_MACH_DIR_632_A1,			/* D-Link DIR-632 rev. A1 */
 	ATH79_MACH_DIR_825_B1,			/* D-Link DIR-825 rev. B1 */
 	ATH79_MACH_DIR_825_C1,			/* D-Link DIR-825 rev. C1 */
 	ATH79_MACH_DIR_835_A1,			/* D-Link DIR-835 rev. A1 */
diff --git a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c
index 3f2f64e2ae..18c8df23fd 100644
--- a/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c
+++ b/target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_ar7240.c
@@ -1248,7 +1248,7 @@ static struct ar7240sw *ar7240_probe(struct ag71xx *ag)
 		  AR7240_MASK_CTRL_VERSION_M;
 
 	if (sw_is_ar7240(as)) {
-		swdev->name = "AR7240/AR9330 built-in switch";
+		swdev->name = "AR7240/AR7242/AR9330 built-in switch";
 		swdev->ports = AR7240_NUM_PORTS - 1;
 	} else if (sw_is_ar934x(as)) {
 		swdev->name = "AR934X built-in switch";
diff --git a/target/linux/ar71xx/generic/config-default b/target/linux/ar71xx/generic/config-default
index d3c8000f6d..40d93027aa 100644
--- a/target/linux/ar71xx/generic/config-default
+++ b/target/linux/ar71xx/generic/config-default
@@ -61,6 +61,7 @@ CONFIG_ATH79_MACH_DB120=y
 CONFIG_ATH79_MACH_DGL_5500_A1=y
 CONFIG_ATH79_MACH_DHP_1565_A1=y
 CONFIG_ATH79_MACH_DIR_505_A1=y
+CONFIG_ATH79_MACH_DIR_632_A1=y
 CONFIG_ATH79_MACH_DIR_825_B1=y
 CONFIG_ATH79_MACH_DIR_825_C1=y
 CONFIG_ATH79_MACH_DIR_869_A1=y
diff --git a/target/linux/ar71xx/image/generic-legacy-devices.mk b/target/linux/ar71xx/image/generic-legacy-devices.mk
index a784a1a205..cc9193d1a2 100644
--- a/target/linux/ar71xx/image/generic-legacy-devices.mk
+++ b/target/linux/ar71xx/image/generic-legacy-devices.mk
@@ -167,6 +167,12 @@ define LegacyDevice/DHP1565A1
 endef
 LEGACY_DEVICES += DHP1565A1
 
+define LegacyDevice/DIR632A1
+  DEVICE_TITLE := D-Link DIR-632 rev. A1
+  DEVICE_PACKAGES := kmod-usb-core kmod-usb2 kmod-usb-ledtrig-usbport
+endef
+LEGACY_DEVICES += DIR632A1
+
 define LegacyDevice/DIR825C1
   DEVICE_TITLE := D-Link DIR-825 rev. C1
   DEVICE_PACKAGES := kmod-usb-core kmod-usb2 kmod-usb-ledtrig-usbport
diff --git a/target/linux/ar71xx/image/legacy.mk b/target/linux/ar71xx/image/legacy.mk
index 363e0956c7..9feda055c9 100644
--- a/target/linux/ar71xx/image/legacy.mk
+++ b/target/linux/ar71xx/image/legacy.mk
@@ -241,6 +241,7 @@ bxu2000n2_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,1408k(kerne
 cameo_ap81_mtdlayout=mtdparts=spi0.0:128k(u-boot)ro,64k(config)ro,3840k(firmware),64k(art)ro
 cameo_ap91_mtdlayout=mtdparts=spi0.0:192k(u-boot)ro,64k(nvram)ro,3712k(firmware),64k(mac)ro,64k(art)ro
 cameo_ap99_mtdlayout=mtdparts=spi0.0:192k(u-boot)ro,64k(nvram)ro,3520k(firmware),64k(mac)ro,192k(lp)ro,64k(art)ro
+cameo_ap101_mtdlayout=mtdparts=spi0.0:256k(u-boot),64k(nvram)ro,7552k(firmware),64k(mac)ro,192k(lp)ro,64k(art)ro
 cameo_ap121_mtdlayout=mtdparts=spi0.0:64k(u-boot)ro,64k(art)ro,64k(mac)ro,64k(nvram)ro,192k(language)ro,3648k(firmware)
 cameo_ap121_mtdlayout_8M=mtdparts=spi0.0:64k(u-boot)ro,64k(art)ro,64k(mac)ro,64k(nvram)ro,256k(language)ro,7680k@0x80000(firmware)
 cameo_ap123_mtdlayout_4M=mtdparts=spi0.0:64k(u-boot)ro,64k(nvram)ro,3712k(firmware),192k(lang)ro,64k(art)ro
@@ -408,6 +409,10 @@ Image/Build/CameoAP99/buildkernel=$(call MkuImageLzma,$(2),$(3) $(cameo_ap99_mtd
 Image/Build/CameoAP99=$(call Image/Build/Cameo,$(1),$(2),$(3),$(cameo_ap99_mtdlayout),$(4),65536)
 Image/Build/CameoAP99/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(cameo_ap99_mtdlayout))
 
+Image/Build/CameoAP101/buildkernel=$(call MkuImageLzma,$(2),$(3) $(cameo_ap101_mtdlayout))
+Image/Build/CameoAP101=$(call Image/Build/Cameo,$(1),$(2),$(3),$(cameo_ap101_mtdlayout),$(4),65536)
+Image/Build/CameoAP101/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(cameo_ap101_mtdlayout))
+
 Image/Build/CameoAP123_4M/buildkernel=$(call MkuImageLzma,$(2),$(3) $(cameo_ap123_mtdlayout_4M))
 Image/Build/CameoAP123_4M=$(call Image/Build/Cameo,$(1),$(2),$(3),$(cameo_ap123_mtdlayout_4M),$(4),26)
 Image/Build/CameoAP123_4M/initramfs=$(call MkuImageLzma/initramfs,$(2),$(3) $(cameo_ap123_mtdlayout_4M))
@@ -897,6 +902,8 @@ $(eval $(call SingleProfile,AthLzma,64k,DB120,db120,DB120,ttyS0,115200,$$(db120_
 $(eval $(call SingleProfile,AthLzma,64k,HORNETUBx2,hornet-ub-x2,HORNET-UB,ttyATH0,115200,$$(alfa_mtdlayout_16M),KRuImage,65536))
 $(eval $(call SingleProfile,AthLzma,64k,TUBE2H16M,tube2h-16M,TUBE2H,ttyATH0,115200,$$(alfa_mtdlayout_16M),KRuImage,65536))
 
+$(eval $(call SingleProfile,CameoAP101,64kraw,DIR632A1,dir-632-a1,DIR-632-A1,ttyS0,115200,"A101-AR7242-RT-100324-02"))
+
 $(eval $(call SingleProfile,CameoAP121_8M,64kraw-nojffs,DIR505A1,dir-505-a1,DIR-505-A1,ttyATH0,115200,"HORNET-PACKET-DIR505A1-3",1.99.99,""))
 
 $(eval $(call SingleProfile,CameoAP135,64kraw,DGL5500A1,dgl-5500-a1,DGL-5500-A1,ttyS0,115200,$$(dgl_5500_mtdlayout),"00AP135AR9558-RT-130508-00"))
-- 
2.17.0

