Skip to content

Commit 6d35efe

Browse files
committed
drivers: ethernet: eth_stm32_hal: Add stm32n6 ethernet support
-Update the ETH_STM32_HAL menu configuration to conditionally select USE_STM32_HAL_RIF if SOC_SERIES_STM32N6X is enabled. -Align Ethernet descriptors to 32 bytes for STM32N6 to ensure efficient DMA operations and improve cache line efficiency and overall performance -Add RISAF configuration in eth_initialize function for STM32N6 series to set up master and slave security attributes for the Ethernet peripheral. -Ensure RISAF configuration is done before enabling the Ethernet clock to maintain proper security attributes. Signed-off-by: IBEN EL HADJ MESSAOUD Marwa <[email protected]>
1 parent cf2112c commit 6d35efe

File tree

2 files changed

+107
-27
lines changed

2 files changed

+107
-27
lines changed

drivers/ethernet/Kconfig.stm32_hal

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ menuconfig ETH_STM32_HAL
99
default y
1010
depends on DT_HAS_ST_STM32_ETHERNET_ENABLED
1111
select USE_STM32_HAL_ETH
12-
select NOCACHE_MEMORY if SOC_SERIES_STM32H7X && CPU_CORTEX_M7
12+
select USE_STM32_HAL_RIF if SOC_SERIES_STM32N6X
13+
select NOCACHE_MEMORY if (SOC_SERIES_STM32H7X && CPU_CORTEX_M7)
1314
select HWINFO
1415
select ETH_DSA_SUPPORT
1516
select PINCTRL
16-
select MDIO if SOC_SERIES_STM32H5X || SOC_SERIES_STM32H7X
17+
select MDIO if SOC_SERIES_STM32H5X || SOC_SERIES_STM32H7X || SOC_SERIES_STM32N6X
1718
imply CRC
1819
help
1920
Enable STM32 HAL based Ethernet driver. It is available for
@@ -26,7 +27,8 @@ choice ETH_STM32_HAL_API_VERSION
2627

2728
config ETH_STM32_HAL_API_V2
2829
bool "Use official STM32Cube HAL driver"
29-
depends on SOC_SERIES_STM32H7X || SOC_SERIES_STM32H5X || SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X
30+
depends on SOC_SERIES_STM32H7X || SOC_SERIES_STM32H5X || SOC_SERIES_STM32F4X || SOC_SERIES_STM32F7X || SOC_SERIES_STM32N6X
31+
select USE_STM32_HAL_ETH_EX if SOC_SERIES_STM32N6X
3032
help
3133
Use the official STM32Cube HAL driver instead of the legacy one.
3234

@@ -73,7 +75,12 @@ config ETH_STM32_HAL_PHY_ADDRESS
7375
config ETH_STM32_HAL_MII
7476
bool "Use MII interface"
7577
help
76-
Use the MII physical interface instead of RMII.
78+
Use the MII physical interface instead of RMII and RGMII.
79+
80+
config ETH_STM32_HAL_RGMII
81+
bool "Use GRMII interface"
82+
help
83+
Use the GRMII physical interface instead of RMII and MII.
7784

7885
config ETH_STM32_CARRIER_CHECK_RX_IDLE_TIMEOUT_MS
7986
int "Carrier check timeout period (ms)"
@@ -105,6 +112,12 @@ config ETH_STM32_SPEED_10M
105112
Set this if using 10 Mbps and when autonegotiation is disabled, otherwise speed
106113
is 100 Mbps
107114

115+
config ETH_STM32_SPEED_1000M
116+
bool "Set speed to 1000 Mbps when autonegotiation is disabled"
117+
help
118+
Set this if using 1000 Mbps and when autonegotiation is disabled, otherwise speed
119+
is 10 or 100 Mbps
120+
108121
config ETH_STM32_MODE_HALFDUPLEX
109122
bool "Half duplex mode"
110123
help

drivers/ethernet/eth_stm32_hal.c

Lines changed: 90 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ static const struct device *eth_stm32_phy_dev = DEVICE_PHY_BY_NAME(0);
6565

6666
#endif
6767

68-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
68+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) || DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
6969

7070
#define PHY_BSR ((uint16_t)0x0001U) /*!< Transceiver Basic Status Register */
7171
#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */
@@ -78,6 +78,9 @@ static const struct device *eth_stm32_phy_dev = DEVICE_PHY_BY_NAME(0);
7878

7979
#define ETH_MEDIA_INTERFACE_MII HAL_ETH_MII_MODE
8080
#define ETH_MEDIA_INTERFACE_RMII HAL_ETH_RMII_MODE
81+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
82+
#define ETH_MEDIA_INTERFACE_RGMII HAL_ETH_RGMII_MODE
83+
#endif
8184

