aboutsummaryrefslogtreecommitdiffstats
path: root/src/alx.h
blob: 78bbe5da058c11d9469059559cc815a3c0f9d36a (plain)
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
/*
 * 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_

#define ALX_WATCHDOG_TIME   (5 * HZ)

/* alx_ring_header is a single, contiguous block of memory space
 * used by the three descriptor rings (tpd, rfd, rrd)
 */
struct alx_ring_header {
	/* virt addr */
	void        *desc;
	/* phy addr */
	dma_addr_t   dma;
	u32          size;
};

/* alx_buffer wraps around a pointer to a socket buffer
 * so a DMA physical address can be stored along with the skb
 */
struct alx_buffer {
	struct sk_buff *skb;
	/* DMA address */
	DEFINE_DMA_UNMAP_ADDR(dma);
	/* buffer size */
	DEFINE_DMA_UNMAP_LEN(size);
	/* information of this buffer */
	u16		flags;
};
#define ALX_BUF_TX_FIRSTFRAG	0x1

/* rx queue */
struct alx_rx_queue {
	struct net_device *netdev;
	/* device pointer for dma operation */
	struct device *dev;
	/* rrd ring virtual addr */
	struct rrd_desc *rrd_hdr;
	/* rrd ring physical addr */
	dma_addr_t rrd_dma;
	/* rfd ring virtual addr */
	struct rfd_desc *rfd_hdr;
	/* rfd ring physical addr */
	dma_addr_t rfd_dma;
	/* info for rx-skbs */
	struct alx_buffer *bf_info;

	/* number of ring elements */
	u16 count;
	/* rfd producer index */
	u16 pidx;
	/* rfd consumer index */
	u16 cidx;
	u16 rrd_cidx;
	/* register saving producer index */
	u16 p_reg;
	/* register saving consumer index */
	u16 c_reg;
	/* queue index */
	u16 qidx;
	unsigned long flag;

	struct sk_buff_head list;
};
#define ALX_RQ_USING		1
#define ALX_RX_ALLOC_THRESH	32

/* tx queue */
struct alx_tx_queue {
	struct net_device *netdev;
	/* device pointer for dma operation */
	struct device *dev;
	/* tpd ring virtual addr */
	struct tpd_desc *tpd_hdr;
	dma_addr_t tpd_dma;
	/* info for tx-skbs pending on HW */
	struct alx_buffer *bf_info;
	/* number of ring elements  */
	u16 count;
	/* producer index */
	u16 pidx;
	/* consumer index */
	atomic_t cidx;
	/* register saving producer index */
	u16 p_reg;
	/* register saving consumer index */
	u16 c_reg;
	/* queue index */
	u16 qidx;
};

#define ALX_TX_WAKEUP_THRESH(_tq) ((_tq)->count / 4)
#define ALX_DEFAULT_TX_WORK		128

struct alx_napi {
	struct napi_struct	napi;
	struct alx_adapter	*adpt;
	struct alx_rx_queue	*rxq;
	struct alx_tx_queue	*txq;
	int			vec_idx;
	u32			vec_mask;
	char			irq_lbl[IFNAMSIZ];
};

enum ALX_FLAGS {
	ALX_FLAG_USING_MSIX = 0,
	ALX_FLAG_USING_MSI,
	ALX_FLAG_RESETING,
	ALX_FLAG_TESTING,
	ALX_FLAG_HALT,
	ALX_FLAG_FPGA,
	ALX_FLAG_TASK_PENDING,
	ALX_FLAG_TASK_CHK_LINK,
	ALX_FLAG_TASK_RESET,
	ALX_FLAG_TASK_UPDATE_SMB,

	ALX_FLAG_NUMBER_OF_FLAGS,
};


struct alx_hw;
/*
 *board specific private data structure
 */
struct alx_adapter {
	struct net_device	*netdev;
	struct pci_dev		*pdev;

	struct alx_hw		hw;

	u16			bd_number;

	/* totally msix vectors */
	int			nr_vec;
	struct msix_entry	*msix_ent;

	/* all descriptor memory */
	struct alx_ring_header	ring_header;
	int			tx_ringsz;
	int			rx_ringsz;
	int			rxbuf_size;

	struct alx_napi		*qnapi[8];
	/* number of napi for TX-Q */
	int			nr_txq;
	/* number of napi for RX-Q */
	int			nr_rxq;
	/* number independent hw RX-Q */
	int			nr_hwrxq;
	/* total napi for TX-Q/RX-Q */
	int			nr_napi;

	/* lock for updating stats */
	spinlock_t		smb_lock;

	struct work_struct	task;
	struct net_device_stats net_stats;
	atomic_t		irq_sem;
	u16			msg_enable;

	unsigned long		flags;

	/* ethtool private flags */
	u32			eth_pflags;
	int			eth_diag_vect;
	int			eth_diag_cnt;
};


#define ALX_FLAG(_adpt, _FLAG) (\
	test_bit(ALX_FLAG_##_FLAG, &(_adpt)->flags))
#define ALX_FLAG_SET(_adpt, _FLAG) (\
	set_bit(ALX_FLAG_##_FLAG, &(_adpt)->flags))
#define ALX_FLAG_CLEAR(_adpt, _FLAG) (\
	clear_bit(ALX_FLAG_##_FLAG, &(_adpt)->flags))

static inline struct alx_rx_queue *alx_hw_rxq(struct alx_rx_queue *rxq)
{
	struct alx_adapter *adpt = netdev_priv(rxq->netdev);

	return ALX_CAP(&adpt->hw, MRQ) ? rxq : adpt->qnapi[0]->rxq;
}

/* needed by alx_ethtool.c */
extern void alx_configure(struct alx_adapter *adpt);
extern void alx_free_all_ring_resources(struct alx_adapter *adpt);
extern int alx_setup_all_ring_resources(struct alx_adapter *adpt);
extern void alx_init_def_rss_idt(struct alx_adapter *adpt);
extern int alx_alloc_rxring_buf(struct alx_adapter *adpt,
				struct alx_rx_queue *rxq);
extern void alx_init_intr(struct alx_adapter *adpt);
extern void alx_disable_advanced_intr(struct alx_adapter *adpt);
extern void alx_reinit(struct alx_adapter *adpt);
extern void alx_set_ethtool_ops(struct net_device *dev);
extern char alx_drv_name[];
extern char alx_drv_version[];

#endif