<commit_before>/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2009-2012 Cavium, Inc
 */

#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/etherdevice.h>
#include <linux/capability.h>
#include <linux/net_tstamp.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/spinlock.h>
#include <linux/if_vlan.h>
#include <linux/of_mdio.h>
#include <linux/module.h>
#include <linux/of_net.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/phy.h>
#include <linux/io.h>

#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-mixx-defs.h>
#include <asm/octeon/cvmx-agl-defs.h>

#define DRV_NAME "octeon_mgmt"
#define DRV_VERSION "2.0"
#define DRV_DESCRIPTION \
	"Cavium Networks Octeon MII (management) port Network Driver"

#define OCTEON_MGMT_NAPI_WEIGHT 16

/*
 * Ring sizes that are powers of two allow for more efficient modulo
 * opertions.
 */
#define OCTEON_MGMT_RX_RING_SIZE 512
#define OCTEON_MGMT_TX_RING_SIZE 128

/* Allow 8 bytes for vlan and FCS. */
#define OCTEON_MGMT_RX_HEADROOM (ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN)

union mgmt_port_ring_entry {
	u64 d64;
	struct {
		u64    reserved_62_63:2;
		/* Length of the buffer/packet in bytes */
		u64    len:14;
		/* For TX, signals that the packet should be timestamped */
		u64    tstamp:1;
		/* The RX error code */
		u64    code:7;
#define RING_ENTRY_CODE_DONE 0xf
#define RING_ENTRY_CODE_MORE 0x10
		/* Physical address of the buffer */
		u64    addr:40;
	} s;
};

#define MIX_ORING1	0x0
#define MIX_ORING2	0x8
#define MIX_IRING1	0x10
#define MIX_IRING2	0x18
#define MIX_CTL		0x20
#define MIX_IRHWM	0x28
#define MIX_IRCNT	0x30
#define MIX_ORHWM	0x38
#define MIX_ORCNT	0x40
#define MIX_ISR		0x48
#define MIX_INTENA	0x50
#define MIX_REMCNT	0x58
#define MIX_BIST	0x78

#define AGL_GMX_PRT_CFG			0x10
#define AGL_GMX_RX_FRM_CTL		0x18
#define AGL_GMX_RX_FRM_MAX		0x30
#define AGL_GMX_RX_JABBER		0x38
#define AGL_GMX_RX_STATS_CTL		0x50

#define AGL_GMX_RX_STATS_PKTS_DRP	0xb0
#define AGL_GMX_RX_STATS_OCTS_DRP	0xb8
#define AGL_GMX_RX_STATS_PKTS_BAD	0xc0

#define AGL_GMX_RX_ADR_CTL		0x100
#define AGL_GMX_RX_ADR_CAM_EN		0x108
#define AGL_GMX_RX_ADR_CAM0		0x180
#define AGL_GMX_RX_ADR_CAM1		0x188
#define AGL_GMX_RX_ADR_CAM2		0x190
#define AGL_GMX_RX_ADR_CAM3		0x198
#define AGL_GMX_RX_ADR_CAM4		0x1a0
#define AGL_GMX_RX_ADR_CAM5		0x1a8

#define AGL_GMX_TX_CLK			0x208
#define AGL_GMX_TX_STATS_CTL		0x268
#define AGL_GMX_TX_CTL			0x270
#define AGL_GMX_TX_STAT0		0x280
#define AGL_GMX_TX_STAT1		0x288
#define AGL_GMX_TX_STAT2		0x290
#define AGL_GMX_TX_STAT3		0x298
#define AGL_GMX_TX_STAT4		0x2a0
#define AGL_GMX_TX_STAT5		0x2a8
#define AGL_GMX_TX_STAT6		0x2b0
#define AGL_GMX_TX_STAT7		0x2b8
#define AGL_GMX_TX_STAT8		0x2c0
#define AGL_GMX_TX_STAT9		0x2c8

struct octeon_mgmt {
	struct net_device *netdev;
	u64 mix;
	u64 agl;
	u64 agl_prt_ctl;
	int port;
	int irq;
	bool has_rx_tstamp;
	u64 *tx_ring;
	dma_addr_t tx_ring_handle;
	unsigned int tx_next;
	unsigned int tx_next_clean;
	unsigned int tx_current_fill;
	/* The tx_list lock also protects the ring related variables */
	struct sk_buff_head tx_list;

	/* RX variables only touched in napi_poll.  No locking necessary. */
	u64 *rx_ring;
	dma_addr_t rx_ring_handle;
	unsigned int rx_next;
	unsigned int rx_next_fill;
	unsigned int rx_current_fill;
	struct sk_buff_head rx_list;

	spinlock_t lock;
	unsigned int last_duplex;
	unsigned int last_link;
	unsigned int last_speed;
	struct device *dev;
	struct napi_struct napi;
	struct tasklet_struct tx_clean_tasklet;
	struct phy_device *phydev;
	struct device_node *phy_np;
	resource_size_t mix_phys;
	resource_size_t mix_size;
	resource_size_t agl_phys;
	resource_size_t agl_size;
	resource_size_t agl_prt_ctl_phys;
	resource_size_t agl_prt_ctl_size;
};

