Skip to content

Commit 2f23eb2

Browse files
erwangojhedberg
authored andcommitted
drivers: ethernet: stm32: Split ptp functions into a dedicated source file
In an effort to make stm32 eth driver files easier to read and maintain, split the ptp code in a dedicated file. Signed-off-by: Erwan Gouriou <[email protected]>
1 parent b1a9e39 commit 2f23eb2

File tree

4 files changed

+365
-344
lines changed

4 files changed

+365
-344
lines changed

drivers/ethernet/CMakeLists.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ zephyr_library_sources_ifdef(CONFIG_ETH_ESP32 eth_esp32.c)
2929
zephyr_library_sources_ifdef(CONFIG_ETH_LITEX_LITEETH eth_litex_liteeth.c)
3030
zephyr_library_sources_ifdef(CONFIG_ETH_SMSC911X eth_smsc911x.c)
3131
zephyr_library_sources_ifdef(CONFIG_ETH_STELLARIS eth_stellaris.c)
32-
zephyr_library_sources_ifdef(CONFIG_ETH_STM32_HAL eth_stm32_hal_common.c)
3332
zephyr_library_sources_ifdef(CONFIG_ETH_W5500 eth_w5500.c)
3433
zephyr_library_sources_ifdef(CONFIG_ETH_SAM_GMAC eth_sam_gmac.c)
3534
zephyr_library_sources_ifdef(CONFIG_ETH_CYCLONEV eth_cyclonev.c)
@@ -53,6 +52,11 @@ if(CONFIG_ETH_NXP_S32_NETC)
5352
zephyr_library_sources_ifdef(CONFIG_DT_HAS_NXP_S32_NETC_VSI_ENABLED eth_nxp_s32_netc_vsi.c)
5453
endif()
5554

55+
if(CONFIG_ETH_STM32_HAL)
56+
zephyr_library_sources(eth_stm32_hal_common.c)
57+
zephyr_library_sources_ifdef(CONFIG_PTP_CLOCK_STM32_HAL eth_stm32_hal_ptp.c)
58+
endif()
59+
5660
zephyr_library_sources_ifdef(CONFIG_ETH_NXP_S32_GMAC eth_nxp_s32_gmac.c)
5761
zephyr_library_sources_ifdef(CONFIG_ETH_NUMAKER eth_numaker.c)
5862

drivers/ethernet/eth_stm32_hal_common.c

Lines changed: 0 additions & 335 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,6 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
3838
#include <zephyr/net/dsa.h>
3939
#endif
4040

41-
#if defined(CONFIG_PTP_CLOCK_STM32_HAL)
42-
#include <zephyr/drivers/ptp_clock.h>
43-
#endif /* CONFIG_PTP_CLOCK_STM32_HAL */
4441

4542
#include "eth.h"
4643
#include "eth_stm32_hal_priv.h"
@@ -145,12 +142,6 @@ struct eth_stm32_tx_buffer_header {
145142
bool used;
146143
};
147144

148-
struct eth_stm32_tx_context {
149-
struct net_pkt *pkt;
150-
uint16_t first_tx_buffer_index;
151-
bool used;
152-
};
153-
154145
static struct eth_stm32_rx_buffer_header dma_rx_buffer_header[ETH_RXBUFNB];
155146
static struct eth_stm32_tx_buffer_header dma_tx_buffer_header[ETH_TXBUFNB];
156147
static struct eth_stm32_tx_context dma_tx_context[ETH_TX_DESC_CNT];
@@ -303,29 +294,6 @@ static void setup_mac_filter(ETH_HandleTypeDef *heth)
303294
}
304295
#endif /* CONFIG_ETH_STM32_HAL_API_V2 */
305296

