aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/pensando/ionic/ionic_lif.h
blob: 1d9a35745bcef861d380e144224a896c10e60c1e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright(c) 2017 - 2019 Pensando Systems, Inc */

#ifndef _IONIC_LIF_H_
#define _IONIC_LIF_H_

#include <linux/pci.h>

#define IONIC_ADMINQ_LENGTH	16	/* must be a power of two */
#define IONIC_NOTIFYQ_LENGTH	64	/* must be a power of two */

#define IONIC_MAX_NUM_NAPI_CNTR		(NAPI_POLL_WEIGHT + 1)
#define IONIC_MAX_NUM_SG_CNTR		(IONIC_TX_MAX_SG_ELEMS + 1)

struct ionic_tx_stats {
	u64 pkts;
	u64 bytes;
};

struct ionic_rx_stats {
	u64 pkts;
	u64 bytes;
};

#define IONIC_QCQ_F_INITED		BIT(0)
#define IONIC_QCQ_F_SG			BIT(1)
#define IONIC_QCQ_F_INTR		BIT(2)
#define IONIC_QCQ_F_NOTIFYQ		BIT(5)

struct ionic_napi_stats {
	u64 poll_count;
	u64 work_done_cntr[IONIC_MAX_NUM_NAPI_CNTR];
};

struct ionic_q_stats {
	union {
		struct ionic_tx_stats tx;
		struct ionic_rx_stats rx;
	};
};

struct ionic_qcq {
	void *base;
	dma_addr_t base_pa;
	unsigned int total_size;
	struct ionic_queue q;
	struct ionic_cq cq;
	struct ionic_intr_info intr;
	struct napi_struct napi;
	struct ionic_napi_stats napi_stats;
	struct ionic_q_stats *stats;
	unsigned int flags;
	struct dentry *dentry;
};

#define q_to_qcq(q)		container_of(q, struct ionic_qcq, q)
#define napi_to_qcq(napi)	container_of(napi, struct ionic_qcq, napi)
#define napi_to_cq(napi)	(&napi_to_qcq(napi)->cq)

enum ionic_lif_state_flags {
	IONIC_LIF_INITED,
	IONIC_LIF_UP,
	IONIC_LIF_QUEUE_RESET,

	/* leave this as last */
	IONIC_LIF_STATE_SIZE
};

#define IONIC_LIF_NAME_MAX_SZ		32
struct ionic_lif {
	char name[IONIC_LIF_NAME_MAX_SZ];
	struct list_head list;
	struct net_device *netdev;
	DECLARE_BITMAP(state, IONIC_LIF_STATE_SIZE);
	struct ionic *ionic;
	bool registered;
	unsigned int index;
	unsigned int hw_index;
	unsigned int kern_pid;
	u64 __iomem *kern_dbpage;
	spinlock_t adminq_lock;		/* lock for AdminQ operations */
	struct ionic_qcq *adminqcq;
	struct ionic_qcq *notifyqcq;
	u64 last_eid;
	unsigned int neqs;
	unsigned int nxqs;
	u64 hw_features;

	struct ionic_lif_info *info;
	dma_addr_t info_pa;
	u32 info_sz;

	unsigned long *dbid_inuse;
	unsigned int dbid_count;
	struct dentry *dentry;
	u32 flags;
};

static inline int ionic_wait_for_bit(struct ionic_lif *lif, int bitname)
{
	unsigned long tlimit = jiffies + HZ;

	while (test_and_set_bit(bitname, lif->state) &&
	       time_before(jiffies, tlimit))
		usleep_range(100, 200);

	return test_bit(bitname, lif->state);
}

int ionic_lifs_alloc(struct ionic *ionic);
void ionic_lifs_free(struct ionic *ionic);
void ionic_lifs_deinit(struct ionic *ionic);
int ionic_lifs_init(struct ionic *ionic);
int ionic_lifs_register(struct ionic *ionic);
void ionic_lifs_unregister(struct ionic *ionic);
int ionic_lif_identify(struct ionic *ionic, u8 lif_type,
		       union ionic_lif_identity *lif_ident);
int ionic_lifs_size(struct ionic *ionic);

int ionic_open(struct net_device *netdev);
int ionic_stop(struct net_device *netdev);
int ionic_reset_queues(struct ionic_lif *lif);

static inline void debug_stats_napi_poll(struct ionic_qcq *qcq,
					 unsigned int work_done)
{
	qcq->napi_stats.poll_count++;

	if (work_done > (IONIC_MAX_NUM_NAPI_CNTR - 1))
		work_done = IONIC_MAX_NUM_NAPI_CNTR - 1;

	qcq->napi_stats.work_done_cntr[work_done]++;
}

#define DEBUG_STATS_CQE_CNT(cq)		((cq)->compl_count++)
#define DEBUG_STATS_INTR_REARM(intr)	((intr)->rearm_count++)
#define DEBUG_STATS_NAPI_POLL(qcq, work_done) \
	debug_stats_napi_poll(qcq, work_done)

#endif /* _IONIC_LIF_H_ */