1 /* SPDX-License-Identifier: GPL-2.0+ */ 2 /* 3 * OPEN Alliance 10BASE‑T1x MAC‑PHY Serial Interface framework 4 * 5 * Link: https://opensig.org/download/document/OPEN_Alliance_10BASET1x_MAC-PHY_Serial_Interface_V1.1.pdf 6 * 7 * Author: Parthiban Veerasooran <parthiban.veerasooran@microchip.com> 8 */ 9 10 #include <linux/etherdevice.h> 11 #include <linux/spi/spi.h> 12 13 /* OPEN Alliance TC6 registers */ 14 /* Standard Capabilities Register */ 15 #define OA_TC6_REG_STDCAP 0x0002 16 #define OA_TC6_STDCAP_DIRECT_PHY_REG_ACCESS BIT(8) 17 18 /* Reset Control and Status Register */ 19 #define OA_TC6_REG_RESET 0x0003 20 #define OA_TC6_RESET_SWRESET BIT(0) /* Software Reset */ 21 22 /* Configuration Register #0 */ 23 #define OA_TC6_REG_CONFIG0 0x0004 24 #define OA_TC6_CONFIG0_SYNC BIT(15) 25 #define OA_TC6_CONFIG0_ZARFE_ENABLE BIT(12) 26 #define OA_TC6_CONFIG0_PROTE BIT(5) 27 28 /* Configuration Register #2 */ 29 #define OA_TC6_REG_CONFIG2 0x0006 30 31 /* Status Register #0 */ 32 #define OA_TC6_REG_STATUS0 0x0008 33 #define OA_TC6_STATUS0_RESETC BIT(6) /* Reset Complete */ 34 #define OA_TC6_STATUS0_HEADER_ERROR BIT(5) 35 #define OA_TC6_STATUS0_LOSS_OF_FRAME_ERROR BIT(4) 36 #define OA_TC6_STATUS0_RX_BUFFER_OVERFLOW_ERROR BIT(3) 37 #define OA_TC6_STATUS0_TX_PROTOCOL_ERROR BIT(0) 38 39 /* Buffer Status Register */ 40 #define OA_TC6_REG_BUFFER_STATUS 0x000B 41 #define OA_TC6_BUFFER_STATUS_TX_CREDITS_AVAILABLE GENMASK(15, 8) 42 #define OA_TC6_BUFFER_STATUS_RX_CHUNKS_AVAILABLE GENMASK(7, 0) 43 44 /* Interrupt Mask Register #0 */ 45 #define OA_TC6_REG_INT_MASK0 0x000C 46 #define OA_TC6_INT_MASK0_HEADER_ERR_MASK BIT(5) 47 #define OA_TC6_INT_MASK0_LOSS_OF_FRAME_ERR_MASK BIT(4) 48 #define OA_TC6_INT_MASK0_RX_BUFFER_OVERFLOW_ERR_MASK BIT(3) 49 #define OA_TC6_INT_MASK0_TX_PROTOCOL_ERR_MASK BIT(0) 50 #define OA_TC6_INT_MASK0_ALL_INTERRUPTS (GENMASK(5, 0) | \ 51 GENMASK(12, 7)) 52 53 /* PHY Clause 22 registers base address and mask */ 54 #define OA_TC6_PHY_STD_REG_ADDR_BASE 0xFF00 55 #define OA_TC6_PHY_STD_REG_ADDR_MASK 0x1F 56 57 /* Memory map selector (MMS) values as per table 6 in the 58 * OPEN Alliance specification. 59 */ 60 #define OA_TC6_MAC_MMS1 1 61 #define OA_TC6_PHY_C45_PCS_MMS2 2 /* MMD 3 */ 62 #define OA_TC6_PHY_C45_PMA_PMD_MMS3 3 /* MMD 1 */ 63 #define OA_TC6_PHY_C45_VS_PLCA_MMS4 4 /* MMD 31 */ 64 #define OA_TC6_PHY_C45_AUTO_NEG_MMS5 5 /* MMD 7 */ 65 #define OA_TC6_PHY_C45_POWER_UNIT_MMS6 6 /* MMD 13 */ 66 67 struct oa_tc6; 68 69 enum oa_tc6_quirk_flag { 70 OA_TC6_BROKEN_PHY = BIT(0), 71 }; 72 73 struct oa_tc6_quirks { 74 enum oa_tc6_quirk_flag quirk_flags; 75 }; 76 77 struct oa_tc6 *oa_tc6_init(struct spi_device *spi, struct net_device *netdev, 78 struct oa_tc6_quirks *quirks); 79 void oa_tc6_exit(struct oa_tc6 *tc6); 80 int oa_tc6_write_register(struct oa_tc6 *tc6, u32 address, u32 value); 81 int oa_tc6_write_register_mms(struct oa_tc6 *tc6, u8 mms, u16 address, 82 u32 value); 83 int oa_tc6_write_registers(struct oa_tc6 *tc6, u32 address, u32 value[], 84 u8 length); 85 int oa_tc6_read_register(struct oa_tc6 *tc6, u32 address, u32 *value); 86 int oa_tc6_read_register_mms(struct oa_tc6 *tc6, u8 mms, u16 address, 87 u32 *value); 88 int oa_tc6_read_registers(struct oa_tc6 *tc6, u32 address, u32 value[], 89 u8 length); 90 netdev_tx_t oa_tc6_start_xmit(struct oa_tc6 *tc6, struct sk_buff *skb); 91 int oa_tc6_zero_align_receive_frame_enable(struct oa_tc6 *tc6); 92 int oa_tc6_mdiobus_read_c45(struct mii_bus *bus, int addr, int devnum, 93 int regnum); 94 int oa_tc6_mdiobus_write_c45(struct mii_bus *bus, int addr, int devnum, 95 int regnum, u16 val); 96