Skip to content

Commit 77ef9bc

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. -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 f9ee609 commit 77ef9bc

File tree

2 files changed

+88
-24
lines changed

2 files changed

+88
-24
lines changed

drivers/ethernet/Kconfig.stm32_hal

Lines changed: 10 additions & 3 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

@@ -75,6 +77,11 @@ config ETH_STM32_HAL_MII
7577
help
7678
Use the MII physical interface instead of RMII.
7779

80+
config ETH_STM32_HAL_GRMII
81+
bool "Use GRMII interface"
82+
help
83+
Use the GRMII physical interface instead of RMII and MII.
84+
7885
config ETH_STM32_CARRIER_CHECK_RX_IDLE_TIMEOUT_MS
7986
int "Carrier check timeout period (ms)"
8087
default 500

drivers/ethernet/eth_stm32_hal.c

Lines changed: 78 additions & 21 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

@@ -105,8 +108,14 @@ static const struct device *eth_stm32_phy_dev = DEVICE_PHY_BY_NAME(0);
105108
#define __eth_stm32_buf __aligned(4)
106109
#endif
107110

111+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
112+
static ETH_DMADescTypeDef dma_rx_desc_tab[ETH_DMA_RX_CH_CNT][ETH_RXBUFNB] __eth_stm32_desc;
113+
static ETH_DMADescTypeDef dma_tx_desc_tab[ETH_DMA_TX_CH_CNT][ETH_TXBUFNB] __eth_stm32_desc;
114+
#else
108115
static ETH_DMADescTypeDef dma_rx_desc_tab[ETH_RXBUFNB] __eth_stm32_desc;
109116
static ETH_DMADescTypeDef dma_tx_desc_tab[ETH_TXBUFNB] __eth_stm32_desc;
117+
#endif
118+
110119
static uint8_t dma_rx_buffer[ETH_RXBUFNB][ETH_STM32_RX_BUF_SIZE] __eth_stm32_buf;
111120
static uint8_t dma_tx_buffer[ETH_TXBUFNB][ETH_STM32_TX_BUF_SIZE] __eth_stm32_buf;
112121

@@ -253,7 +262,7 @@ static inline void setup_mac_filter(ETH_HandleTypeDef *heth)
253262
{
254263
__ASSERT_NO_MSG(heth != NULL);
255264

256-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
265+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) || DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
257266
ETH_MACFilterConfigTypeDef MACFilterConf;
258267

259268
HAL_ETH_GetMACFilterConfig(heth, &MACFilterConf);
@@ -294,7 +303,7 @@ static inline void setup_mac_filter(ETH_HandleTypeDef *heth)
294303
tmp = heth->Instance->MACFFR;
295304
k_sleep(K_MSEC(1));
296305
heth->Instance->MACFFR = tmp;
297-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
306+
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet || st_stm32n6_ethernet) */
298307
}
299308

300309
#if defined(CONFIG_PTP_CLOCK_STM32_HAL)
@@ -807,19 +816,24 @@ void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
807816
__ASSERT_NO_MSG(heth != NULL);
808817

809818
uint32_t dma_error;
810-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
819+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) || DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
811820
uint32_t mac_error;
812-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
821+
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet || st_stm32n6_ethernet) */
813822
const uint32_t error_code = HAL_ETH_GetError(heth);
814823

815824
struct eth_stm32_hal_dev_data *dev_data =
816825
CONTAINER_OF(heth, struct eth_stm32_hal_dev_data, heth);
817826

818827
switch (error_code) {
828+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
829+
case HAL_ETH_ERROR_DMA_CH0:
830+
case HAL_ETH_ERROR_DMA_CH1:
831+
#else
819832
case HAL_ETH_ERROR_DMA:
833+
#endif
820834
dma_error = HAL_ETH_GetDMAError(heth);
821835

822-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
836+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) || DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
823837
if ((dma_error & ETH_DMA_RX_WATCHDOG_TIMEOUT_FLAG) ||
824838
(dma_error & ETH_DMA_RX_PROCESS_STOPPED_FLAG) ||
825839
(dma_error & ETH_DMA_RX_BUFFER_UNAVAILABLE_FLAG)) {
@@ -840,10 +854,10 @@ void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
840854
(dma_error & ETH_DMASR_TJTS)) {
841855
eth_stats_update_errors_tx(dev_data->iface);
842856
}
843-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
857+
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet || st_stm32n6_ethernet) */
844858
break;
845859

846-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
860+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) || DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
847861
case HAL_ETH_ERROR_MAC:
848862
mac_error = HAL_ETH_GetMACError(heth);
849863

@@ -860,16 +874,16 @@ void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
860874
eth_stats_update_errors_tx(dev_data->iface);
861875
}
862876
break;
863-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
877+
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet || st_stm32n6_ethernet) */
864878
}
865879

866-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
880+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) || DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
867881
dev_data->stats.error_details.rx_crc_errors = heth->Instance->MMCRCRCEPR;
868882
dev_data->stats.error_details.rx_align_errors = heth->Instance->MMCRAEPR;
869883
#else
870884
dev_data->stats.error_details.rx_crc_errors = heth->Instance->MMCRFCECR;
871885
dev_data->stats.error_details.rx_align_errors = heth->Instance->MMCRFAECR;
872-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
886+
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet || st_stm32n6_ethernet) */
873887

