Skip to content

Commit 276996d

Browse files
arvinfnashif
authored andcommitted
drivers: eth_sam_gmac: use PHY driver
This commit removes PHY and MDIO specific code from the ATSAM Ethernet driver and instead relies on a separate PHY driver to handle the PHY. Signed-off-by: Arvin Farahmand <[email protected]>
1 parent f845cdd commit 276996d

File tree

6 files changed

+36
-422
lines changed

6 files changed

+36
-422
lines changed

drivers/ethernet/CMakeLists.txt

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,6 @@ zephyr_library_sources_ifdef(CONFIG_ETH_GECKO
77
phy_gecko.c
88
)
99

10-
zephyr_library_sources_ifdef(CONFIG_ETH_SAM_GMAC
11-
eth_sam_gmac.c
12-
phy_sam_gmac.c
13-
)
14-
1510
zephyr_library_sources_ifdef(CONFIG_ETH_XLNX_GEM
1611
eth_xlnx_gem.c
1712
phy_xlnx_gem.c
@@ -27,6 +22,8 @@ zephyr_library_sources_ifdef(CONFIG_ETH_SMSC911X eth_smsc911x.c)
2722
zephyr_library_sources_ifdef(CONFIG_ETH_STELLARIS eth_stellaris.c)
2823
zephyr_library_sources_ifdef(CONFIG_ETH_STM32_HAL eth_stm32_hal.c)
2924
zephyr_library_sources_ifdef(CONFIG_ETH_W5500 eth_w5500.c)
25+
zephyr_library_sources_ifdef(CONFIG_ETH_SAM_GMAC eth_sam_gmac.c)
26+
zephyr_library_sources_ifdef(CONFIG_DSA_KSZ8XXX dsa_ksz8xxx.c)
3027

3128
if(CONFIG_ETH_NATIVE_POSIX)
3229
zephyr_library_named(drivers__ethernet__native_posix)

drivers/ethernet/Kconfig.sam_gmac

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ menuconfig ETH_SAM_GMAC
77
bool "Atmel SAM Ethernet driver"
88
depends on SOC_FAMILY_SAM0 || SOC_FAMILY_SAM
99
select NOCACHE_MEMORY if ARCH_HAS_NOCACHE_MEMORY_SUPPORT
10+
select MDIO
1011
help
1112
Enable Atmel SAM MCU Family Ethernet driver.
1213

@@ -68,14 +69,6 @@ config ETH_SAM_GMAC_BUF_RX_COUNT
6869
fit at least two Ethernet frames: one being received by the GMAC module
6970
and the other being processed by the higher layer networking stack.
7071

71-
config ETH_SAM_GMAC_MONITOR_PERIOD
72-
int "Monitor task execution period"
73-
default 1000
74-
help
75-
Monitor task execution period in milliseconds. The monitor task is
76-
periodically executed to detect and report any changes in the PHY
77-
link status to the operating system.
78-
7972
config ETH_SAM_GMAC_MAC_I2C_EEPROM
8073
bool "Read from an I2C EEPROM"
8174
help
@@ -112,14 +105,6 @@ config ETH_SAM_GMAC_MAC_I2C_DEV_NAME
112105

113106
endif # ETH_SAM_GMAC_MAC_I2C_EEPROM
114107

115-
config ETH_SAM_GMAC_PHY_ADDR
116-
int "GMAC PHY Address"
117-
default 0
118-
help
119-
GMAC PHY Address as used by IEEE 802.3, Section 2 MII compatible PHY
120-
transceivers. If you have a single PHY on board it is safe to leave it
121-
at 0 which is the broadcast address.
122-
123108
config PTP_CLOCK_SAM_GMAC
124109
bool "SAM GMAC PTP clock driver support"
125110
default y

drivers/ethernet/eth_sam_gmac.c

Lines changed: 32 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
3636
#include <sys/util.h>
3737
#include <errno.h>
3838
#include <stdbool.h>
39+
#include <net/phy.h>
3940
#include <net/net_pkt.h>
4041
#include <net/net_if.h>
4142
#include <net/ethernet.h>
4243
#include <ethernet/eth_stats.h>
4344
#include <drivers/i2c.h>
4445
#include <soc.h>
45-
#include "phy_sam_gmac.h"
4646
#include "eth_sam_gmac_priv.h"
4747

4848
#include "eth.h"
@@ -241,9 +241,8 @@ static void tx_descriptors_init(Gmac *gmac, struct gmac_queue *queue);
241241
static int nonpriority_queue_init(Gmac *gmac, struct gmac_queue *queue);
242242

243243
#if GMAC_PRIORITY_QUEUE_NUM >= 1
244-
static inline void set_receive_buf_queue_pointer(
245-
Gmac *gmac,
246-
struct gmac_queue *queue)
244+
static inline void set_receive_buf_queue_pointer(Gmac *gmac,
245+
struct gmac_queue *queue)
247246
{
248247
/* Set Receive Buffer Queue Pointer Register */
249248
if (queue->que_idx == GMAC_QUE_0) {
@@ -360,9 +359,8 @@ static int queue_init(Gmac *gmac, struct gmac_queue *queue)
360359

361360
#else
362361

363-
static inline void set_receive_buf_queue_pointer(
364-
Gmac *gmac,
365-
struct gmac_queue *queue)
362+
static inline void set_receive_buf_queue_pointer(Gmac *gmac,
363+
struct gmac_queue *queue)
366364
{
367365
gmac->GMAC_RBQB = (uint32_t)queue->rx_desc_list.buf;
368366
}
@@ -1093,7 +1091,7 @@ static int gmac_init(Gmac *gmac, uint32_t gmac_ncfgr_val)
10931091
}
10941092

10951093
/* Set Network Control Register to its default value, clear stats. */
1096-
gmac->GMAC_NCR = GMAC_NCR_CLRSTAT;
1094+
gmac->GMAC_NCR = GMAC_NCR_CLRSTAT | GMAC_NCR_MPE;
10971095

10981096
/* Disable all interrupts */
10991097
gmac->GMAC_IDR = UINT32_MAX;
@@ -1160,14 +1158,15 @@ static int gmac_init(Gmac *gmac, uint32_t gmac_ncfgr_val)
11601158
return 0;
11611159
}
11621160

1163-
static void link_configure(Gmac *gmac, uint32_t flags)
1161+
static void link_configure(Gmac *gmac, bool full_duplex, bool speed_100M)
11641162
{
11651163
uint32_t val;
11661164

11671165
val = gmac->GMAC_NCFGR;
11681166

11691167
val &= ~(GMAC_NCFGR_FD | GMAC_NCFGR_SPD);
1170-
val |= flags & (GMAC_NCFGR_FD | GMAC_NCFGR_SPD);
1168+
val |= (full_duplex) ? GMAC_NCFGR_FD : 0;
1169+
val |= (speed_100M) ? GMAC_NCFGR_SPD : 0;
11711170

11721171
gmac->GMAC_NCFGR = val;
11731172

@@ -1819,47 +1818,35 @@ static void generate_mac(uint8_t mac_addr[6])
18191818
#endif
18201819
}
18211820

1822-
static void monitor_work_handler(struct k_work *work)
1821+
static void phy_link_state_changed(const struct device *pdev,
1822+
struct phy_link_state *state,
1823+
void *user_data)
18231824
{
1824-
struct eth_sam_dev_data *const dev_data =
1825-
CONTAINER_OF(work, struct eth_sam_dev_data, monitor_work);
1826-
const struct device *dev = net_if_get_device(dev_data->iface);
1825+
const struct device *dev = (struct device *) user_data;
1826+
struct eth_sam_dev_data *const dev_data = DEV_DATA(dev);
18271827
const struct eth_sam_dev_cfg *const cfg = DEV_CFG(dev);
1828-
bool link_status;
1829-
uint32_t link_config;
1830-
int result;
1828+
bool is_up;
18311829

1832-
/* Poll PHY link status */
1833-
link_status = phy_sam_gmac_link_status_get(&cfg->phy);
1830+
is_up = state->is_up;
18341831

1835-
if (link_status && !dev_data->link_up) {
1832+
if (is_up && !dev_data->link_up) {
18361833
LOG_INF("Link up");
18371834

18381835
/* Announce link up status */
18391836
dev_data->link_up = true;
18401837
net_eth_carrier_on(dev_data->iface);
18411838

1842-
/* PHY auto-negotiate link parameters */
1843-
result = phy_sam_gmac_auto_negotiate(&cfg->phy, &link_config);
1844-
if (result < 0) {
1845-
LOG_ERR("ETH PHY auto-negotiate sequence failed");
1846-
goto finally;
1847-
}
1848-
1849-
/* Set up link parameters */
1850-
link_configure(cfg->regs, link_config);
1851-
} else if (!link_status && dev_data->link_up) {
1839+
/* Set up link */
1840+
link_configure(cfg->regs,
1841+
PHY_LINK_IS_FULL_DUPLEX(state->speed),
1842+
PHY_LINK_IS_SPEED_100M(state->speed));
1843+
} else if (!is_up && dev_data->link_up) {
18521844
LOG_INF("Link down");
18531845

18541846
/* Announce link down status */
18551847
dev_data->link_up = false;
18561848
net_eth_carrier_off(dev_data->iface);
18571849
}
1858-
1859-
finally:
1860-
/* Submit delayed work */
1861-
k_work_reschedule(&dev_data->monitor_work,
1862-
K_MSEC(CONFIG_ETH_SAM_GMAC_MONITOR_PERIOD));
18631850
}
18641851

18651852
static void eth0_iface_init(struct net_if *iface)
@@ -1967,19 +1954,14 @@ static void eth0_iface_init(struct net_if *iface)
19671954

19681955
#endif
19691956
#endif
1957+
if (device_is_ready(cfg->phy_dev)) {
1958+
phy_link_callback_set(cfg->phy_dev, &phy_link_state_changed,
1959+
(void *)dev);
19701960

1971-
/* PHY initialize */
1972-
result = phy_sam_gmac_init(&cfg->phy);
1973-
if (result < 0) {
1974-
LOG_ERR("ETH PHY Initialization Error");
1975-
return;
1961+
} else {
1962+
LOG_ERR("PHY device not ready");
19761963
}
19771964

1978-
/* Initialise monitor */
1979-
k_work_init_delayable(&dev_data->monitor_work, monitor_work_handler);
1980-
k_work_reschedule(&dev_data->monitor_work,
1981-
K_MSEC(CONFIG_ETH_SAM_GMAC_MONITOR_PERIOD));
1982-
19831965
/* Do not start the interface until PHY link is up */
19841966
net_if_flag_set(iface, NET_IF_NO_AUTO_START);
19851967

@@ -2229,7 +2211,11 @@ static const struct eth_sam_dev_cfg eth0_config = {
22292211
.pin_list_size = ARRAY_SIZE(pins_eth0),
22302212
#endif
22312213
.config_func = eth0_irq_config,
2232-
.phy = {(Gmac *)DT_INST_REG_ADDR(0), CONFIG_ETH_SAM_GMAC_PHY_ADDR},
2214+
#if DT_NODE_EXISTS(DT_CHILD(DT_DRV_INST(0), phy))
2215+
.phy_dev = DEVICE_DT_GET(DT_CHILD(DT_DRV_INST(0), phy))
2216+
#else
2217+
#error "No PHY driver specified"
2218+
#endif
22332219
};
22342220

22352221
static struct eth_sam_dev_data eth0_data = {

drivers/ethernet/eth_sam_gmac_priv.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ struct eth_sam_dev_cfg {
267267
uint32_t pin_list_size;
268268
#endif
269269
void (*config_func)(void);
270-
struct phy_sam_gmac_dev phy;
270+
const struct device *phy_dev;
271271
};
272272

273273
/* Device run time data */
@@ -277,7 +277,6 @@ struct eth_sam_dev_data {
277277
const struct device *ptp_clock;
278278
#endif
279279
uint8_t mac_addr[6];
280-
struct k_work_delayable monitor_work;
281280
bool link_up;
282281
struct gmac_queue queue_list[GMAC_QUEUE_NUM];
283282
};

0 commit comments

Comments
 (0)