/*
################################################################################
#
# RTL8198 MDIO char driver header
#
# Copyright(c) 2010 Realtek Semiconductor Corp. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, see .
#
# Author:
# Realtek WiFi AP software team
# No. 2, Innovation Road II, Hsinchu Science Park, Hsinchu 300, Taiwan
#
################################################################################
*/
/*================================================================*/
#ifndef INCLUDE_RTL_MDIO_H
#define INCLUDE_RTL_MDIO_H
/*================================================================*/
/* Compiling Flags */
#define KDB_ERR // defined to print out error message
//#define KDB_MSG // defined to print out debug message
//#define SIMULATION // defined to do simuation
#ifndef CONFIG_RTK_VOIP_ETHERNET_DSP_IS_DSP
#define JUMP_CMD // defined to add jump ioctl cmd, for development purpose
#endif
/*================================================================*/
/* Constant Definitions */
#define DRIVER_NAME "rtl_mdio"
#define DRIVER_VER "0.2"
#define IO_LEN 0x40
#define DRIVER_MAJOR 14
#define MDIO_BUFSIZE 516 //2 + 2 + 2*255 + 2
#define EV_QUE_MAX 16
//#define BIT(x) (1 << (x))
// RTL8197B IRQ number and Register offset
#define NFBI_BASE 0xb8019000 // NFBI base address
#define REG_RCR (0x00+NFBI_BASE) // Receive Command Register
#define REG_SSR (0x04+NFBI_BASE) // Send Status Register
#define REG_SYSCR (0x08+NFBI_BASE) // System Control Register
#define REG_SYSSR (0x0C+NFBI_BASE) // System Status Register
#define REG_IMR (0x10+NFBI_BASE) // Interrupt Mask Register
#define REG_ISR (0x14+NFBI_BASE) // Interrupt Status Register
#define REG_BMCR (0x20+NFBI_BASE) // Basic Mode Control Register
#define REG_BMSR (0x24+NFBI_BASE) // Basic Mode Status Register
#define REG_ANAR (0x28+NFBI_BASE) // Auto-Negotiation Advertisement Register
#define REG_ANLPAR (0x2C+NFBI_BASE) // Auto-Negotiation Link Partner Ability Register
#define REG_NFBIRR (0x30+NFBI_BASE) // NFBI Reset Control Register
// bitmask definition for ISR
#define IP_ISOLATION BIT(15) // ISOLATION Interrupt Pending
#define IP_ETHMAC BIT(14) // Enable/disable Ethernet MAC
#define IP_WLANMAC BIT(13) // Enable/disable WLAN MAC
#define IP_ETHPHY BIT(12) // Enable/disable Ethernet PHY
#define IP_WLANPHY BIT(11) // Enable/disable WLAN PHY
#define IP_SELMIICLK BIT(10) // Select MII Clock Speed
#define IP_RSVD9 BIT(9) // Reserved
#define IP_CUSTOM8 BIT(8) // Customized used 8
#define IP_CUSTOM7 BIT(7) // Customized used 7
#define IP_CUSTOM6 BIT(6) // Customized used 6
#define IP_CUSTOM5 BIT(5) // Customized used 5
#define IP_CUSTOM4 BIT(4) // Customized used 4
#define IP_CUSTOM3 BIT(3) // Customized used 3
#define IP_MSGFETCH BIT(2) // Previous msg has been fetched
#define IP_NEWMSG BIT(1) // New msg has come
#define IP_RSVD0 BIT(0) // Reserved
// bitmask definition for SCR
#define CR_ISOLATION BIT(15) // ISOLATION control bit
#define CR_ETHMAC BIT(14) // Ethernet MAC control bit
#define CR_WLANMAC BIT(13) // WLAN MAC control bit
#define CR_ETHPHY BIT(12) // Ethernet PHY control bi
#define CR_WLANPHY BIT(11) // WLAN PHY control bit
#define CR_SELMIICLK (BIT(10)|BIT(9)) // Select MII Clock Speed control bit
#define CR_CUSTOM8 BIT(8) // Customized used 8
#define CR_CUSTOM7 BIT(7) // Customized used 7
#define CR_CUSTOM6 BIT(6) // Customized used 6
#define CR_CUSTOM5 BIT(5) // Customized used 5
#define CR_CUSTOM4 BIT(4) // Customized used 4
#define CR_CUSTOM3 BIT(3) // Customized used 3
#define CR_CUSTOM2 BIT(2) // Customized used 2
#define CR_CUSTOM1 BIT(1) // Customized used 1
#define CR_CUSTOM0 BIT(0) // Customized used 0
// bitmask definition for SYSSR
#define SR_CheckSumDone BIT(15)
#define SR_CheckSumOK BIT(14)
#define SR_WLANLink BIT(13)
#define SR_EthLink BIT(12)
#define SR_EthPHYStatusChange BIT(11)
#define SR_AllSoftwareReady BIT(10)
#define SR_USBInsertStatus BIT(7)
#define SR_USBRemoveStatus BIT(6)
#define SR_BootcodeReady BIT(5)
// rx cmd id bitmask
#define FIRST_CMD_MASK BIT(15)
// All received interrupt mask
#ifdef CONFIG_RTK_VOIP_ETHERNET_DSP_IS_DSP
#define NEEDED_IRQ_MASK (IP_NEWMSG|IP_MSGFETCH|IP_SELMIICLK|IP_WLANPHY| \
IP_ETHPHY|IP_WLANMAC|IP_ETHMAC|IP_ISOLATION|IP_CUSTOM3)
#else
#define NEEDED_IRQ_MASK (IP_NEWMSG|IP_MSGFETCH|IP_SELMIICLK|IP_WLANPHY| \
IP_ETHPHY|IP_WLANMAC|IP_ETHMAC|IP_ISOLATION)
#endif
/* Ether register base address */
#define MACCR_BASE 0xbb804000 /* Internal Ether MAC base address */
#define PCRAM_BASE (MACCR_BASE+0x100) /* Per-port Configuration Register */
#define PCRP0 (0x004 + PCRAM_BASE) /* Port Configuration Register of Port 0 */
#define PCRP3 (0x010 + PCRAM_BASE) /* Port Configuration Register of Port 3 */
#define P0GMIICR (0x04C + PCRAM_BASE) /* Port-0 GMII Configuration Register */
#define PauseFlowControl 8 /* Bit-shift number of PauseFlowControl */
/* MAC control register field definitions */
#define MDCIOCR (0x004+MACCR_BASE) /* MDC/MDIO Command */
#define MDCIOSR (0x008+MACCR_BASE) /* MDC/MDIO Status */
//#define STATUS (1<<31) /* 0: Process Done, 1: In progress */
//STATUS has been defined in linux-2.6.30/arch/rlx/include/asm/ptrace.h
#define MDCIO_STATUS (1<<31) /* 0: Process Done, 1: In progress */
/* MDCIOCR - MDC/MDIO Command */
#define COMMAND_READ (0<<31) /* 0:Read Access, 1:Write Access */
#define COMMAND_WRITE (1<<31) /* 0:Read Access, 1:Write Access */
#define PHYADD_OFFSET (24) /* PHY Address, said, PHY ID */
#define REGADD_OFFSET (16) /* PHY Register */
#define ETH_PORT_NUM (3) /* Port number of built-in Ether phy */
#define MII_PORT_NUM (0) /* Port number of NFBI MII */
// rx cmd state
enum {
STATE_RX_INIT,
STATE_RX_WAIT_LEN,
STATE_RX_WAIT_DATA,
STATE_RX_WAIT_DAEMON
};
// tx status state
enum {
STATE_TX_INIT,
STATE_TX_IN_PROGRESS
};
// indication event id
enum {
IND_CMD_EV,
IND_SYSCTL_EV
};
// cmd id of write data
enum {
WRITE_MDIO,
SET_CMD_TIMEOUT,
SET_PHY_POLL_TIME,
SET_HOST_PID,
};
// cmd id of ioctl
#define MDIO_IOC_MAGIC 'k'
#define MDIO_IOCTL_SET_HOST_PID _IOW(MDIO_IOC_MAGIC, 0, int)
#define MDIO_IOCTL_SET_CMD_TIMEOUT _IOW(MDIO_IOC_MAGIC, 1, char)
#define MDIO_IOCTL_SET_PHY_POLL_TIME _IOW(MDIO_IOC_MAGIC, 2, char)
#define MDIO_IOCTL_READ_MEM _IOWR(MDIO_IOC_MAGIC, 3, int)
#define MDIO_IOCTL_WRITE_MEM _IOW(MDIO_IOC_MAGIC, 4, struct mdio_mem32_param)
#define MDIO_IOCTL_SET_MII_PAUSE _IOW(MDIO_IOC_MAGIC, 5, char)
#define MDIO_IOCTL_SET_SUSPEND _IOW(MDIO_IOC_MAGIC, 6, char)
#define MDIO_IOCTL_READ_SCR _IOR(MDIO_IOC_MAGIC, 7, int)
#define MDIO_IOCTL_JUMP_ADDR _IOW(MDIO_IOC_MAGIC, 8, int)
#define MDIO_IOCTL_PRIV_CMD _IOW(MDIO_IOC_MAGIC, 9, int)
#define MDIO_IOCTL_GET_REG _IOWR(MDIO_IOC_MAGIC, 10, struct reg_param)
#define MDIO_IOCTL_SET_REG _IOW(MDIO_IOC_MAGIC, 11, struct reg_param)
#define MDIO_IOCTL_SET_MII_CLK _IOW(MDIO_IOC_MAGIC, 12, int)
#define MDIO_IOCTL_SET_ETH_PAUSE _IOW(MDIO_IOC_MAGIC, 13, char)
#ifdef CONFIG_RTK_VOIP_ETHERNET_DSP_IS_DSP
#define MDIO_IOCTL_READ_DSP_ID _IOW(MDIO_IOC_MAGIC, 14, unsigned int)
#define MDIO_IOCTL_MAXNR 14
#else
#define MDIO_IOCTL_MAXNR 13
#endif
#define TIME_DIFF(a, b) ((a >= b)? (a - b):(0xffffffff - b + a + 1))
#define EVT_BUF_OFFSET ((int)(long *)&(((struct evt_msg *)0)->buf))
#ifdef REG32
#undef REG32
#endif
#define REG32(reg) (*((volatile unsigned long *)(reg)))
#ifdef WRITE_MEM32
#undef WRITE_MEM32
#undef READ_MEM32
#endif
#define WRITE_MEM32(reg,val) REG32(reg)=val
#define READ_MEM32(reg) REG32(reg)
#ifndef SIMULATION
#define register_read_dw(offset) (REG32(offset))
#define register_write_dw(offset, data) (REG32(offset)=data)
#endif
#define PUT_IN_DATA(data) { \
memcpy(&priv->data_in.buf[priv->data_in.len], &data, 2); \
priv->data_in.len += 2; \
}
#define RESET_RX_STATE { \
priv->rx_cmd_state = STATE_RX_INIT; \
priv->data_in.len = 0; \
priv->rx_cmd_time = 0; \
}
#ifdef KDB_MSG
#define DEBUGK_OUT(fmt, args...) printk("%s_%s: "fmt, DRIVER_NAME, __FUNCTION__, ## args)
#define ASSERT(expr) \
if(!(expr)) { \
printk( "\033[33;41m%s:%d: assert(%s)\033[m\n", \
__FILE__,__LINE__,#expr); \
}
#else
#define DEBUGK_OUT(fmt, args...)
#define ASSERT(expr)
#endif
#ifdef KDB_ERR
#define DEBUGK_ERR(fmt, args...) printk("%s_%s_ERR: "fmt, DRIVER_NAME, __FUNCTION__, ## args)
#else
#define DEBUGK_ERR(fmt, args...)
#endif
/*================================================================*/
/* Structure Definition */
struct buf_ar {
int len;
unsigned char buf[MDIO_BUFSIZE];
};
struct evt_msg {
int id; // event id
int len; // length in buf
unsigned char buf[MDIO_BUFSIZE];
};
struct mdio_mem32_param {
unsigned long addr;
unsigned long val;
};
struct reg_param {
unsigned long addr;
unsigned long val;
};
#ifdef __KERNEL__
struct mdio_priv {
int cmd_timeout; // in 10ms
int phy_reg_poll_time; // in 10ms
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
int host_pid; // pid of host-daemon
#else
struct pid *host_pid;
#endif
int poll_timer_up;
int force_power_down;
struct timer_list reg_poll_timer;
unsigned long reg_BMCR_read, reg_BMCR_write;
unsigned long reg_BMSR_read;
unsigned long reg_ANAR_read, reg_ANAR_write;
unsigned long reg_ANLPAR_read;
int eth_phy_link_status;
struct file *filp;
struct buf_ar data_out;
struct buf_ar data_in;
int rx_cmd_state;
unsigned long rx_cmd_time;
int rx_cmd_remain_len;
int tx_status_state;
int tx_status_transmitting_len;
int evt_que_head, evt_que_tail;
struct evt_msg ind_evt_que[EV_QUE_MAX];
spinlock_t reglock;
};
#endif
#endif // INCLUDE_RTL_MDIO_H