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
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
|
/*
* Copyright (C) 2015 Cavium, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*/
#ifndef NIC_H
#define NIC_H
#include <linux/netdevice.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include "thunder_bgx.h"
/* PCI device IDs */
#define PCI_DEVICE_ID_THUNDER_NIC_PF 0xA01E
#define PCI_DEVICE_ID_THUNDER_PASS1_NIC_VF 0x0011
#define PCI_DEVICE_ID_THUNDER_NIC_VF 0xA034
#define PCI_DEVICE_ID_THUNDER_BGX 0xA026
/* PCI BAR nos */
#define PCI_CFG_REG_BAR_NUM 0
#define PCI_MSIX_REG_BAR_NUM 4
/* NIC SRIOV VF count */
#define MAX_NUM_VFS_SUPPORTED 128
#define DEFAULT_NUM_VF_ENABLED 8
#define NIC_TNS_BYPASS_MODE 0
#define NIC_TNS_MODE 1
/* NIC priv flags */
#define NIC_SRIOV_ENABLED BIT(0)
/* Min/Max packet size */
#define NIC_HW_MIN_FRS 64
#define NIC_HW_MAX_FRS 9200 /* 9216 max packet including FCS */
/* Max pkinds */
#define NIC_MAX_PKIND 16
/* Rx Channels */
/* Receive channel configuration in TNS bypass mode
* Below is configuration in TNS bypass mode
* BGX0-LMAC0-CHAN0 - VNIC CHAN0
* BGX0-LMAC1-CHAN0 - VNIC CHAN16
* ...
* BGX1-LMAC0-CHAN0 - VNIC CHAN128
* ...
* BGX1-LMAC3-CHAN0 - VNIC CHAN174
*/
#define NIC_INTF_COUNT 2 /* Interfaces btw VNIC and TNS/BGX */
#define NIC_CHANS_PER_INF 128
#define NIC_MAX_CHANS (NIC_INTF_COUNT * NIC_CHANS_PER_INF)
#define NIC_CPI_COUNT 2048 /* No of channel parse indices */
/* TNS bypass mode: 1-1 mapping between VNIC and BGX:LMAC */
#define NIC_MAX_BGX MAX_BGX_PER_CN88XX
#define NIC_CPI_PER_BGX (NIC_CPI_COUNT / NIC_MAX_BGX)
#define NIC_MAX_CPI_PER_LMAC 64 /* Max when CPI_ALG is IP diffserv */
#define NIC_RSSI_PER_BGX (NIC_RSSI_COUNT / NIC_MAX_BGX)
/* Tx scheduling */
#define NIC_MAX_TL4 1024
#define NIC_MAX_TL4_SHAPERS 256 /* 1 shaper for 4 TL4s */
#define NIC_MAX_TL3 256
#define NIC_MAX_TL3_SHAPERS 64 /* 1 shaper for 4 TL3s */
#define NIC_MAX_TL2 64
#define NIC_MAX_TL2_SHAPERS 2 /* 1 shaper for 32 TL2s */
#define NIC_MAX_TL1 2
/* TNS bypass mode */
#define NIC_TL2_PER_BGX 32
#define NIC_TL4_PER_BGX (NIC_MAX_TL4 / NIC_MAX_BGX)
#define NIC_TL4_PER_LMAC (NIC_MAX_TL4 / NIC_CHANS_PER_INF)
/* NIC VF Interrupts */
#define NICVF_INTR_CQ 0
#define NICVF_INTR_SQ 1
#define NICVF_INTR_RBDR 2
#define NICVF_INTR_PKT_DROP 3
#define NICVF_INTR_TCP_TIMER 4
#define NICVF_INTR_MBOX 5
#define NICVF_INTR_QS_ERR 6
#define NICVF_INTR_CQ_SHIFT 0
#define NICVF_INTR_SQ_SHIFT 8
#define NICVF_INTR_RBDR_SHIFT 16
#define NICVF_INTR_PKT_DROP_SHIFT 20
#define NICVF_INTR_TCP_TIMER_SHIFT 21
#define NICVF_INTR_MBOX_SHIFT 22
#define NICVF_INTR_QS_ERR_SHIFT 23
#define NICVF_INTR_CQ_MASK (0xFF << NICVF_INTR_CQ_SHIFT)
#define NICVF_INTR_SQ_MASK (0xFF << NICVF_INTR_SQ_SHIFT)
#define NICVF_INTR_RBDR_MASK (0x03 << NICVF_INTR_RBDR_SHIFT)
#define NICVF_INTR_PKT_DROP_MASK BIT(NICVF_INTR_PKT_DROP_SHIFT)
#define NICVF_INTR_TCP_TIMER_MASK BIT(NICVF_INTR_TCP_TIMER_SHIFT)
#define NICVF_INTR_MBOX_MASK BIT(NICVF_INTR_MBOX_SHIFT)
#define NICVF_INTR_QS_ERR_MASK BIT(NICVF_INTR_QS_ERR_SHIFT)
/* MSI-X interrupts */
#define NIC_PF_MSIX_VECTORS 10
#define NIC_VF_MSIX_VECTORS 20
#define NIC_PF_INTR_ID_ECC0_SBE 0
#define NIC_PF_INTR_ID_ECC0_DBE 1
#define NIC_PF_INTR_ID_ECC1_SBE 2
#define NIC_PF_INTR_ID_ECC1_DBE 3
#define NIC_PF_INTR_ID_ECC2_SBE 4
#define NIC_PF_INTR_ID_ECC2_DBE 5
#define NIC_PF_INTR_ID_ECC3_SBE 6
#define NIC_PF_INTR_ID_ECC3_DBE 7
#define NIC_PF_INTR_ID_MBOX0 8
#define NIC_PF_INTR_ID_MBOX1 9
/* Global timer for CQ timer thresh interrupts
* Calculated for SCLK of 700Mhz
* value written should be a 1/16th of what is expected
*
* 1 tick per 0.05usec = value of 2.2
* This 10% would be covered in CQ timer thresh value
*/
#define NICPF_CLK_PER_INT_TICK 2
/* Time to wait before we decide that a SQ is stuck.
*
* Since both pkt rx and tx notifications are done with same CQ,
* when packets are being received at very high rate (eg: L2 forwarding)
* then freeing transmitted skbs will be delayed and watchdog
* will kick in, resetting interface. Hence keeping this value high.
*/
#define NICVF_TX_TIMEOUT (50 * HZ)
struct nicvf_cq_poll {
struct nicvf *nicvf;
u8 cq_idx; /* Completion queue index */
struct napi_struct napi;
};
#define NIC_RSSI_COUNT 4096 /* Total no of RSS indices */
#define NIC_MAX_RSS_HASH_BITS 8
#define NIC_MAX_RSS_IDR_TBL_SIZE (1 << NIC_MAX_RSS_HASH_BITS)
#define RSS_HASH_KEY_SIZE 5 /* 320 bit key */
struct nicvf_rss_info {
bool enable;
#define RSS_L2_EXTENDED_HASH_ENA BIT(0)
#define RSS_IP_HASH_ENA BIT(1)
#define RSS_TCP_HASH_ENA BIT(2)
#define RSS_TCP_SYN_DIS BIT(3)
#define RSS_UDP_HASH_ENA BIT(4)
#define RSS_L4_EXTENDED_HASH_ENA BIT(5)
#define RSS_ROCE_ENA BIT(6)
#define RSS_L3_BI_DIRECTION_ENA BIT(7)
#define RSS_L4_BI_DIRECTION_ENA BIT(8)
u64 cfg;
u8 hash_bits;
u16 rss_size;
u8 ind_tbl[NIC_MAX_RSS_IDR_TBL_SIZE];
u64 key[RSS_HASH_KEY_SIZE];
} ____cacheline_aligned_in_smp;
enum rx_stats_reg_offset {
RX_OCTS = 0x0,
RX_UCAST = 0x1,
RX_BCAST = 0x2,
RX_MCAST = 0x3,
RX_RED = 0x4,
RX_RED_OCTS = 0x5,
RX_ORUN = 0x6,
RX_ORUN_OCTS = 0x7,
RX_FCS = 0x8,
RX_L2ERR = 0x9,
RX_DRP_BCAST = 0xa,
RX_DRP_MCAST = 0xb,
RX_DRP_L3BCAST = 0xc,
RX_DRP_L3MCAST = 0xd,
RX_STATS_ENUM_LAST,
};
enum tx_stats_reg_offset {
TX_OCTS = 0x0,
TX_UCAST = 0x1,
TX_BCAST = 0x2,
TX_MCAST = 0x3,
TX_DROP = 0x4,
TX_STATS_ENUM_LAST,
};
struct nicvf_hw_stats {
u64 rx_bytes;
u64 rx_ucast_frames;
u64 rx_bcast_frames;
u64 rx_mcast_frames;
u64 rx_fcs_errors;
u64 rx_l2_errors;
u64 rx_drop_red;
u64 rx_drop_red_bytes;
u64 rx_drop_overrun;
u64 rx_drop_overrun_bytes;
u64 rx_drop_bcast;
u64 rx_drop_mcast;
u64 rx_drop_l3_bcast;
u64 rx_drop_l3_mcast;
u64 rx_bgx_truncated_pkts;
u64 rx_jabber_errs;
u64 rx_fcs_errs;
u64 rx_bgx_errs;
u64 rx_prel2_errs;
u64 rx_l2_hdr_malformed;
u64 rx_oversize;
u64 rx_undersize;
u64 rx_l2_len_mismatch;
u64 rx_l2_pclp;
u64 rx_ip_ver_errs;
u64 rx_ip_csum_errs;
u64 rx_ip_hdr_malformed;
u64 rx_ip_payload_malformed;
u64 rx_ip_ttl_errs;
u64 rx_l3_pclp;
u64 rx_l4_malformed;
u64 rx_l4_csum_errs;
u64 rx_udp_len_errs;
u64 rx_l4_port_errs;
u64 rx_tcp_flag_errs;
u64 rx_tcp_offset_errs;
u64 rx_l4_pclp;
u64 rx_truncated_pkts;
u64 tx_bytes_ok;
u64 tx_ucast_frames_ok;
u64 tx_bcast_frames_ok;
u64 tx_mcast_frames_ok;
u64 tx_drops;
};
struct nicvf_drv_stats {
/* Rx */
u64 rx_frames_ok;
u64 rx_frames_64;
u64 rx_frames_127;
u64 rx_frames_255;
u64 rx_frames_511;
u64 rx_frames_1023;
u64 rx_frames_1518;
u64 rx_frames_jumbo;
u64 rx_drops;
/* Tx */
u64 tx_frames_ok;
u64 tx_drops;
u64 tx_tso;
u64 txq_stop;
u64 txq_wake;
};
struct nicvf {
struct nicvf *pnicvf;
struct net_device *netdev;
struct pci_dev *pdev;
u8 vf_id;
u8 node;
u8 tns_mode:1;
u8 sqs_mode:1;
u8 loopback_supported:1;
u16 mtu;
struct queue_set *qs;
#define MAX_SQS_PER_VF_SINGLE_NODE 5
#define MAX_SQS_PER_VF 11
u8 sqs_id;
u8 sqs_count; /* Secondary Qset count */
struct nicvf *snicvf[MAX_SQS_PER_VF];
u8 rx_queues;
u8 tx_queues;
u8 max_queues;
void __iomem *reg_base;
bool link_up;
u8 duplex;
u32 speed;
struct page *rb_page;
u32 rb_page_offset;
bool rb_alloc_fail;
bool rb_work_scheduled;
struct delayed_work rbdr_work;
struct tasklet_struct rbdr_task;
struct tasklet_struct qs_err_task;
struct tasklet_struct cq_task;
struct nicvf_cq_poll *napi[8];
struct nicvf_rss_info rss_info;
u8 cpi_alg;
/* Interrupt coalescing settings */
u32 cq_coalesce_usecs;
u32 msg_enable;
struct nicvf_hw_stats hw_stats;
struct nicvf_drv_stats drv_stats;
struct bgx_stats bgx_stats;
struct work_struct reset_task;
/* MSI-X */
bool msix_enabled;
u8 num_vec;
struct msix_entry msix_entries[NIC_VF_MSIX_VECTORS];
char irq_name[NIC_VF_MSIX_VECTORS][20];
bool irq_allocated[NIC_VF_MSIX_VECTORS];
/* VF <-> PF mailbox communication */
bool pf_acked;
bool pf_nacked;
bool set_mac_pending;
} ____cacheline_aligned_in_smp;
/* PF <--> VF Mailbox communication
* Eight 64bit registers are shared between PF and VF.
* Separate set for each VF.
* Writing '1' into last register mbx7 means end of message.
*/
/* PF <--> VF mailbox communication */
#define NIC_PF_VF_MAILBOX_SIZE 2
#define NIC_MBOX_MSG_TIMEOUT 2000 /* ms */
/* Mailbox message types */
#define NIC_MBOX_MSG_READY 0x01 /* Is PF ready to rcv msgs */
#define NIC_MBOX_MSG_ACK 0x02 /* ACK the message received */
#define NIC_MBOX_MSG_NACK 0x03 /* NACK the message received */
#define NIC_MBOX_MSG_QS_CFG 0x04 /* Configure Qset */
#define NIC_MBOX_MSG_RQ_CFG 0x05 /* Configure receive queue */
#define NIC_MBOX_MSG_SQ_CFG 0x06 /* Configure Send queue */
#define NIC_MBOX_MSG_RQ_DROP_CFG 0x07 /* Configure receive queue */
#define NIC_MBOX_MSG_SET_MAC 0x08 /* Add MAC ID to DMAC filter */
#define NIC_MBOX_MSG_SET_MAX_FRS 0x09 /* Set max frame size */
#define NIC_MBOX_MSG_CPI_CFG 0x0A /* Config CPI, RSSI */
#define NIC_MBOX_MSG_RSS_SIZE 0x0B /* Get RSS indir_tbl size */
#define NIC_MBOX_MSG_RSS_CFG 0x0C /* Config RSS table */
#define NIC_MBOX_MSG_RSS_CFG_CONT 0x0D /* RSS config continuation */
#define NIC_MBOX_MSG_RQ_BP_CFG 0x0E /* RQ backpressure config */
#define NIC_MBOX_MSG_RQ_SW_SYNC 0x0F /* Flush inflight pkts to RQ */
#define NIC_MBOX_MSG_BGX_STATS 0x10 /* Get stats from BGX */
#define NIC_MBOX_MSG_BGX_LINK_CHANGE 0x11 /* BGX:LMAC link status */
#define NIC_MBOX_MSG_ALLOC_SQS 0x12 /* Allocate secondary Qset */
#define NIC_MBOX_MSG_NICVF_PTR 0x13 /* Send nicvf ptr to PF */
#define NIC_MBOX_MSG_PNICVF_PTR 0x14 /* Get primary qset nicvf ptr */
#define NIC_MBOX_MSG_SNICVF_PTR 0x15 /* Send sqet nicvf ptr to PVF */
#define NIC_MBOX_MSG_LOOPBACK 0x16 /* Set interface in loopback */
#define NIC_MBOX_MSG_CFG_DONE 0xF0 /* VF configuration done */
#define NIC_MBOX_MSG_SHUTDOWN 0xF1 /* VF is being shutdown */
struct nic_cfg_msg {
u8 msg;
u8 vf_id;
u8 node_id;
u8 tns_mode:1;
u8 sqs_mode:1;
u8 loopback_supported:1;
u8 mac_addr[ETH_ALEN];
};
/* Qset configuration */
struct qs_cfg_msg {
u8 msg;
u8 num;
u8 sqs_count;
u64 cfg;
};
/* Receive queue configuration */
struct rq_cfg_msg {
u8 msg;
u8 qs_num;
u8 rq_num;
u64 cfg;
};
/* Send queue configuration */
struct sq_cfg_msg {
u8 msg;
u8 qs_num;
u8 sq_num;
bool sqs_mode;
u64 cfg;
};
/* Set VF's MAC address */
struct set_mac_msg {
u8 msg;
u8 vf_id;
u8 mac_addr[ETH_ALEN];
};
/* Set Maximum frame size */
struct set_frs_msg {
u8 msg;
u8 vf_id;
u16 max_frs;
};
/* Set CPI algorithm type */
struct cpi_cfg_msg {
u8 msg;
u8 vf_id;
u8 rq_cnt;
u8 cpi_alg;
};
/* Get RSS table size */
struct rss_sz_msg {
u8 msg;
u8 vf_id;
u16 ind_tbl_size;
};
/* Set RSS configuration */
struct rss_cfg_msg {
u8 msg;
u8 vf_id;
u8 hash_bits;
u8 tbl_len;
u8 tbl_offset;
#define RSS_IND_TBL_LEN_PER_MBX_MSG 8
u8 ind_tbl[RSS_IND_TBL_LEN_PER_MBX_MSG];
};
struct bgx_stats_msg {
u8 msg;
u8 vf_id;
u8 rx;
u8 idx;
u64 stats;
};
/* Physical interface link status */
struct bgx_link_status {
u8 msg;
u8 link_up;
u8 duplex;
u32 speed;
};
/* Get Extra Qset IDs */
struct sqs_alloc {
u8 msg;
u8 vf_id;
u8 qs_count;
};
struct nicvf_ptr {
u8 msg;
u8 vf_id;
bool sqs_mode;
u8 sqs_id;
u64 nicvf;
};
/* Set interface in loopback mode */
struct set_loopback {
u8 msg;
u8 vf_id;
bool enable;
};
/* 128 bit shared memory between PF and each VF */
union nic_mbx {
struct { u8 msg; } msg;
struct nic_cfg_msg nic_cfg;
struct qs_cfg_msg qs;
struct rq_cfg_msg rq;
struct sq_cfg_msg sq;
struct set_mac_msg mac;
struct set_frs_msg frs;
struct cpi_cfg_msg cpi_cfg;
struct rss_sz_msg rss_size;
struct rss_cfg_msg rss_cfg;
struct bgx_stats_msg bgx_stats;
struct bgx_link_status link_status;
struct sqs_alloc sqs_alloc;
struct nicvf_ptr nicvf;
struct set_loopback lbk;
};
#define NIC_NODE_ID_MASK 0x03
#define NIC_NODE_ID_SHIFT 44
static inline int nic_get_node_id(struct pci_dev *pdev)
{
u64 addr = pci_resource_start(pdev, PCI_CFG_REG_BAR_NUM);
return ((addr >> NIC_NODE_ID_SHIFT) & NIC_NODE_ID_MASK);
}
int nicvf_set_real_num_queues(struct net_device *netdev,
int tx_queues, int rx_queues);
int nicvf_open(struct net_device *netdev);
int nicvf_stop(struct net_device *netdev);
int nicvf_send_msg_to_pf(struct nicvf *vf, union nic_mbx *mbx);
void nicvf_config_rss(struct nicvf *nic);
void nicvf_set_rss_key(struct nicvf *nic);
void nicvf_set_ethtool_ops(struct net_device *netdev);
void nicvf_update_stats(struct nicvf *nic);
void nicvf_update_lmac_stats(struct nicvf *nic);
#endif /* NIC_H */
|