306-
#if defined(CONFIG_PTP_CLOCK_STM32_HAL)
307-
static bool eth_is_ptp_pkt(struct net_if *iface, struct net_pkt *pkt)
308-
{
309-
if (ntohs(NET_ETH_HDR(pkt)->type) != NET_ETH_PTYPE_PTP) {
310-
return false;
311-
}
312-
313-
net_pkt_set_priority(pkt, NET_PRIORITY_CA);
314-
315-
return true;
316-
}
317-
318-
void HAL_ETH_TxPtpCallback(uint32_t *buff, ETH_TimeStampTypeDef *timestamp)
319-
{
320-
struct eth_stm32_tx_context *ctx = (struct eth_stm32_tx_context *)buff;
321-
322-
ctx->pkt->timestamp.second = timestamp->TimeStampHigh;
323-
ctx->pkt->timestamp.nanosecond = timestamp->TimeStampLow;
324-
325-
net_if_add_tx_timestamp(ctx->pkt);
326-
}
327-
#endif /* CONFIG_PTP_CLOCK_STM32_HAL */
328-
329297
#if defined(CONFIG_ETH_STM32_HAL_API_V2)
330298
static int eth_tx(const struct device *dev, struct net_pkt *pkt)
331299
{
@@ -1343,15 +1311,6 @@ static const struct device *eth_stm32_hal_get_phy(const struct device *dev)
13431311
return eth_stm32_phy_dev;
13441312
}
13451313

