Commit 1dbe1369 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'sxgbe'

Byungho An says:

This is 14th posting for SAMSUNG SXGBE driver.

Changes since v1:
- changed name of driver to SXGbE as per Ben's comment
- squashed Joe's neatening for many stuff in original patches

Changes since v2:
- updated and split binding document as per Mark's comment
- clean up codes as per Joe's comment
- removed unused fields and clean up codes as per Francois's comment
- removed module parameters as per Dave's comment
- moved driver directory to samsung/sxgbe/

Changes since v3:
- fixed Missing a blank line after declarations as per Dave's comment
- clean up codes as per Joe's comment
- removed reference of net_device.{irq, base_addr} as per Francois's comment

Changes since v4:
- updated binding document and DT related function as per Mark's comment

Changes since v5:
- updated binding document and DT related function as per Florian's comment
- fixed typo and shortened code as per Joe's comment

Changes since v6:
- updated TSO related functions as per Rayagond's comment
- updated binding document as per Mark's comment
- removed WoL patch from this patch set

Changes since v7:
- updated TSO related functions as per Rayagond's comment

Changes since v8:
- removed select and depends statement from vendor sub-section as per
  Dave's comment

Changes since v9:
- removed adv-add-map, force-sf-dma-modei and force-thresh-dma-mode from
  binding documnet as per Mark's comment

Changes since v10:
- clean up codes as per Francois's comment

Changes since v11:
- clean up mdio_read/write codes as per Francois's comment
- changed irq acquisition error path as per Francois's comment
- updated mdio and platform related codes as per Tomasz'comment
- clean up dma related codes as per Vince's comment

Changes since v12:
- fixed typo