8285
/* Only one tx_buffer is sufficient to pass only 1 dma_buffer */
8386
#define ETH_TXBUF_DEF_NB 1U
@@ -86,7 +89,7 @@ static const struct device *eth_stm32_phy_dev = DEVICE_PHY_BY_NAME(0);
8689
#define IS_ETH_DMATXDESC_OWN(dma_tx_desc) (dma_tx_desc->Status & \
8790
ETH_DMATXDESC_OWN)
8891

89-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
92+
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet || st_stm32n6_ethernet) */
9093

9194
#define ETH_DMA_TX_TIMEOUT_MS 20U /* transmit timeout in milliseconds */
9295

@@ -97,6 +100,10 @@ static const struct device *eth_stm32_phy_dev = DEVICE_PHY_BY_NAME(0);
97100
#elif defined(CONFIG_SOC_SERIES_STM32H7X)
98101
#define __eth_stm32_desc __attribute__((section(".eth_stm32_desc")))
99102
#define __eth_stm32_buf __attribute__((section(".eth_stm32_buf")))
103+
#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
104+
#define __eth_stm32_rx_desc ALIGN_32BYTES(__attribute__((section(".RxDecripSection"))))
105+
#define __eth_stm32_tx_desc ALIGN_32BYTES(__attribute__((section(".TxDecripSection"))))
106+
#define __eth_stm32_buf ALIGN_32BYTES(__attribute__((section(".eth_stm32_buf"))))
100107
#elif defined(CONFIG_NOCACHE_MEMORY)
101108
#define __eth_stm32_desc __nocache __aligned(4)
102109
#define __eth_stm32_buf __nocache __aligned(4)
@@ -105,8 +112,14 @@ static const struct device *eth_stm32_phy_dev = DEVICE_PHY_BY_NAME(0);
105112
#define __eth_stm32_buf __aligned(4)
106113
#endif
107114

115+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
116+
static ETH_DMADescTypeDef dma_rx_desc_tab[ETH_DMA_RX_CH_CNT][ETH_RXBUFNB] __eth_stm32_rx_desc;
117+
static ETH_DMADescTypeDef dma_tx_desc_tab[ETH_DMA_TX_CH_CNT][ETH_TXBUFNB] __eth_stm32_tx_desc;
118+
#else
108119
static ETH_DMADescTypeDef dma_rx_desc_tab[ETH_RXBUFNB] __eth_stm32_desc;
109120
static ETH_DMADescTypeDef dma_tx_desc_tab[ETH_TXBUFNB] __eth_stm32_desc;
121+
#endif
122+
110123
static uint8_t dma_rx_buffer[ETH_RXBUFNB][ETH_STM32_RX_BUF_SIZE] __eth_stm32_buf;
111124
static uint8_t dma_tx_buffer[ETH_TXBUFNB][ETH_STM32_TX_BUF_SIZE] __eth_stm32_buf;
112125

@@ -253,7 +266,7 @@ static inline void setup_mac_filter(ETH_HandleTypeDef *heth)
253266
{
254267
__ASSERT_NO_MSG(heth != NULL);
255268

256-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
269+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) || DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
257270
ETH_MACFilterConfigTypeDef MACFilterConf;
258271

259272
HAL_ETH_GetMACFilterConfig(heth, &MACFilterConf);
@@ -294,7 +307,7 @@ static inline void setup_mac_filter(ETH_HandleTypeDef *heth)
294307
tmp = heth->Instance->MACFFR;
295308
k_sleep(K_MSEC(1));
296309
heth->Instance->MACFFR = tmp;
297-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
310+
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet || st_stm32n6_ethernet) */
298311
}
299312

300313
#if defined(CONFIG_PTP_CLOCK_STM32_HAL)
@@ -807,19 +820,24 @@ void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
807820
__ASSERT_NO_MSG(heth != NULL);
808821

809822
uint32_t dma_error;
810-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
823+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) || DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
811824
uint32_t mac_error;
812-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
825+
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet || st_stm32n6_ethernet) */
813826
const uint32_t error_code = HAL_ETH_GetError(heth);
814827

815828
struct eth_stm32_hal_dev_data *dev_data =
816829
CONTAINER_OF(heth, struct eth_stm32_hal_dev_data, heth);
817830

818831
switch (error_code) {
832+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
833+
case HAL_ETH_ERROR_DMA_CH0:
834+
case HAL_ETH_ERROR_DMA_CH1:
835+
#else
819836
case HAL_ETH_ERROR_DMA:
837+
#endif
820838
dma_error = HAL_ETH_GetDMAError(heth);
821839

822-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
840+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) || DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
823841
if ((dma_error & ETH_DMA_RX_WATCHDOG_TIMEOUT_FLAG) ||
824842
(dma_error & ETH_DMA_RX_PROCESS_STOPPED_FLAG) ||
825843
(dma_error & ETH_DMA_RX_BUFFER_UNAVAILABLE_FLAG)) {
@@ -840,10 +858,10 @@ void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
840858
(dma_error & ETH_DMASR_TJTS)) {
841859
eth_stats_update_errors_tx(dev_data->iface);
842860
}
843-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
861+
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet || st_stm32n6_ethernet) */
844862
break;
845863