1346-
#if defined(CONFIG_PTP_CLOCK_STM32_HAL)
1347-
static const struct device *eth_stm32_get_ptp_clock(const struct device *dev)
1348-
{
1349-
struct eth_stm32_hal_dev_data *dev_data = dev->data;
1350-
1351-
return dev_data->ptp_clock;
1352-
}
1353-
#endif /* CONFIG_PTP_CLOCK_STM32_HAL */
1354-
13551314
#if defined(CONFIG_NET_STATISTICS_ETHERNET)
13561315
static struct net_stats_eth *eth_stm32_hal_get_stats(const struct device *dev)
13571316
{
@@ -1430,297 +1389,3 @@ static struct eth_stm32_hal_dev_data eth0_data = {
14301389
ETH_NET_DEVICE_DT_INST_DEFINE(0, eth_initialize,
14311390
NULL, &eth0_data, &eth0_config,
14321391
CONFIG_ETH_INIT_PRIORITY, &eth_api, ETH_STM32_HAL_MTU);
1433-
1434-
#if defined(CONFIG_PTP_CLOCK_STM32_HAL)
1435-
1436-
struct ptp_context {
1437-
struct eth_stm32_hal_dev_data *eth_dev_data;
1438-
};
1439-
1440-
static struct ptp_context ptp_stm32_0_context;
1441-
1442-
static int ptp_clock_stm32_set(const struct device *dev,
1443-
struct net_ptp_time *tm)
1444-
{
1445-
struct ptp_context *ptp_context = dev->data;
1446-
struct eth_stm32_hal_dev_data *eth_dev_data = ptp_context->eth_dev_data;
1447-
ETH_HandleTypeDef *heth = &eth_dev_data->heth;
1448-
unsigned int key;
1449-
1450-
key = irq_lock();
1451-
1452-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
1453-
heth->Instance->MACSTSUR = tm->second;
1454-
heth->Instance->MACSTNUR = tm->nanosecond;
1455-
heth->Instance->MACTSCR |= ETH_MACTSCR_TSINIT;
1456-
while (heth->Instance->MACTSCR & ETH_MACTSCR_TSINIT_Msk) {
1457-
/* spin lock */
1458-
}
1459-
#else
1460-
heth->Instance->PTPTSHUR = tm->second;
1461-
heth->Instance->PTPTSLUR = tm->nanosecond;
1462-
heth->Instance->PTPTSCR |= ETH_PTPTSCR_TSSTI;
1463-
while (heth->Instance->PTPTSCR & ETH_PTPTSCR_TSSTI_Msk) {
1464-
/* spin lock */
1465-
}
1466-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
1467-
1468-
irq_unlock(key);
1469-
1470-
return 0;
1471-
}
1472-
1473-
static int ptp_clock_stm32_get(const struct device *dev,
1474-
struct net_ptp_time *tm)
1475-
{
1476-
struct ptp_context *ptp_context = dev->data;
1477-
struct eth_stm32_hal_dev_data *eth_dev_data = ptp_context->eth_dev_data;
1478-
ETH_HandleTypeDef *heth = &eth_dev_data->heth;
1479-
unsigned int key;
1480-
uint32_t second_2;
1481-
1482-
key = irq_lock();
1483-
1484-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
1485-
tm->second = heth->Instance->MACSTSR;
1486-
tm->nanosecond = heth->Instance->MACSTNR;
1487-
second_2 = heth->Instance->MACSTSR;
1488-
#else
1489-
tm->second = heth->Instance->PTPTSHR;
1490-
tm->nanosecond = heth->Instance->PTPTSLR;
1491-
second_2 = heth->Instance->PTPTSHR;
1492-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
1493-
1494-
irq_unlock(key);
1495-
1496-
if (tm->second != second_2 && tm->nanosecond < NSEC_PER_SEC / 2) {
1497-
/* Second rollover has happened during first measurement: second register
1498-
* was read before second boundary and nanosecond register was read after.
1499-
* We will use second_2 as a new second value.
1500-
*/
1501-
tm->second = second_2;
1502-
}
1503-
1504-
return 0;
1505-
}
1506-
1507-
static int ptp_clock_stm32_adjust(const struct device *dev, int increment)
1508-
{
1509-
struct ptp_context *ptp_context = dev->data;
1510-
struct eth_stm32_hal_dev_data *eth_dev_data = ptp_context->eth_dev_data;
1511-
ETH_HandleTypeDef *heth = &eth_dev_data->heth;
1512-
int key, ret;
1513-
1514-
if ((increment <= (int32_t)(-NSEC_PER_SEC)) ||
1515-
(increment >= (int32_t)NSEC_PER_SEC)) {
1516-
ret = -EINVAL;
1517-
} else {
1518-
key = irq_lock();
1519-
1520-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
1521-
heth->Instance->MACSTSUR = 0;
1522-
if (increment >= 0) {
1523-
heth->Instance->MACSTNUR = increment;
1524-
} else {
1525-
heth->Instance->MACSTNUR = ETH_MACSTNUR_ADDSUB | (NSEC_PER_SEC + increment);
1526-
}
1527-
heth->Instance->MACTSCR |= ETH_MACTSCR_TSUPDT;
1528-
while (heth->Instance->MACTSCR & ETH_MACTSCR_TSUPDT_Msk) {
1529-
/* spin lock */
1530-
}
1531-
#else
1532-
heth->Instance->PTPTSHUR = 0;
1533-
if (increment >= 0) {
1534-
heth->Instance->PTPTSLUR = increment;
1535-
} else {
1536-
heth->Instance->PTPTSLUR = ETH_PTPTSLUR_TSUPNS | (-increment);
1537-
}
1538-
heth->Instance->PTPTSCR |= ETH_PTPTSCR_TSSTU;
1539-
while (heth->Instance->PTPTSCR & ETH_PTPTSCR_TSSTU_Msk) {
1540-
/* spin lock */
1541-
}
1542-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
1543-
1544-
ret = 0;
1545-
irq_unlock(key);
1546-
}
1547-
1548-
return ret;
1549-
}
1550-
1551-
static int ptp_clock_stm32_rate_adjust(const struct device *dev, double ratio)
1552-
{
1553-
struct ptp_context *ptp_context = dev->data;
1554-
struct eth_stm32_hal_dev_data *eth_dev_data = ptp_context->eth_dev_data;
1555-
ETH_HandleTypeDef *heth = &eth_dev_data->heth;
1556-
int key, ret;
1557-
uint32_t addend_val;
1558-
1559-
key = irq_lock();
1560-
1561-
/* Limit possible ratio */
1562-
if (ratio * 100 < CONFIG_ETH_STM32_HAL_PTP_CLOCK_ADJ_MIN_PCT ||
1563-
ratio * 100 > CONFIG_ETH_STM32_HAL_PTP_CLOCK_ADJ_MAX_PCT) {
1564-
ret = -EINVAL;
1565-
goto error;
1566-
}
1567-
1568-
/* Update addend register */
1569-
addend_val = UINT32_MAX * (double)eth_dev_data->clk_ratio * ratio;
1570-
1571-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
1572-
heth->Instance->MACTSAR = addend_val;
1573-
heth->Instance->MACTSCR |= ETH_MACTSCR_TSADDREG;
1574-
while (heth->Instance->MACTSCR & ETH_MACTSCR_TSADDREG_Msk) {
1575-
/* spin lock */
1576-
}
1577-
#else
1578-
heth->Instance->PTPTSAR = addend_val;
1579-
heth->Instance->PTPTSCR |= ETH_PTPTSCR_TSARU;
1580-
while (heth->Instance->PTPTSCR & ETH_PTPTSCR_TSARU_Msk) {
1581-
/* spin lock */
1582-
}
1583-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
1584-
1585-
ret = 0;
1586-
1587-
error:
1588-
irq_unlock(key);
1589-
1590-
return ret;
1591-
}
1592-
1593-
static DEVICE_API(ptp_clock, api) = {
1594-
.set = ptp_clock_stm32_set,
1595-
.get = ptp_clock_stm32_get,
1596-
.adjust = ptp_clock_stm32_adjust,
1597-
.rate_adjust = ptp_clock_stm32_rate_adjust,
1598-
};
1599-
1600-
static int ptp_stm32_init(const struct device *port)
1601-
{
1602-
const struct device *const dev = DEVICE_DT_GET(DT_NODELABEL(mac));
1603-
struct eth_stm32_hal_dev_data *eth_dev_data = dev->data;
1604-
const struct eth_stm32_hal_dev_cfg *eth_cfg = dev->config;
1605-
struct ptp_context *ptp_context = port->data;
1606-
ETH_HandleTypeDef *heth = &eth_dev_data->heth;
1607-
int ret;
1608-
uint32_t ptp_hclk_rate;
1609-
uint32_t ss_incr_ns;
1610-
uint32_t addend_val;
1611-
1612-
eth_dev_data->ptp_clock = port;
1613-
ptp_context->eth_dev_data = eth_dev_data;
1614-
1615-
/* Mask the Timestamp Trigger interrupt */
1616-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
1617-
heth->Instance->MACIER &= ~(ETH_MACIER_TSIE);
1618-
#else
1619-
heth->Instance->MACIMR &= ~(ETH_MACIMR_TSTIM);
1620-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
1621-
1622-
/* Enable timestamping */
1623-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
1624-
heth->Instance->MACTSCR |= ETH_MACTSCR_TSENA;
1625-
#else
1626-
heth->Instance->PTPTSCR |= ETH_PTPTSCR_TSE;
1627-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
1628-
1629-
/* Query ethernet clock rate */
1630-
ret = clock_control_get_rate(DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE),
1631-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
1632-
(clock_control_subsys_t)&eth_cfg->pclken,
1633-
#else
1634-
(clock_control_subsys_t)&eth_cfg->pclken_ptp,
1635-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
1636-
&ptp_hclk_rate);
1637-
if (ret) {
1638-
LOG_ERR("Failed to query ethernet clock");
1639-
return -EIO;
1640-
}
1641-
1642-
/* Program the subsecond increment register based on the PTP clock freq */
1643-
if (NSEC_PER_SEC % CONFIG_ETH_STM32_HAL_PTP_CLOCK_SRC_HZ != 0) {
1644-
LOG_ERR("PTP clock period must be an integer nanosecond value");
1645-
return -EINVAL;
1646-
}
1647-
ss_incr_ns = NSEC_PER_SEC / CONFIG_ETH_STM32_HAL_PTP_CLOCK_SRC_HZ;
1648-
if (ss_incr_ns > UINT8_MAX) {
1649-
LOG_ERR("PTP clock period is more than %d nanoseconds", UINT8_MAX);
1650-
return -EINVAL;
1651-
}
1652-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
1653-
heth->Instance->MACSSIR = ss_incr_ns << ETH_MACMACSSIR_SSINC_Pos;
1654-
#else
1655-
heth->Instance->PTPSSIR = ss_incr_ns;
1656-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
1657-
1658-
/* Program timestamp addend register */
1659-
eth_dev_data->clk_ratio =
1660-
((double)CONFIG_ETH_STM32_HAL_PTP_CLOCK_SRC_HZ) / ((double)ptp_hclk_rate);
1661-
/*
1662-
* clk_ratio is a ratio between desired PTP clock frequency and HCLK rate.
1663-
* Because HCLK is defined by a physical oscillator, it might drift due
1664-
* to manufacturing tolerances and environmental effects (e.g. temperature).
1665-
* It gets adjusted by calling ptp_clock_stm32_rate_adjust().
1666-
*/
1667-
addend_val =
1668-
UINT32_MAX * eth_dev_data->clk_ratio;
1669-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
1670-
heth->Instance->MACTSAR = addend_val;
1671-
heth->Instance->MACTSCR |= ETH_MACTSCR_TSADDREG;
1672-
while (heth->Instance->MACTSCR & ETH_MACTSCR_TSADDREG_Msk) {
1673-
k_yield();
1674-
}
1675-
#else
1676-
heth->Instance->PTPTSAR = addend_val;
1677-
heth->Instance->PTPTSCR |= ETH_PTPTSCR_TSARU;
1678-
while (heth->Instance->PTPTSCR & ETH_PTPTSCR_TSARU_Msk) {
1679-
k_yield();
1680-
}
1681-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
1682-
1683-
/* Enable fine timestamp correction method */
1684-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
1685-
heth->Instance->MACTSCR |= ETH_MACTSCR_TSCFUPDT;
1686-
#else
1687-
heth->Instance->PTPTSCR |= ETH_PTPTSCR_TSFCU;
1688-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
1689-
1690-
/* Enable nanosecond rollover into a new second */
1691-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
1692-
heth->Instance->MACTSCR |= ETH_MACTSCR_TSCTRLSSR;
1693-
#else
1694-
heth->Instance->PTPTSCR |= ETH_PTPTSCR_TSSSR;
1695-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
1696-
1697-
/* Initialize timestamp */
1698-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
1699-
heth->Instance->MACSTSUR = 0;
1700-
heth->Instance->MACSTNUR = 0;
1701-
heth->Instance->MACTSCR |= ETH_MACTSCR_TSINIT;
1702-
while (heth->Instance->MACTSCR & ETH_MACTSCR_TSINIT_Msk) {
1703-
k_yield();
1704-
}
1705-
#else
1706-
heth->Instance->PTPTSHUR = 0;
1707-
heth->Instance->PTPTSLUR = 0;
1708-
heth->Instance->PTPTSCR |= ETH_PTPTSCR_TSSTI;
1709-
while (heth->Instance->PTPTSCR & ETH_PTPTSCR_TSSTI_Msk) {
1710-
k_yield();
1711-
}
1712-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
1713-
1714-
#if defined(CONFIG_ETH_STM32_HAL_API_V2)
1715-
/* Set PTP Configuration done */
1716-
heth->IsPtpConfigured = ETH_STM32_PTP_CONFIGURED;
1717-
#endif
1718-
1719-
return 0;
1720-
}
1721-
1722-
DEVICE_DEFINE(stm32_ptp_clock_0, PTP_CLOCK_NAME, ptp_stm32_init,
1723-
NULL, &ptp_stm32_0_context, NULL, POST_KERNEL,
1724-
CONFIG_ETH_STM32_HAL_PTP_CLOCK_INIT_PRIO, &api);
1725-
1726-
#endif /* CONFIG_PTP_CLOCK_STM32_HAL */

0 commit comments

Comments
 (0)