1e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian/* Applied Micro X-Gene SoC Ethernet Driver
2e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian *
3e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian * Copyright (c) 2014, Applied Micro Circuits Corporation
4e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian * Authors: Iyappan Subramanian <isubramanian@apm.com>
5e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian *	    Ravi Patel <rapatel@apm.com>
6e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian *	    Keyur Chudgar <kchudgar@apm.com>
7e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian *
8e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian * This program is free software; you can redistribute  it and/or modify it
9e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian * under  the terms of  the GNU General  Public License as published by the
10e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian * Free Software Foundation;  either version 2 of the  License, or (at your
11e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian * option) any later version.
12e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian *
13e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian * This program is distributed in the hope that it will be useful,
14e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian * but WITHOUT ANY WARRANTY; without even the implied warranty of
15e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian * GNU General Public License for more details.
17e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian *
18e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian * You should have received a copy of the GNU General Public License
19e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian */
21e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian
22e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian#ifndef __XGENE_ENET_MAIN_H__
23e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian#define __XGENE_ENET_MAIN_H__
24e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian
25e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian#include <linux/clk.h>
26e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian#include <linux/of_platform.h>
27e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian#include <linux/of_net.h>
28e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian#include <linux/of_mdio.h>
29e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian#include <linux/module.h>
30e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian#include <net/ip.h>
31e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian#include <linux/prefetch.h>
32e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian#include <linux/if_vlan.h>
33e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian#include <linux/phy.h>
34e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian#include "xgene_enet_hw.h"
35e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian
36e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian#define XGENE_DRV_VERSION	"v1.0"
37e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian#define XGENE_ENET_MAX_MTU	1536
38e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian#define SKB_BUFFER_SIZE		(XGENE_ENET_MAX_MTU - NET_IP_ALIGN)
39e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian#define NUM_PKT_BUF	64
40e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian#define NUM_BUFPOOL	32
41bdd330f0506b2c4d02d5453fa32e785f0c348388Iyappan Subramanian#define START_ETH_BUFNUM	2
42bdd330f0506b2c4d02d5453fa32e785f0c348388Iyappan Subramanian#define START_BP_BUFNUM		0x22
43bdd330f0506b2c4d02d5453fa32e785f0c348388Iyappan Subramanian#define START_RING_NUM		8
44e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian
4532f784b50e14c653ad0f010fbd5921a5f8caf846Iyappan Subramanian#define PHY_POLL_LINK_ON	(10 * HZ)
4632f784b50e14c653ad0f010fbd5921a5f8caf846Iyappan Subramanian#define PHY_POLL_LINK_OFF	(PHY_POLL_LINK_ON / 5)
4732f784b50e14c653ad0f010fbd5921a5f8caf846Iyappan Subramanian
48e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian/* software context of a descriptor ring */
49e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanianstruct xgene_enet_desc_ring {
50e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	struct net_device *ndev;
51e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	u16 id;
52e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	u16 num;
53e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	u16 head;
54e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	u16 tail;
55e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	u16 slots;
56e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	u16 irq;
57e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	u32 size;
58e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	u32 state[NUM_RING_CONFIG];
59e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	void __iomem *cmd_base;
60e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	void __iomem *cmd;
61e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	dma_addr_t dma;
62e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	u16 dst_ring_num;
63e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	u8 nbufpool;
64e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	struct sk_buff *(*rx_skb);
65e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	struct sk_buff *(*cp_skb);
66e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	enum xgene_enet_ring_cfgsize cfgsize;
67e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	struct xgene_enet_desc_ring *cp_ring;
68e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	struct xgene_enet_desc_ring *buf_pool;
69e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	struct napi_struct napi;
70e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	union {
71e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian		void *desc_addr;
72e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian		struct xgene_enet_raw_desc *raw_desc;
73e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian		struct xgene_enet_raw_desc16 *raw_desc16;
74e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	};
75e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian};
76e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian
77d0eb74582fa7b5c15710d293a3c4d8d3409ae165Iyappan Subramanianstruct xgene_mac_ops {
78d0eb74582fa7b5c15710d293a3c4d8d3409ae165Iyappan Subramanian	void (*init)(struct xgene_enet_pdata *pdata);
79d0eb74582fa7b5c15710d293a3c4d8d3409ae165Iyappan Subramanian	void (*reset)(struct xgene_enet_pdata *pdata);
80d0eb74582fa7b5c15710d293a3c4d8d3409ae165Iyappan Subramanian	void (*tx_enable)(struct xgene_enet_pdata *pdata);
81d0eb74582fa7b5c15710d293a3c4d8d3409ae165Iyappan Subramanian	void (*rx_enable)(struct xgene_enet_pdata *pdata);
82d0eb74582fa7b5c15710d293a3c4d8d3409ae165Iyappan Subramanian	void (*tx_disable)(struct xgene_enet_pdata *pdata);
83d0eb74582fa7b5c15710d293a3c4d8d3409ae165Iyappan Subramanian	void (*rx_disable)(struct xgene_enet_pdata *pdata);
84d0eb74582fa7b5c15710d293a3c4d8d3409ae165Iyappan Subramanian	void (*set_mac_addr)(struct xgene_enet_pdata *pdata);
85dc8385f0c0f46ca18c1c8ab59c9f565dc7cfa6bfIyappan Subramanian	void (*link_state)(struct work_struct *work);
86d0eb74582fa7b5c15710d293a3c4d8d3409ae165Iyappan Subramanian};
87d0eb74582fa7b5c15710d293a3c4d8d3409ae165Iyappan Subramanian
88d0eb74582fa7b5c15710d293a3c4d8d3409ae165Iyappan Subramanianstruct xgene_port_ops {
89c3f4465d272fa94d5a077c502e83d3e712ec8d62Iyappan Subramanian	int (*reset)(struct xgene_enet_pdata *pdata);
90d0eb74582fa7b5c15710d293a3c4d8d3409ae165Iyappan Subramanian	void (*cle_bypass)(struct xgene_enet_pdata *pdata,
91d0eb74582fa7b5c15710d293a3c4d8d3409ae165Iyappan Subramanian			   u32 dst_ring_num, u16 bufpool_id);
92d0eb74582fa7b5c15710d293a3c4d8d3409ae165Iyappan Subramanian	void (*shutdown)(struct xgene_enet_pdata *pdata);
93d0eb74582fa7b5c15710d293a3c4d8d3409ae165Iyappan Subramanian};
94d0eb74582fa7b5c15710d293a3c4d8d3409ae165Iyappan Subramanian
95e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian/* ethernet private data */
96e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanianstruct xgene_enet_pdata {
97e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	struct net_device *ndev;
98e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	struct mii_bus *mdio_bus;
99e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	struct phy_device *phy_dev;
100e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	int phy_speed;
101e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	struct clk *clk;
102e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	struct platform_device *pdev;
103e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	struct xgene_enet_desc_ring *tx_ring;
104e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	struct xgene_enet_desc_ring *rx_ring;
105e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	char *dev_name;
106e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	u32 rx_buff_cnt;
107e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	u32 tx_qcnt_hi;
108e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	u32 cp_qcnt_hi;
109e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	u32 cp_qcnt_low;
110e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	u32 rx_irq;
111e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	void __iomem *eth_csr_addr;
112e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	void __iomem *eth_ring_if_addr;
113e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	void __iomem *eth_diag_csr_addr;
114e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	void __iomem *mcx_mac_addr;
115e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	void __iomem *mcx_mac_csr_addr;
116e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	void __iomem *base_addr;
117e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	void __iomem *ring_csr_addr;
118e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	void __iomem *ring_cmd_addr;
119e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	int phy_mode;
1200148d38d36b76b190ddddff68f02d2617ada3bcbIyappan Subramanian	enum xgene_enet_rm rm;
121e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	struct rtnl_link_stats64 stats;
122d0eb74582fa7b5c15710d293a3c4d8d3409ae165Iyappan Subramanian	struct xgene_mac_ops *mac_ops;
123d0eb74582fa7b5c15710d293a3c4d8d3409ae165Iyappan Subramanian	struct xgene_port_ops *port_ops;
1240148d38d36b76b190ddddff68f02d2617ada3bcbIyappan Subramanian	struct delayed_work link_work;
125e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian};
126e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian
12732f784b50e14c653ad0f010fbd5921a5f8caf846Iyappan Subramanianstruct xgene_indirect_ctl {
12832f784b50e14c653ad0f010fbd5921a5f8caf846Iyappan Subramanian	void __iomem *addr;
12932f784b50e14c653ad0f010fbd5921a5f8caf846Iyappan Subramanian	void __iomem *ctl;
13032f784b50e14c653ad0f010fbd5921a5f8caf846Iyappan Subramanian	void __iomem *cmd;
13132f784b50e14c653ad0f010fbd5921a5f8caf846Iyappan Subramanian	void __iomem *cmd_done;
13232f784b50e14c653ad0f010fbd5921a5f8caf846Iyappan Subramanian};
13332f784b50e14c653ad0f010fbd5921a5f8caf846Iyappan Subramanian
134e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian/* Set the specified value into a bit-field defined by its starting position
135e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian * and length within a single u64.
136e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian */
137e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanianstatic inline u64 xgene_enet_set_field_value(int pos, int len, u64 val)
138e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian{
139e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	return (val & ((1ULL << len) - 1)) << pos;
140e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian}
141e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian
142e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian#define SET_VAL(field, val) \
143e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian		xgene_enet_set_field_value(field ## _POS, field ## _LEN, val)
144e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian
145e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian#define SET_BIT(field) \
146e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian		xgene_enet_set_field_value(field ## _POS, 1, 1)
147e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian
148e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian/* Get the value from a bit-field defined by its starting position
149e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian * and length within the specified u64.
150e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian */
151e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanianstatic inline u64 xgene_enet_get_field_value(int pos, int len, u64 src)
152e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian{
153e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	return (src >> pos) & ((1ULL << len) - 1);
154e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian}
155e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian
156e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian#define GET_VAL(field, src) \
157e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian		xgene_enet_get_field_value(field ## _POS, field ## _LEN, src)
158e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian
159e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanianstatic inline struct device *ndev_to_dev(struct net_device *ndev)
160e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian{
161e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian	return ndev->dev.parent;
162e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian}
163e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian
164e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanianvoid xgene_enet_set_ethtool_ops(struct net_device *netdev);
165e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian
166e6ad767305eb6ea80ce06c1eaa1b0977e8361998Iyappan Subramanian#endif /* __XGENE_ENET_MAIN_H__ */
167