blob: 397a387e169ec45aa035798c8334e68666cd11b6 [file] [log] [blame]
/* Mediatek STAR MAC network driver.
*
* Copyright (c) 2016-2017 Mediatek Corporation
*
* 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.
*/
#ifndef _STAR_H_
#define _STAR_H_
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/ip.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/netdevice.h>
#include <linux/platform_device.h>
#include <linux/mii.h>
#include <linux/version.h>
#include <linux/dma-mapping.h>
#include <linux/syscalls.h>
#include <linux/fcntl.h>
#include <linux/regulator/consumer.h>
#include "star_mac.h"
#include "star_phy.h"
/* use rmii mode */
#define CONFIG_STAR_USE_RMII_MODE
#define ETH_MAX_FRAME_SIZE 1536
#define ETH_SKB_ALIGNMENT 16
#define TX_DESC_NUM 128
#define RX_DESC_NUM 128
#define TX_DESC_TOTAL_SIZE (sizeof(tx_desc) * TX_DESC_NUM)
#define RX_DESC_TOTAL_SIZE (sizeof(rx_desc) * RX_DESC_NUM)
#define ETH_EXTRA_PKT_LEN 36
#define ETH_ADDR_LEN 6
#define STAR_NAPI_WEIGHT (RX_DESC_NUM << 1)
/* Star Ethernet Configuration*/
/* ====================================== */
#define star_intr_disable(dev) \
star_set_reg(star_int_mask((dev)->base), 0xffffffff)
#define star_intr_enable(dev) \
star_set_reg(star_int_mask((dev)->base), 0)
#define star_intr_clear(dev, intrStatus) \
star_set_reg(star_int_sta((dev)->base), intrStatus)
#define star_intr_status(dev) \
star_get_reg(star_int_sta((dev)->base))
#define star_intr_rx_enable(dev) \
star_clear_bit(star_int_mask((dev)->base), STAR_INT_STA_RXC)
#define star_intr_rx_disable(dev) \
star_set_bit(star_int_mask((dev)->base), STAR_INT_STA_RXC)
#define star_intr_mask(dev) \
star_get_reg(star_int_mask((dev)->base))
#define RX_RESUME BIT(2)
#define RX_STOP BIT(1)
#define RX_START BIT(0)
#define dma_tx_start_and_reset_tx_desc(dev) \
star_set_bit(star_tx_dma_ctrl((dev)->base), TX_START)
#define dma_rx_start_and_reset_rx_desc(dev) \
star_set_bit(star_rx_dma_ctrl((dev)->base), RX_START)
#define star_dma_tx_enable(dev) \
star_set_bit(star_tx_dma_ctrl((dev)->base), TX_RESUME)
#define star_dma_tx_disable(dev) \
star_set_bit(star_tx_dma_ctrl((dev)->base), TX_STOP)
#define star_dma_rx_enable(dev) \
star_set_bit(star_rx_dma_ctrl((dev)->base), RX_RESUME)
#define star_dma_rx_disable(dev) \
star_set_bit(star_rx_dma_ctrl((dev)->base), RX_STOP)
#define star_dma_tx_resume(dev) star_dma_tx_enable(dev)
#define star_dma_rx_resume(dev) star_dma_rx_enable(dev)
#define star_reset_hash_table(dev) \
star_set_bit(star_test1((dev)->base), STAR_TEST1_RST_HASH_BIST)
#define star_dma_rx_valid(ctrl_len) \
(((ctrl_len & RX_FS) != 0) && ((ctrl_len & RX_LS) != 0) && \
((ctrl_len & RX_CRCERR) == 0) && ((ctrl_len & RX_OSIZE) == 0))
#define star_dma_rx_crc_err(ctrl_len) ((ctrl_len & RX_CRCERR) ? 1 : 0)
#define star_dma_rx_over_size(ctrl_len) ((ctrl_len & RX_OSIZE) ? 1 : 0)
#define star_dma_rx_length(ctrl_len) \
((ctrl_len >> RX_LEN_OFFSET) & RX_LEN_MASK)
#define star_dma_tx_length(ctrl_len) \
((ctrl_len >> TX_LEN_OFFSET) & TX_LEN_MASK)
#define star_arl_promisc_enable(dev) \
star_set_bit(STAR_ARL_CFG((dev)->base), STAR_ARL_CFG_MISCMODE)
enum wol_type {
WOL_NONE = 0,
MAC_WOL,
PHY_WOL,
};
/**
* @brief structure for Star private data
* @wol: ethernet mac wol type status
* @wol_flag: normal wol: set true to enable, set false to disable.
*/
typedef struct star_private_s {
struct regulator *phy_regulator;
struct clk *core_clk, *reg_clk, *trans_clk;
star_dev star_dev;
struct net_device *dev;
dma_addr_t desc_dma_addr;
uintptr_t desc_vir_addr;
u32 phy_addr;
/* star lock */
spinlock_t lock;
struct tasklet_struct dsr;
bool tsk_tx;
struct napi_struct napi;
struct mii_if_info mii;
struct input_dev *idev;
bool opened;
bool support_wol;
bool support_rmii;
int eint_irq;
int eint_pin;
enum wol_type wol;
bool wol_flag;
} star_private;
struct eth_phy_ops {
u32 addr;
/* value of phy reg3(identifier2) */
u32 phy_id;
void (*init)(star_dev *sdev);
void (*wol_enable)(struct net_device *netdev);
void (*wol_disable)(struct net_device *netdev);
};
/* debug level */
enum {
STAR_ERR = 0,
STAR_WARN,
STAR_DBG,
STAR_VERB,
STAR_DBG_MAX
};
#ifndef STAR_DBG_LVL_DEFAULT
#define STAR_DBG_LVL_DEFAULT STAR_ERR
#endif
extern int star_dbg_level;
/* star mac memory barrier */
#define star_mb() mb()
#define STAR_MSG(lvl, fmt...) do {\
if (lvl <= star_dbg_level)\
pr_err("star: " fmt);\
} while (0)
static inline void star_set_reg(void __iomem *reg, u32 value)
{
STAR_MSG(STAR_VERB, "star_set_reg(%p)=%08x\n", reg, value);
iowrite32(value, reg);
}
static inline u32 star_get_reg(void __iomem *reg)
{
u32 data = ioread32(reg);
STAR_MSG(STAR_VERB, "star_get_reg(%p)=%08x\n", reg, data);
return data;
}
static inline void star_set_bit(void __iomem *reg, u32 bit)
{
u32 data = ioread32(reg);
data |= bit;
STAR_MSG(STAR_VERB, "star_set_bit(%p,bit:%08x)=%08x\n", reg, bit, data);
iowrite32(data, reg);
star_mb();
}
static inline void star_clear_bit(void __iomem *reg, u32 bit)
{
u32 data = ioread32(reg);
data &= ~bit;
STAR_MSG(STAR_VERB,
"star_clear_bit(%p,bit:%08x)=%08x\n", reg, bit, data);
iowrite32(data, reg);
star_mb();
}
static inline u32 star_get_bit_mask(void __iomem *reg, u32 mask, u32 offset)
{
u32 data = ioread32(reg);
data = ((data >> offset) & mask);
STAR_MSG(STAR_VERB,
"star_get_bit_mask(%p,mask:%08x,offset:%08x)=%08x(data)\n",
reg, mask, offset, data);
return data;
}
static inline u32 star_is_set_bit(void __iomem *reg, u32 bit)
{
u32 data = ioread32(reg);
data &= bit;
STAR_MSG(STAR_VERB,
"star_is_set_bit(%p,bit:%08x)=%08x\n", reg, bit, data);
return data ? 1 : 0;
}
int star_get_wol_flag(star_private *star_prv);
void star_set_wol_flag(star_private *star_prv, bool flag);
int star_get_dbg_level(void);
void star_set_dbg_level(int dbg);
#endif /* _STAR_H_ */