846-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
864+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) || DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
847865
case HAL_ETH_ERROR_MAC:
848866
mac_error = HAL_ETH_GetMACError(heth);
849867

@@ -860,16 +878,16 @@ void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
860878
eth_stats_update_errors_tx(dev_data->iface);
861879
}
862880
break;
863-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
881+
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet || st_stm32n6_ethernet) */
864882
}
865883

866-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
884+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) || DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
867885
dev_data->stats.error_details.rx_crc_errors = heth->Instance->MMCRCRCEPR;
868886
dev_data->stats.error_details.rx_align_errors = heth->Instance->MMCRAEPR;
869887
#else
870888
dev_data->stats.error_details.rx_crc_errors = heth->Instance->MMCRFCECR;
871889
dev_data->stats.error_details.rx_align_errors = heth->Instance->MMCRFAECR;
872-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
890+
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet || st_stm32n6_ethernet) */
873891

874892
#endif /* CONFIG_NET_STATISTICS_ETHERNET */
875893
}
@@ -913,6 +931,32 @@ static void generate_mac(uint8_t *mac_addr)
913931
#endif
914932
}
915933

934+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
935+
/**
936+
* Configures the RISAF (RIF Security Attribute Framework) for Ethernet on STM32N6.
937+
* This function sets up the master and slave security attributes for the Ethernet peripheral.
938+
*/
939+
940+
static void RISAF_Config(void)
941+
{
942+
/* Define and initialize the master configuration structure */
943+
RIMC_MasterConfig_t RIMC_master = {0};
944+
945+
/* Enable the clock for the RIFSC (RIF Security Controller) */
946+
__HAL_RCC_RIFSC_CLK_ENABLE();
947+
948+
RIMC_master.MasterCID = RIF_CID_1;
949+
RIMC_master.SecPriv = RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV;
950+
951+
/* Configure the master attributes for the Ethernet peripheral (ETH1) */
952+
HAL_RIF_RIMC_ConfigMasterAttributes(RIF_MASTER_INDEX_ETH1, &RIMC_master);
953+
954+
/* Set the secure and privileged attributes for the Ethernet peripheral (ETH1) as a slave */
955+
HAL_RIF_RISC_SetSlaveSecureAttributes(RIF_RISC_PERIPH_INDEX_ETH1,
956+
RIF_ATTRIBUTE_SEC | RIF_ATTRIBUTE_PRIV);
957+
}
958+
#endif
959+
916960
static int eth_initialize(const struct device *dev)
917961
{
918962
struct eth_stm32_hal_dev_data *dev_data;
@@ -936,6 +980,11 @@ static int eth_initialize(const struct device *dev)
936980
return -ENODEV;
937981
}
938982

983+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
984+
/* RISAF Configuration */
985+
RISAF_Config();
986+
#endif
987+
939988
/* enable clock */
940989
ret = clock_control_on(dev_data->clock,
941990
(clock_control_subsys_t)&cfg->pclken);
@@ -967,8 +1016,15 @@ static int eth_initialize(const struct device *dev)
9671016
heth->Init.MACAddr = dev_data->mac_addr;
9681017

9691018
#if defined(CONFIG_ETH_STM32_HAL_API_V2)
1019+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
1020+
for (int ch = 0; ch < ETH_DMA_CH_CNT; ch++) {
1021+
heth->Init.TxDesc[ch] = dma_tx_desc_tab[ch];
1022+
heth->Init.RxDesc[ch] = dma_rx_desc_tab[ch];
1023+
}
1024+
#else
9701025
heth->Init.TxDesc = dma_tx_desc_tab;
9711026
heth->Init.RxDesc = dma_rx_desc_tab;
1027+
#endif
9721028
heth->Init.RxBuffLen = ETH_STM32_RX_BUF_SIZE;
9731029
#endif /* CONFIG_ETH_STM32_HAL_API_V2 */
9741030

@@ -987,11 +1043,11 @@ static int eth_initialize(const struct device *dev)
9871043
/* Enable timestamping of RX packets. We enable all packets to be
9881044
* timestamped to cover both IEEE 1588 and gPTP.
9891045
*/
990-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
1046+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) || DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
9911047
heth->Instance->MACTSCR |= ETH_MACTSCR_TSENALL;
9921048
#else
9931049
heth->Instance->PTPTSCR |= ETH_PTPTSCR_TSSARFE;
994-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
1050+
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet || st_stm32n6_ethernet) */
9951051
#endif /* CONFIG_PTP_CLOCK_STM32_HAL */
9961052