Changes since v13:
- clean up error path codes for irqs as per Francois's comment
- removed unsupported functions for ehttoolirq as per Ben's comment
Signed-off-by: default avatarDavid S. Miller <>
parents fcb144b5 66890ed6
* Samsung 10G Ethernet driver (SXGBE)
Required properties:
- compatible: Should be "samsung,sxgbe-v2.0a"
- reg: Address and length of the register set for the device
- interrupt-parent: Should be the phandle for the interrupt controller
that services interrupts for this device
- interrupts: Should contain the SXGBE interrupts
These interrupts are ordered by fixed and follows variable
trasmit DMA interrupts, receive DMA interrupts and lpi interrupt.
index 0 - this is fixed common interrupt of SXGBE and it is always
index 1 to 25 - 8 variable trasmit interrupts, variable 16 receive interrupts
and 1 optional lpi interrupt.
- phy-mode: String, operation mode of the PHY interface.
Supported values are: "sgmii", "xgmii".
- samsung,pbl: Integer, Programmable Burst Length.
Supported values are 1, 2, 4, 8, 16, or 32.
- samsung,burst-map: Integer, Program the possible bursts supported by sxgbe
This is an interger and represents allowable DMA bursts when fixed burst.
Allowable range is 0x01-0x3F. When this field is set fixed burst is enabled.
When fixed length is needed for burst mode, it can be set within allowable
Optional properties:
- mac-address: 6 bytes, mac address
- max-frame-size: Maximum Transfer Unit (IEEE defined MTU), rather
than the maximum frame size.
aliases {
ethernet0 = <&sxgbe0>;
sxgbe0: ethernet@1a040000 {
compatible = "samsung,sxgbe-v2.0a";
reg = <0 0x1a040000 0 0x10000>;
interrupt-parent = <&gic>;
interrupts = <0 209 4>, <0 185 4>, <0 186 4>, <0 187 4>,
<0 188 4>, <0 189 4>, <0 190 4>, <0 191 4>,
<0 192 4>, <0 193 4>, <0 194 4>, <0 195 4>,
<0 196 4>, <0 197 4>, <0 198 4>, <0 199 4>,
<0 200 4>, <0 201 4>, <0 202 4>, <0 203 4>,
<0 204 4>, <0 205 4>, <0 206 4>, <0 207 4>,
<0 208 4>, <0 210 4>;
samsung,pbl = <0x08>
samsung,burst-map = <0x20>
mac-address = [ 00 11 22 33 44 55 ]; /* Filled in by U-Boot */
max-frame-size = <9000>;
phy-mode = "xgmii";
......@@ -7550,6 +7550,15 @@ S: Supported
L: (moderated for non-subscribers)
F: drivers/clk/samsung/
M: Byungho An <>
M: Girish K S <>
M: Siva Reddy Kallam <>
M: Vipul Pandya <>
S: Supported
F: drivers/net/ethernet/samsung/sxgbe/
M: Greg Kroah-Hartman <>
......@@ -150,6 +150,7 @@ config S6GMAC
To compile this driver as a module, choose M here. The module
will be called s6gmac.
source "drivers/net/ethernet/samsung/Kconfig"
source "drivers/net/ethernet/seeq/Kconfig"
source "drivers/net/ethernet/silan/Kconfig"
source "drivers/net/ethernet/sis/Kconfig"
......@@ -61,6 +61,7 @@ obj-$(CONFIG_NET_VENDOR_REALTEK) += realtek/
obj-$(CONFIG_SH_ETH) += renesas/
obj-$(CONFIG_NET_VENDOR_RDC) += rdc/
obj-$(CONFIG_S6GMAC) += s6gmac.o
obj-$(CONFIG_NET_VENDOR_SAMSUNG) += samsung/
obj-$(CONFIG_NET_VENDOR_SEEQ) += seeq/
obj-$(CONFIG_NET_VENDOR_SILAN) += silan/
obj-$(CONFIG_NET_VENDOR_SIS) += sis/
# Samsung Ethernet device configuration
bool "Samsung Ethernet device"
default y
This is the driver for the SXGBE 10G Ethernet IP block found on Samsung
source "drivers/net/ethernet/samsung/sxgbe/Kconfig"
# Makefile for the Samsung Ethernet device drivers.
obj-$(CONFIG_SXGBE_ETH) += sxgbe/
config SXGBE_ETH
tristate "Samsung 10G/2.5G/1G SXGBE Ethernet driver"
depends on HAS_IOMEM && HAS_DMA
select PHYLIB
select CRC32
select PTP_1588_CLOCK
This is the driver for the SXGBE 10G Ethernet IP block found on Samsung
obj-$(CONFIG_SXGBE_ETH) += samsung-sxgbe.o
samsung-sxgbe-objs:= sxgbe_platform.o sxgbe_main.o sxgbe_desc.o \
sxgbe_dma.o sxgbe_core.o sxgbe_mtl.o sxgbe_mdio.o \
sxgbe_ethtool.o sxgbe_xpcs.o $(samsung-sxgbe-y)
/* 10G controller driver for Samsung SoCs
* Copyright (C) 2013 Samsung Electronics Co., Ltd.
* Author: Siva Reddy Kallam <>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
#ifndef __SXGBE_COMMON_H__
#define __SXGBE_COMMON_H__
/* forward references */
struct sxgbe_desc_ops;
struct sxgbe_dma_ops;
struct sxgbe_mtl_ops;
#define SXGBE_RESOURCE_NAME "sam_sxgbeeth"
#define DRV_MODULE_VERSION "November_2013"
/* MAX HW feature words */
#define SXGBE_HW_WORDS 3
/* CSR Frequency Access Defines*/
#define SXGBE_CSR_F_150M 150000000
#define SXGBE_CSR_F_250M 250000000
#define SXGBE_CSR_F_300M 300000000
#define SXGBE_CSR_F_350M 350000000
#define SXGBE_CSR_F_400M 400000000
#define SXGBE_CSR_F_500M 500000000
/* pause time */
#define SXGBE_PAUSE_TIME 0x200
/* tx queues */
#define SXGBE_RX_QUEUES 16
/* Calculated based how much time does it take to fill 256KB Rx memory
* at 10Gb speed at 156MHz clock rate and considered little less then
* the actual value.
#define SXGBE_MAX_DMA_RIWT 0x70
#define SXGBE_MIN_DMA_RIWT 0x01
/* Tx coalesce parameters */
#define SXGBE_COAL_TX_TIMER 40000
#define SXGBE_MAX_COAL_TX_TICK 100000
#define SXGBE_TX_FRAMES 128
/* SXGBE TX FIFO is 8K, Rx FIFO is 16K */
#define BUF_SIZE_16KiB 16384
#define BUF_SIZE_8KiB 8192
#define BUF_SIZE_4KiB 4096
#define BUF_SIZE_2KiB 2048
/* Flow Control defines */
#define SXGBE_FLOW_OFF 0
#define SXGBE_FLOW_RX 1
#define SXGBE_FLOW_TX 2
#define SF_DMA_MODE 1 /* DMA STORE-AND-FORWARD Operation Mode */
/* errors */
#define RX_GMII_ERR 0x01
#define RX_WATCHDOG_ERR 0x02
#define RX_CRC_ERR 0x03
#define RX_GAINT_ERR 0x04
#define RX_IP_HDR_ERR 0x05
#define RX_PAYLOAD_ERR 0x06
#define RX_OVERFLOW_ERR 0x07
/* pkt type */
#define RX_LEN_PKT 0x00
#define RX_MACCTL_PKT 0x01
#define RX_DCBCTL_PKT 0x02
#define RX_ARP_PKT 0x03
#define RX_OAM_PKT 0x04
#define RX_UNTAG_PKT 0x05
#define RX_OTHER_PKT 0x07
#define RX_SVLAN_PKT 0x08
#define RX_CVLAN_PKT 0x09
#define RX_NOT_IP_PKT 0x00
#define RX_IPV4_TCP_PKT 0x01
#define RX_IPV4_UDP_PKT 0x02
#define RX_IPV4_ICMP_PKT 0x03
#define RX_IPV4_UNKNOWN_PKT 0x07
#define RX_IPV6_TCP_PKT 0x09
#define RX_IPV6_UDP_PKT 0x0A
#define RX_IPV6_ICMP_PKT 0x0B
#define RX_IPV6_UNKNOWN_PKT 0x0F
#define RX_NO_PTP 0x00
#define RX_PTP_SYNC 0x01
#define RX_PTP_FOLLOW_UP 0x02
#define RX_PTP_DELAY_REQ 0x03
#define RX_PTP_DELAY_RESP 0x04
#define RX_PTP_PDELAY_REQ 0x05
#define RX_PTP_PDELAY_RESP 0x06
#define RX_PTP_ANNOUNCE 0x08
#define RX_PTP_MGMT 0x09
#define RX_PTP_SIGNAL 0x0A
#define RX_PTP_RESV_MSG 0x0F
/* EEE-LPI mode flags*/
#define TX_ENTRY_LPI_MODE 0x10
#define TX_EXIT_LPI_MODE 0x20
#define RX_ENTRY_LPI_MODE 0x40
#define RX_EXIT_LPI_MODE 0x80
/* EEE-LPI Interrupt status flag */
/* EEE-LPI Default timer values */
#define LPI_MAC_WAIT_TIMER 0x00
/* EEE-LPI Control and status definitions */
enum dma_irq_status {
tx_hard_error = BIT(0),
tx_bump_tc = BIT(1),
handle_tx = BIT(2),
rx_hard_error = BIT(3),
rx_bump_tc = BIT(4),
handle_rx = BIT(5),
/* MMC control defines */
#define SXGBE_MMC_CTRL_CNT_FRZ 0x00000008
/* SXGBE HW ADDR regs */
#define SXGBE_ADDR_HIGH(reg) (((reg > 15) ? 0x00000800 : 0x00000040) + \
(reg * 8))
#define SXGBE_ADDR_LOW(reg) (((reg > 15) ? 0x00000804 : 0x00000044) + \
(reg * 8))
#define SXGBE_MAX_PERFECT_ADDRESSES 32 /* Maximum unicast perfect filtering */
#define SXGBE_FRAME_FILTER 0x00000004 /* Frame Filter */
/* SXGBE Frame Filter defines */
#define SXGBE_FRAME_FILTER_PR 0x00000001 /* Promiscuous Mode */
#define SXGBE_FRAME_FILTER_HUC 0x00000002 /* Hash Unicast */
#define SXGBE_FRAME_FILTER_HMC 0x00000004 /* Hash Multicast */
#define SXGBE_FRAME_FILTER_DAIF 0x00000008 /* DA Inverse Filtering */
#define SXGBE_FRAME_FILTER_PM 0x00000010 /* Pass all multicast */
#define SXGBE_FRAME_FILTER_DBF 0x00000020 /* Disable Broadcast frames */
#define SXGBE_FRAME_FILTER_SAIF 0x00000100 /* Inverse Filtering */
#define SXGBE_FRAME_FILTER_SAF 0x00000200 /* Source Address Filter */
#define SXGBE_FRAME_FILTER_HPF 0x00000400 /* Hash or perfect Filter */
#define SXGBE_FRAME_FILTER_RA 0x80000000 /* Receive all mode */
#define SXGBE_HASH_HIGH 0x00000008 /* Multicast Hash Table High */
#define SXGBE_HASH_LOW 0x0000000c /* Multicast Hash Table Low */
#define SXGBE_HI_REG_AE 0x80000000
/* Minimum and maximum MTU */
#define MIN_MTU 68
#define MAX_MTU 9000
#define SXGBE_FOR_EACH_QUEUE(max_queues, queue_num) \
for (queue_num = 0; queue_num < max_queues; queue_num++)
#define DRV_VERSION "1.0.0"
#define START_MAC_REG_OFFSET 0x0000
#define START_MTL_REG_OFFSET 0x1000
#define START_DMA_REG_OFFSET 0x3000
#define REG_SPACE_SIZE 0x2000
/* sxgbe statistics counters */
struct sxgbe_extra_stats {
/* TX/RX IRQ events */
unsigned long tx_underflow_irq;
unsigned long tx_process_stopped_irq;
unsigned long tx_ctxt_desc_err;
unsigned long tx_threshold;
unsigned long rx_threshold;
unsigned long tx_pkt_n;
unsigned long rx_pkt_n;
unsigned long normal_irq_n;
unsigned long tx_normal_irq_n;
unsigned long rx_normal_irq_n;
unsigned long napi_poll;
unsigned long tx_clean;
unsigned long tx_reset_ic_bit;
unsigned long rx_process_stopped_irq;
unsigned long rx_underflow_irq;
/* Bus access errors */
unsigned long fatal_bus_error_irq;
unsigned long tx_read_transfer_err;
unsigned long tx_write_transfer_err;
unsigned long tx_desc_access_err;
unsigned long tx_buffer_access_err;
unsigned long tx_data_transfer_err;
unsigned long rx_read_transfer_err;
unsigned long rx_write_transfer_err;
unsigned long rx_desc_access_err;
unsigned long rx_buffer_access_err;
unsigned long rx_data_transfer_err;
/* EEE-LPI stats */
unsigned long tx_lpi_entry_n;
unsigned long tx_lpi_exit_n;
unsigned long rx_lpi_entry_n;
unsigned long rx_lpi_exit_n;
unsigned long eee_wakeup_error_n;
/* RX specific */
/* L2 error */
unsigned long rx_code_gmii_err;
unsigned long rx_watchdog_err;
unsigned long rx_crc_err;
unsigned long rx_gaint_pkt_err;
unsigned long ip_hdr_err;
unsigned long ip_payload_err;
unsigned long overflow_error;
/* L2 Pkt type */
unsigned long len_pkt;
unsigned long mac_ctl_pkt;
unsigned long dcb_ctl_pkt;
unsigned long arp_pkt;
unsigned long oam_pkt;
unsigned long untag_okt;
unsigned long other_pkt;
unsigned long svlan_tag_pkt;
unsigned long cvlan_tag_pkt;
unsigned long dvlan_ocvlan_icvlan_pkt;
unsigned long dvlan_osvlan_isvlan_pkt;
unsigned long dvlan_osvlan_icvlan_pkt;
unsigned long dvan_ocvlan_icvlan_pkt;
/* L3/L4 Pkt type */
unsigned long not_ip_pkt;
unsigned long ip4_tcp_pkt;
unsigned long ip4_udp_pkt;
unsigned long ip4_icmp_pkt;
unsigned long ip4_unknown_pkt;
unsigned long ip6_tcp_pkt;
unsigned long ip6_udp_pkt;
unsigned long ip6_icmp_pkt;
unsigned long ip6_unknown_pkt;
/* Filter specific */
unsigned long vlan_filter_match;
unsigned long sa_filter_fail;
unsigned long da_filter_fail;
unsigned long hash_filter_pass;
unsigned long l3_filter_match;
unsigned long l4_filter_match;
/* RX context specific */
unsigned long timestamp_dropped;
unsigned long rx_msg_type_no_ptp;
unsigned long rx_ptp_type_sync;
unsigned long rx_ptp_type_follow_up;
unsigned long rx_ptp_type_delay_req;
unsigned long rx_ptp_type_delay_resp;
unsigned long rx_ptp_type_pdelay_req;
unsigned long rx_ptp_type_pdelay_resp;
unsigned long rx_ptp_type_pdelay_follow_up;
unsigned long rx_ptp_announce;
unsigned long rx_ptp_mgmt;
unsigned long rx_ptp_signal;
unsigned long rx_ptp_resv_msg_type;
struct mac_link {
int port;
int duplex;
int speed;
struct mii_regs {
unsigned int addr; /* MII Address */
unsigned int data; /* MII Data */
struct sxgbe_core_ops {
/* MAC core initialization */
void (*core_init)(void __iomem *ioaddr);
/* Dump MAC registers */
void (*dump_regs)(void __iomem *ioaddr);
/* Handle extra events on specific interrupts hw dependent */
int (*host_irq_status)(void __iomem *ioaddr,
struct sxgbe_extra_stats *x);
/* Set power management mode (e.g. magic frame) */
void (*pmt)(void __iomem *ioaddr, unsigned long mode);
/* Set/Get Unicast MAC addresses */
void (*set_umac_addr)(void __iomem *ioaddr, unsigned char *addr,
unsigned int reg_n);
void (*get_umac_addr)(void __iomem *ioaddr, unsigned char *addr,
unsigned int reg_n);
void (*enable_rx)(void __iomem *ioaddr, bool enable);
void (*enable_tx)(void __iomem *ioaddr, bool enable);
/* controller version specific operations */
int (*get_controller_version)(void __iomem *ioaddr);
/* If supported then get the optional core features */
unsigned int (*get_hw_feature)(void __iomem *ioaddr,
unsigned char feature_index);
/* adjust SXGBE speed */
void (*set_speed)(void __iomem *ioaddr, unsigned char speed);
/* EEE-LPI specific operations */
void (*set_eee_mode)(void __iomem *ioaddr);
void (*reset_eee_mode)(void __iomem *ioaddr);
void (*set_eee_timer)(void __iomem *ioaddr, const int ls,
const int tw);
void (*set_eee_pls)(void __iomem *ioaddr, const int link);
/* Enable disable checksum offload operations */
void (*enable_rx_csum)(void __iomem *ioaddr);
void (*disable_rx_csum)(void __iomem *ioaddr);
const struct sxgbe_core_ops *sxgbe_get_core_ops(void);
struct sxgbe_ops {
const struct sxgbe_core_ops *mac;
const struct sxgbe_desc_ops *desc;
const struct sxgbe_dma_ops *dma;
const struct sxgbe_mtl_ops *mtl;
struct mii_regs mii; /* MII register Addresses */
struct mac_link link;
unsigned int ctrl_uid;
unsigned int ctrl_id;
/* SXGBE private data structures */
struct sxgbe_tx_queue {
unsigned int irq_no;
struct sxgbe_priv_data *priv_ptr;
struct sxgbe_tx_norm_desc *dma_tx;
dma_addr_t dma_tx_phy;
dma_addr_t *tx_skbuff_dma;
struct sk_buff **tx_skbuff;
struct timer_list txtimer;
spinlock_t tx_lock; /* lock for tx queues */
unsigned int cur_tx;
unsigned int dirty_tx;
u32 tx_count_frames;
u32 tx_coal_frames;
u32 tx_coal_timer;
int hwts_tx_en;
u16 prev_mss;
u8 queue_no;
struct sxgbe_rx_queue {
struct sxgbe_priv_data *priv_ptr;
struct sxgbe_rx_norm_desc *dma_rx;
struct sk_buff **rx_skbuff;
unsigned int cur_rx;
unsigned int dirty_rx;
unsigned int irq_no;
u32 rx_riwt;
dma_addr_t *rx_skbuff_dma;
dma_addr_t dma_rx_phy;
u8 queue_no;
/* SXGBE HW capabilities */
struct sxgbe_hw_features {
/****** CAP [0] *******/
unsigned int pmt_remote_wake_up;
unsigned int pmt_magic_frame;
/* IEEE 1588-2008 */
unsigned int atime_stamp;
unsigned int eee;
unsigned int tx_csum_offload;
unsigned int rx_csum_offload;
unsigned int multi_macaddr;
unsigned int tstamp_srcselect;
unsigned int sa_vlan_insert;
/****** CAP [1] *******/
unsigned int rxfifo_size;
unsigned int txfifo_size;
unsigned int atstmap_hword;
unsigned int dcb_enable;
unsigned int splithead_enable;
unsigned int tcpseg_offload;
unsigned int debug_mem;
unsigned int rss_enable;
unsigned int hash_tsize;
unsigned int l3l4_filer_size;
/* This value is in bytes and
* as mentioned in HW features
* of SXGBE data book
unsigned int rx_mtl_qsize;
unsigned int tx_mtl_qsize;
/****** CAP [2] *******/
/* TX and RX number of channels */
unsigned int rx_mtl_queues;
unsigned int tx_mtl_queues;
unsigned int rx_dma_channels;
unsigned int tx_dma_channels;
unsigned int pps_output_count;
unsigned int aux_input_count;
struct sxgbe_priv_data {
/* DMA descriptos */
struct sxgbe_tx_queue *txq[SXGBE_TX_QUEUES];
struct sxgbe_rx_queue *rxq[SXGBE_RX_QUEUES];
u8 cur_rx_qnum;
unsigned int dma_tx_size;
unsigned int dma_rx_size;
unsigned int dma_buf_sz;
u32 rx_riwt;
struct napi_struct napi;
void __iomem *ioaddr;
struct net_device *dev;
struct device *device;
struct sxgbe_ops *hw; /* sxgbe specific ops */
int no_csum_insertion;
int irq;
int rxcsum_insertion;
spinlock_t stats_lock; /* lock for tx/rx statatics */
struct phy_device *phydev;
int oldlink;
int speed;
int oldduplex;
struct mii_bus *mii;
int mii_irq[PHY_MAX_ADDR];
u8 rx_pause