Merge pull request #15200 from maribu/mii
drivers: Add utilities for Ethernet Media-Independent Interface (MII) and use them in STM32 `periph_eth`
This commit is contained in:
commit
c1b0e47e98
@ -35,6 +35,7 @@
|
||||
#include "f2f4f7/cfg_clock_default_120.h"
|
||||
#include "cfg_i2c1_pb8_pb9.h"
|
||||
#include "cfg_usb_otg_fs.h"
|
||||
#include "mii.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -248,7 +249,7 @@ static const adc_conf_t adc_config[] = {
|
||||
static const eth_conf_t eth_config = {
|
||||
.mode = RMII,
|
||||
.addr = { 0 },
|
||||
.speed = ETH_SPEED_100TX_FD,
|
||||
.speed = MII_BMCR_SPEED_100 | MII_BMCR_FULL_DPLX,
|
||||
.dma = 6,
|
||||
.dma_chan = 8,
|
||||
.phy_addr = 0x00,
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
#include "cfg_rtt_default.h"
|
||||
#include "cfg_timer_tim2.h"
|
||||
#include "cfg_usb_otg_fs.h"
|
||||
#include "mii.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -219,7 +220,7 @@ static const spi_conf_t spi_config[] = {
|
||||
static const eth_conf_t eth_config = {
|
||||
.mode = RMII,
|
||||
.addr = { 0 },
|
||||
.speed = ETH_SPEED_100TX_FD,
|
||||
.speed = MII_BMCR_SPEED_100 | MII_BMCR_FULL_DPLX,
|
||||
.dma = 7,
|
||||
.dma_chan = 8,
|
||||
.phy_addr = 0x00,
|
||||
|
||||
@ -35,6 +35,7 @@
|
||||
#include "cfg_rtt_default.h"
|
||||
#include "cfg_timer_tim2.h"
|
||||
#include "cfg_usb_otg_fs.h"
|
||||
#include "mii.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -167,7 +168,7 @@ static const spi_conf_t spi_config[] = {
|
||||
static const eth_conf_t eth_config = {
|
||||
.mode = RMII,
|
||||
.addr = { 0 },
|
||||
.speed = ETH_SPEED_100TX_FD,
|
||||
.speed = MII_BMCR_SPEED_100 | MII_BMCR_FULL_DPLX,
|
||||
.dma = 3,
|
||||
.dma_chan = 8,
|
||||
.phy_addr = 0x00,
|
||||
|
||||
@ -1018,34 +1018,24 @@ void dma_prepare(dma_t dma, void *mem, size_t len, bool incr_mem);
|
||||
* @brief STM32 Ethernet configuration mode
|
||||
*/
|
||||
typedef enum {
|
||||
MII = 18, /**< Configuration for MII */
|
||||
RMII = 9, /**< Configuration for RMII */
|
||||
SMI = 2, /**< Configuration for SMI */
|
||||
MII = 18, /**< Configuration for MII */
|
||||
RMII = 9, /**< Configuration for RMII */
|
||||
SMI = 2, /**< Configuration for SMI */
|
||||
} eth_mode_t;
|
||||
|
||||
/**
|
||||
* @brief STM32 Ethernet speed options
|
||||
*/
|
||||
typedef enum {
|
||||
ETH_SPEED_10T_HD = 0x0000,
|
||||
ETH_SPEED_10T_FD = 0x0100,
|
||||
ETH_SPEED_100TX_HD = 0x2000,
|
||||
ETH_SPEED_100TX_FD = 0x2100,
|
||||
} eth_speed_t;
|
||||
|
||||
/**
|
||||
* @brief Ethernet Peripheral configuration
|
||||
*/
|
||||
typedef struct {
|
||||
eth_mode_t mode; /**< Select configuration mode */
|
||||
uint8_t addr[6]; /**< Ethernet MAC address */
|
||||
eth_speed_t speed; /**< Speed selection */
|
||||
uint16_t speed; /**< Speed selection */
|
||||
uint8_t dma; /**< Locical CMA Descriptor used for TX */
|
||||
uint8_t dma_chan; /**< DMA channel used for TX */
|
||||
char phy_addr; /**< PHY address */
|
||||
uint8_t phy_addr; /**< PHY address */
|
||||
gpio_t pins[]; /**< Pins to use. MII requires 18 pins,
|
||||
RMII 9 and SMI 9. Not all speeds are
|
||||
supported by all modes. */
|
||||
RMII 9 and SMI 9. Not all speeds are
|
||||
supported by all modes. */
|
||||
} eth_conf_t;
|
||||
|
||||
/**
|
||||
@ -1144,121 +1134,6 @@ typedef struct eth_dma_desc {
|
||||
#define TX_DESC_STAT_OWN (BIT31) /**< If set, descriptor is owned by DMA, otherwise by CPU */
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @name Ethernet PHY Common Registers
|
||||
* @{
|
||||
*/
|
||||
#define PHY_BMCR (0x00)
|
||||
#define PHY_BSMR (0x01)
|
||||
#define PHY_PHYIDR1 (0x02)
|
||||
#define PHY_PHYIDR2 (0x03)
|
||||
#define PHY_ANAR (0x04)
|
||||
#define PHY_ANLPAR (0x05)
|
||||
#define PHY_ANER (0x06)
|
||||
#define PHY_ANNPTR (0x07)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Ethernet PHY BMCR Fields
|
||||
* @{
|
||||
*/
|
||||
#define BMCR_RESET (0x8000)
|
||||
#define BMCR_LOOPBACK (0x4000)
|
||||
#define BMCR_SPEED_SELECT (0x2000)
|
||||
#define BMCR_AN (0x1000)
|
||||
#define BMCR_POWER_DOWN (0x0800)
|
||||
#define BMCR_ISOLATE (0x0400)
|
||||
#define BMCR_RESTART_AN (0x0200)
|
||||
#define BMCR_DUPLEX_MODE (0x0100)
|
||||
#define BMCR_COLLISION_TEST (0x0080)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Ethernet PHY BSMR Fields
|
||||
* @{
|
||||
*/
|
||||
#define BSMR_100BASE_T4 (0x8000)
|
||||
#define BSMR_100BASE_TX_FDUPLEX (0x4000)
|
||||
#define BSMR_100BASE_TX_HDUPLEX (0x2000)
|
||||
#define BSMR_10BASE_T_FDUPLEX (0x1000)
|
||||
#define BSMR_10BASE_T_HDUPLEX (0x0800)
|
||||
#define BSMR_NO_PREAMBLE (0x0040)
|
||||
#define BSMR_AN_COMPLETE (0x0020)
|
||||
#define BSMR_REMOTE_FAULT (0x0010)
|
||||
#define BSMR_AN_ABILITY (0x0008)
|
||||
#define BSMR_LINK_STATUS (0x0004)
|
||||
#define BSMR_JABBER_DETECT (0x0002)
|
||||
#define BSMR_EXTENDED_CAP (0x0001)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Ethernet PHY PHYIDR1 Fields
|
||||
*/
|
||||
#define PHYIDR1_OUI (0xffff)
|
||||
|
||||
/**
|
||||
* @name Ethernet PHY PHYIDR2 Fields
|
||||
* @{
|
||||
*/
|
||||
#define PHYIDR2_OUI (0xfe00)
|
||||
#define PHYIDR2_MODEL (0x01f0)
|
||||
#define PHYIDR2_REV (0x0007)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Ethernet PHY ANAR Fields
|
||||
* @{
|
||||
*/
|
||||
#define ANAR_NEXT_PAGE (0x8000)
|
||||
#define ANAR_REMOTE_FAULT (0x2000)
|
||||
#define ANAR_PAUSE (0x0600)
|
||||
#define ANAR_100BASE_T4 (0x0200)
|
||||
#define ANAR_100BASE_TX_FDUPLEX (0x0100)
|
||||
#define ANAR_100BASE_TX_HDUPLEX (0x0080)
|
||||
#define ANAR_10BASE_T_FDUPLEX (0x0040)
|
||||
#define ANAR_10BASE_T_HDUPLEX (0x0020)
|
||||
#define ANAR_SELECTOR (0x000f)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Ethernet PHY ANLPAR Fields
|
||||
* @{
|
||||
*/
|
||||
#define ANLPAR_NEXT_PAGE (0x8000)
|
||||
#define ANLPAR_ACK (0x4000)
|
||||
#define ANLPAR_REMOTE_FAULT (0x2000)
|
||||
#define ANLPAR_PAUSE (0x0600)
|
||||
#define ANLPAR_100BASE_T4 (0x0200)
|
||||
#define ANLPAR_100BASE_TX_FDUPLEX (0x0100)
|
||||
#define ANLPAR_100BASE_TX_HDUPLEX (0x0080)
|
||||
#define ANLPAR_10BASE_T_FDUPLEX (0x0040)
|
||||
#define ANLPAR_10BASE_T_HDUPLEX (0x0020)
|
||||
#define ANLPAR_SELECTOR (0x000f)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Ethernet PHY ANNPTR Fields
|
||||
* @{
|
||||
*/
|
||||
#define ANNPTR_NEXT_PAGE (0x8000)
|
||||
#define ANNPTR_MSG_PAGE (0x2000)
|
||||
#define ANNPTR_ACK2 (0x1000)
|
||||
#define ANNPTR_TOGGLE_TX (0x0800)
|
||||
#define ANNPTR_CODE (0x03ff)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Ethernet PHY ANER Fields
|
||||
* @{
|
||||
*/
|
||||
#define ANER_PDF (0x0010)
|
||||
#define ANER_LP_NEXT_PAGE_ABLE (0x0008)
|
||||
#define ANER_NEXT_PAGE_ABLE (0x0004)
|
||||
#define ANER_PAGE_RX (0x0002)
|
||||
#define ANER_LP_AN_ABLE (0x0001)
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
#include "bitarithm.h"
|
||||
#include "iolist.h"
|
||||
#include "luid.h"
|
||||
#include "mii.h"
|
||||
#include "mutex.h"
|
||||
#include "net/ethernet.h"
|
||||
#include "net/netdev/eth.h"
|
||||
@ -150,7 +151,7 @@ static inline void _mii_reg_write(uint8_t reg, uint16_t value)
|
||||
|
||||
static inline bool _get_link_status(void)
|
||||
{
|
||||
return (_mii_reg_read(PHY_BSMR) & BSMR_LINK_STATUS);
|
||||
return (_mii_reg_read(MII_BMSR) & MII_BMSR_LINK);
|
||||
}
|
||||
|
||||
static void stm32_eth_get_addr(char *out)
|
||||
@ -305,7 +306,7 @@ static int stm32_eth_init(netdev_t *netdev)
|
||||
|
||||
/* configure the PHY (standard for all PHY's) */
|
||||
/* if there's no PHY, this has no effect */
|
||||
_mii_reg_write(PHY_BMCR, BMCR_RESET);
|
||||
_mii_reg_write(MII_BMCR, MII_BMCR_RESET);
|
||||
|
||||
/* speed from conf */
|
||||
ETH->MACCR |= (ETH_MACCR_ROD | ETH_MACCR_IPCO | ETH_MACCR_APCS |
|
||||
@ -351,7 +352,7 @@ static int stm32_eth_init(netdev_t *netdev)
|
||||
|
||||
/* configure speed, do it at the end so the PHY had time to
|
||||
* reset */
|
||||
_mii_reg_write(PHY_BMCR, eth_config.speed);
|
||||
_mii_reg_write(MII_BMCR, eth_config.speed);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
179
drivers/include/mii.h
Normal file
179
drivers/include/mii.h
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (C) 2020 Otto-von-Guericke-Universität Magdeburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser General
|
||||
* Public License v2.1. See the file LICENSE in the top level directory for more
|
||||
* details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup drivers_mii Ethernet Media-Independent Interface (MII)
|
||||
* Utilities
|
||||
* @ingroup drivers_netdev
|
||||
*
|
||||
* This module contains constants and helpers as library to help working with
|
||||
* Ethernet PHYs connected via the Media-Independent Interface (MII) or the
|
||||
* Reduced Media-Independent Interface (RMII)
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Interface definition for MII/RMII h
|
||||
*
|
||||
* @author Marian Buschsieweke <marian.buschsieweke@ovgu.de>
|
||||
*/
|
||||
|
||||
#ifndef MII_H
|
||||
#define MII_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "bitarithm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Common MII Management Register Set
|
||||
*
|
||||
* All registers except @ref MII_BMCR and @ref MII_BMSR are extended registers.
|
||||
* Support for extended registers is indicated by the @ref MII_BMSR_EXTENDED
|
||||
* bit in the @ref MII_BMSR register.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
#define MII_BMCR (0x00U) /**< Basic mode control register */
|
||||
#define MII_BMSR (0x01U) /**< Basic mode status register */
|
||||
#define MII_PHYID1 (0x02U) /**< PHY Identifier 1 */
|
||||
#define MII_PHYID2 (0x03U) /**< PHY Identifier 2 */
|
||||
#define MII_ADVERTISE (0x04U) /**< Auto-Negotiation Advertisement */
|
||||
#define MII_LPA (0x05U) /**< Link Parter Abilities */
|
||||
#define MII_EXPANSION (0x06U) /**< Auto-Negotiation Expansion */
|
||||
#define MII_ESTATUS (0x0fU) /**< Extended Status Register */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Bits in the MII Basic Mode Control Register
|
||||
* @{
|
||||
*/
|
||||
#define MII_BMCR_RESET BIT15 /**< Set to perform PHY reset */
|
||||
#define MII_BMCR_LOOP BIT14 /**< Set to enable loopback mode */
|
||||
#define MII_BMCR_AN_ENABLE BIT12 /**< Set to enable auto-negotiation */
|
||||
#define MII_BMCR_POWER_DOWN BIT11 /**< Set to power down PHY */
|
||||
#define MII_BMCR_ISOLATE BIT10 /**< Set to electrically isolate PHY from
|
||||
MII (PHY becomes inoperational) */
|
||||
#define MII_BMCR_AN_RESTART BIT9 /**< Set to restart auto-negotation */
|
||||
#define MII_BMCR_FULL_DPLX BIT8 /**< Set for full duplex */
|
||||
#define MII_BMCR_HALF_DPLX (0) /**< Set for half duplex */
|
||||
#define MII_BMCR_COLL_TEST BIT7 /**< Set to enable collision signal test */
|
||||
#define MII_BMCR_SPEED_10 (0) /**< Set speed to 10 Mbps */
|
||||
#define MII_BMCR_SPEED_100 BIT13 /**< Set speed to 100 Mbps */
|
||||
#define MII_BMCR_SPEED_1000 BIT6 /**< Set speed to 1 Gbps */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Bits in the MII Basic Mode Status Register
|
||||
* @{
|
||||
*/
|
||||
#define MII_BMSR_100_T4 BIT15 /**< PHY supports 100BASE-T4 (half-duplex) */
|
||||
#define MII_BMSR_100_TX_F BIT14 /**< PHY supports 100BASE-TX, full duplex */
|
||||
#define MII_BMSR_100_TX_H BIT13 /**< PHY supports 100BASE-TX, half duplex */
|
||||
#define MII_BMSR_10_F BIT12 /**< PHY supports 10BASE-T, full duplex */
|
||||
#define MII_BMSR_10_H BIT11 /**< PHY supports 10BASE-T, half duplex */
|
||||
#define MII_BMSR_100_T2_F BIT10 /**< PHY supports 100BASE-T2, full duplex */
|
||||
#define MII_BMSR_100_T2_H BIT9 /**< PHY supports 100BASE-T2, half duplex */
|
||||
#define MII_BMSR_ESTATUS BIT8 /**< Set, if @ref MII_ESTATUS is
|
||||
available */
|
||||
#define MII_BMSR_AN_DONE BIT5 /**< Set when auto-negotiation is done */
|
||||
#define MII_BMSR_FAULT BIT4 /**< Set when remote fault condition
|
||||
is detected */
|
||||
#define MII_BMSR_HAS_AN BIT3 /**< Set if PHY can auto-negotiate */
|
||||
#define MII_BMSR_LINK BIT2 /**< Set if link is up */
|
||||
#define MII_BMSR_JABBER BIT1 /**< Set when jabber condition detected */
|
||||
#define MII_BMSR_EXTENDED BIT0 /**< Extended MII registers available */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Bits in the MII Extended Mode Advertisement Register
|
||||
* @{
|
||||
*/
|
||||
#define MII_ADVERTISE_100_F BIT8 /**< Advertise 100BASE-T, full duplex */
|
||||
#define MII_ADVERTISE_100_H BIT7 /**< Advertise 100BASE-T, half duplex */
|
||||
#define MII_ADVERTISE_10_F BIT6 /**< Advertise 10BASE-T, full duplex */
|
||||
#define MII_ADVERTISE_10_H BIT5 /**< Advertise 10BASE-T, half duplex */
|
||||
#define MII_ADVERTISE_100 (BIT7 | BIT8) /**< Advertise 100BASE-T */
|
||||
#define MII_ADVERTISE_10 (BIT5 | BIT6) /**< Advertise 10BASE-T */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Bits in the MII Extended Mode Advertisement Register
|
||||
* @{
|
||||
*/
|
||||
#define MII_LPA_100_F BIT8 /**< Partner can 100BASE-T, full duplex */
|
||||
#define MII_LPA_100_H BIT7 /**< Partner can 100BASE-T, half duplex */
|
||||
#define MII_LPA_10_F BIT6 /**< Partner can 10BASE-T, full duplex */
|
||||
#define MII_LPA_10_H BIT5 /**< Partner can 10BASE-T, half duplex */
|
||||
#define MII_LPA_100 (BIT7 | BIT8) /**< Partner can 100BASE-T */
|
||||
#define MII_LPA_10 (BIT5 | BIT6) /**< Partner can 10BASE-T */
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Check if an Ethernet PHY supports 100 Mbps at full duplex
|
||||
*
|
||||
* @param[in] bmsr Value of the MII basic mode status register
|
||||
*
|
||||
* @retval true PHY supports 100 Mbps at full duplex
|
||||
* @retval false PHY does not support 100 Mbps at full duplex
|
||||
*/
|
||||
static inline bool mii_can_100_mbps_full_dp(uint16_t bmsr)
|
||||
{
|
||||
return (bmsr & (MII_BMSR_100_TX_F | MII_BMSR_100_T2_F));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if an Ethernet PHY supports 100 Mbps at half duplex
|
||||
*
|
||||
* @param[in] bmsr Value of the MII basic mode status register
|
||||
*
|
||||
* @retval true PHY supports 100 Mbps at half duplex
|
||||
* @retval false PHY does not support 100 Mbps at half duplex
|
||||
*/
|
||||
static inline bool mii_can_100_mbps_half_dp(uint16_t bmsr)
|
||||
{
|
||||
return (bmsr & (MII_BMSR_100_T4 | MII_BMSR_100_TX_H | MII_BMSR_100_T2_H));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if an Ethernet PHY supports 10 Mbps at full duplex
|
||||
*
|
||||
* @param[in] bmsr Value of the MII basic mode status register
|
||||
*
|
||||
* @retval true PHY supports 10 Mbps at full duplex
|
||||
* @retval false PHY does not support 10 Mbps at full duplex
|
||||
*/
|
||||
static inline bool mii_can_10_mbps_full_dp(uint16_t bmsr)
|
||||
{
|
||||
return (bmsr & MII_BMSR_10_F);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if an Ethernet PHY supports 10 Mbps at half duplex
|
||||
*
|
||||
* @param[in] bmsr Value of the MII basic mode status register
|
||||
*
|
||||
* @retval true PHY supports 10 Mbps at half duplex
|
||||
* @retval false PHY does not support 10 Mbps at half duplex
|
||||
*/
|
||||
static inline bool mii_can_10_mbps_half_dp(uint16_t bmsr)
|
||||
{
|
||||
return (bmsr & MII_BMSR_10_H);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* MII_H */
|
||||
/** @} */
|
||||
Loading…
x
Reference in New Issue
Block a user