static void octeon_mgmt_set_rx_irq(struct octeon_mgmt *p, int enable)
{
	union cvmx_mixx_intena mix_intena;
	unsigned long flags;

	spin_lock_irqsave(&p->lock, flags);
	mix_intena.u64 = cvmx_read_csr(p->mix + MIX_INTENA);
	mix_intena.s.ithena = enable ? 1 : 0;
	cvmx_write_csr(p->mix + MIX_INTENA, mix_intena.u64);
	spin_unlock_irqrestore(&p->lock, flags);
}

static void octeon_mgmt_set_tx_irq(struct octeon_mgmt *p, int enable)
{
	union cvmx_mixx_intena mix_intena;
	unsigned long flags;

	spin_lock_irqsave(&p->lock, flags);
	mix_intena.u64 = cvmx_read_csr(p->mix + MIX_INTENA);
	mix_intena.s.othena = enable ? 1 : 0;
	cvmx_write_csr(p->mix + MIX_INTENA, mix_intena.u64);
	spin_unlock_irqrestore(&p->lock, flags);
}

static inline void octeon_mgmt_enable_rx_irq(struct octeon_mgmt *p)
{
	octeon_mgmt_set_rx_irq(p, 1);
}

static inline void octeon_mgmt_disable_rx_irq(struct octeon_mgmt *p)
{
	octeon_mgmt_set_rx_irq(p, 0);
}

static inline void octeon_mgmt_enable_tx_irq(struct octeon_mgmt *p)
{
	octeon_mgmt_set_tx_irq(p, 1);
}

static inline void octeon_mgmt_disable_tx_irq(struct octeon_mgmt *p)
{
	octeon_mgmt_set_tx_irq(p, 0);
}

static unsigned int ring_max_fill(unsigned int ring_size)
{
	return ring_size - 8;
}

static unsigned int ring_size_to_bytes(unsigned int ring_size)
{
	return ring_size * sizeof(union mgmt_port_ring_entry);
}

