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