mirror of https://gitee.com/openkylin/linux.git
net: netcp: Add Keystone NetCP core ethernet driver
The network coprocessor (NetCP) is a hardware accelerator available in Keystone SoCs that processes Ethernet packets. NetCP consists of following hardware components 1 Gigabit Ethernet (GbE) subsystem with a Ethernet switch sub-module to send and receive packets. 2 Packet Accelerator (PA) module to perform packet classification operations such as header matching, and packet modification operations such as checksum generation. 3 Security Accelerator(SA) capable of performing IPSec operations on ingress/egress packets. 4 An optional 10 Gigabit Ethernet Subsystem (XGbE) which includes a 3-port Ethernet switch sub-module capable of 10Gb/s and 1Gb/s rates per Ethernet port. 5 Packet DMA and Queue Management Subsystem (QMSS) to enqueue and dequeue packets and DMA the packets between memory and NetCP hardware components described above. NetCP core driver make use of the Keystone Navigator driver API to allocate DMA channel for the Ethenet device and to handle packet queue/de-queue, Please refer API's in include/linux/soc/ti/knav_dma.h and drivers/soc/ti/knav_qmss.h for details. NetCP driver consists of NetCP core driver and at a minimum Gigabit Ethernet (GBE) module (1) driver to implement the Network device function. Other modules (2,3) can be optionally added to achieve supported hardware acceleration function. The initial version of the driver include NetCP core driver and GBE driver modules. Please refer Documentation/devicetree/bindings/net/keystone-netcp.txt for design of the driver. Cc: David Miller <davem@davemloft.net> Cc: Rob Herring <robh+dt@kernel.org> Cc: Grant Likely <grant.likely@linaro.org> Cc: Santosh Shilimkar <santosh.shilimkar@kernel.org> Cc: Pawel Moll <pawel.moll@arm.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Ian Campbell <ijc+devicetree@hellion.org.uk> Cc: Kumar Gala <galak@codeaurora.org> Signed-off-by: Murali Karicheri <m-karicheri2@ti.com> Signed-off-by: Wingman Kwok <w-kwok2@ti.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
44eefcdfb9
commit
84640e27f2
|
@ -9609,6 +9609,13 @@ F: drivers/power/lp8788-charger.c
|
|||
F: drivers/regulator/lp8788-*.c
|
||||
F: include/linux/mfd/lp8788*.h
|
||||
|
||||
TI NETCP ETHERNET DRIVER
|
||||
M: Wingman Kwok <w-kwok2@ti.com>
|
||||
M: Murali Karicheri <m-karicheri2@ti.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/net/ethernet/ti/netcp*
|
||||
|
||||
TI TWL4030 SERIES SOC CODEC DRIVER
|
||||
M: Peter Ujfalusi <peter.ujfalusi@ti.com>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
|
|
|
@ -73,12 +73,23 @@ config TI_CPSW
|
|||
config TI_CPTS
|
||||
boolean "TI Common Platform Time Sync (CPTS) Support"
|
||||
depends on TI_CPSW
|
||||
depends on TI_CPSW || TI_KEYSTONE_NET
|
||||
select PTP_1588_CLOCK
|
||||
---help---
|
||||
This driver supports the Common Platform Time Sync unit of
|
||||
the CPSW Ethernet Switch. The unit can time stamp PTP UDP/IPv4
|
||||
and Layer 2 packets, and the driver offers a PTP Hardware Clock.
|
||||
|
||||
config TI_KEYSTONE_NETCP
|
||||
tristate "TI Keystone NETCP Ethernet subsystem Support"
|
||||
depends on OF
|
||||
depends on KEYSTONE_NAVIGATOR_DMA && KEYSTONE_NAVIGATOR_QMSS
|
||||
---help---
|
||||
This driver supports TI's Keystone NETCP Ethernet subsystem.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called keystone_netcp.
|
||||
|
||||
config TLAN
|
||||
tristate "TI ThunderLAN support"
|
||||
depends on (PCI || EISA)
|
||||
|
|
|
@ -10,3 +10,6 @@ obj-$(CONFIG_TI_DAVINCI_CPDMA) += davinci_cpdma.o
|
|||
obj-$(CONFIG_TI_CPSW_PHY_SEL) += cpsw-phy-sel.o
|
||||
obj-$(CONFIG_TI_CPSW) += ti_cpsw.o
|
||||
ti_cpsw-y := cpsw_ale.o cpsw.o cpts.o
|
||||
|
||||
obj-$(CONFIG_TI_KEYSTONE_NETCP) += keystone_netcp.o
|
||||
keystone_netcp-y := netcp_core.o
|
||||
|
|
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
* NetCP driver local header
|
||||
*
|
||||
* Copyright (C) 2014 Texas Instruments Incorporated
|
||||
* Authors: Sandeep Nair <sandeep_n@ti.com>
|
||||
* Sandeep Paulraj <s-paulraj@ti.com>
|
||||
* Cyril Chemparathy <cyril@ti.com>
|
||||
* Santosh Shilimkar <santosh.shilimkar@ti.com>
|
||||
* Wingman Kwok <w-kwok2@ti.com>
|
||||
* Murali Karicheri <m-karicheri2@ti.com>
|
||||
*
|
||||
* 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 version 2.
|
||||
*
|
||||
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
|
||||
* kind, whether express or implied; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
#ifndef __NETCP_H__
|
||||
#define __NETCP_H__
|
||||
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/soc/ti/knav_dma.h>
|
||||
|
||||
/* Maximum Ethernet frame size supported by Keystone switch */
|
||||
#define NETCP_MAX_FRAME_SIZE 9504
|
||||
|
||||
#define SGMII_LINK_MAC_MAC_AUTONEG 0
|
||||
#define SGMII_LINK_MAC_PHY 1
|
||||
#define SGMII_LINK_MAC_MAC_FORCED 2
|
||||
#define SGMII_LINK_MAC_FIBER 3
|
||||
#define SGMII_LINK_MAC_PHY_NO_MDIO 4
|
||||
#define XGMII_LINK_MAC_PHY 10
|
||||
#define XGMII_LINK_MAC_MAC_FORCED 11
|
||||
|
||||
struct netcp_device;
|
||||
|
||||
struct netcp_tx_pipe {
|
||||
struct netcp_device *netcp_device;
|
||||
void *dma_queue;
|
||||
unsigned int dma_queue_id;
|
||||
u8 dma_psflags;
|
||||
void *dma_channel;
|
||||
const char *dma_chan_name;
|
||||
};
|
||||
|
||||
#define ADDR_NEW BIT(0)
|
||||
#define ADDR_VALID BIT(1)
|
||||
|
||||
enum netcp_addr_type {
|
||||
ADDR_ANY,
|
||||
ADDR_DEV,
|
||||
ADDR_UCAST,
|
||||
ADDR_MCAST,
|
||||
ADDR_BCAST
|
||||
};
|
||||
|
||||
struct netcp_addr {
|
||||
struct netcp_intf *netcp;
|
||||
unsigned char addr[ETH_ALEN];
|
||||
enum netcp_addr_type type;
|
||||
unsigned int flags;
|
||||
struct list_head node;
|
||||
};
|
||||
|
||||
struct netcp_intf {
|
||||
struct device *dev;
|
||||
struct device *ndev_dev;
|
||||
struct net_device *ndev;
|
||||
bool big_endian;
|
||||
unsigned int tx_compl_qid;
|
||||
void *tx_pool;
|
||||
struct list_head txhook_list_head;
|
||||
unsigned int tx_pause_threshold;
|
||||
void *tx_compl_q;
|
||||
|
||||
unsigned int tx_resume_threshold;
|
||||
void *rx_queue;
|
||||
void *rx_pool;
|
||||
struct list_head rxhook_list_head;
|
||||
unsigned int rx_queue_id;
|
||||
void *rx_fdq[KNAV_DMA_FDQ_PER_CHAN];
|
||||
u32 rx_buffer_sizes[KNAV_DMA_FDQ_PER_CHAN];
|
||||
struct napi_struct rx_napi;
|
||||
struct napi_struct tx_napi;
|
||||
|
||||
void *rx_channel;
|
||||
const char *dma_chan_name;
|
||||
u32 rx_pool_size;
|
||||
u32 rx_pool_region_id;
|
||||
u32 tx_pool_size;
|
||||
u32 tx_pool_region_id;
|
||||
struct list_head module_head;
|
||||
struct list_head interface_list;
|
||||
struct list_head addr_list;
|
||||
bool netdev_registered;
|
||||
bool primary_module_attached;
|
||||
|
||||
/* Lock used for protecting Rx/Tx hook list management */
|
||||
spinlock_t lock;
|
||||
struct netcp_device *netcp_device;
|
||||
struct device_node *node_interface;
|
||||
|
||||
/* DMA configuration data */
|
||||
u32 msg_enable;
|
||||
u32 rx_queue_depths[KNAV_DMA_FDQ_PER_CHAN];
|
||||
};
|
||||
|
||||
#define NETCP_PSDATA_LEN KNAV_DMA_NUM_PS_WORDS
|
||||
struct netcp_packet {
|
||||
struct sk_buff *skb;
|
||||
u32 *epib;
|
||||
u32 *psdata;
|
||||
unsigned int psdata_len;
|
||||
struct netcp_intf *netcp;
|
||||
struct netcp_tx_pipe *tx_pipe;
|
||||
bool rxtstamp_complete;
|
||||
void *ts_context;
|
||||
|
||||
int (*txtstamp_complete)(void *ctx, struct netcp_packet *pkt);
|
||||
};
|
||||
|
||||
static inline u32 *netcp_push_psdata(struct netcp_packet *p_info,
|
||||
unsigned int bytes)
|
||||
{
|
||||
u32 *buf;
|
||||
unsigned int words;
|
||||
|
||||
if ((bytes & 0x03) != 0)
|
||||
return NULL;
|
||||
words = bytes >> 2;
|
||||
|
||||
if ((p_info->psdata_len + words) > NETCP_PSDATA_LEN)
|
||||
return NULL;
|
||||
|
||||
p_info->psdata_len += words;
|
||||
buf = &p_info->psdata[NETCP_PSDATA_LEN - p_info->psdata_len];
|
||||
return buf;
|
||||
}
|
||||
|
||||
static inline int netcp_align_psdata(struct netcp_packet *p_info,
|
||||
unsigned int byte_align)
|
||||
{
|
||||
int padding;
|
||||
|
||||
switch (byte_align) {
|
||||
case 0:
|
||||
padding = -EINVAL;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
padding = 0;
|
||||
break;
|
||||
case 8:
|
||||
padding = (p_info->psdata_len << 2) % 8;
|
||||
break;
|
||||
case 16:
|
||||
padding = (p_info->psdata_len << 2) % 16;
|
||||
break;
|
||||
default:
|
||||
padding = (p_info->psdata_len << 2) % byte_align;
|
||||
break;
|
||||
}
|
||||
return padding;
|
||||
}
|
||||
|
||||
struct netcp_module {
|
||||
const char *name;
|
||||
struct module *owner;
|
||||
bool primary;
|
||||
|
||||
/* probe/remove: called once per NETCP instance */
|
||||
int (*probe)(struct netcp_device *netcp_device,
|
||||
struct device *device, struct device_node *node,
|
||||
void **inst_priv);
|
||||
int (*remove)(struct netcp_device *netcp_device, void *inst_priv);
|
||||
|
||||
/* attach/release: called once per network interface */
|
||||
int (*attach)(void *inst_priv, struct net_device *ndev,
|
||||
struct device_node *node, void **intf_priv);
|
||||
int (*release)(void *intf_priv);
|
||||
int (*open)(void *intf_priv, struct net_device *ndev);
|
||||
int (*close)(void *intf_priv, struct net_device *ndev);
|
||||
int (*add_addr)(void *intf_priv, struct netcp_addr *naddr);
|
||||
int (*del_addr)(void *intf_priv, struct netcp_addr *naddr);
|
||||
int (*add_vid)(void *intf_priv, int vid);
|
||||
int (*del_vid)(void *intf_priv, int vid);
|
||||
int (*ioctl)(void *intf_priv, struct ifreq *req, int cmd);
|
||||
|
||||
/* used internally */
|
||||
struct list_head module_list;
|
||||
struct list_head interface_list;
|
||||
};
|
||||
|
||||
int netcp_register_module(struct netcp_module *module);
|
||||
void netcp_unregister_module(struct netcp_module *module);
|
||||
void *netcp_module_get_intf_data(struct netcp_module *module,
|
||||
struct netcp_intf *intf);
|
||||
|
||||
int netcp_txpipe_init(struct netcp_tx_pipe *tx_pipe,
|
||||
struct netcp_device *netcp_device,
|
||||
const char *dma_chan_name, unsigned int dma_queue_id);
|
||||
int netcp_txpipe_open(struct netcp_tx_pipe *tx_pipe);
|
||||
int netcp_txpipe_close(struct netcp_tx_pipe *tx_pipe);
|
||||
|
||||
typedef int netcp_hook_rtn(int order, void *data, struct netcp_packet *packet);
|
||||
int netcp_register_txhook(struct netcp_intf *netcp_priv, int order,
|
||||
netcp_hook_rtn *hook_rtn, void *hook_data);
|
||||
int netcp_unregister_txhook(struct netcp_intf *netcp_priv, int order,
|
||||
netcp_hook_rtn *hook_rtn, void *hook_data);
|
||||
int netcp_register_rxhook(struct netcp_intf *netcp_priv, int order,
|
||||
netcp_hook_rtn *hook_rtn, void *hook_data);
|
||||
int netcp_unregister_rxhook(struct netcp_intf *netcp_priv, int order,
|
||||
netcp_hook_rtn *hook_rtn, void *hook_data);
|
||||
void *netcp_device_find_module(struct netcp_device *netcp_device,
|
||||
const char *name);
|
||||
|
||||
/* SGMII functions */
|
||||
int netcp_sgmii_reset(void __iomem *sgmii_ofs, int port);
|
||||
int netcp_sgmii_get_port_link(void __iomem *sgmii_ofs, int port);
|
||||
int netcp_sgmii_config(void __iomem *sgmii_ofs, int port, u32 interface);
|
||||
|
||||
/* XGBE SERDES init functions */
|
||||
int netcp_xgbe_serdes_init(void __iomem *serdes_regs, void __iomem *xgbe_regs);
|
||||
|
||||
#endif /* __NETCP_H__ */
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue