917 lines
23 KiB
C
Raw Normal View History

2024-09-09 08:57:42 +00:00
/*
* Copyright (c) 2012 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _ALX_H_
#define _ALX_H_
#include <linux/types.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/vmalloc.h>
#include <linux/string.h>
#include <linux/in.h>
#include <linux/interrupt.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/sctp.h>
#include <linux/pkt_sched.h>
#include <linux/ipv6.h>
#include <linux/slab.h>
#include <net/checksum.h>
#include <net/ip6_checksum.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/mii.h>
#include <linux/cpumask.h>
#include <linux/aer.h>
#include <linux/version.h>
#include <asm/byteorder.h>
#ifdef MDM_PLATFORM
#include <linux/ipa_odu_bridge.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0))
#include <linux/msm_pcie.h>
#else
#include <mach/msm_pcie.h>
#endif
#endif
#include "alx_sw.h"
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
#define __devinit
#define __devexit
#define __devexit_p
#endif
#define ALX_LINK_DOWN_CONFIG 1
#define ALX_HIB_TASK_CONFIG 1
#define ALX_HIB_TIMER_CONFIG 1
#ifdef MDM_PLATFORM
#define MAX_AR8151_BW 900
#define ALX_IPA_SYS_PIPE_MAX_PKTS_DESC 200
#define ALX_IPA_SYS_PIPE_MIN_PKTS_DESC 5
#define ALX_IPA_SYS_PIPE_DNE_PKTS ALX_IPA_SYS_PIPE_MAX_PKTS_DESC*3
#define ALX_IPA_INACTIVITY_DELAY_MS 1000
/* Protocol Specific Offsets*/
#define ALX_IP_OFFSET 14
#define ALX_IP_HEADER_SIZE 20
#define ALX_DHCP_SRV_PORT 67
#define ALX_DHCP_CLI_PORT 68
#endif
/*
* Definition to enable some features
*/
#undef CONFIG_ALX_MSIX
#undef CONFIG_ALX_MSI
#undef CONFIG_ALX_MTQ
#undef CONFIG_ALX_MRQ
#undef CONFIG_ALX_RSS
/* #define CONFIG_ALX_MSIX */
#define CONFIG_ALX_MSI
#define CONFIG_ALX_MTQ
#define CONFIG_ALX_MRQ
#ifdef CONFIG_ALX_MRQ
#define CONFIG_ALX_RSS
#endif
#define ALX_MSG_DEFAULT 0
/* Logging functions and macros */
#define alx_err(adpt, fmt, ...) \
netdev_err(adpt->netdev, fmt, ##__VA_ARGS__)
#define ALX_VLAN_TO_TAG(_vlan, _tag) \
do { \
_tag = ((((_vlan) >> 8) & 0xFF) | (((_vlan) & 0xFF) << 8)); \
} while (0)
#define ALX_TAG_TO_VLAN(_tag, _vlan) \
do { \
_vlan = ((((_tag) >> 8) & 0xFF) | (((_tag) & 0xFF) << 8)) ; \
} while (0)
/* Coalescing Message Block */
struct coals_msg_block {
int test;
};
#define BAR_0 0
#define ALX_DEF_RX_BUF_SIZE 1536
#define ALX_MAX_JUMBO_PKT_SIZE (9*1024)
#define ALX_MAX_TSO_PKT_SIZE (7*1024)
#define ALX_MAX_ETH_FRAME_SIZE ALX_MAX_JUMBO_PKT_SIZE
#define ALX_MIN_ETH_FRAME_SIZE 68
#define ALX_MAX_RX_QUEUES 8
#define ALX_MAX_TX_QUEUES 4
#define ALX_MAX_HANDLED_INTRS 5
#define ALX_WATCHDOG_TIME (5 * HZ)
struct alx_cmb {
char name[IFNAMSIZ + 9];
void *cmb;
dma_addr_t dma;
};
struct alx_smb {
char name[IFNAMSIZ + 9];
void *smb;
dma_addr_t dma;
};
/*
* RRD : definition
*/
/* general parameter format of rrd */
struct alx_sw_rrdes_general {
#if defined(__LITTLE_ENDIAN_BITFIELD)
/* dword 0 */
u32 xsum:16;
u32 nor:4; /* number of RFD */
u32 si:12; /* start index of rfd-ring */
/* dword 1 */
u32 hash;
/* dword 2 */
u32 vlan_tag:16; /* vlan-tag */
u32 pid:8; /* Header Length of Header-Data Split. WORD unit */
u32 reserve0:1;
u32 rss_cpu:3; /* CPU number used by RSS */
u32 rss_flag:4; /* rss_flag 0, TCP(IPv6) flag for RSS hash algrithm
* rss_flag 1, IPv6 flag for RSS hash algrithm
* rss_flag 2, TCP(IPv4) flag for RSS hash algrithm
* rss_flag 3, IPv4 flag for RSS hash algrithm */
/* dword 3 */
u32 pkt_len:14; /* length of the packet */
u32 l4f:1; /* L4(TCP/UDP) checksum failed */
u32 ipf:1; /* IP checksum failed */
u32 vlan_flag:1; /* vlan tag */
u32 proto:3;
u32 res:1; /* received error summary */
u32 crc:1; /* crc error */
u32 fae:1; /* frame alignment error */
u32 trunc:1; /* truncated packet, larger than MTU */
u32 runt:1; /* runt packet */
u32 icmp:1; /* incomplete packet due to insufficient rx-desc*/
u32 bar:1; /* broadcast address received */
u32 mar:1; /* multicast address received */
u32 type:1; /* ethernet type */
u32 fov:1; /* fifo overflow*/
u32 lene:1; /* length error */
u32 update:1; /* update*/
#elif defined(__BIG_ENDIAN_BITFIELD)
/* dword 0 */
u32 si:12;
u32 nor:4;
u32 xsum:16;
/* dword 1 */
u32 hash;
/* dword 2 */
u32 rss_flag:4;
u32 rss_cpu:3;
u32 reserve0:1;
u32 pid:8;
u32 vlan_tag:16;
/* dword 3 */
u32 update:1;
u32 lene:1;
u32 fov:1;
u32 type:1;
u32 mar:1;
u32 bar:1;
u32 icmp:1;
u32 runt:1;
u32 trunc:1;
u32 fae:1;
u32 crc:1;
u32 res:1;
u32 proto:3;
u32 vlan_flag:1;
u32 ipf:1;
u32 l4f:1;
u32 pkt_len:14;
#else
#error "Please fix <asm/byteorder.h>"
#endif
};
union alx_hw_rrdesc {
/* dword flat format */
struct {
__le32 dw0;
__le32 dw1;
__le32 dw2;
__le32 dw3;
} dfmt;
/* qword flat format */
struct {
__le64 qw0;
__le64 qw1;
} qfmt;
};
/*
* XXX: we should not use this guy, best to just
* do all le32_to_cpu() conversions on the spot.
*/
union alx_sw_rrdesc {
struct alx_sw_rrdes_general genr;
/* dword flat format */
struct {
u32 dw0;
u32 dw1;
u32 dw2;
u32 dw3;
} dfmt;
/* qword flat format */
struct {
u64 qw0;
u64 qw1;
} qfmt;
};
/*
* RFD : definition
*/
/* general parameter format of rfd */
struct alx_sw_rfdes_general {
u64 addr;
};
union alx_hw_rfdesc {
/* dword flat format */
struct {
__le32 dw0;
__le32 dw1;
} dfmt;
/* qword flat format */
struct {
__le64 qw0;
} qfmt;
};
/*
* XXX: we should not use this guy, best to just
* do all le32_to_cpu() conversions on the spot.
*/
union alx_sw_rfdesc {
struct alx_sw_rfdes_general genr;
/* dword flat format */
struct {
u32 dw0;
u32 dw1;
} dfmt;
/* qword flat format */
struct {
u64 qw0;
} qfmt;
};
/* RRD Proto Defination as per spec*/
enum alx_rrd_proto {
RRD_PROTO_NON_IP = 0,
RRD_PROTO_IPv4,
RRD_PROTO_IPv6_TCP,
RRD_PROTO_IPv4_TCP,
RRD_PROTO_IPv6_UDP,
RRD_PROTO_IPv4_UDP,
RRD_PROTO_IPv6,
RRD_PROTO_LLDP
};
/*
* TPD : definition
*/
/* general parameter format of tpd */
struct alx_sw_tpdes_general {
#if defined(__LITTLE_ENDIAN_BITFIELD)
/* dword 0 */
u32 buffer_len:16; /* include 4-byte CRC */
u32 vlan_tag:16;
/* dword 1 */
u32 l4hdr_offset:8; /* l4 header offset to the 1st byte of packet */
u32 c_csum:1;
u32 ip_csum:1;
u32 tcp_csum:1;
u32 udp_csum:1;
u32 lso:1;
u32 lso_v2:1;
u32 vtagged:1; /* vlan-id tagged already */
u32 instag:1; /* insert vlan tag */
u32 ipv4:1; /* ipv4 packet */
u32 type:1; /* type of packet (ethernet_ii(0) or snap(1)) */
u32 reserve:12;
u32 epad:1; /* even byte padding when this packet */
u32 last_frag:1; /* last fragment(buffer) of the packet */
u64 addr;
#elif defined(__BIG_ENDIAN_BITFIELD)
/* dword 0 */
u32 vlan_tag:16;
u32 buffer_len:16;
/* dword 1 */
u32 last_frag:1;
u32 epad:1;
u32 reserve:12;
u32 type:1;
u32 ipv4:1;
u32 instag:1;
u32 vtagged:1;
u32 lso_v2:1;
u32 lso:1;
u32 udp_csum:1;
u32 tcp_csum:1;
u32 ip_csum:1;
u32 c_csum:1;
u32 l4hdr_offset:8;
u64 addr;
#else
#error "Please fix <asm/byteorder.h>"
#endif
};
/* custom checksum parameter format of tpd */
struct alx_sw_tpdes_checksum {
#if defined(__LITTLE_ENDIAN_BITFIELD)
/* dword 0 */
u32 buffer_len:16;
u32 vlan_tag:16;
/* dword 1 */
u32 payld_offset:8; /* payload offset to the 1st byte of packet */
u32 c_csum:1; /* do custom checksum offload */
u32 ip_csum:1; /* do ip(v4) header checksum offload */
u32 tcp_csum:1; /* do tcp checksum offload, both ipv4 and ipv6 */
u32 udp_csum:1; /* do udp checksum offlaod, both ipv4 and ipv6 */
u32 lso:1;
u32 lso_v2:1;
u32 vtagged:1; /* vlan-id tagged already */
u32 instag:1; /* insert vlan tag */
u32 ipv4:1; /* ipv4 packet */
u32 type:1; /* type of packet (ethernet_ii(0) or snap(1)) */
u32 cxsum_offset:8; /* checksum offset to the 1st byte of packet */
u32 reserve:4;
u32 epad:1; /* even byte padding when this packet */
u32 last_frag:1; /* last fragment(buffer) of the packet */
u64 addr;
#elif defined(__BIG_ENDIAN_BITFIELD)
/* dword 0 */
u32 vlan_tag:16;
u32 buffer_len:16;
/* dword 1 */
u32 last_frag:1;
u32 epad:1;
u32 reserve:4;
u32 cxsum_offset:8;
u32 type:1;
u32 ipv4:1;
u32 instag:1;
u32 vtagged:1;
u32 lso_v2:1;
u32 lso:1;
u32 udp_csum:1;
u32 tcp_csum:1;
u32 ip_csum:1;
u32 c_csum:1;
u32 payld_offset:8;
u64 addr;
#else
#error "Please fix <asm/byteorder.h>"
#endif
};
/* tcp large send format (v1/v2) of tpd */
struct alx_sw_tpdes_tso {
#if defined(__LITTLE_ENDIAN_BITFIELD)
/* dword 0 */
u32 buffer_len:16; /* include 4-byte CRC */
u32 vlan_tag:16;
/* dword 1 */
u32 tcphdr_offset:8; /* tcp hdr offset to the 1st byte of packet */
u32 c_csum:1;
u32 ip_csum:1;
u32 tcp_csum:1;
u32 udp_csum:1;
u32 lso:1; /* do tcp large send (ipv4 only) */
u32 lso_v2:1; /* must be 0 in this format */
u32 vtagged:1; /* vlan-id tagged already */
u32 instag:1; /* insert vlan tag */
u32 ipv4:1; /* ipv4 packet */
u32 type:1; /* type of packet (ethernet_ii(1) or snap(0)) */
u32 mss:13; /* mss if do tcp large send */
u32 last_frag:1; /* last fragment(buffer) of the packet */
u32 pkt_len; /* packet length in ext tpd */
u32 reserve;
#elif defined(__BIG_ENDIAN_BITFIELD)
/* dword 0 */
u32 vlan_tag:16;
u32 buffer_len:16;
/* dword 1 */
u32 last_frag:1;
u32 mss:13;
u32 type:1;
u32 ipv4:1;
u32 instag:1;
u32 vtagged:1;
u32 lso_v2:1;
u32 lso:1;
u32 udp_csum:1;
u32 tcp_csum:1;
u32 ip_csum:1;
u32 c_csum:1;
u32 tcphdr_offset:8;
u32 pkt_len;
u32 reserve;
#else
#error "Please fix <asm/byteorder.h>"
#endif
};
union alx_hw_tpdesc {
/* dword flat format */
struct {
__le32 dw0;
__le32 dw1;
__le32 dw2;
__le32 dw3;
} dfmt;
/* qword flat format */
struct {
__le64 qw0;
__le64 qw1;
} qfmt;
};
/*
* XXX: we should not use this guy, best to just
* do all le32_to_cpu() conversions on the spot.
*/
union alx_sw_tpdesc {
struct alx_sw_tpdes_general genr;
struct alx_sw_tpdes_checksum csum;
struct alx_sw_tpdes_tso tso;
/* dword flat format */
struct {
u32 dw0;
u32 dw1;
u32 dw2;
u32 dw3;
} dfmt;
/* qword flat format */
struct {
u64 qw0;
u64 qw1;
} qfmt;
};
#define ALX_RRD(_que, _i) \
(&(((union alx_hw_rrdesc *)(_que)->rrq.rrdesc)[(_i)]))
#define ALX_RFD(_que, _i) \
(&(((union alx_hw_rfdesc *)(_que)->rfq.rfdesc)[(_i)]))
#define ALX_TPD(_que, _i) \
(&(((union alx_hw_tpdesc *)(_que)->tpq.tpdesc)[(_i)]))
/*
* alx_ring_header represents a single, contiguous block of DMA space
* mapped for the three descriptor rings (tpd, rfd, rrd) and the two
* message blocks (cmb, smb) described below
*/
struct alx_ring_header {
void *desc; /* virtual address */
dma_addr_t dma; /* physical address*/
unsigned int size; /* length in bytes */
unsigned int used;
};
/*
* alx_buffer is wrapper around a pointer to a socket buffer
* so a DMA handle can be stored along with the skb
*/
struct alx_buffer {
struct sk_buff *skb; /* socket buffer */
u16 length; /* rx buffer length */
dma_addr_t dma;
};
struct alx_sw_buffer {
struct sk_buff *skb; /* socket buffer */
u32 vlan_tag:16;
u32 vlan_flag:1;
u32 reserved:15;
};
/* receive free descriptor (rfd) queue */
struct alx_rfd_queue {
struct alx_buffer *rfbuff;
union alx_hw_rfdesc *rfdesc; /* virtual address */
dma_addr_t rfdma; /* physical address */
u16 size; /* length in bytes */
u16 count; /* number of descriptors in the ring */
u16 produce_idx; /* it's written to rxque->produce_reg */
u16 consume_idx; /* unused*/
};
/* receive return desciptor (rrd) queue */
struct alx_rrd_queue {
union alx_hw_rrdesc *rrdesc; /* virtual address */
dma_addr_t rrdma; /* physical address */
u16 size; /* length in bytes */
u16 count; /* number of descriptors in the ring */
u16 produce_idx; /* unused */
u16 consume_idx; /* rxque->consume_reg */
};
/* software desciptor (swd) queue */
struct alx_swd_queue {
struct alx_sw_buffer *swbuff;
u16 count; /* number of descriptors in the ring */
u16 produce_idx;
u16 consume_idx;
};
/* rx queue */
struct alx_rx_queue {
struct device *dev; /* device for dma mapping */
struct net_device *netdev; /* netdev ring belongs to */
struct alx_msix_param *msix;
struct alx_rrd_queue rrq;
struct alx_rfd_queue rfq;
struct alx_swd_queue swq;
u16 que_idx; /* index in multi rx queues*/
u16 max_packets; /* max work per interrupt */
u16 produce_reg;
u16 consume_reg;
u32 flags;
};
#define ALX_RX_FLAG_SW_QUE 0x00000001
#define ALX_RX_FLAG_HW_QUE 0x00000002
#define CHK_RX_FLAG(_flag) CHK_FLAG(rxque, RX, _flag)
#define SET_RX_FLAG(_flag) SET_FLAG(rxque, RX, _flag)
#define CLI_RX_FLAG(_flag) CLI_FLAG(rxque, RX, _flag)
#define GET_RF_BUFFER(_rque, _i) (&((_rque)->rfq.rfbuff[(_i)]))
#define GET_SW_BUFFER(_rque, _i) (&((_rque)->swq.swbuff[(_i)]))
/* transimit packet descriptor (tpd) ring */
struct alx_tpd_queue {
struct alx_buffer *tpbuff;
union alx_hw_tpdesc *tpdesc; /* virtual address */
dma_addr_t tpdma; /* physical address */
u16 size; /* length in bytes */
u16 count; /* number of descriptors in the ring */
u16 produce_idx;
u16 consume_idx;
u16 last_produce_idx;
};
/* tx queue */
struct alx_tx_queue {
struct device *dev; /* device for dma mapping */
struct net_device *netdev; /* netdev ring belongs to */
struct alx_tpd_queue tpq;
struct alx_msix_param *msix;
u16 que_idx; /* needed for multiqueue queue management */
u16 max_packets; /* max packets per interrupt */
u16 produce_reg;
u16 consume_reg;
};
#define GET_TP_BUFFER(_tque, _i) (&((_tque)->tpq.tpbuff[(_i)]))
/*
* definition for array allocations.
*/
#define ALX_MAX_MSIX_INTRS 16
#define ALX_MAX_RX_QUEUES 8
#define ALX_MAX_TX_QUEUES 4
enum alx_msix_type {
alx_msix_type_rx,
alx_msix_type_tx,
alx_msix_type_other,
};
#define ALX_MSIX_TYPE_OTH_TIMER 0
#define ALX_MSIX_TYPE_OTH_ALERT 1
#define ALX_MSIX_TYPE_OTH_SMB 2
#define ALX_MSIX_TYPE_OTH_PHY 3
/* ALX_MAX_MSIX_INTRS of these are allocated,
* but we only use one per queue-specific vector.
*/
struct alx_msix_param {
struct alx_adapter *adpt;
unsigned int vec_idx; /* index in HW interrupt vector */
char name[IFNAMSIZ + 9];
/* msix interrupts for queue */
u8 rx_map[ALX_MAX_RX_QUEUES];
u8 tx_map[ALX_MAX_TX_QUEUES];
u8 rx_count; /* Rx ring count assigned to this vector */
u8 tx_count; /* Tx ring count assigned to this vector */
struct napi_struct napi;
cpumask_var_t affinity_mask;
u32 flags;
};
#define ALX_MSIX_FLAG_RX0 0x00000001
#define ALX_MSIX_FLAG_RX1 0x00000002
#define ALX_MSIX_FLAG_RX2 0x00000004
#define ALX_MSIX_FLAG_RX3 0x00000008
#define ALX_MSIX_FLAG_RX4 0x00000010
#define ALX_MSIX_FLAG_RX5 0x00000020
#define ALX_MSIX_FLAG_RX6 0x00000040
#define ALX_MSIX_FLAG_RX7 0x00000080
#define ALX_MSIX_FLAG_TX0 0x00000100
#define ALX_MSIX_FLAG_TX1 0x00000200
#define ALX_MSIX_FLAG_TX2 0x00000400
#define ALX_MSIX_FLAG_TX3 0x00000800
#define ALX_MSIX_FLAG_TIMER 0x00001000
#define ALX_MSIX_FLAG_ALERT 0x00002000
#define ALX_MSIX_FLAG_SMB 0x00004000
#define ALX_MSIX_FLAG_PHY 0x00008000
#define ALX_MSIX_FLAG_RXS (\
ALX_MSIX_FLAG_RX0 |\
ALX_MSIX_FLAG_RX1 |\
ALX_MSIX_FLAG_RX2 |\
ALX_MSIX_FLAG_RX3 |\
ALX_MSIX_FLAG_RX4 |\
ALX_MSIX_FLAG_RX5 |\
ALX_MSIX_FLAG_RX6 |\
ALX_MSIX_FLAG_RX7)
#define ALX_MSIX_FLAG_TXS (\
ALX_MSIX_FLAG_TX0 |\
ALX_MSIX_FLAG_TX1 |\
ALX_MSIX_FLAG_TX2 |\
ALX_MSIX_FLAG_TX3)
#define ALX_MSIX_FLAG_ALL (\
ALX_MSIX_FLAG_RXS |\
ALX_MSIX_FLAG_TXS |\
ALX_MSIX_FLAG_TIMER |\
ALX_MSIX_FLAG_ALERT |\
ALX_MSIX_FLAG_SMB |\
ALX_MSIX_FLAG_PHY)
#define CHK_MSIX_FLAG(_flag) CHK_FLAG(msix, MSIX, _flag)
#define SET_MSIX_FLAG(_flag) SET_FLAG(msix, MSIX, _flag)
#define CLI_MSIX_FLAG(_flag) CLI_FLAG(msix, MSIX, _flag)
#ifdef MDM_PLATFORM
/**
* * struct alx_ipa_stats - ALX - ODU_Bridge/IPA Stats
* * @send_msg: MSG Send to ODU_Bridge
* * @recv_msg: MSG Recd from ODU_Bridge/IPA
* * @rx_ipa_excep: Exception packets send from ODU_Bridge/IPA; packets
* * that need to be delivered to network stack
* * @rx_ipa_write_done: MSG Recd from ODU_Bridge/IPA when message posted to
* * IPA HW
* * This function sets the link local ipv6 address provided by IOCTL
* */
struct alx_ipa_stats {
/* RX Side */
uint64_t rx_ipa_excep;
uint64_t rx_ipa_write_done;
uint64_t rx_ipa_send;
uint64_t rx_ipa_send_fail;
/* TX Side*/
uint64_t tx_ipa_send;
uint64_t tx_ipa_send_err;
/* Frag Stats */
uint64_t non_ip_frag_pkt;
/* Flow Control Stats */
uint64_t flow_control_pkt_drop;
uint64_t ipa_low_watermark_cnt;
};
enum alx_ipa_rm_state {
ALX_IPA_RM_RELEASED,
ALX_IPA_RM_REQUESTED,
ALX_IPA_RM_GRANT_PENDING,
ALX_IPA_RM_GRANTED,
};
/**
* struct alx_ipa_ctx - ALX IPA Context
* @stats: ALX - IPA brigde stats
* @debugfs_dir: Debug FS handle for alx
* @ipa_prod_rm_state: IPA Producer Pipe RM state
* @ipa_cons_rm_state: IPA Consumer Pipe RM state
* @alx_ipa_perf_requested: Set to true when perf profile have been requested.
* @ipa_rm_lock: Lock to syncronize IPA Prod/Cons RM state access
* @rm_ipa_lock: Lock to syncronize ipa_rx_completion access
* @ipa_rx_completion: Keeps track of pending IPA WRITE DONE Evts
* @ipa_comp_wait: Wait source used to keep APPS awake
* when packets are submitted to IPA
**/
struct alx_ipa_ctx {
struct alx_ipa_stats stats;
struct dentry *debugfs_dir;
enum alx_ipa_rm_state ipa_prod_rm_state;
enum alx_ipa_rm_state ipa_cons_rm_state;
bool alx_ipa_perf_requested;
spinlock_t ipa_rm_state_lock;
spinlock_t rm_ipa_lock;
uint64_t ipa_rx_completion;
uint64_t alx_tx_completion;
bool acquire_wake_src;
struct wakeup_source rm_ipa_wait;
bool ipa_ready;
};
struct alx_ipa_rx_desc_node {
struct list_head link;
struct sk_buff * skb_ptr;
};
#endif
/*
*board specific private data structure
*/
struct alx_adapter {
struct net_device *netdev;
struct pci_dev *pdev;
#ifdef MDM_PLATFORM
struct alx_ipa_ctx *palx_ipa;
struct msm_pcie_register_event msm_pcie_event;
#endif
struct net_device_stats net_stats;
bool netdev_registered;
u16 bd_number; /* board number;*/
struct alx_msix_param *msix[ALX_MAX_MSIX_INTRS];
struct msix_entry *msix_entries;
int num_msix_rxques;
int num_msix_txques;
int num_msix_noques; /* true count of msix_noques for device */
int num_msix_intrs;
int min_msix_intrs;
int max_msix_intrs;
/* All Descriptor memory */
struct alx_ring_header ring_header;
/* TX */
struct alx_tx_queue *tx_queue[ALX_MAX_TX_QUEUES];
/* RX */
struct alx_rx_queue *rx_queue[ALX_MAX_RX_QUEUES];
u16 num_txques;
u16 num_rxques; /* equal max(num_hw_rxques, num_sw_rxques) */
u16 num_hw_rxques;
u16 num_sw_rxques;
u16 max_rxques;
u16 max_txques;
u16 num_txdescs;
u16 num_rxdescs;
u32 rxbuf_size;
struct alx_cmb cmb;
struct alx_smb smb;
/* structs defined in alx_hw.h */
struct alx_hw hw;
struct alx_hw_stats hw_stats;
u32 *config_space;
struct work_struct alx_task;
struct timer_list alx_timer;
unsigned long link_jiffies;
u32 wol;
spinlock_t tx_lock;
spinlock_t rx_lock;
atomic_t irq_sem;
#ifdef MDM_PLATFORM
u16 ipa_high_watermark;
u16 ipa_low_watermark;
u16 pendq_cnt;
u16 freeq_cnt;
u16 ipa_free_desc_cnt;
spinlock_t flow_ctrl_lock;
struct list_head pend_queue_head;
struct list_head free_queue_head;
struct work_struct ipa_send_task;
#endif
u16 msg_enable;
#ifdef MDM_PLATFORM
unsigned long flags[3];
#else
unsigned long flags[2];
#endif
};
#define ALX_ADPT_FLAG_0_MSI_CAP 0x00000001
#define ALX_ADPT_FLAG_0_MSI_EN 0x00000002
#define ALX_ADPT_FLAG_0_MSIX_CAP 0x00000004
#define ALX_ADPT_FLAG_0_MSIX_EN 0x00000008
#define ALX_ADPT_FLAG_0_MRQ_CAP 0x00000010
#define ALX_ADPT_FLAG_0_MRQ_EN 0x00000020
#define ALX_ADPT_FLAG_0_MTQ_CAP 0x00000040
#define ALX_ADPT_FLAG_0_MTQ_EN 0x00000080
#define ALX_ADPT_FLAG_0_SRSS_CAP 0x00000100
#define ALX_ADPT_FLAG_0_SRSS_EN 0x00000200
#define ALX_ADPT_FLAG_0_FIXED_MSIX 0x00000400
#define ALX_ADPT_FLAG_0_TASK_REINIT_REQ 0x00010000 /* reinit */
#define ALX_ADPT_FLAG_0_TASK_LSC_REQ 0x00020000
#define ALX_ADPT_FLAG_1_STATE_TESTING 0x00000001
#define ALX_ADPT_FLAG_1_STATE_RESETTING 0x00000002
#define ALX_ADPT_FLAG_1_STATE_DOWN 0x00000004
#define ALX_ADPT_FLAG_1_STATE_WATCH_DOG 0x00000008
#define ALX_ADPT_FLAG_1_STATE_DIAG_RUNNING 0x00000010
#define ALX_ADPT_FLAG_1_STATE_INACTIVE 0x00000020
#ifdef MDM_PLATFORM
#define ALX_ADPT_FLAG_2_ODU_CONNECT 0x00000001
#define ALX_ADPT_FLAG_2_IPA_RM 0x00000002
#define ALX_ADPT_FLAG_2_DEBUGFS_INIT 0x00000004
#define ALX_ADPT_FLAG_2_ODU_INIT 0x00000008
#define ALX_ADPT_FLAG_2_WQ_SCHED 0x00000010
#endif
#define CHK_ADPT_FLAG(_idx, _flag) \
CHK_FLAG_ARRAY(adpt, _idx, ADPT, _flag)
#define SET_ADPT_FLAG(_idx, _flag) \
SET_FLAG_ARRAY(adpt, _idx, ADPT, _flag)
#define CLI_ADPT_FLAG(_idx, _flag) \
CLI_FLAG_ARRAY(adpt, _idx, ADPT, _flag)
/* default to trying for four seconds */
#define ALX_TRY_LINK_TIMEOUT (4 * HZ)
#define ALX_OPEN_CTRL_IRQ_EN 0x00000001
#define ALX_OPEN_CTRL_RESET_MAC 0x00000002
#define ALX_OPEN_CTRL_RESET_PHY 0x00000004
#define ALX_OPEN_CTRL_RESET_ALL (\
ALX_OPEN_CTRL_RESET_MAC |\
ALX_OPEN_CTRL_RESET_PHY)
/* needed by alx_ethtool.c */
extern char alx_drv_name[];
extern void alx_reinit_locked(struct alx_adapter *adpt);
extern void alx_set_ethtool_ops(struct net_device *netdev);
extern void alx_update_hw_stats(struct alx_adapter *adpt);
#ifdef ETHTOOL_OPS_COMPAT
extern int ethtool_ioctl(struct ifreq *ifr);
#endif
#endif /* _ALX_H_ */