874888
#endif /* CONFIG_NET_STATISTICS_ETHERNET */
875889
}
@@ -913,6 +927,32 @@ static void generate_mac(uint8_t *mac_addr)
913927
#endif
914928
}
915929

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

979+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
980+
/* RISAF Configuration */
981+
RISAF_Config();
982+
#endif
983+
939984
/* enable clock */
940985
ret = clock_control_on(dev_data->clock,
941986
(clock_control_subsys_t)&cfg->pclken);
@@ -967,8 +1012,15 @@ static int eth_initialize(const struct device *dev)
9671012
heth->Init.MACAddr = dev_data->mac_addr;
9681013

9691014
#if defined(CONFIG_ETH_STM32_HAL_API_V2)
1015+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
1016+
for (int ch = 0; ch < ETH_DMA_CH_CNT; ch++) {
1017+
heth->Init.TxDesc[ch] = dma_tx_desc_tab[ch];
1018+
heth->Init.RxDesc[ch] = dma_rx_desc_tab[ch];
1019+
}
1020+
#else
9701021
heth->Init.TxDesc = dma_tx_desc_tab;
9711022
heth->Init.RxDesc = dma_rx_desc_tab;
1023+
#endif
9721024
heth->Init.RxBuffLen = ETH_STM32_RX_BUF_SIZE;
9731025
#endif /* CONFIG_ETH_STM32_HAL_API_V2 */
9741026

@@ -987,11 +1039,11 @@ static int eth_initialize(const struct device *dev)
9871039
/* Enable timestamping of RX packets. We enable all packets to be
9881040
* timestamped to cover both IEEE 1588 and gPTP.
9891041
*/
990-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
1042+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) || DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
9911043
heth->Instance->MACTSCR |= ETH_MACTSCR_TSENALL;
9921044
#else
9931045
heth->Instance->PTPTSCR |= ETH_PTPTSCR_TSSARFE;
994-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
1046+
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet || st_stm32n6_ethernet) */
9951047
#endif /* CONFIG_PTP_CLOCK_STM32_HAL */
9961048

9971049
#if defined(CONFIG_ETH_STM32_HAL_API_V2)
@@ -1080,13 +1132,13 @@ static void eth_stm32_mcast_filter(const struct device *dev, const struct ethern
10801132

10811133
__ASSERT_NO_MSG(hash_index < ARRAY_SIZE(dev_data->hash_index_cnt));
10821134

1083-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
1135+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) || DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
10841136
hash_table[0] = heth->Instance->MACHT0R;
10851137
hash_table[1] = heth->Instance->MACHT1R;
10861138
#else
10871139
hash_table[0] = heth->Instance->MACHTLR;
10881140
hash_table[1] = heth->Instance->MACHTHR;
1089-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
1141+
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet || st_stm32n6_ethernet) */
10901142

10911143
if (filter->set) {
10921144
dev_data->hash_index_cnt[hash_index]++;
@@ -1103,13 +1155,13 @@ static void eth_stm32_mcast_filter(const struct device *dev, const struct ethern
11031155
}
11041156
}
11051157

1106-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
1158+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) || DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
11071159
heth->Instance->MACHT0R = hash_table[0];
11081160
heth->Instance->MACHT1R = hash_table[1];
11091161
#else
11101162
heth->Instance->MACHTLR = hash_table[0];
11111163
heth->Instance->MACHTHR = hash_table[1];
1112-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
1164+
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet || st_stm32n6_ethernet) */
11131165
}
11141166

11151167
#endif /* CONFIG_ETH_STM32_MULTICAST_FILTER */
@@ -1224,7 +1276,7 @@ static int eth_stm32_hal_set_config(const struct device *dev,
12241276
break;
12251277
case ETHERNET_CONFIG_TYPE_PROMISC_MODE:
12261278
#if defined(CONFIG_NET_PROMISCUOUS_MODE)
1227-
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet)
1279+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) || DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
12281280
if (config->promisc_mode) {
12291281
heth->Instance->MACPFR |= ETH_MACPFR_PR;
12301282
} else {
@@ -1236,7 +1288,7 @@ static int eth_stm32_hal_set_config(const struct device *dev,
12361288
} else {
12371289
heth->Instance->MACFFR &= ~ETH_MACFFR_PM;
12381290
}
1239-
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet) */
1291+
#endif /* DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_ethernet || st_stm32n6_ethernet) */
12401292
ret = 0;
12411293
#endif /* CONFIG_NET_PROMISCUOUS_MODE */
12421294
break;
@@ -1331,7 +1383,12 @@ static struct eth_stm32_hal_dev_data eth0_data = {
13311383
ETH_CHECKSUM_BY_HARDWARE : ETH_CHECKSUM_BY_SOFTWARE,
13321384
#endif /* !CONFIG_SOC_SERIES_STM32H7X */
13331385
.MediaInterface = IS_ENABLED(CONFIG_ETH_STM32_HAL_MII) ?
1334-
ETH_MEDIA_INTERFACE_MII : ETH_MEDIA_INTERFACE_RMII,
1386+
ETH_MEDIA_INTERFACE_MII :
1387+
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_ethernet)
1388+
IS_ENABLED(CONFIG_ETH_STM32_HAL_GRMII) ?
1389+
ETH_MEDIA_INTERFACE_RGMII :
1390+
#endif
1391+
ETH_MEDIA_INTERFACE_RMII,
13351392
},
13361393
},
13371394
};

0 commit comments

Comments
 (0)