Iyappan Subramanian | e6ad767 | 2014-08-07 15:14:28 -0700 | [diff] [blame] | 1 | /* Applied Micro X-Gene SoC Ethernet Driver |
| 2 | * |
| 3 | * Copyright (c) 2014, Applied Micro Circuits Corporation |
| 4 | * Authors: Iyappan Subramanian <isubramanian@apm.com> |
| 5 | * Ravi Patel <rapatel@apm.com> |
| 6 | * Keyur Chudgar <kchudgar@apm.com> |
| 7 | * |
| 8 | * This program is free software; you can redistribute it and/or modify it |
| 9 | * under the terms of the GNU General Public License as published by the |
| 10 | * Free Software Foundation; either version 2 of the License, or (at your |
| 11 | * option) any later version. |
| 12 | * |
| 13 | * This program is distributed in the hope that it will be useful, |
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | * GNU General Public License for more details. |
| 17 | * |
| 18 | * You should have received a copy of the GNU General Public License |
| 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 20 | */ |
| 21 | |
| 22 | #ifndef __XGENE_ENET_MAIN_H__ |
| 23 | #define __XGENE_ENET_MAIN_H__ |
| 24 | |
Feng Kan | de7b5b3d | 2015-01-06 15:41:33 -0700 | [diff] [blame] | 25 | #include <linux/acpi.h> |
Iyappan Subramanian | e6ad767 | 2014-08-07 15:14:28 -0700 | [diff] [blame] | 26 | #include <linux/clk.h> |
Feng Kan | de7b5b3d | 2015-01-06 15:41:33 -0700 | [diff] [blame] | 27 | #include <linux/efi.h> |
Iyappan Subramanian | b5d7a06 | 2016-01-21 16:07:41 -0800 | [diff] [blame] | 28 | #include <linux/irq.h> |
Feng Kan | de7b5b3d | 2015-01-06 15:41:33 -0700 | [diff] [blame] | 29 | #include <linux/io.h> |
Iyappan Subramanian | e6ad767 | 2014-08-07 15:14:28 -0700 | [diff] [blame] | 30 | #include <linux/of_platform.h> |
| 31 | #include <linux/of_net.h> |
| 32 | #include <linux/of_mdio.h> |
| 33 | #include <linux/module.h> |
| 34 | #include <net/ip.h> |
| 35 | #include <linux/prefetch.h> |
| 36 | #include <linux/if_vlan.h> |
| 37 | #include <linux/phy.h> |
| 38 | #include "xgene_enet_hw.h" |
Iyappan Subramanian | 76f94a9 | 2016-02-17 15:00:39 -0800 | [diff] [blame] | 39 | #include "xgene_enet_cle.h" |
Iyappan Subramanian | bc1b7c1 | 2015-04-28 13:52:39 -0700 | [diff] [blame] | 40 | #include "xgene_enet_ring2.h" |
Iyappan Subramanian | 8089a96 | 2016-07-25 17:12:41 -0700 | [diff] [blame] | 41 | #include "../../../phy/mdio-xgene.h" |
Iyappan Subramanian | e6ad767 | 2014-08-07 15:14:28 -0700 | [diff] [blame] | 42 | |
| 43 | #define XGENE_DRV_VERSION "v1.0" |
| 44 | #define XGENE_ENET_MAX_MTU 1536 |
| 45 | #define SKB_BUFFER_SIZE (XGENE_ENET_MAX_MTU - NET_IP_ALIGN) |
Iyappan Subramanian | 949c40b | 2015-08-26 11:48:05 -0700 | [diff] [blame] | 46 | #define BUFLEN_16K (16 * 1024) |
Iyappan Subramanian | e6ad767 | 2014-08-07 15:14:28 -0700 | [diff] [blame] | 47 | #define NUM_PKT_BUF 64 |
| 48 | #define NUM_BUFPOOL 32 |
Iyappan Subramanian | 9b00eb4 | 2015-08-26 11:48:06 -0700 | [diff] [blame] | 49 | #define MAX_EXP_BUFFS 256 |
| 50 | #define XGENE_ENET_MSS 1448 |
| 51 | #define XGENE_MIN_ENET_FRAME_SIZE 60 |
Keyur Chudgar | ca62645 | 2015-03-17 11:27:13 -0700 | [diff] [blame] | 52 | |
Iyappan Subramanian | 1b090a4 | 2016-05-13 16:52:59 -0700 | [diff] [blame] | 53 | #define XGENE_MAX_ENET_IRQ 16 |
| 54 | #define XGENE_NUM_RX_RING 8 |
| 55 | #define XGENE_NUM_TX_RING 8 |
| 56 | #define XGENE_NUM_TXC_RING 8 |
Iyappan Subramanian | 107dec2 | 2016-02-17 15:00:41 -0800 | [diff] [blame] | 57 | |
Keyur Chudgar | ca62645 | 2015-03-17 11:27:13 -0700 | [diff] [blame] | 58 | #define START_CPU_BUFNUM_0 0 |
| 59 | #define START_ETH_BUFNUM_0 2 |
| 60 | #define START_BP_BUFNUM_0 0x22 |
| 61 | #define START_RING_NUM_0 8 |
| 62 | #define START_CPU_BUFNUM_1 12 |
| 63 | #define START_ETH_BUFNUM_1 10 |
| 64 | #define START_BP_BUFNUM_1 0x2A |
| 65 | #define START_RING_NUM_1 264 |
Iyappan Subramanian | e6ad767 | 2014-08-07 15:14:28 -0700 | [diff] [blame] | 66 | |
Iyappan Subramanian | 149e9ab | 2015-09-08 15:50:26 -0700 | [diff] [blame] | 67 | #define XG_START_CPU_BUFNUM_1 12 |
| 68 | #define XG_START_ETH_BUFNUM_1 2 |
| 69 | #define XG_START_BP_BUFNUM_1 0x22 |
| 70 | #define XG_START_RING_NUM_1 264 |
| 71 | |
Iyappan Subramanian | bc1b7c1 | 2015-04-28 13:52:39 -0700 | [diff] [blame] | 72 | #define X2_START_CPU_BUFNUM_0 0 |
| 73 | #define X2_START_ETH_BUFNUM_0 0 |
| 74 | #define X2_START_BP_BUFNUM_0 0x20 |
| 75 | #define X2_START_RING_NUM_0 0 |
Iyappan Subramanian | bc1b7c1 | 2015-04-28 13:52:39 -0700 | [diff] [blame] | 76 | #define X2_START_CPU_BUFNUM_1 0xc |
| 77 | #define X2_START_ETH_BUFNUM_1 0 |
| 78 | #define X2_START_BP_BUFNUM_1 0x20 |
| 79 | #define X2_START_RING_NUM_1 256 |
| 80 | |
Iyappan Subramanian | 6772b65 | 2015-03-25 12:19:12 -0700 | [diff] [blame] | 81 | #define IRQ_ID_SIZE 16 |
Iyappan Subramanian | 6772b65 | 2015-03-25 12:19:12 -0700 | [diff] [blame] | 82 | |
Iyappan Subramanian | 32f784b | 2014-10-13 17:05:34 -0700 | [diff] [blame] | 83 | #define PHY_POLL_LINK_ON (10 * HZ) |
| 84 | #define PHY_POLL_LINK_OFF (PHY_POLL_LINK_ON / 5) |
| 85 | |
Iyappan Subramanian | bc1b7c1 | 2015-04-28 13:52:39 -0700 | [diff] [blame] | 86 | enum xgene_enet_id { |
| 87 | XGENE_ENET1 = 1, |
| 88 | XGENE_ENET2 |
| 89 | }; |
| 90 | |
Iyappan Subramanian | e6ad767 | 2014-08-07 15:14:28 -0700 | [diff] [blame] | 91 | /* software context of a descriptor ring */ |
| 92 | struct xgene_enet_desc_ring { |
| 93 | struct net_device *ndev; |
| 94 | u16 id; |
| 95 | u16 num; |
| 96 | u16 head; |
| 97 | u16 tail; |
Iyappan Subramanian | 9b00eb4 | 2015-08-26 11:48:06 -0700 | [diff] [blame] | 98 | u16 exp_buf_tail; |
Iyappan Subramanian | e6ad767 | 2014-08-07 15:14:28 -0700 | [diff] [blame] | 99 | u16 slots; |
| 100 | u16 irq; |
Iyappan Subramanian | 6772b65 | 2015-03-25 12:19:12 -0700 | [diff] [blame] | 101 | char irq_name[IRQ_ID_SIZE]; |
Iyappan Subramanian | e6ad767 | 2014-08-07 15:14:28 -0700 | [diff] [blame] | 102 | u32 size; |
Iyappan Subramanian | 9dd3c79 | 2015-04-30 16:09:17 -0700 | [diff] [blame] | 103 | u32 state[X2_NUM_RING_CONFIG]; |
Iyappan Subramanian | e6ad767 | 2014-08-07 15:14:28 -0700 | [diff] [blame] | 104 | void __iomem *cmd_base; |
| 105 | void __iomem *cmd; |
| 106 | dma_addr_t dma; |
Iyappan Subramanian | ed9b7da | 2015-04-28 13:52:38 -0700 | [diff] [blame] | 107 | dma_addr_t irq_mbox_dma; |
| 108 | void *irq_mbox_addr; |
Iyappan Subramanian | e6ad767 | 2014-08-07 15:14:28 -0700 | [diff] [blame] | 109 | u16 dst_ring_num; |
| 110 | u8 nbufpool; |
Iyappan Subramanian | 107dec2 | 2016-02-17 15:00:41 -0800 | [diff] [blame] | 111 | u8 index; |
Iyappan Subramanian | e6ad767 | 2014-08-07 15:14:28 -0700 | [diff] [blame] | 112 | struct sk_buff *(*rx_skb); |
| 113 | struct sk_buff *(*cp_skb); |
Iyappan Subramanian | 9b00eb4 | 2015-08-26 11:48:06 -0700 | [diff] [blame] | 114 | dma_addr_t *frag_dma_addr; |
Iyappan Subramanian | e6ad767 | 2014-08-07 15:14:28 -0700 | [diff] [blame] | 115 | enum xgene_enet_ring_cfgsize cfgsize; |
| 116 | struct xgene_enet_desc_ring *cp_ring; |
| 117 | struct xgene_enet_desc_ring *buf_pool; |
| 118 | struct napi_struct napi; |
| 119 | union { |
| 120 | void *desc_addr; |
| 121 | struct xgene_enet_raw_desc *raw_desc; |
| 122 | struct xgene_enet_raw_desc16 *raw_desc16; |
| 123 | }; |
Iyappan Subramanian | 9b00eb4 | 2015-08-26 11:48:06 -0700 | [diff] [blame] | 124 | __le64 *exp_bufs; |
Iyappan Subramanian | 3bb502f | 2016-05-13 16:53:00 -0700 | [diff] [blame] | 125 | u64 tx_packets; |
| 126 | u64 tx_bytes; |
| 127 | u64 rx_packets; |
| 128 | u64 rx_bytes; |
| 129 | u64 rx_dropped; |
| 130 | u64 rx_errors; |
| 131 | u64 rx_length_errors; |
| 132 | u64 rx_crc_errors; |
| 133 | u64 rx_frame_errors; |
| 134 | u64 rx_fifo_errors; |
Iyappan Subramanian | e6ad767 | 2014-08-07 15:14:28 -0700 | [diff] [blame] | 135 | }; |
| 136 | |
Iyappan Subramanian | d0eb745 | 2014-10-09 18:32:05 -0700 | [diff] [blame] | 137 | struct xgene_mac_ops { |
| 138 | void (*init)(struct xgene_enet_pdata *pdata); |
| 139 | void (*reset)(struct xgene_enet_pdata *pdata); |
| 140 | void (*tx_enable)(struct xgene_enet_pdata *pdata); |
| 141 | void (*rx_enable)(struct xgene_enet_pdata *pdata); |
| 142 | void (*tx_disable)(struct xgene_enet_pdata *pdata); |
| 143 | void (*rx_disable)(struct xgene_enet_pdata *pdata); |
Iyappan Subramanian | 9a8c5dd | 2016-07-25 17:12:36 -0700 | [diff] [blame] | 144 | void (*set_speed)(struct xgene_enet_pdata *pdata); |
Iyappan Subramanian | d0eb745 | 2014-10-09 18:32:05 -0700 | [diff] [blame] | 145 | void (*set_mac_addr)(struct xgene_enet_pdata *pdata); |
Iyappan Subramanian | 9b00eb4 | 2015-08-26 11:48:06 -0700 | [diff] [blame] | 146 | void (*set_mss)(struct xgene_enet_pdata *pdata); |
Iyappan Subramanian | dc8385f | 2014-10-13 17:05:33 -0700 | [diff] [blame] | 147 | void (*link_state)(struct work_struct *work); |
Iyappan Subramanian | d0eb745 | 2014-10-09 18:32:05 -0700 | [diff] [blame] | 148 | }; |
| 149 | |
| 150 | struct xgene_port_ops { |
Iyappan Subramanian | c3f4465 | 2014-11-03 11:59:55 -0800 | [diff] [blame] | 151 | int (*reset)(struct xgene_enet_pdata *pdata); |
Iyappan Subramanian | cb11c06 | 2016-07-25 17:12:37 -0700 | [diff] [blame] | 152 | void (*clear)(struct xgene_enet_pdata *pdata, |
| 153 | struct xgene_enet_desc_ring *ring); |
Iyappan Subramanian | d0eb745 | 2014-10-09 18:32:05 -0700 | [diff] [blame] | 154 | void (*cle_bypass)(struct xgene_enet_pdata *pdata, |
| 155 | u32 dst_ring_num, u16 bufpool_id); |
| 156 | void (*shutdown)(struct xgene_enet_pdata *pdata); |
| 157 | }; |
| 158 | |
Iyappan Subramanian | 81cefb8 | 2015-04-28 13:52:37 -0700 | [diff] [blame] | 159 | struct xgene_ring_ops { |
| 160 | u8 num_ring_config; |
| 161 | u8 num_ring_id_shift; |
| 162 | struct xgene_enet_desc_ring * (*setup)(struct xgene_enet_desc_ring *); |
| 163 | void (*clear)(struct xgene_enet_desc_ring *); |
| 164 | void (*wr_cmd)(struct xgene_enet_desc_ring *, int); |
| 165 | u32 (*len)(struct xgene_enet_desc_ring *); |
Iyappan Subramanian | 107dec2 | 2016-02-17 15:00:41 -0800 | [diff] [blame] | 166 | void (*coalesce)(struct xgene_enet_desc_ring *); |
Iyappan Subramanian | 81cefb8 | 2015-04-28 13:52:37 -0700 | [diff] [blame] | 167 | }; |
| 168 | |
Iyappan Subramanian | 76f94a9 | 2016-02-17 15:00:39 -0800 | [diff] [blame] | 169 | struct xgene_cle_ops { |
| 170 | int (*cle_init)(struct xgene_enet_pdata *pdata); |
| 171 | }; |
| 172 | |
Iyappan Subramanian | e6ad767 | 2014-08-07 15:14:28 -0700 | [diff] [blame] | 173 | /* ethernet private data */ |
| 174 | struct xgene_enet_pdata { |
| 175 | struct net_device *ndev; |
| 176 | struct mii_bus *mdio_bus; |
| 177 | struct phy_device *phy_dev; |
| 178 | int phy_speed; |
| 179 | struct clk *clk; |
| 180 | struct platform_device *pdev; |
Iyappan Subramanian | bc1b7c1 | 2015-04-28 13:52:39 -0700 | [diff] [blame] | 181 | enum xgene_enet_id enet_id; |
Iyappan Subramanian | 107dec2 | 2016-02-17 15:00:41 -0800 | [diff] [blame] | 182 | struct xgene_enet_desc_ring *tx_ring[XGENE_NUM_TX_RING]; |
| 183 | struct xgene_enet_desc_ring *rx_ring[XGENE_NUM_RX_RING]; |
| 184 | u16 tx_level[XGENE_NUM_TX_RING]; |
| 185 | u16 txc_level[XGENE_NUM_TX_RING]; |
Iyappan Subramanian | e6ad767 | 2014-08-07 15:14:28 -0700 | [diff] [blame] | 186 | char *dev_name; |
| 187 | u32 rx_buff_cnt; |
| 188 | u32 tx_qcnt_hi; |
Iyappan Subramanian | 107dec2 | 2016-02-17 15:00:41 -0800 | [diff] [blame] | 189 | u32 irqs[XGENE_MAX_ENET_IRQ]; |
| 190 | u8 rxq_cnt; |
| 191 | u8 txq_cnt; |
Iyappan Subramanian | 6772b65 | 2015-03-25 12:19:12 -0700 | [diff] [blame] | 192 | u8 cq_cnt; |
Iyappan Subramanian | e6ad767 | 2014-08-07 15:14:28 -0700 | [diff] [blame] | 193 | void __iomem *eth_csr_addr; |
| 194 | void __iomem *eth_ring_if_addr; |
| 195 | void __iomem *eth_diag_csr_addr; |
| 196 | void __iomem *mcx_mac_addr; |
Iyappan Subramanian | e6ad767 | 2014-08-07 15:14:28 -0700 | [diff] [blame] | 197 | void __iomem *mcx_mac_csr_addr; |
| 198 | void __iomem *base_addr; |
| 199 | void __iomem *ring_csr_addr; |
| 200 | void __iomem *ring_cmd_addr; |
Iyappan Subramanian | e6ad767 | 2014-08-07 15:14:28 -0700 | [diff] [blame] | 201 | int phy_mode; |
Iyappan Subramanian | 0148d38 | 2014-10-09 18:32:06 -0700 | [diff] [blame] | 202 | enum xgene_enet_rm rm; |
Iyappan Subramanian | 76f94a9 | 2016-02-17 15:00:39 -0800 | [diff] [blame] | 203 | struct xgene_enet_cle cle; |
Iyappan Subramanian | e6ad767 | 2014-08-07 15:14:28 -0700 | [diff] [blame] | 204 | struct rtnl_link_stats64 stats; |
Julia Lawall | 3cdb730 | 2015-12-08 21:18:25 +0100 | [diff] [blame] | 205 | const struct xgene_mac_ops *mac_ops; |
| 206 | const struct xgene_port_ops *port_ops; |
Iyappan Subramanian | 81cefb8 | 2015-04-28 13:52:37 -0700 | [diff] [blame] | 207 | struct xgene_ring_ops *ring_ops; |
Julia Lawall | b555a3d | 2016-05-01 14:36:28 +0200 | [diff] [blame] | 208 | const struct xgene_cle_ops *cle_ops; |
Iyappan Subramanian | 0148d38 | 2014-10-09 18:32:06 -0700 | [diff] [blame] | 209 | struct delayed_work link_work; |
Keyur Chudgar | ca62645 | 2015-03-17 11:27:13 -0700 | [diff] [blame] | 210 | u32 port_id; |
| 211 | u8 cpu_bufnum; |
| 212 | u8 eth_bufnum; |
| 213 | u8 bp_bufnum; |
| 214 | u16 ring_num; |
Iyappan Subramanian | 9b00eb4 | 2015-08-26 11:48:06 -0700 | [diff] [blame] | 215 | u32 mss; |
Iyappan Subramanian | 16615a4c | 2015-10-26 15:25:15 -0700 | [diff] [blame] | 216 | u8 tx_delay; |
| 217 | u8 rx_delay; |
Iyappan Subramanian | 8089a96 | 2016-07-25 17:12:41 -0700 | [diff] [blame] | 218 | bool mdio_driver; |
Iyappan Subramanian | e6ad767 | 2014-08-07 15:14:28 -0700 | [diff] [blame] | 219 | }; |
| 220 | |
Iyappan Subramanian | 32f784b | 2014-10-13 17:05:34 -0700 | [diff] [blame] | 221 | struct xgene_indirect_ctl { |
| 222 | void __iomem *addr; |
| 223 | void __iomem *ctl; |
| 224 | void __iomem *cmd; |
| 225 | void __iomem *cmd_done; |
| 226 | }; |
| 227 | |
Iyappan Subramanian | e6ad767 | 2014-08-07 15:14:28 -0700 | [diff] [blame] | 228 | static inline struct device *ndev_to_dev(struct net_device *ndev) |
| 229 | { |
| 230 | return ndev->dev.parent; |
| 231 | } |
| 232 | |
Iyappan Subramanian | 76f94a9 | 2016-02-17 15:00:39 -0800 | [diff] [blame] | 233 | static inline u16 xgene_enet_dst_ring_num(struct xgene_enet_desc_ring *ring) |
| 234 | { |
| 235 | struct xgene_enet_pdata *pdata = netdev_priv(ring->ndev); |
| 236 | |
| 237 | return ((u16)pdata->rm << 10) | ring->num; |
| 238 | } |
| 239 | |
Iyappan Subramanian | e6ad767 | 2014-08-07 15:14:28 -0700 | [diff] [blame] | 240 | void xgene_enet_set_ethtool_ops(struct net_device *netdev); |
| 241 | |
| 242 | #endif /* __XGENE_ENET_MAIN_H__ */ |