#ifndef LAN78XX_REGS_H
#define LAN78XX_REGS_H

/*
 * Register/bit definitions for Microchip LAN75xx/LAN78xx USB ethernet
 * controllers.  Reproduced from OpenBSD's if_muereg.h.
 *
 * Copyright (c) 2018 Kevin Lo <kevlo@openbsd.org>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <exec/types.h>

#define LAN78XX_USB_VENDOR_ID 0x0424
#define LAN78XX_USB_PRODUCT_ID_7500 0x7500
#define LAN78XX_USB_PRODUCT_ID_7505 0x7505
#define LAN78XX_USB_PRODUCT_ID_7800 0x7800
#define LAN78XX_USB_PRODUCT_ID_7801 0x7801
#define LAN78XX_USB_PRODUCT_ID_7850 0x7850

/* "LAN7500 family" quirk flag — LAN7500/7505 follow the older register map. */
#define LAN78XX_FLAG_LAN7500 0x0001

/* USB vendor requests. */
#define LAN78XX_USB_REQ_WRITE_REG 0xA0
#define LAN78XX_USB_REQ_READ_REG 0xA1

/* Ethernet frame sizing. */
#define ETHER_ADDR_SIZE 6
#define ETHER_MIN_LEN 60
#define ETHER_CRC_LEN 4
#define ETHER_MAX_LEN 1518
#define ETHER_MAX_VLAN_LEN 1522
#define ETHERPKT_SIZE 1500
#define RAWPKT_SIZE 1514

/*
 * EEPROM layout (the OpenBSD code labels the valid-indicator byte
 * offset 0, the six-byte MAC at offset 1).
 */
#define LAN78XX_EEPROM_INDICATOR 0xA5
#define LAN78XX_EE_IND_OFFSET 0x00
#define LAN78XX_EE_MAC_OFFSET 0x01

/* Registers. */
#define LAN78XX_REG_INT_STS 0x00C
#define LAN78XX_REG_HW_CFG 0x010
#define LAN78XX_REG_PMT_CTL 0x014
#define LAN78XX_REG_DP_SEL 0x024
#define LAN78XX_REG_DP_CMD 0x028
#define LAN78XX_REG_DP_ADDR 0x02C
#define LAN78XX_REG_DP_DATA 0x030
#define LAN78XX_REG_BURST_CAP 0x034
#define LAN78XX_REG_BULK_IN_DELAY 0x03C
#define LAN78XX_REG_E2P_CMD 0x040
#define LAN78XX_REG_E2P_DATA 0x044
#define LAN78XX_REG_RFE_CTL 0x060
#define LAN78XX_REG_USB_CFG0 0x080
#define LAN78XX_REG_USB_CFG1 0x084
#define LAN78XX_REG_FCT_RX_CTL 0x090
#define LAN78XX_REG_FCT_TX_CTL 0x094
#define LAN78XX_REG_FCT_RX_FIFO_END 0x098
#define LAN78XX_REG_FCT_TX_FIFO_END 0x098
#define LAN78XX_REG_FCT_FLOW 0x0A0
#define LAN78XX_REG_7800_RFE_CTL 0x0B0
#define LAN78XX_REG_7800_FCT_RX_CTL 0x0C0
#define LAN78XX_REG_7800_FCT_TX_CTL 0x0C4
#define LAN78XX_REG_7800_FCT_FLOW 0x0D0
#define LAN78XX_REG_MAC_CR 0x100
#define LAN78XX_REG_MAC_RX 0x104
#define LAN78XX_REG_MAC_TX 0x108
#define LAN78XX_REG_FLOW 0x10C
#define LAN78XX_REG_RX_ADDRH 0x118
#define LAN78XX_REG_RX_ADDRL 0x11C
#define LAN78XX_REG_MII_ACC 0x120
#define LAN78XX_REG_MII_DATA 0x124
#define LAN78XX_REG_ADDR_FILTX 0x300
#define LAN78XX_REG_7800_ADDR_FILTX 0x400

/* Burst/bulk-in-delay register aliases on LAN7800-class parts. */
#define LAN78XX_REG_7800_BURST_CAP LAN78XX_REG_FCT_RX_CTL
#define LAN78XX_REG_7800_BULK_IN_DELAY LAN78XX_REG_FCT_TX_CTL

/* HW_CFG */
#define LAN78XX_HW_CFG_SRST 0x00000001UL
#define LAN78XX_HW_CFG_LRST 0x00000002UL
#define LAN78XX_HW_CFG_BCE 0x00000004UL
#define LAN78XX_HW_CFG_MEF 0x00000010UL
#define LAN78XX_HW_CFG_BIR 0x00000080UL
#define LAN78XX_HW_CFG_LED0_EN 0x00100000UL
#define LAN78XX_HW_CFG_LED1_EN 0x00200000UL

/* PMT_CTL */
#define LAN78XX_PMT_CTL_PHY_RST 0x00000010UL
#define LAN78XX_PMT_CTL_READY 0x00000080UL

/* DP_SEL */
#define LAN78XX_DP_SEL_RSEL_MASK 0x0000000FUL
#define LAN78XX_DP_SEL_VHF 0x00000001UL
#define LAN78XX_DP_SEL_DPRDY 0x80000000UL
#define LAN78XX_DP_SEL_VHF_HASH_LEN 16
#define LAN78XX_DP_SEL_VHF_VLAN_LEN 128

/* DP_CMD */
#define LAN78XX_DP_CMD_WRITE 0x00000001UL