9971053
#if defined(CONFIG_ETH_STM32_HAL_API_V2)
@@ -1024,8 +1080,14 @@ static int eth_initialize(const struct device *dev)
10241080
HAL_ETH_GetMACConfig(heth, &mac_config);
10251081
mac_config.DuplexMode = IS_ENABLED(CONFIG_ETH_STM32_MODE_HALFDUPLEX) ?
10261082
ETH_HALFDUPLEX_MODE : ETH_FULLDUPLEX_MODE;
1027-
mac_config.Speed = IS_ENABLED(CONFIG_ETH_STM32_SPEED_10M) ?
1028-
ETH_SPEED_10M : ETH_SPEED_100M;
1083+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
1084+
mac_config.Speed = IS_ENABLED(CONFIG_ETH_STM32_SPEED_1000M) ? ETH_SPEED_1000M :
1085+
(IS_ENABLED(CONFIG_ETH_STM32_SPEED_10M) ?
1086+
ETH_SPEED_10M : ETH_SPEED_100M);
1087+
#else
1088+
mac_config.Speed = IS_ENABLED(CONFIG_ETH_STM32_SPEED_10M) ? ETH_SPEED_10M : ETH_SPEED_100M;
1089+
#endif
1090+
10291091
hal_ret = HAL_ETH_SetMACConfig(heth, &mac_config);
10301092
if (hal_ret != HAL_OK) {
10311093
LOG_ERR("HAL_ETH_SetMACConfig: failed: %d", hal_ret);
@@ -1080,13 +1142,13 @@ static void eth_stm32_mcast_filter(const struct device *dev, const struct ethern
10801142

10811143
__ASSERT_NO_MSG(hash_index < ARRAY_SIZE(dev_data->hash_index_cnt));
10821144

1083-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
1145+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) || DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
10841146
hash_table[0] = heth->Instance->MACHT0R;
10851147
hash_table[1] = heth->Instance->MACHT1R;
10861148
#else
10871149
hash_table[0] = heth->Instance->MACHTLR;
10881150
hash_table[1] = heth->Instance->MACHTHR;
1089-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
1151+
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet || st_stm32n6_ethernet) */
10901152

10911153
if (filter->set) {
10921154
dev_data->hash_index_cnt[hash_index]++;
@@ -1103,13 +1165,13 @@ static void eth_stm32_mcast_filter(const struct device *dev, const struct ethern
11031165
}
11041166
}
11051167

1106-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
1168+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) || DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
11071169
heth->Instance->MACHT0R = hash_table[0];
11081170
heth->Instance->MACHT1R = hash_table[1];
11091171
#else
11101172
heth->Instance->MACHTLR = hash_table[0];
11111173
heth->Instance->MACHTHR = hash_table[1];
1112-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
1174+
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet || st_stm32n6_ethernet) */
11131175
}
11141176

11151177
#endif /* CONFIG_ETH_STM32_MULTICAST_FILTER */
@@ -1224,7 +1286,7 @@ static int eth_stm32_hal_set_config(const struct device *dev,
12241286
break;
12251287
case ETHERNET_CONFIG_TYPE_PROMISC_MODE:
12261288
#if defined(CONFIG_NET_PROMISCUOUS_MODE)
1227-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
1289+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) || DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
12281290
if (config->promisc_mode) {
12291291
heth->Instance->MACPFR |= ETH_MACPFR_PR;
12301292
} else {
@@ -1236,7 +1298,7 @@ static int eth_stm32_hal_set_config(const struct device *dev,
12361298
} else {
12371299
heth->Instance->MACFFR &= ~ETH_MACFFR_PM;
12381300
}
1239-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
1301+
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet || st_stm32n6_ethernet) */
12401302
ret = 0;
12411303
#endif /* CONFIG_NET_PROMISCUOUS_MODE */
12421304
break;
@@ -1331,7 +1393,12 @@ static struct eth_stm32_hal_dev_data eth0_data = {
13311393
ETH_CHECKSUM_BY_HARDWARE : ETH_CHECKSUM_BY_SOFTWARE,
13321394
#endif /* !CONFIG_SOC_SERIES_STM32H7X */
13331395
.MediaInterface = IS_ENABLED(CONFIG_ETH_STM32_HAL_MII) ?
1334-
ETH_MEDIA_INTERFACE_MII : ETH_MEDIA_INTERFACE_RMII,
1396+
ETH_MEDIA_INTERFACE_MII :
1397+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
1398+
IS_ENABLED(CONFIG_ETH_STM32_HAL_RGMII) ?
1399+
ETH_MEDIA_INTERFACE_RGMII :
1400+
#endif
1401+
ETH_MEDIA_INTERFACE_RMII,
13351402
},
13361403
},
13371404
};

0 commit comments

Comments
 (0)