fm10k/src/fm10k.h
2020-10-20 20:08:09 +02:00

1142 lines
30 KiB
C

/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2013 - 2018 Intel Corporation. */
#ifndef _FM10K_H_
#define _FM10K_H_
#include "kcompat.h"
#include <linux/types.h>
#include <linux/etherdevice.h>
#include <linux/cpumask.h>
#include <linux/rtnetlink.h>
#include <linux/if_vlan.h>
#include <linux/pci.h>
#include <linux/uio_driver.h>
#include "fm10k_pf.h"
#include "fm10k_vf.h"
#ifndef SYS_LINK_PROP_DIS
typedef struct _fm10k_dev_mng {
char *name;
char *desc;
struct pci_dev *pdev; /* PCI device */
struct net_device *ndev; /* net device */
unsigned long mem_map;
uint8_t bus;
uint8_t slot;
uint8_t func;
uint8_t bus_p;
uint8_t slot_p;
uint8_t func_p;
u_int32_t device;
u_int32_t vendor;
u_int32_t subvendor;
u_int32_t subdevice;
int ifindex;
spinlock_t bypass_wr_lock;
int port_num;
int sw_num;
int pep;
/* #endif */
} fm10k_dev_mng_t;
typedef struct _fm10k_dev {
char *name;
char *desc;
struct pci_dev *pdev; /* PCI device */
struct net_device *ndev; /* net device */
fm10k_dev_mng_t *pfm10k_dev_c;
struct pci_dev *pdev_mng;
unsigned long mem_map;
uint8_t bus;
uint8_t slot;
uint8_t func;
uint8_t bus_p;
uint8_t slot_p;
uint8_t func_p;
u_int32_t device;
u_int32_t vendor;
u_int32_t subvendor;
u_int32_t subdevice;
int ifindex;
int port_num;
int epl_num;
int epl;
int lane_num;
int sw_num;
int pep;
} fm10k_dev_t;
#endif
#define ETH_P_IES ETH_P_XDSA
#define FM10K_MAX_JUMBO_FRAME_SIZE 15342 /* Maximum supported size 15K */
#define MAX_QUEUES FM10K_MAX_QUEUES_PF
#define FM10K_MIN_RXD 128
#define FM10K_MAX_RXD 4096
#define FM10K_DEFAULT_RXD 256
#define FM10K_MIN_TXD 128
#define FM10K_MAX_TXD 4096
#define FM10K_DEFAULT_TXD 256
#define FM10K_DEFAULT_TX_WORK 256
#define FM10K_RXBUFFER_256 256
#define FM10K_RX_HDR_LEN FM10K_RXBUFFER_256
#define FM10K_RXBUFFER_2048 2048
#define FM10K_RX_BUFSZ FM10K_RXBUFFER_2048
/* How many Rx Buffers do we bundle into one write to the hardware ? */
#define FM10K_RX_BUFFER_WRITE 16 /* Must be power of 2 */
#ifdef NETIF_F_HW_L2FW_DOFFLOAD
#define FM10K_MAX_STATIONS 63
struct fm10k_l2_accel {
int size;
u16 count;
u16 dglort;
struct rcu_head rcu;
struct net_device *macvlan[0];
};
#endif
enum fm10k_ring_state_t {
__FM10K_TX_DETECT_HANG,
__FM10K_HANG_CHECK_ARMED,
__FM10K_TX_XPS_INIT_DONE,
/* This must be last and is used to calculate BITMAP size */
__FM10K_TX_STATE_SIZE__,
};
#define check_for_tx_hang(ring) \
test_bit(__FM10K_TX_DETECT_HANG, (ring)->state)
#define set_check_for_tx_hang(ring) \
set_bit(__FM10K_TX_DETECT_HANG, (ring)->state)
#define clear_check_for_tx_hang(ring) \
clear_bit(__FM10K_TX_DETECT_HANG, (ring)->state)
struct fm10k_tx_buffer {
struct fm10k_tx_desc *next_to_watch;
struct sk_buff *skb;
unsigned int bytecount;
u16 gso_segs;
u16 tx_flags;
DEFINE_DMA_UNMAP_ADDR(dma);
DEFINE_DMA_UNMAP_LEN(len);
};
struct fm10k_rx_buffer {
dma_addr_t dma;
struct page *page;
u32 page_offset;
};
struct fm10k_queue_stats {
u64 packets;
u64 bytes;
};
struct fm10k_tx_queue_stats {
u64 restart_queue;
u64 csum_err;
u64 tx_busy;
u64 tx_done_old;
u64 csum_good;
};
struct fm10k_rx_queue_stats {
u64 alloc_failed;
u64 csum_err;
u64 errors;
u64 csum_good;
u64 switch_errors;
u64 drops;
u64 pp_errors;
u64 link_errors;
u64 length_errors;
};
struct fm10k_ring {
struct fm10k_q_vector *q_vector;/* backpointer to host q_vector */
struct net_device *netdev; /* netdev ring belongs to */
struct device *dev; /* device for DMA mapping */
#ifdef NETIF_F_HW_L2FW_DOFFLOAD
struct fm10k_l2_accel __rcu *l2_accel; /* L2 acceleration list */
#endif
void *desc; /* descriptor ring memory */
union {
struct fm10k_tx_buffer *tx_buffer;
struct fm10k_rx_buffer *rx_buffer;
};
u32 __iomem *tail;
DECLARE_BITMAP(state, __FM10K_TX_STATE_SIZE__);
dma_addr_t dma; /* phys. address of descriptor ring */
unsigned int size; /* length in bytes */
u8 queue_index; /* needed for queue management */
u8 reg_idx; /* holds the special value that gets
* the hardware register offset
* associated with this ring, which is
* different for DCB and RSS modes
*/
u8 qos_pc; /* priority class of queue */
u16 vid; /* default VLAN ID of queue */
u16 count; /* amount of descriptors */
u16 next_to_alloc;
u16 next_to_use;
u16 next_to_clean;
struct fm10k_queue_stats stats;
#ifdef HAVE_NDO_GET_STATS64
struct u64_stats_sync syncp;
#endif
union {
/* Tx */
struct fm10k_tx_queue_stats tx_stats;
/* Rx */
struct {
struct fm10k_rx_queue_stats rx_stats;
struct sk_buff *skb;
};
};
} ____cacheline_internodealigned_in_smp;
struct fm10k_ring_container {
struct fm10k_ring *ring; /* pointer to linked list of rings */
unsigned int total_bytes; /* total bytes processed this int */
unsigned int total_packets; /* total packets processed this int */
u16 work_limit; /* total work allowed per interrupt */
u16 itr; /* interrupt throttle rate value */
u8 itr_scale; /* ITR adjustment based on PCI speed */
u8 count; /* total number of rings in vector */
};
#define FM10K_ITR_MAX 0x0FFF /* maximum value for ITR */
#define FM10K_ITR_10K 100 /* 100us */
#define FM10K_ITR_20K 50 /* 50us */
#define FM10K_ITR_40K 25 /* 25us */
#define FM10K_ITR_ADAPTIVE 0x8000 /* adaptive interrupt moderation flag */
#define ITR_IS_ADAPTIVE(itr) (!!(itr & FM10K_ITR_ADAPTIVE))
#define FM10K_TX_ITR_DEFAULT FM10K_ITR_40K
#define FM10K_RX_ITR_DEFAULT FM10K_ITR_20K
#define FM10K_ITR_ENABLE (FM10K_ITR_AUTOMASK | FM10K_ITR_MASK_CLEAR)
static inline struct netdev_queue *txring_txq(const struct fm10k_ring *ring)
{
return &ring->netdev->_tx[ring->queue_index];
}
/* iterator for handling rings in ring container */
#define fm10k_for_each_ring(pos, head) \
for (pos = &(head).ring[(head).count]; (--pos) >= (head).ring;)
#define MAX_Q_VECTORS 256
#define MIN_Q_VECTORS 1
enum fm10k_non_q_vectors {
FM10K_MBX_VECTOR,
#define NON_Q_VECTORS_VF FM10K_UIO_VECTOR
FM10K_UIO_VECTOR,
NON_Q_VECTORS_PF
};
#define NON_Q_VECTORS(hw) (((hw)->mac.type == fm10k_mac_pf) ? \
NON_Q_VECTORS_PF : \
NON_Q_VECTORS_VF)
#define MIN_MSIX_COUNT(hw) (MIN_Q_VECTORS + NON_Q_VECTORS(hw))
struct fm10k_q_vector {
struct fm10k_intfc *interface;
u32 __iomem *itr; /* pointer to ITR register for this vector */
u16 v_idx; /* index of q_vector within interface array */
struct fm10k_ring_container rx, tx;
struct napi_struct napi;
cpumask_t affinity_mask;
char name[IFNAMSIZ + 9];
#ifdef CONFIG_DEBUG_FS
struct dentry *dbg_q_vector;
#endif /* CONFIG_DEBUG_FS */
struct rcu_head rcu; /* to avoid race with update stats on free */
/* for dynamic allocation of rings associated with this q_vector */
struct fm10k_ring ring[0] ____cacheline_internodealigned_in_smp;
};
enum fm10k_ring_f_enum {
RING_F_RSS,
RING_F_QOS,
RING_F_ARRAY_SIZE /* must be last in enum set */
};
struct fm10k_ring_feature {
u16 limit; /* upper limit on feature indices */
u16 indices; /* current value of indices */
u16 mask; /* Mask used for feature to ring mapping */
u16 offset; /* offset to start of feature */
};
struct fm10k_iov_data {
unsigned int num_vfs;
unsigned int next_vf_mbx;
struct rcu_head rcu;
struct fm10k_vf_info vf_info[0];
};
struct fm10k_udp_port {
struct list_head list;
sa_family_t sa_family;
__be16 port;
};
enum fm10k_macvlan_request_type {
FM10K_UC_MAC_REQUEST,
FM10K_MC_MAC_REQUEST,
FM10K_VLAN_REQUEST
};
struct fm10k_macvlan_request {
enum fm10k_macvlan_request_type type;
struct list_head list;
union {
struct fm10k_mac_request {
u8 addr[ETH_ALEN];
u16 glort;
u16 vid;
} mac;
struct fm10k_vlan_request {
u32 vid;
u8 vsi;
} vlan;
};
bool set;
};
/* one work queue for entire driver */
extern struct workqueue_struct *fm10k_workqueue;
/* The following enumeration contains flags which indicate or enable modified
* driver behaviors. To avoid race conditions, the flags are stored in
* a BITMAP in the fm10k_intfc structure. The BITMAP should be accessed using
* atomic *_bit() operations.
*/
enum fm10k_flags_t {
FM10K_FLAG_RESET_REQUESTED,
FM10K_FLAG_RSS_FIELD_IPV4_UDP,
FM10K_FLAG_RSS_FIELD_IPV6_UDP,
FM10K_FLAG_SWPRI_CONFIG,
#ifndef IFF_RXFH_CONFIGURED
FM10K_FLAG_RXFH_CONFIGURED,
#endif
FM10K_FLAG_UIO_REGISTERED,
FM10K_FLAG_IES_MODE,
/* __FM10K_FLAGS_SIZE__ is used to calculate the size of
* interface->flags and must be the last value in this
* enumeration.
*/
__FM10K_FLAGS_SIZE__
};
enum fm10k_state_t {
__FM10K_RESETTING,
__FM10K_RESET_DETACHED,
__FM10K_RESET_SUSPENDED,
__FM10K_DOWN,
__FM10K_SERVICE_SCHED,
__FM10K_SERVICE_REQUEST,
__FM10K_SERVICE_DISABLE,
__FM10K_MACVLAN_SCHED,
__FM10K_MACVLAN_REQUEST,
__FM10K_MACVLAN_DISABLE,
__FM10K_LINK_DOWN,
__FM10K_UPDATING_STATS,
/* This value must be last and determines the BITMAP size */
__FM10K_STATE_SIZE__,
};
struct fm10k_intfc {
#ifdef HAVE_VLAN_RX_REGISTER
/* vlgrp must be first member of structure */
struct vlan_group *vlgrp;
#endif
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
struct net_device *netdev;
#ifdef NETIF_F_HW_L2FW_DOFFLOAD
struct fm10k_l2_accel *l2_accel; /* pointer to L2 acceleration list */
#endif
struct pci_dev *pdev;
DECLARE_BITMAP(state, __FM10K_STATE_SIZE__);
/* Access flag values using atomic *_bit() operations */
DECLARE_BITMAP(flags, __FM10K_FLAGS_SIZE__);
int xcast_mode;
/* Tx fast path data */
int num_tx_queues;
u16 tx_itr;
/* Rx fast path data */
int num_rx_queues;
u16 rx_itr;
/* TX */
struct fm10k_ring *tx_ring[MAX_QUEUES] ____cacheline_aligned_in_smp;
u64 restart_queue;
u64 tx_busy;
u64 tx_csum_errors;
u64 alloc_failed;
u64 rx_csum_errors;
u64 tx_bytes_nic;
u64 tx_packets_nic;
u64 rx_bytes_nic;
u64 rx_packets_nic;
u64 rx_drops_nic;
u64 rx_overrun_pf;
u64 rx_overrun_vf;
/* Debug Statistics */
u64 hw_sm_mbx_full;
u64 hw_csum_tx_good;
u64 hw_csum_rx_good;
u64 rx_switch_errors;
u64 rx_drops;
u64 rx_pp_errors;
u64 rx_link_errors;
u64 rx_length_errors;
u32 tx_timeout_count;
/* RX */
struct fm10k_ring *rx_ring[MAX_QUEUES];
/* Queueing vectors */
struct fm10k_q_vector *q_vector[MAX_Q_VECTORS];
struct msix_entry *msix_entries;
int num_q_vectors; /* current number of q_vectors for device */
struct fm10k_ring_feature ring_feature[RING_F_ARRAY_SIZE];
/* SR-IOV information management structure */
struct fm10k_iov_data *iov_data;
u16 init_vfs;
struct fm10k_hw_stats stats;
struct fm10k_hw hw;
/* Mailbox lock */
spinlock_t mbx_lock;
u32 __iomem *uc_addr;
u32 __iomem *sw_addr;
u16 msg_enable;
u16 tx_ring_count;
u16 rx_ring_count;
struct timer_list service_timer;
struct work_struct service_task;
unsigned long next_stats_update;
unsigned long next_tx_hang_check;
unsigned long last_reset;
unsigned long link_down_event;
bool host_ready;
#ifndef SYS_LINK_PROP_DIS
bool epl_ready;
bool host_up;
int epl;
int epl_num;
int lane_num;
int epl_port;
int pep_port;
int eth_mode;
int speed;
unsigned long mem_map;
fm10k_dev_t *fm10k_dev;
fm10k_dev_mng_t *fm10k_dev_mng;
struct fm10k_intfc *interface_c;
#endif
bool lport_map_failed;
u32 reta[FM10K_RETA_SIZE];
u32 rssrk[FM10K_RSSRK_SIZE];
/* UDP encapsulation port tracking information */
struct list_head vxlan_port;
struct list_head geneve_port;
/* MAC/VLAN update queue */
struct list_head macvlan_requests;
struct delayed_work macvlan_task;
/* MAC/VLAN update queue lock */
spinlock_t macvlan_lock;
/* UIO device capabilities structure */
struct uio_info uio;
/* UIO irqcontrol task */
struct work_struct uio_task;
/* UIO interrupt setting */
bool uio_int_enable;
#ifdef CONFIG_DEBUG_FS
struct dentry *dbg_intfc;
#endif /* CONFIG_DEBUG_FS */
#ifdef HAVE_DCBNL_IEEE
#ifdef CONFIG_DCB
u8 pfc_en;
#endif
#endif /* HAVE_DCBNL_IEEE */
u8 rx_pause;
/* GLORT resources in use by PF */
u16 glort;
u16 glort_count;
/* VLAN ID for updating multicast/unicast lists */
u16 vid;
};
static inline void fm10k_mbx_lock(struct fm10k_intfc *interface)
{
spin_lock(&interface->mbx_lock);
}
static inline void fm10k_mbx_unlock(struct fm10k_intfc *interface)
{
spin_unlock(&interface->mbx_lock);
}
static inline int fm10k_mbx_trylock(struct fm10k_intfc *interface)
{
return spin_trylock(&interface->mbx_lock);
}
/* fm10k_test_staterr - test bits in Rx descriptor status and error fields */
static inline __le32 fm10k_test_staterr(union fm10k_rx_desc *rx_desc,
const u32 stat_err_bits)
{
return rx_desc->d.staterr & cpu_to_le32(stat_err_bits);
}
/* fm10k_desc_unused - calculate if we have unused descriptors */
static inline u16 fm10k_desc_unused(struct fm10k_ring *ring)
{
s16 unused = ring->next_to_clean - ring->next_to_use - 1;
return likely(unused < 0) ? unused + ring->count : unused;
}
#define FM10K_TX_DESC(R, i) \
(&(((struct fm10k_tx_desc *)((R)->desc))[i]))
#define FM10K_RX_DESC(R, i) \
(&(((union fm10k_rx_desc *)((R)->desc))[i]))
#define FM10K_MAX_TXD_PWR 14
#define FM10K_MAX_DATA_PER_TXD (1u << FM10K_MAX_TXD_PWR)
/* Tx Descriptors needed, worst case */
#define TXD_USE_COUNT(S) DIV_ROUND_UP((S), FM10K_MAX_DATA_PER_TXD)
#if (MAX_SKB_FRAGS < 16)
#define DESC_NEEDED ((MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE)) + 4)
#else
#define DESC_NEEDED (MAX_SKB_FRAGS + 4)
#endif
enum fm10k_tx_flags {
/* Tx offload flags */
FM10K_TX_FLAGS_CSUM = 0x01,
};
struct fm10k_ies {
__be64 ts;
struct fm10k_ftag ftag;
};
/* This structure is stored as little endian values as that is the native
* format of the Rx descriptor. The ordering of these fields is reversed
* from the actual ftag header to allow for a single bswap to take care
* of placing all of the values in network order
*/
union fm10k_ftag_info {
__le64 ftag;
struct {
/* dglort and sglort combined into a single 32bit desc read */
__le32 glort;
/* upper 16 bits of VLAN are reserved 0 for swpri_type_user */
__le32 vlan;
} d;
struct {
__le16 dglort;
__le16 sglort;
__le16 vlan;
__le16 swpri_type_user;
} w;
};
#define FTAG_ZLEN (ETH_ZLEN + sizeof(struct fm10k_ftag))
struct fm10k_cb {
union {
__le64 tstamp;
unsigned long ts_tx_timeout;
};
union fm10k_ftag_info fi;
};
#define FM10K_CB(skb) ((struct fm10k_cb *)(skb)->cb)
/* main */
extern char fm10k_driver_name[];
extern const char fm10k_driver_version[];
int fm10k_init_queueing_scheme(struct fm10k_intfc *interface);
void fm10k_clear_queueing_scheme(struct fm10k_intfc *interface);
#ifdef HAVE_NDO_FEATURES_CHECK
__be16 fm10k_tx_encap_offload(struct sk_buff *skb);
#endif
netdev_tx_t fm10k_xmit_frame_ring(struct sk_buff *skb,
struct fm10k_ring *tx_ring);
void fm10k_tx_timeout_reset(struct fm10k_intfc *interface);
u64 fm10k_get_tx_pending(struct fm10k_ring *ring, bool in_sw);
bool fm10k_check_tx_hang(struct fm10k_ring *tx_ring);
void fm10k_alloc_rx_buffers(struct fm10k_ring *rx_ring, u16 cleaned_count);
/* PCI */
void fm10k_mbx_free_irq(struct fm10k_intfc *);
int fm10k_mbx_request_irq(struct fm10k_intfc *);
void fm10k_qv_free_irq(struct fm10k_intfc *interface);
int fm10k_qv_request_irq(struct fm10k_intfc *interface);
int fm10k_register_pci_driver(void);
void fm10k_unregister_pci_driver(void);
void fm10k_up(struct fm10k_intfc *interface);
void fm10k_down(struct fm10k_intfc *interface);
void fm10k_update_stats(struct fm10k_intfc *interface);
void fm10k_service_event_schedule(struct fm10k_intfc *interface);
void fm10k_macvlan_schedule(struct fm10k_intfc *interface);
void fm10k_update_rx_drop_en(struct fm10k_intfc *interface);
#ifdef CONFIG_NET_POLL_CONTROLLER
void fm10k_netpoll(struct net_device *netdev);
#endif
/* Netdev */
#ifdef HAVE_ENCAP_CSUM_OFFLOAD
struct net_device *fm10k_alloc_netdev(const struct fm10k_info *info);
#else
struct net_device *fm10k_alloc_netdev(void);
#endif
int fm10k_setup_rx_resources(struct fm10k_ring *);
int fm10k_setup_tx_resources(struct fm10k_ring *);
void fm10k_free_rx_resources(struct fm10k_ring *);
void fm10k_free_tx_resources(struct fm10k_ring *);
void fm10k_clean_all_rx_rings(struct fm10k_intfc *);
void fm10k_clean_all_tx_rings(struct fm10k_intfc *);
void fm10k_unmap_and_free_tx_resource(struct fm10k_ring *,
struct fm10k_tx_buffer *);
void fm10k_restore_rx_state(struct fm10k_intfc *);
void fm10k_reset_rx_state(struct fm10k_intfc *);
int fm10k_setup_tc(struct net_device *dev, u8 tc);
int fm10k_open(struct net_device *netdev);
int fm10k_close(struct net_device *netdev);
int ies10k_spi_read_flash(struct fm10k_intfc *interface, int addr, u8 *data, int len, int freq_khz);
int fm10k_queue_vlan_request(struct fm10k_intfc *interface, u32 vid,
u8 vsi, bool set);
int fm10k_queue_mac_request(struct fm10k_intfc *interface, u16 glort,
const unsigned char *addr, u16 vid, bool set);
void fm10k_clear_macvlan_queue(struct fm10k_intfc *interface,
u16 glort, bool vlans);
/* UIO */
#if IS_ENABLED(CONFIG_UIO)
int fm10k_uio_request_irq(struct fm10k_intfc *interface);
void fm10k_uio_free_irq(struct fm10k_intfc *interface);
int fm10k_uio_probe(struct fm10k_intfc *interface);
void fm10k_uio_remove(struct fm10k_intfc *interface);
#else
static inline int fm10k_uio_request_irq(struct fm10k_intfc *intfc) { return 0; }
#define fm10k_uio_free_irq(interface) do {} while (0)
static inline int fm10k_uio_probe(struct fm10k_intfc *interface) { return 0; }
#define fm10k_uio_remove(interface) do {} while (0)
#endif
/* IES */
__be16 ies_type_trans(struct sk_buff *skb);
static inline bool fm10k_is_ies(struct net_device *dev)
{
struct fm10k_intfc *interface = netdev_priv(dev);
return test_bit(FM10K_FLAG_IES_MODE, interface->flags);
}
extern struct packet_type ies_packet_type;
/* Ethtool */
void fm10k_set_ethtool_ops(struct net_device *dev);
void fm10k_write_reta(struct fm10k_intfc *interface, const u32 *indir);
/* Param */
int fm10k_check_options(struct fm10k_intfc *interface);
/* IOV */
s32 fm10k_iov_event(struct fm10k_intfc *interface);
s32 fm10k_iov_mbx(struct fm10k_intfc *interface);
void fm10k_iov_suspend(struct pci_dev *pdev);
int fm10k_iov_resume(struct pci_dev *pdev);
void fm10k_iov_disable(struct pci_dev *pdev);
int fm10k_iov_configure(struct pci_dev *pdev, int num_vfs);
s32 fm10k_iov_update_pvid(struct fm10k_intfc *interface, u16 glort, u16 pvid);
#ifdef IFLA_VF_MAX
int fm10k_ndo_set_vf_mac(struct net_device *netdev, int vf_idx, u8 *mac);
#ifdef IFLA_VF_VLAN_INFO_MAX
int fm10k_ndo_set_vf_vlan(struct net_device *netdev,
int vf_idx, u16 vid, u8 qos, __be16 vlan_proto);
#else
int fm10k_ndo_set_vf_vlan(struct net_device *netdev,
int vf_idx, u16 vid, u8 qos);
#endif
#ifdef HAVE_NDO_SET_VF_MIN_MAX_TX_RATE
int fm10k_ndo_set_vf_bw(struct net_device *netdev, int vf_idx,
int __always_unused min_rate, int max_rate);
#else
int fm10k_ndo_set_vf_bw(struct net_device *netdev, int vf_idx, int max_rate);
#endif
int fm10k_ndo_get_vf_config(struct net_device *netdev,
int vf_idx, struct ifla_vf_info *ivi);
#endif
/* DebugFS */
#ifdef CONFIG_DEBUG_FS
void fm10k_dbg_q_vector_init(struct fm10k_q_vector *q_vector);
void fm10k_dbg_q_vector_exit(struct fm10k_q_vector *q_vector);
void fm10k_dbg_intfc_init(struct fm10k_intfc *interface);
void fm10k_dbg_intfc_exit(struct fm10k_intfc *interface);
void fm10k_dbg_init(void);
void fm10k_dbg_exit(void);
#else
static inline void fm10k_dbg_q_vector_init(struct fm10k_q_vector *q_vector) {}
static inline void fm10k_dbg_q_vector_exit(struct fm10k_q_vector *q_vector) {}
static inline void fm10k_dbg_intfc_init(struct fm10k_intfc *interface) {}
static inline void fm10k_dbg_intfc_exit(struct fm10k_intfc *interface) {}
static inline void fm10k_dbg_init(void) {}
static inline void fm10k_dbg_exit(void) {}
#endif /* CONFIG_DEBUG_FS */
/* DCB */
#ifdef HAVE_DCBNL_IEEE
#ifdef CONFIG_DCB
void fm10k_dcbnl_set_ops(struct net_device *dev);
#else
static inline void fm10k_dcbnl_set_ops(struct net_device *dev) {}
#endif
#endif /* HAVE_DCBNL_IEEE */
#ifndef SYS_LINK_PROP_DIS
enum ies_port_state {
/* NOTE! Order is important. See the table in ies_port_set_state. */
/* The port is in working order (symbol lock, alignment done) and
* ready to receive a frame.
*/
IES_PORT_STATE_UP = 0,
/* Deprecated. Use ''IES_PORT_MODE_ADMIN_DOWN'' instead. */
IES_PORT_STATE_ADMIN_DOWN,
/* Deprecated. Use ''IES_PORT_MODE_ADMIN_PWRDOWN'' instead. */
IES_PORT_STATE_ADMIN_PWRDOWN,
/* Deprecated. Use ''IES_PORT_MODE_BIST'' instead. */
IES_PORT_STATE_BIST,
/* The SERDES transmits remote fault constantly and the receiver is
* disabled.
*/
IES_PORT_STATE_REMOTE_FAULT,
/* Indicates the absence of any signal on any lane. */
IES_PORT_STATE_DOWN,
/* Some lanes have either signal or partial synchronization. */
IES_PORT_STATE_PARTIALLY_UP,
/* Indicates continuous reception of a local fault condition. A remote
* fault is automatically sent continuously.
*/
IES_PORT_STATE_LOCAL_FAULT,
/* Indicates that DFE tuning is still in progress. */
IES_PORT_STATE_DFE_TUNING
};
enum ies_port_mode {
/* NOTE! Order is important. See the table in ies_port_set_state. */
/* The port is in working order (symbol lock, alignment done) and
* ready to receive a frame.
*/
IES_PORT_MODE_UP = IES_PORT_STATE_UP,
/* The port is administratively set down with the SERDES
* transmitting an idle pattern but the receiver disabled.
*/
IES_PORT_MODE_ADMIN_DOWN = IES_PORT_STATE_ADMIN_DOWN,
/* The port is administratively set down with the SERDES
* shut down and no signal transmitted.
*/
IES_PORT_MODE_ADMIN_PWRDOWN = IES_PORT_STATE_ADMIN_PWRDOWN,
/* The receiver is expecting a Built In Self Test sequence. The subMode
* argument to ies_port_set_state or ies_set_port_state_v2 is used to
* specify the test pattern.
*/
IES_PORT_MODE_BIST = IES_PORT_STATE_BIST,
/* The SERDES transmits remote fault constantly and the receiver is
* disabled.
*/
IES_PORT_MODE_REMOTE_FAULT = IES_PORT_STATE_REMOTE_FAULT,
/* Indicates continuous reception of a local fault condition. A remote
* fault is automatically sent continuously.
*/
IES_PORT_MODE_LOCAL_FAULT = IES_PORT_STATE_LOCAL_FAULT
};
#define IES10K_CM_USAGE_BASE 0xE60000
#define IES10K_CM_USAGE_SIZE 0x010000
/* Various per-port pause reception settings */
#define IES10K_CM_PAUSE_CFG(index) \
(0x000001 * (index) + 0x000800 + IES10K_CM_USAGE_BASE)
#define IES10K_CM_PAUSE_CFG_WIDTH 1
#define IES10K_CM_PAUSE_CFG_ENTRIES 48
#define IES10K_CM_PAUSE_CFG_L_PAUSEMASK 0
#define IES10K_CM_PAUSE_CFG_H_PAUSEMASK 7
/* Mapping from Pause Class to SMP */
#define IES10K_CM_PC_SMP_MAP(index) \
(0x000001 * (index) + 0x0008c0 + IES10K_CM_USAGE_BASE)
#define IES10K_EPL_BASE (0x0E0000)
/* MAC and Reconciliation Sublayer configuration */
#define IES10K_MAC_CFG(index1, index0, word) \
(0x000400 * (index1) + 0x000080 * (index0) + \
(word) + 0x000010 + IES10K_EPL_BASE)
#define IES10K_MAC_CFG_WIDTH 7
#define IES10K_MAC_CFG_ENTRIES_0 4
#define IES10K_MAC_CFG_ENTRIES_1 9
#define IES10K_MAC_CFG_L_TXANTIBUBBLEWATERMARK 0
#define IES10K_MAC_CFG_H_TXANTIBUBBLEWATERMARK 5
#define IES10K_MAC_CFG_L_TXRATEFIFOWATERMARK 6
#define IES10K_MAC_CFG_H_TXRATEFIFOWATERMARK 9
#define IES10K_MAC_CFG_L_TXRATEFIFOFASTINC 10
#define IES10K_MAC_CFG_H_TXRATEFIFOFASTINC 17
#define IES10K_MAC_CFG_L_TXRATEFIFOSLOWINC 18
#define IES10K_MAC_CFG_H_TXRATEFIFOSLOWINC 25
#define IES10K_MAC_CFG_L_TXIDLEMINIFGBYTES 26
#define IES10K_MAC_CFG_H_TXIDLEMINIFGBYTES 31
#define IES10K_MAC_CFG_L_TXCLOCKCOMPENSATIONTIMEOUT 32
#define IES10K_MAC_CFG_H_TXCLOCKCOMPENSATIONTIMEOUT 47
#define IES10K_MAC_CFG_B_TXCLOCKCOMPENSATIONENABLE 48
#define IES10K_MAC_CFG_L_TXFAULTMODE 49
#define IES10K_MAC_CFG_H_TXFAULTMODE 51
#define IES10K_MAC_CFG_L_TXPCACTTIMESCALE 52
#define IES10K_MAC_CFG_H_TXPCACTTIMESCALE 55
#define IES10K_MAC_CFG_L_TXPCACTTIMEOUT 56
#define IES10K_MAC_CFG_H_TXPCACTTIMEOUT 63
#define IES10K_MAC_CFG_L_TXDRAINMODE 64
#define IES10K_MAC_CFG_H_TXDRAINMODE 65
#define IES10K_MAC_CFG_L_TXMINCOLUMNS 66
#define IES10K_MAC_CFG_H_TXMINCOLUMNS 71
#define IES10K_MAC_CFG_B_TXLPIDLEREQUEST 108
#define IES10K_MAC_CFG_B_TXLPIAUTOMATIC 109
#define IES10K_MAC_CFG_L_TXLPITIMEOUT 110
#define IES10K_MAC_CFG_H_TXLPITIMEOUT 117
#define IES10K_MAC_CFG_L_TXLPITIMESCALE 118
#define IES10K_MAC_CFG_H_TXLPITIMESCALE 119
#define IES10K_MAC_CFG_L_TXLPIHOLDTIMEOUT 120
#define IES10K_MAC_CFG_H_TXLPIHOLDTIMEOUT 127
#define IES10K_MAC_CFG_L_TXLPIHOLDTIMESCALE 128
#define IES10K_MAC_CFG_H_TXLPIHOLDTIMESCALE 129
#define IES10K_MAC_CFG_L_TXFCSMODE 130
#define IES10K_MAC_CFG_H_TXFCSMODE 132
#define IES10K_MAC_CFG_B_TXIDLEENABLEDIC 134
#define IES10K_MAC_CFG_L_RXMINFRAMELENGTH 136
#define IES10K_MAC_CFG_H_RXMINFRAMELENGTH 143
#define IES10K_MAC_CFG_L_RXMAXFRAMELENGTH 144
#define IES10K_MAC_CFG_H_RXMAXFRAMELENGTH 159
#define IES10K_MAC_CFG_B_IEEE1588ENABLE 168
#define IES10K_MAC_CFG_B_PREAMBLEMODE 170
#define IES10K_MAC_CFG_B_RXDRAIN 173
#define IES10K_MAC_CFG_B_RXIGNOREIFGERRORS 180
#define IES10K_MGMT_BASE 0x000000
/* SPI_CTRL */
#define IES10K_SPI_CTRL() (0x000c29 + IES10K_MGMT_BASE)
#define IES10K_SPI_CTRL_WIDTH 1
#define IES10K_SPI_CTRL_L_FREQ 0
#define IES10K_SPI_CTRL_H_FREQ 9
#define IES10K_SPI_CTRL_B_BUSY 21
/* SPI_HEADER */
#define IES10K_SPI_HEADER() (0x000c28 + IES10K_MGMT_BASE)
#define IES10K_SPI_HEADER_WIDTH 1
/* SPI_RX_DATA */
#define IES10K_SPI_RX_DATA() (0x000c27 + IES10K_MGMT_BASE)
#define IES10K_SPI_RX_DATA_WIDTH 1
#define DBI410T_IF_SERIES(pid) \
(pid==0x01B0)
#define DBI410_IF_SERIES(pid) \
((pid==0x01B1)|| \
(pid==0x01B2)|| \
(pid==0x01B3)|| \
(pid==0x01B4))
#define DBI240_IF_SERIES(pid) \
((pid==0x01B8)|| \
(pid==0x01B9)|| \
(pid==0x01BC)|| \
(pid==0x01BA))
#define DBI2100_IF_SERIES(pid) \
(pid==0x01BC)
#define DBI100H_IF_SERIES(pid) \
((pid==0x01C0)|| \
(pid==0x01C2))
#define DBI100L_IF_SERIES(pid) \
(pid==0x01C1)
#define DBI25_IF_SERIES(pid) \
(pid==0x01C8)
#define BPCTL_WRITE_REG(a, reg, value) \
(writel((value), (void *)(((a)->mem_map) + reg*4)))
#define BPCTL_READ_REG(a, reg) ( \
readl((void *)((a)->mem_map) + reg*4))
inline static void ies_bitfield_set32_multi32(u32 *array, int hi_bit, int lo_bit,
u32 value)
{
int value_pos = 0;
int word = lo_bit / 32;
int rel_lo_bit = lo_bit % 32;
int rel_hi_bit = rel_lo_bit + (hi_bit - lo_bit);
do {
u32 mask;
mask = (rel_hi_bit < 31 ? (2 << rel_hi_bit) : 0) - 1;
mask >>= rel_lo_bit;
mask <<= rel_lo_bit;
array[word] = ((array[word] & ~mask) |
(((value >> value_pos) << rel_lo_bit) & mask));
value_pos += (32 - rel_lo_bit);
rel_hi_bit -= 32;
rel_lo_bit = 0;
++word;
} while (rel_hi_bit >= 0);
}
/* Get a named field of 1 bit within a 32-bit value. */
#define IES_GET_BIT(rvalue, regname, bitname) \
((rvalue >> regname ## _B_ ## bitname) & 1)
/* Set a named field of 1 bit within a 32-bit value. */
#define IES_SET_BIT(lvalue, regname, bitname, bitvalue) \
(lvalue = (lvalue & ~(1 << regname ## _B_ ## bitname)) | \
((bitvalue & 1) << regname ## _B_ ## bitname))
/* Get the maximum unsigned value a named field (< 33 bits) can hold. */
#define IES_FIELD_UNSIGNED_MAX(regname, fieldname) \
((2 << (regname ## _H_ ## fieldname \
- regname ## _L_ ## fieldname)) - 1)
/* Get a named field of 2-32 bits within a 32-bit value. */
#define IES_GET_FIELD(rvalue, regname, fieldname) \
((rvalue >> regname ## _L_ ## fieldname) & \
((2 << (regname ## _H_ ## fieldname \
- regname ## _L_ ## fieldname)) - 1))
/* Set a named field of 2-32 bits within a 32-bit value. */
#define IES_SET_FIELD(lvalue, regname, fieldname, fieldvalue) \
(lvalue ^= (((lvalue >> regname ## _L_ ## fieldname) \
^ fieldvalue) & ((2 << (regname ## _H_ ## fieldname \
- regname ## _L_ ## fieldname)) - 1)) \
<< regname ## _L_ ## fieldname)
/* Get a named field of 2-32 bits within an array of 32-bit values. */
#define IES_ARRAY_GET_FIELD(array, regname, fieldname) \
ies_bitfield_get32_multi32(array, regname ## _H_ ## fieldname, \
regname ## _L_ ## fieldname)
/* Set a named field of 2-32 bits within an array of 32-bit values. */
#define IES_ARRAY_SET_FIELD(array, regname, fieldname, fieldvalue) \
ies_bitfield_set32_multi32(array, regname ## _H_ ## fieldname, \
regname ## _L_ ## fieldname, fieldvalue)
/* Various per-port pause reception settings */
#define IES10K_CM_PAUSE_CFG(index) \
(0x000001 * (index) + 0x000800 + IES10K_CM_USAGE_BASE)
#define IES10K_CM_PAUSE_CFG_WIDTH 1
#define IES10K_CM_PAUSE_CFG_ENTRIES 48
#define IES10K_CM_PAUSE_CFG_L_PAUSEMASK 0
#define IES10K_CM_PAUSE_CFG_H_PAUSEMASK 7
inline static int convert_adminmode_txlinkfault(int mode)
{
int link_fault;
/* Program the output pattern based on the TxFaultMode */
switch (mode) {
case IES_PORT_MODE_ADMIN_DOWN:
link_fault = 1;
break;
case IES_PORT_MODE_LOCAL_FAULT:
link_fault = 2;
break;
case IES_PORT_MODE_REMOTE_FAULT:
link_fault = 3;
break;
default:
link_fault = 0;
break;
}
return link_fault;
}
/**
* iespl_read_u32 - read a 32-bit register.
*
* @sw: the switch number.
* @addr: the switch register address to read.
* @val: pointer to the location where the register value will be stored.
*
* Returns 0 on success.
**/
inline static int iespl_read_u32(struct fm10k_intfc *interface, u32 addr, u32 *val)
{
u32 value = 0;
if(!interface->mem_map)
return -1;
value = BPCTL_READ_REG(interface, addr);
*val = value;
return 0;
}
/**
* iespl_write_u32 - write a 32-bit register.
*
* @sw: the switch number.
* @addr: the switch register address to write.
* @val: the register value to write.
*
* Returns 0 on success.
*/
inline static int iespl_write_u32(struct fm10k_intfc *interface, u32 addr, u32 val)
{
if(!interface->mem_map)
return -1;
BPCTL_WRITE_REG(interface, addr, val);
return 0;
}
inline static int iespl_read_mult_u32(struct fm10k_intfc *interface, u32 addr, int n, u32 *val)
{
u32 value;
int i;
if(!interface->mem_map)
return -1;
for (i = 0; i < n; i++) {
value = BPCTL_READ_REG(interface, (addr + i));
val[i] = value;
}
return 0;
}
inline static int iespl_write_mult_u32(struct fm10k_intfc *interface, u32 addr, int n, u32 *val)
{
int i;
if(!interface->mem_map)
return -1;
for (i = 0; i < n; i++) {
BPCTL_WRITE_REG(interface, (addr + i), val[i]);
}
return 0;
}
typedef struct _bpmod_info_t {
unsigned int vendor;
unsigned int device;
unsigned int subvendor;
unsigned int subdevice;
unsigned int index;
char *bp_name;
} bpmod_info_t;
#define SILICOM_SVID 0x1374
typedef enum {
SET_LINK_PROP,
} CMND_TYPE_FM ;
#define MAGIC_NUM 'J'
/* for passing single values */
struct fm10k_cmd {
int status;
int data[8];
int in_param[8];
int out_param[8];
};
#define IOCTL_TX_MSG(cmd) _IOWR(MAGIC_NUM, cmd, struct fm10k_cmd)
#define FM10K_DEVICE_NODE "/dev/fm10k0"
#define FM10K_DEVICE_NAME "fm10k"
#endif /* SYS_LINK_PROP_DIS */
#endif /* _FM10K_H_ */