/* E2P_CMD */
#define LAN78XX_E2P_CMD_ADDR_MASK 0x000001FFUL
#define LAN78XX_E2P_CMD_READ 0x00000000UL
#define LAN78XX_E2P_CMD_TIMEOUT 0x00000400UL
#define LAN78XX_E2P_CMD_BUSY 0x80000000UL

/* RFE_CTL */
#define LAN78XX_RFE_CTL_PERFECT 0x00000002UL
#define LAN78XX_RFE_CTL_MCAST_HASH 0x00000008UL
#define LAN78XX_RFE_CTL_UNICAST 0x00000100UL
#define LAN78XX_RFE_CTL_MULTICAST 0x00000200UL
#define LAN78XX_RFE_CTL_BROADCAST 0x00000400UL

/* USB_CFG0 */
#define LAN78XX_USB_CFG0_BCE 0x00000020UL
#define LAN78XX_USB_CFG0_BIR 0x00000040UL

/* USB_CFG1 */
#define LAN78XX_USB_CFG1_LTM_ENABLE 0x00000100UL
#define LAN78XX_USB_CFG1_DEV_U1_INIT_EN 0x00000400UL
#define LAN78XX_USB_CFG1_DEV_U2_INIT_EN 0x00001000UL

/* FCT_RX_CTL / FCT_TX_CTL */
#define LAN78XX_FCT_RX_CTL_EN 0x80000000UL
#define LAN78XX_FCT_TX_CTL_EN 0x80000000UL

/* MAC_CR */
#define LAN78XX_MAC_CR_RST 0x00000001UL
#define LAN78XX_MAC_CR_FULL_DUPLEX 0x00000008UL
#define LAN78XX_MAC_CR_AUTO_SPEED 0x00000800UL
#define LAN78XX_MAC_CR_AUTO_DUPLEX 0x00001000UL
#define LAN78XX_MAC_CR_GMII_EN 0x00080000UL

/* MAC_RX */
#define LAN78XX_MAC_RX_RXEN 0x00000001UL
#define LAN78XX_MAC_RX_MAX_SIZE_MASK 0x3FFF0000UL
#define LAN78XX_MAC_RX_MAX_SIZE_SHIFT 16
#define LAN78XX_MAC_RX_MAX_LEN(x) (((x) << LAN78XX_MAC_RX_MAX_SIZE_SHIFT) & LAN78XX_MAC_RX_MAX_SIZE_MASK)

/* MAC_TX */
#define LAN78XX_MAC_TX_TXEN 0x00000001UL

/* FLOW */
#define LAN78XX_FLOW_PAUSE_TIME 0x0000FFFFUL
#define LAN78XX_FLOW_RX_FCEN 0x20000000UL
#define LAN78XX_FLOW_TX_FCEN 0x40000000UL

/* MII_ACC */
#define LAN78XX_MII_ACC_BUSY 0x00000001UL
#define LAN78XX_MII_ACC_WRITE 0x00000002UL
#define LAN78XX_MII_ACC_READ 0x00000000UL
#define LAN78XX_MII_ACC_REGADDR_SHIFT 6
#define LAN78XX_MII_ACC_REGADDR_MASK 0x000007C0UL
#define LAN78XX_MII_ACC_PHY_ADDR_SHIFT 11
#define LAN78XX_MII_ACC_PHY_ADDR_MASK 0x0000F800UL
#define LAN78XX_PHY_INTERNAL 1

/* Perfect address filter register */
#define LAN78XX_ADDR_FILTX_VALID 0x80000000UL

/* Burst cap/bulk-in defaults (micro-packet framing tuneables). */
#define LAN78XX_DEFAULT_BULKIN_DELAY 0x00002000UL
#define LAN78XX_7800_DEFAULT_BULKIN_DELAY 0x00000800UL

#define LAN78XX_BURST_MAX_BUFSZ 129
#define LAN78XX_BURST_MIN_BUFSZ 37
#define LAN78XX_7800_BURST_MAX_BUFSZ 24
#define LAN78XX_7800_BURST_MIN_BUFSZ 12

/*
 * Aggregate RX transfer size — the chip coalesces many frames into one
 * bulk-IN transfer.  We pick the 7800-class "max" which is comfortably
 * larger than a single MTU.
 */
#define LAN78XX_TRANSFER_BUFFER_SIZE 18944
#define LAN78XX_RX_BUFFER_SIZE LAN78XX_TRANSFER_BUFFER_SIZE
#define LAN78XX_TX_BUFFER_SIZE 2048

/* TX command header (prepended to every outgoing packet). */
#define LAN78XX_TX_CMD_LEN 8
#define LAN78XX_TX_CMD_A_FCS 0x00400000UL
#define LAN78XX_TX_CMD_A_LEN_MASK 0x000FFFFFUL

/* RX command header (prepended to every incoming packet). */
#define LAN78XX_RX_CMD_LEN 10
#define LAN78XX_RX_CMD_A_RED 0x00400000UL
#define LAN78XX_RX_CMD_A_LEN_MASK 0x00003FFFUL

/* MII PHY registers used by the link watcher (subset of IEEE 802.3 MII). */
#define LAN78XX_MII_BMCR 0x00
#define LAN78XX_MII_BMSR 0x01
#define LAN78XX_BMSR_LSTATUS 0x0004 /* link status (sticky) */
#define LAN78XX_BMSR_ANEGCOMPLETE 0x0020

#endif