static void octeon_mgmt_rx_fill_ring(struct net_device *netdev)
{
	struct octeon_mgmt *p = netdev_priv(netdev);

	while (p->rx_current_fill < ring_max_fill(OCTEON_MGMT_RX_RING_SIZE)) {
		unsigned int size;<commit_msg>netdev: octeon_mgmt: Remove some useless 'inline'<commit_after>/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2009-2012 Cavium, Inc
 */

#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/etherdevice.h>
#include <linux/capability.h>
#include <linux/net_tstamp.h>
#include <linux/interrupt.h>
#include <linux/netdevice.h>
#include <linux/spinlock.h>
#include <linux/if_vlan.h>
#include <linux/of_mdio.h>
#include <linux/module.h>
#include <linux/of_net.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/phy.h>
#include <linux/io.h>

#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-mixx-defs.h>
#include <asm/octeon/cvmx-agl-defs.h>

#define DRV_NAME "octeon_mgmt"
#define DRV_VERSION "2.0"
#define DRV_DESCRIPTION \
	"Cavium Networks Octeon MII (management) port Network Driver"

#define OCTEON_MGMT_NAPI_WEIGHT 16

/*
 * Ring sizes that are powers of two allow for more efficient modulo
 * opertions.
 */
#define OCTEON_MGMT_RX_RING_SIZE 512
#define OCTEON_MGMT_TX_RING_SIZE 128

/* Allow 8 bytes for vlan and FCS. */
#define OCTEON_MGMT_RX_HEADROOM (ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN)

union mgmt_port_ring_entry {
	u64 d64;
	struct {
		u64    reserved_62_63:2;
		/* Length of the buffer/packet in bytes */
		u64    len:14;
		/* For TX, signals that the packet should be timestamped */
		u64    tstamp:1;
		/* The RX error code */
		u64    code:7;
#define RING_ENTRY_CODE_DONE 0xf
#define RING_ENTRY_CODE_MORE 0x10
		/* Physical address of the buffer */
		u64    addr:40;
	} s;
};

#define MIX_ORING1	0x0
#define MIX_ORING2	0x8
#define MIX_IRING1	0x10
#define MIX_IRING2	0x18
#define MIX_CTL		0x20
#define MIX_IRHWM	0x28
#define MIX_IRCNT	0x30
#define MIX_ORHWM	0x38
#define MIX_ORCNT	0x40
#define MIX_ISR		0x48
#define MIX_INTENA	0x50
#define MIX_REMCNT	0x58
#define MIX_BIST	0x78

#define AGL_GMX_PRT_CFG			0x10
#define AGL_GMX_RX_FRM_CTL		0x18
#define AGL_GMX_RX_FRM_MAX		0x30
#define AGL_GMX_RX_JABBER		0x38
#define AGL_GMX_RX_STATS_CTL		0x50

#define AGL_GMX_RX_STATS_PKTS_DRP	0xb0
#define AGL_GMX_RX_STATS_OCTS_DRP	0xb8
#define AGL_GMX_RX_STATS_PKTS_BAD	0xc0

#define AGL_GMX_RX_ADR_CTL		0x100
#define AGL_GMX_RX_ADR_CAM_EN		0x108
#define AGL_GMX_RX_ADR_CAM0		0x180
#define AGL_GMX_RX_ADR_CAM1		0x188
#define AGL_GMX_RX_ADR_CAM2		0x190
#define AGL_GMX_RX_ADR_CAM3		0x198
#define AGL_GMX_RX_ADR_CAM4		0x1a0
#define AGL_GMX_RX_ADR_CAM5		0x1a8

#define AGL_GMX_TX_CLK			0x208
#define AGL_GMX_TX_STATS_CTL		0x268
#define AGL_GMX_TX_CTL			0x270
#define AGL_GMX_TX_STAT0		0x280
#define AGL_GMX_TX_STAT1		0x288
#define AGL_GMX_TX_STAT2		0x290
#define AGL_GMX_TX_STAT3		0x298
#define AGL_GMX_TX_STAT4		0x2a0
#define AGL_GMX_TX_STAT5		0x2a8
#define AGL_GMX_TX_STAT6		0x2b0
#define AGL_GMX_TX_STAT7		0x2b8
#define AGL_GMX_TX_STAT8		0x2c0
#define AGL_GMX_TX_STAT9		0x2c8

struct octeon_mgmt {
	struct net_device *netdev;
	u64 mix;
	u64 agl;
	u64 agl_prt_ctl;
	int port;
	int irq;
	bool has_rx_tstamp;
	u64 *tx_ring;
	dma_addr_t tx_ring_handle;
	unsigned int tx_next;
	unsigned int tx_next_clean;
	unsigned int tx_current_fill;
	/* The tx_list lock also protects the ring related variables */
	struct sk_buff_head tx_list;

	/* RX variables only touched in napi_poll.  No locking necessary. */
	u64 *rx_ring;
	dma_addr_t rx_ring_handle;
	unsigned int rx_next;
	unsigned int rx_next_fill;
	unsigned int rx_current_fill;
	struct sk_buff_head rx_list;

	spinlock_t lock;
	unsigned int last_duplex;
	unsigned int last_link;
	unsigned int last_speed;
	struct device *dev;
	struct napi_struct napi;
	struct tasklet_struct tx_clean_tasklet;
	struct phy_device *phydev;
	struct device_node *phy_np;
	resource_size_t mix_phys;
	resource_size_t mix_size;
	resource_size_t agl_phys;
	resource_size_t agl_size;
	resource_size_t agl_prt_ctl_phys;
	resource_size_t agl_prt_ctl_size;
};

static void octeon_mgmt_set_rx_irq(struct octeon_mgmt *p, int enable)
{
	union cvmx_mixx_intena mix_intena;
	unsigned long flags;

	spin_lock_irqsave(&p->lock, flags);
	mix_intena.u64 = cvmx_read_csr(p->mix + MIX_INTENA);
	mix_intena.s.ithena = enable ? 1 : 0;
	cvmx_write_csr(p->mix + MIX_INTENA, mix_intena.u64);
	spin_unlock_irqrestore(&p->lock, flags);
}

static void octeon_mgmt_set_tx_irq(struct octeon_mgmt *p, int enable)
{
	union cvmx_mixx_intena mix_intena;
	unsigned long flags;

	spin_lock_irqsave(&p->lock, flags);
	mix_intena.u64 = cvmx_read_csr(p->mix + MIX_INTENA);
	mix_intena.s.othena = enable ? 1 : 0;
	cvmx_write_csr(p->mix + MIX_INTENA, mix_intena.u64);
	spin_unlock_irqrestore(&p->lock, flags);
}

static void octeon_mgmt_enable_rx_irq(struct octeon_mgmt *p)
{
	octeon_mgmt_set_rx_irq(p, 1);
}

static void octeon_mgmt_disable_rx_irq(struct octeon_mgmt *p)
{
	octeon_mgmt_set_rx_irq(p, 0);
}

static void octeon_mgmt_enable_tx_irq(struct octeon_mgmt *p)
{
	octeon_mgmt_set_tx_irq(p, 1);
}

static void octeon_mgmt_disable_tx_irq(struct octeon_mgmt *p)
{
	octeon_mgmt_set_tx_irq(p, 0);
}

static unsigned int ring_max_fill(unsigned int ring_size)
{
	return ring_size - 8;
}

static unsigned int ring_size_to_bytes(unsigned int ring_size)
{
	return ring_size * sizeof(union mgmt_port_ring_entry);
}

static void octeon_mgmt_rx_fill_ring(struct net_device *netdev)
{
	struct octeon_mgmt *p = netdev_priv(netdev);

	while (p->rx_current_fill < ring_max_fill(OCTEON_MGMT_RX_RING_SIZE)) {
		unsigned int size;
{'fraction_non_alphanumeric': 0.08114992721979622, 'fraction_numerical': 0.041666666666666664, 'mean_word_length': 5.504733727810651, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3941532', 'n_tokens_mistral': 5219, 'n_tokens_neox': 4923, 'n_words': 1040}