PKGBUILDs/core/linux-mmp/0005-mmp-ethernet-Adding-ethernet-MAC-address-reading-for.patch

224 lines
6.4 KiB
Diff
Raw Normal View History

2017-09-03 20:23:12 +00:00
From d4c023f35d95eb676b0dce610e35b0c2cce274ca Mon Sep 17 00:00:00 2001
2016-05-02 01:47:12 +00:00
From: Ashokkumar G <0xfee1dead.sa@gmail.com>
Date: Mon, 26 Jan 2015 11:28:52 -0700
2017-09-03 20:23:12 +00:00
Subject: [PATCH 5/9] mmp:ethernet: Adding ethernet MAC address reading for
2016-05-02 01:47:12 +00:00
gplugd
Currently Marvell's pxa168 ethernet driver uses random MAC address
by default instead of reading MAC address from OTP SPI flash.
Adding support to uses MAC address provided instead of random MAC
address by default
Signed-off-by: Ashokkumar G <0xfee1dead.sa@gmail.com>
---
arch/arm/mach-mmp/gplugd.c | 132 ++++++++++++++++++++++++------
drivers/net/ethernet/marvell/pxa168_eth.c | 5 ++
include/linux/pxa168_eth.h | 3 +
3 files changed, 116 insertions(+), 24 deletions(-)
diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c
2017-02-09 01:28:44 +00:00
index 9c441e1b3159..2981c8878ee7 100644
2016-05-02 01:47:12 +00:00
--- a/arch/arm/mach-mmp/gplugd.c
+++ b/arch/arm/mach-mmp/gplugd.c
@@ -22,6 +22,8 @@
#include <mach/pxa168.h>
#include <mach/mfp-pxa168.h>
+#include <uapi/linux/ethtool.h>
+#include <linux/etherdevice.h>
#include "common.h"
static unsigned long gplugd_pin_config[] __initdata = {
@@ -146,27 +148,6 @@ static struct i2c_board_info gplugd_i2c_board_info[] = {
}
};
-/* Bring PHY out of reset by setting GPIO 104 */
-static int gplugd_eth_init(void)
-{
- if (unlikely(gpio_request(104, "ETH_RESET_N"))) {
- printk(KERN_ERR "Can't get hold of GPIO 104 to bring Ethernet "
- "PHY out of reset\n");
- return -EIO;
- }
-
- gpio_direction_output(104, 1);
- gpio_free(104);
- return 0;
-}
-
-struct pxa168_eth_platform_data gplugd_eth_platform_data = {
- .port_number = 0,
- .phy_addr = 0,
- .speed = 0, /* Autonagotiation */
- .init = gplugd_eth_init,
-};
-
static void __init select_disp_freq(void)
{
/* set GPIO 35 & clear GPIO 85 to set LCD External Clock to 74.25 MHz */
@@ -227,6 +208,108 @@ static inline int pxa168_add_spi(int id, struct pxa2xx_spi_master *pdata)
return platform_device_add(pd);
}
+#ifdef CONFIG_MTD
+static void gplugd_parse_enetaddr(const u8 *addr, u8 *enetaddr)
+{
+ char *end;
+ int i;
+
+ for (i = 0; i < 6; ++i) {
+ enetaddr[i] = addr ? simple_strtoul(addr, &end, 16) : 0;
+ if (addr)
+ addr = (*end) ? end + 1 : end;
+ }
+}
+
+static struct pxa168_eth_platform_data gplugd_eth_platform_data;
+
+static void __init read_device_serial_mac(void)
+{
+#define GPLUGD_SERIAL_NUM_LENGTH 14
+#define GPLUGD_MAC_ADDR_LENGTH 18
+ char otp_serial_num[GPLUGD_SERIAL_NUM_LENGTH];
+ char otp_mac_addr[GPLUGD_MAC_ADDR_LENGTH];
+ u8 *mac_addr = gplugd_eth_platform_data.mac_addr;
+ size_t retlen;
+ struct mtd_info *mtd = NULL;
+
+ mtd = get_mtd_device(NULL, 0x00);
+
+ if (!mtd) {
+ pr_err("%s %d: No MTD devices found", __func__, __LINE__);
+ return;
+ }
+
+ if (mtd->_read_user_prot_reg) {
+ if (!mtd->_read_user_prot_reg(mtd, 0, GPLUGD_SERIAL_NUM_LENGTH,
+ &retlen, otp_serial_num)) {
+ if (!mtd->_read_user_prot_reg(mtd,
+ GPLUGD_SERIAL_NUM_LENGTH,
+ GPLUGD_MAC_ADDR_LENGTH,
+ &retlen, otp_mac_addr)) {
+
+ gplugd_parse_enetaddr(otp_mac_addr, mac_addr);
+ } else {
+ pr_err("%s %d: OTP MAC Address read failed\n",
+ __func__, __LINE__);
+ }
+ } else {
+ pr_err("%s %d: OTP Serial Number read failed\n",
+ __func__, __LINE__);
+ }
+ }
+
+ put_mtd_device(mtd);
+}
+#else
+static void __init read_device_serial_mac(void) {}
+#endif
+
+static int device_mac_address(u8 *mac_addr)
+{
+ pr_warn("%s %d: Entry\n", __func__, __LINE__);
+ read_device_serial_mac();
+ if (!is_valid_ether_addr(gplugd_eth_platform_data.mac_addr))
+ return -EINVAL;
+ memcpy(mac_addr, gplugd_eth_platform_data.mac_addr, 6);
+ return 0;
+}
+
+/* Bring PHY out of reset by setting GPIO 104 */
+static int gplugd_eth_init(void)
+{
+ int gpio_enet_reset = 104;
+ int gpio_enet_coma = 102;
+
+ if (unlikely(gpio_request(gpio_enet_reset, "ETH_RESET_N"))) {
+ printk(KERN_ERR "Can't get hold of GPIO %d to bring Ethernet "
+ "PHY out of reset\n", gpio_enet_reset);
+ return -EIO;
+ }
+ if (unlikely(gpio_request(gpio_enet_coma, "ETH_COMA_N"))) {
+ printk(KERN_ERR "Can't get hold of GPIO %d to bring Ethernet "
+ "PHY out of coma\n", gpio_enet_coma);
+ return -EIO;
+ }
+
+
+ gpio_direction_output(gpio_enet_reset, 1);
+ gpio_direction_output(gpio_enet_coma, 1);
+
+ gpio_free(gpio_enet_reset);
+ gpio_free(gpio_enet_coma);
+ return 0;
+}
+
+static struct pxa168_eth_platform_data gplugd_eth_platform_data = {
+ .port_number = 0,
+ .phy_addr = 0,
+ .speed = 0, /* Autonagotiation */
+ .mac_addr = {0x00},
+ .init = gplugd_eth_init,
+ .device_mac = device_mac_address,
+};
+
static void __init gplugd_init(void)
{
mfp_config(ARRAY_AND_SIZE(gplugd_pin_config));
@@ -243,12 +326,13 @@ static void __init gplugd_init(void)
pxa168_add_twsi(0, &i2c_info, ARRAY_AND_SIZE(gplugd_i2c_board_info));
- pxa168_add_eth(&gplugd_eth_platform_data);
+ pxa168_add_spi(2, &pxa_ssp_master_info);
+ spi_register_board_info(gplugD_spi_board_info,
+ ARRAY_SIZE(gplugD_spi_board_info));
pxa168_add_ssp(2);
- pxa168_add_spi(2, &pxa_ssp_master_info);
- spi_register_board_info(gplugD_spi_board_info, ARRAY_SIZE(gplugD_spi_board_info));
+ pxa168_add_eth(&gplugd_eth_platform_data);
}
MACHINE_START(GPLUGD, "PXA168-based GuruPlug Display (gplugD) Platform")
diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c
2017-02-09 01:28:44 +00:00
index c3b209cd0660..9cb99ab9fa47 100644
2016-05-02 01:47:12 +00:00
--- a/drivers/net/ethernet/marvell/pxa168_eth.c
+++ b/drivers/net/ethernet/marvell/pxa168_eth.c
@@ -1552,6 +1552,11 @@ static int pxa168_eth_probe(struct platform_device *pdev)
pep->port_num = pep->pd->port_number;
pep->phy_addr = pep->pd->phy_addr;
+
+ if (pep->pd->device_mac)
+ pep->pd->device_mac(pep->pd->mac_addr);
+ if (is_valid_ether_addr(pep->pd->mac_addr))
+ memcpy(dev->dev_addr, pep->pd->mac_addr, 6);
} else if (pdev->dev.of_node) {
of_property_read_u32(pdev->dev.of_node, "port-id",
&pep->port_num);
diff --git a/include/linux/pxa168_eth.h b/include/linux/pxa168_eth.h
2017-02-09 01:28:44 +00:00
index 18d75e795606..ca941555d9b8 100644
2016-05-02 01:47:12 +00:00
--- a/include/linux/pxa168_eth.h
+++ b/include/linux/pxa168_eth.h
@@ -20,11 +20,14 @@ struct pxa168_eth_platform_data {
int rx_queue_size;
int tx_queue_size;
+ u8 mac_addr[6]; /* mac address if non-zero*/
+
/*
* init callback is used for board specific initialization
* e.g on Aspenite its used to initialize the PHY transceiver.
*/
int (*init)(void);
+ int (*device_mac)(u8 *mac_addr);
};
#endif /* __LINUX_PXA168_ETH_H */
--
2017-09-03 20:23:12 +00:00
2.14.1
2016-05-02 01:47:12 +00:00