Linux Audio

Check our new training course

Loading...
   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
 505
 506
 507
 508
 509
 510
 511
 512
 513
 514
 515
 516
 517
 518
 519
 520
 521
 522
 523
 524
 525
 526
 527
 528
 529
 530
 531
 532
 533
 534
 535
 536
 537
 538
 539
 540
 541
 542
 543
 544
 545
 546
 547
 548
 549
 550
 551
 552
 553
 554
 555
 556
 557
 558
 559
 560
 561
 562
 563
 564
 565
 566
 567
 568
 569
 570
 571
 572
 573
 574
 575
 576
 577
 578
 579
 580
 581
 582
 583
 584
 585
 586
 587
 588
 589
 590
 591
 592
 593
 594
 595
 596
 597
 598
 599
 600
 601
 602
 603
 604
 605
 606
 607
 608
 609
 610
 611
 612
 613
 614
 615
 616
 617
 618
 619
 620
 621
 622
 623
 624
 625
 626
 627
 628
 629
 630
 631
 632
 633
 634
 635
 636
 637
 638
 639
 640
 641
 642
 643
 644
 645
 646
 647
 648
 649
 650
 651
 652
 653
 654
 655
 656
 657
 658
 659
 660
 661
 662
 663
 664
 665
 666
 667
 668
 669
 670
 671
 672
 673
 674
 675
 676
 677
 678
 679
 680
 681
 682
 683
 684
 685
 686
 687
 688
 689
 690
 691
 692
 693
 694
 695
 696
 697
 698
 699
 700
 701
 702
 703
 704
 705
 706
 707
 708
 709
 710
 711
 712
 713
 714
 715
 716
 717
 718
 719
 720
 721
 722
 723
 724
 725
 726
 727
 728
 729
 730
 731
 732
 733
 734
 735
 736
 737
 738
 739
 740
 741
 742
 743
 744
 745
 746
 747
 748
 749
 750
 751
 752
 753
 754
 755
 756
 757
 758
 759
 760
 761
 762
 763
 764
 765
 766
 767
 768
 769
 770
 771
 772
 773
 774
 775
 776
 777
 778
 779
 780
 781
 782
 783
 784
 785
 786
 787
 788
 789
 790
 791
 792
 793
 794
 795
 796
 797
 798
 799
 800
 801
 802
 803
 804
 805
 806
 807
 808
 809
 810
 811
 812
 813
 814
 815
 816
 817
 818
 819
 820
 821
 822
 823
 824
 825
 826
 827
 828
 829
 830
 831
 832
 833
 834
 835
 836
 837
 838
 839
 840
 841
 842
 843
 844
 845
 846
 847
 848
 849
 850
 851
 852
 853
 854
 855
 856
 857
 858
 859
 860
 861
 862
 863
 864
 865
 866
 867
 868
 869
 870
 871
 872
 873
 874
 875
 876
 877
 878
 879
 880
 881
 882
 883
 884
 885
 886
 887
 888
 889
 890
 891
 892
 893
 894
 895
 896
 897
 898
 899
 900
 901
 902
 903
 904
 905
 906
 907
 908
 909
 910
 911
 912
 913
 914
 915
 916
 917
 918
 919
 920
 921
 922
 923
 924
 925
 926
 927
 928
 929
 930
 931
 932
 933
 934
 935
 936
 937
 938
 939
 940
 941
 942
 943
 944
 945
 946
 947
 948
 949
 950
 951
 952
 953
 954
 955
 956
 957
 958
 959
 960
 961
 962
 963
 964
 965
 966
 967
 968
 969
 970
 971
 972
 973
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
/* Copyright (C) 2015-2018 Netronome Systems, Inc. */

/*
 * nfp_net.h
 * Declarations for Netronome network device driver.
 * Authors: Jakub Kicinski <jakub.kicinski@netronome.com>
 *          Jason McMullan <jason.mcmullan@netronome.com>
 *          Rolf Neugebauer <rolf.neugebauer@netronome.com>
 */

#ifndef _NFP_NET_H_
#define _NFP_NET_H_

#include <linux/atomic.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/netdevice.h>
#include <linux/pci.h>
#include <linux/dim.h>
#include <linux/io-64-nonatomic-hi-lo.h>
#include <linux/semaphore.h>
#include <linux/workqueue.h>
#include <net/xdp.h>

#include "nfp_net_ctrl.h"

#define nn_pr(nn, lvl, fmt, args...)					\
	({								\
		struct nfp_net *__nn = (nn);				\
									\
		if (__nn->dp.netdev)					\
			netdev_printk(lvl, __nn->dp.netdev, fmt, ## args); \
		else							\
			dev_printk(lvl, __nn->dp.dev, "ctrl: " fmt, ## args); \
	})

#define nn_err(nn, fmt, args...)	nn_pr(nn, KERN_ERR, fmt, ## args)
#define nn_warn(nn, fmt, args...)	nn_pr(nn, KERN_WARNING, fmt, ## args)
#define nn_info(nn, fmt, args...)	nn_pr(nn, KERN_INFO, fmt, ## args)
#define nn_dbg(nn, fmt, args...)	nn_pr(nn, KERN_DEBUG, fmt, ## args)

#define nn_dp_warn(dp, fmt, args...)					\
	({								\
		struct nfp_net_dp *__dp = (dp);				\
									\
		if (unlikely(net_ratelimit())) {			\
			if (__dp->netdev)				\
				netdev_warn(__dp->netdev, fmt, ## args); \
			else						\
				dev_warn(__dp->dev, fmt, ## args);	\
		}							\
	})

/* Max time to wait for NFP to respond on updates (in seconds) */
#define NFP_NET_POLL_TIMEOUT	5

/* Interval for reading offloaded filter stats */
#define NFP_NET_STAT_POLL_IVL	msecs_to_jiffies(100)

/* Bar allocation */
#define NFP_NET_CTRL_BAR	0
#define NFP_NET_Q0_BAR		2
#define NFP_NET_Q1_BAR		4	/* OBSOLETE */

/* Default size for MTU and freelist buffer sizes */
#define NFP_NET_DEFAULT_MTU		1500U

/* Maximum number of bytes prepended to a packet */
#define NFP_NET_MAX_PREPEND		64

/* Interrupt definitions */
#define NFP_NET_NON_Q_VECTORS		2
#define NFP_NET_IRQ_LSC_IDX		0
#define NFP_NET_IRQ_EXN_IDX		1
#define NFP_NET_MIN_VNIC_IRQS		(NFP_NET_NON_Q_VECTORS + 1)

/* Queue/Ring definitions */
#define NFP_NET_MAX_TX_RINGS	64	/* Max. # of Tx rings per device */
#define NFP_NET_MAX_RX_RINGS	64	/* Max. # of Rx rings per device */
#define NFP_NET_MAX_R_VECS	(NFP_NET_MAX_TX_RINGS > NFP_NET_MAX_RX_RINGS ? \
				 NFP_NET_MAX_TX_RINGS : NFP_NET_MAX_RX_RINGS)
#define NFP_NET_MAX_IRQS	(NFP_NET_NON_Q_VECTORS + NFP_NET_MAX_R_VECS)

#define NFP_NET_TX_DESCS_DEFAULT 4096	/* Default # of Tx descs per ring */
#define NFP_NET_RX_DESCS_DEFAULT 4096	/* Default # of Rx descs per ring */

#define NFP_NET_FL_BATCH	16	/* Add freelist in this Batch size */
#define NFP_NET_XDP_MAX_COMPLETE 2048	/* XDP bufs to reclaim in NAPI poll */

/* MC definitions */
#define NFP_NET_CFG_MAC_MC_MAX	1024	/* The maximum number of MC address per port*/

/* Offload definitions */
#define NFP_NET_N_VXLAN_PORTS	(NFP_NET_CFG_VXLAN_SZ / sizeof(__be16))

#define NFP_NET_RX_BUF_HEADROOM	(NET_SKB_PAD + NET_IP_ALIGN)
#define NFP_NET_RX_BUF_NON_DATA	(NFP_NET_RX_BUF_HEADROOM +		\
				 SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))

/* Forward declarations */
struct nfp_cpp;
struct nfp_dev_info;
struct nfp_dp_ops;
struct nfp_eth_table_port;
struct nfp_net;
struct nfp_net_r_vector;
struct nfp_port;
struct xsk_buff_pool;

struct nfp_nfd3_tx_desc;
struct nfp_nfd3_tx_buf;

struct nfp_nfdk_tx_desc;
struct nfp_nfdk_tx_buf;

/* Convenience macro for wrapping descriptor index on ring size */
#define D_IDX(ring, idx)	((idx) & ((ring)->cnt - 1))

/* Convenience macro for writing dma address into RX/TX descriptors */
#define nfp_desc_set_dma_addr_40b(desc, dma_addr)			\
	do {								\
		__typeof__(desc) __d = (desc);				\
		dma_addr_t __addr = (dma_addr);				\
									\
		__d->dma_addr_lo = cpu_to_le32(lower_32_bits(__addr));	\
		__d->dma_addr_hi = upper_32_bits(__addr) & 0xff;	\
	} while (0)

#define nfp_desc_set_dma_addr_48b(desc, dma_addr)			\
	do {								\
		__typeof__(desc) __d = (desc);				\
		dma_addr_t __addr = (dma_addr);				\
									\
		__d->dma_addr_hi = cpu_to_le16(upper_32_bits(__addr));	\
		__d->dma_addr_lo = cpu_to_le32(lower_32_bits(__addr));	\
	} while (0)

/**
 * struct nfp_net_tx_ring - TX ring structure
 * @r_vec:      Back pointer to ring vector structure
 * @idx:        Ring index from Linux's perspective
 * @data_pending: number of bytes added to current block (NFDK only)
 * @qcp_q:      Pointer to base of the QCP TX queue
 * @txrwb:	TX pointer write back area
 * @cnt:        Size of the queue in number of descriptors
 * @wr_p:       TX ring write pointer (free running)
 * @rd_p:       TX ring read pointer (free running)
 * @qcp_rd_p:   Local copy of QCP TX queue read pointer
 * @wr_ptr_add:	Accumulated number of buffers to add to QCP write pointer
 *		(used for .xmit_more delayed kick)
 * @txbufs:	Array of transmitted TX buffers, to free on transmit (NFD3)
 * @ktxbufs:	Array of transmitted TX buffers, to free on transmit (NFDK)
 * @txds:	Virtual address of TX ring in host memory (NFD3)
 * @ktxds:	Virtual address of TX ring in host memory (NFDK)
 *
 * @qcidx:      Queue Controller Peripheral (QCP) queue index for the TX queue
 * @dma:        DMA address of the TX ring
 * @size:       Size, in bytes, of the TX ring (needed to free)
 * @is_xdp:	Is this a XDP TX ring?
 */
struct nfp_net_tx_ring {
	struct nfp_net_r_vector *r_vec;

	u16 idx;
	u16 data_pending;
	u8 __iomem *qcp_q;
	u64 *txrwb;

	u32 cnt;
	u32 wr_p;
	u32 rd_p;
	u32 qcp_rd_p;

	u32 wr_ptr_add;

	union {
		struct nfp_nfd3_tx_buf *txbufs;
		struct nfp_nfdk_tx_buf *ktxbufs;
	};
	union {
		struct nfp_nfd3_tx_desc *txds;
		struct nfp_nfdk_tx_desc *ktxds;
	};

	/* Cold data follows */
	int qcidx;

	dma_addr_t dma;
	size_t size;
	bool is_xdp;
} ____cacheline_aligned;

/* RX and freelist descriptor format */

#define PCIE_DESC_RX_DD			BIT(7)
#define PCIE_DESC_RX_META_LEN_MASK	GENMASK(6, 0)

/* Flags in the RX descriptor */
#define PCIE_DESC_RX_RSS		cpu_to_le16(BIT(15))
#define PCIE_DESC_RX_I_IP4_CSUM		cpu_to_le16(BIT(14))
#define PCIE_DESC_RX_I_IP4_CSUM_OK	cpu_to_le16(BIT(13))
#define PCIE_DESC_RX_I_TCP_CSUM		cpu_to_le16(BIT(12))
#define PCIE_DESC_RX_I_TCP_CSUM_OK	cpu_to_le16(BIT(11))
#define PCIE_DESC_RX_I_UDP_CSUM		cpu_to_le16(BIT(10))
#define PCIE_DESC_RX_I_UDP_CSUM_OK	cpu_to_le16(BIT(9))
#define PCIE_DESC_RX_DECRYPTED		cpu_to_le16(BIT(8))
#define PCIE_DESC_RX_EOP		cpu_to_le16(BIT(7))
#define PCIE_DESC_RX_IP4_CSUM		cpu_to_le16(BIT(6))
#define PCIE_DESC_RX_IP4_CSUM_OK	cpu_to_le16(BIT(5))
#define PCIE_DESC_RX_TCP_CSUM		cpu_to_le16(BIT(4))
#define PCIE_DESC_RX_TCP_CSUM_OK	cpu_to_le16(BIT(3))
#define PCIE_DESC_RX_UDP_CSUM		cpu_to_le16(BIT(2))
#define PCIE_DESC_RX_UDP_CSUM_OK	cpu_to_le16(BIT(1))
#define PCIE_DESC_RX_VLAN		cpu_to_le16(BIT(0))

#define PCIE_DESC_RX_CSUM_ALL		(PCIE_DESC_RX_IP4_CSUM |	\
					 PCIE_DESC_RX_TCP_CSUM |	\
					 PCIE_DESC_RX_UDP_CSUM |	\
					 PCIE_DESC_RX_I_IP4_CSUM |	\
					 PCIE_DESC_RX_I_TCP_CSUM |	\
					 PCIE_DESC_RX_I_UDP_CSUM)
#define PCIE_DESC_RX_CSUM_OK_SHIFT	1
#define __PCIE_DESC_RX_CSUM_ALL		le16_to_cpu(PCIE_DESC_RX_CSUM_ALL)
#define __PCIE_DESC_RX_CSUM_ALL_OK	(__PCIE_DESC_RX_CSUM_ALL >>	\
					 PCIE_DESC_RX_CSUM_OK_SHIFT)

struct nfp_net_rx_desc {
	union {
		struct {
			__le16 dma_addr_hi; /* High bits of the buf address */
			u8 reserved; /* Must be zero */
			u8 meta_len_dd; /* Must be zero */

			__le32 dma_addr_lo; /* Low bits of the buffer address */
		} __packed fld;

		struct {
			__le16 data_len; /* Length of the frame + meta data */
			u8 reserved;
			u8 meta_len_dd;	/* Length of meta data prepended +
					 * descriptor done flag.
					 */

			__le16 flags;	/* RX flags. See @PCIE_DESC_RX_* */
			__le16 vlan;	/* VLAN if stripped */
		} __packed rxd;

		__le32 vals[2];
	};
};

#define NFP_NET_META_FIELD_MASK GENMASK(NFP_NET_META_FIELD_SIZE - 1, 0)
#define NFP_NET_VLAN_CTAG	0
#define NFP_NET_VLAN_STAG	1

struct nfp_meta_parsed {
	u8 hash_type;
	u8 csum_type;
	u32 hash;
	u32 mark;
	u32 portid;
	__wsum csum;
	struct {
		bool stripped;
		u8 tpid;
		u16 tci;
	} vlan;

#ifdef CONFIG_NFP_NET_IPSEC
	u32 ipsec_saidx;
#endif
};

struct nfp_net_rx_hash {
	__be32 hash_type;
	__be32 hash;
};

/**
 * struct nfp_net_rx_buf - software RX buffer descriptor
 * @frag:	page fragment buffer
 * @dma_addr:	DMA mapping address of the buffer
 */
struct nfp_net_rx_buf {
	void *frag;
	dma_addr_t dma_addr;
};

/**
 * struct nfp_net_xsk_rx_buf - software RX XSK buffer descriptor
 * @dma_addr:	DMA mapping address of the buffer
 * @xdp:	XSK buffer pool handle (for AF_XDP)
 */
struct nfp_net_xsk_rx_buf {
	dma_addr_t dma_addr;
	struct xdp_buff *xdp;
};

/**
 * struct nfp_net_rx_ring - RX ring structure
 * @r_vec:      Back pointer to ring vector structure
 * @cnt:        Size of the queue in number of descriptors
 * @wr_p:       FL/RX ring write pointer (free running)
 * @rd_p:       FL/RX ring read pointer (free running)
 * @idx:        Ring index from Linux's perspective
 * @fl_qcidx:   Queue Controller Peripheral (QCP) queue index for the freelist
 * @qcp_fl:     Pointer to base of the QCP freelist queue
 * @rxbufs:     Array of transmitted FL/RX buffers
 * @xsk_rxbufs: Array of transmitted FL/RX buffers (for AF_XDP)
 * @rxds:       Virtual address of FL/RX ring in host memory
 * @xdp_rxq:    RX-ring info avail for XDP
 * @dma:        DMA address of the FL/RX ring
 * @size:       Size, in bytes, of the FL/RX ring (needed to free)
 */
struct nfp_net_rx_ring {
	struct nfp_net_r_vector *r_vec;

	u32 cnt;
	u32 wr_p;
	u32 rd_p;

	u32 idx;

	int fl_qcidx;
	u8 __iomem *qcp_fl;

	struct nfp_net_rx_buf *rxbufs;
	struct nfp_net_xsk_rx_buf *xsk_rxbufs;
	struct nfp_net_rx_desc *rxds;

	struct xdp_rxq_info xdp_rxq;

	dma_addr_t dma;
	size_t size;
} ____cacheline_aligned;

/**
 * struct nfp_net_r_vector - Per ring interrupt vector configuration
 * @nfp_net:        Backpointer to nfp_net structure
 * @napi:           NAPI structure for this ring vec
 * @tasklet:        ctrl vNIC, tasklet for servicing the r_vec
 * @queue:          ctrl vNIC, send queue
 * @lock:           ctrl vNIC, r_vec lock protects @queue
 * @tx_ring:        Pointer to TX ring
 * @rx_ring:        Pointer to RX ring
 * @xdp_ring:	    Pointer to an extra TX ring for XDP
 * @xsk_pool:	    XSK buffer pool active on vector queue pair (for AF_XDP)
 * @irq_entry:      MSI-X table entry (use for talking to the device)
 * @event_ctr:	    Number of interrupt
 * @rx_dim:	    Dynamic interrupt moderation structure for RX
 * @tx_dim:	    Dynamic interrupt moderation structure for TX
 * @rx_sync:	    Seqlock for atomic updates of RX stats
 * @rx_pkts:        Number of received packets
 * @rx_bytes:	    Number of received bytes
 * @rx_drops:	    Number of packets dropped on RX due to lack of resources
 * @hw_csum_rx_ok:  Counter of packets where the HW checksum was OK
 * @hw_csum_rx_inner_ok: Counter of packets where the inner HW checksum was OK
 * @hw_csum_rx_complete: Counter of packets with CHECKSUM_COMPLETE reported
 * @hw_csum_rx_error:	 Counter of packets with bad checksums
 * @hw_tls_rx:	    Number of packets with TLS decrypted by hardware
 * @tx_sync:	    Seqlock for atomic updates of TX stats
 * @tx_pkts:	    Number of Transmitted packets
 * @tx_bytes:	    Number of Transmitted bytes
 * @hw_csum_tx:	    Counter of packets with TX checksum offload requested
 * @hw_csum_tx_inner:	 Counter of inner TX checksum offload requests
 * @tx_gather:	    Counter of packets with Gather DMA
 * @tx_lso:	    Counter of LSO packets sent
 * @hw_tls_tx:	    Counter of TLS packets sent with crypto offloaded to HW
 * @tls_tx_fallback:	Counter of TLS packets sent which had to be encrypted
 *			by the fallback path because packets came out of order
 * @tls_tx_no_fallback:	Counter of TLS packets not sent because the fallback
 *			path could not encrypt them
 * @tx_errors:	    How many TX errors were encountered
 * @tx_busy:        How often was TX busy (no space)?
 * @rx_replace_buf_alloc_fail:	Counter of RX buffer allocation failures
 * @irq_vector:     Interrupt vector number (use for talking to the OS)
 * @handler:        Interrupt handler for this ring vector
 * @name:           Name of the interrupt vector
 * @affinity_mask:  SMP affinity mask for this vector
 *
 * This structure ties RX and TX rings to interrupt vectors and a NAPI
 * context. This currently only supports one RX and TX ring per
 * interrupt vector but might be extended in the future to allow
 * association of multiple rings per vector.
 */
struct nfp_net_r_vector {
	struct nfp_net *nfp_net;
	union {
		struct napi_struct napi;
		struct {
			struct tasklet_struct tasklet;
			struct sk_buff_head queue;
			spinlock_t lock;
		};
	};

	struct nfp_net_tx_ring *tx_ring;
	struct nfp_net_rx_ring *rx_ring;

	u16 irq_entry;

	u16 event_ctr;
	struct dim rx_dim;
	struct dim tx_dim;

	struct u64_stats_sync rx_sync;
	u64 rx_pkts;
	u64 rx_bytes;
	u64 rx_drops;
	u64 hw_csum_rx_ok;
	u64 hw_csum_rx_inner_ok;
	u64 hw_csum_rx_complete;
	u64 hw_tls_rx;

	u64 hw_csum_rx_error;
	u64 rx_replace_buf_alloc_fail;

	struct nfp_net_tx_ring *xdp_ring;
	struct xsk_buff_pool *xsk_pool;

	struct u64_stats_sync tx_sync;
	u64 tx_pkts;
	u64 tx_bytes;

	u64 ____cacheline_aligned_in_smp hw_csum_tx;
	u64 hw_csum_tx_inner;
	u64 tx_gather;
	u64 tx_lso;
	u64 hw_tls_tx;

	u64 tls_tx_fallback;
	u64 tls_tx_no_fallback;
	u64 tx_errors;
	u64 tx_busy;

	/* Cold data follows */

	u32 irq_vector;
	irq_handler_t handler;
	char name[IFNAMSIZ + 8];
	cpumask_t affinity_mask;
} ____cacheline_aligned;

/* Firmware version as it is written in the 32bit value in the BAR */
struct nfp_net_fw_version {
	u8 minor;
	u8 major;
	u8 class;

	/* This byte can be exploited for more use, currently,
	 * BIT0: dp type, BIT[7:1]: reserved
	 */
	u8 extend;
} __packed;

static inline bool nfp_net_fw_ver_eq(struct nfp_net_fw_version *fw_ver,
				     u8 extend, u8 class, u8 major, u8 minor)
{
	return fw_ver->extend == extend &&
	       fw_ver->class == class &&
	       fw_ver->major == major &&
	       fw_ver->minor == minor;
}

struct nfp_stat_pair {
	u64 pkts;
	u64 bytes;
};

/**
 * struct nfp_net_dp - NFP network device datapath data structure
 * @dev:		Backpointer to struct device
 * @netdev:		Backpointer to net_device structure
 * @is_vf:		Is the driver attached to a VF?
 * @chained_metadata_format:  Firemware will use new metadata format
 * @ktls_tx:		Is kTLS TX enabled?
 * @rx_dma_dir:		Mapping direction for RX buffers
 * @rx_dma_off:		Offset at which DMA packets (for XDP headroom)
 * @rx_offset:		Offset in the RX buffers where packet data starts
 * @ctrl:		Local copy of the control register/word.
 * @ctrl_w1:		Local copy of the control register/word1.
 * @fl_bufsz:		Currently configured size of the freelist buffers
 * @xdp_prog:		Installed XDP program
 * @tx_rings:		Array of pre-allocated TX ring structures
 * @rx_rings:		Array of pre-allocated RX ring structures
 * @ctrl_bar:		Pointer to mapped control BAR
 *
 * @ops:		Callbacks and parameters for this vNIC's NFD version
 * @txrwb:		TX pointer write back area (indexed by queue id)
 * @txrwb_dma:		TX pointer write back area DMA address
 * @txd_cnt:		Size of the TX ring in number of min size packets
 * @rxd_cnt:		Size of the RX ring in number of min size packets
 * @num_r_vecs:		Number of used ring vectors
 * @num_tx_rings:	Currently configured number of TX rings
 * @num_stack_tx_rings:	Number of TX rings used by the stack (not XDP)
 * @num_rx_rings:	Currently configured number of RX rings
 * @mtu:		Device MTU
 * @xsk_pools:		XSK buffer pools, @max_r_vecs in size (for AF_XDP).
 */
struct nfp_net_dp {
	struct device *dev;
	struct net_device *netdev;

	u8 is_vf:1;
	u8 chained_metadata_format:1;
	u8 ktls_tx:1;

	u8 rx_dma_dir;
	u8 rx_offset;

	u32 rx_dma_off;

	u32 ctrl;
	u32 ctrl_w1;
	u32 fl_bufsz;

	struct bpf_prog *xdp_prog;

	struct nfp_net_tx_ring *tx_rings;
	struct nfp_net_rx_ring *rx_rings;

	u8 __iomem *ctrl_bar;

	/* Cold data follows */

	const struct nfp_dp_ops *ops;

	u64 *txrwb;
	dma_addr_t txrwb_dma;

	unsigned int txd_cnt;
	unsigned int rxd_cnt;

	unsigned int num_r_vecs;

	unsigned int num_tx_rings;
	unsigned int num_stack_tx_rings;
	unsigned int num_rx_rings;

	unsigned int mtu;

	struct xsk_buff_pool **xsk_pools;
};

/**
 * struct nfp_net - NFP network device structure
 * @dp:			Datapath structure
 * @dev_info:		NFP ASIC params
 * @id:			vNIC id within the PF (0 for VFs)
 * @fw_ver:		Firmware version
 * @cap:                Capabilities advertised by the Firmware
 * @cap_w1:             Extended capabilities word advertised by the Firmware
 * @max_mtu:            Maximum support MTU advertised by the Firmware
 * @rss_hfunc:		RSS selected hash function
 * @rss_cfg:            RSS configuration
 * @rss_key:            RSS secret key
 * @rss_itbl:           RSS indirection table
 * @xdp:		Information about the driver XDP program
 * @xdp_hw:		Information about the HW XDP program
 * @max_r_vecs:		Number of allocated interrupt vectors for RX/TX
 * @max_tx_rings:       Maximum number of TX rings supported by the Firmware
 * @max_rx_rings:       Maximum number of RX rings supported by the Firmware
 * @stride_rx:		Queue controller RX queue spacing
 * @stride_tx:		Queue controller TX queue spacing
 * @r_vecs:             Pre-allocated array of ring vectors
 * @irq_entries:        Pre-allocated array of MSI-X entries
 * @lsc_handler:        Handler for Link State Change interrupt
 * @lsc_name:           Name for Link State Change interrupt
 * @exn_handler:        Handler for Exception interrupt
 * @exn_name:           Name for Exception interrupt
 * @shared_handler:     Handler for shared interrupts
 * @shared_name:        Name for shared interrupt
 * @reconfig_lock:	Protects @reconfig_posted, @reconfig_timer_active,
 *			@reconfig_sync_present and HW reconfiguration request
 *			regs/machinery from async requests (sync must take
 *			@bar_lock)
 * @reconfig_posted:	Pending reconfig bits coming from async sources
 * @reconfig_timer_active:  Timer for reading reconfiguration results is pending
 * @reconfig_sync_present:  Some thread is performing synchronous reconfig
 * @reconfig_timer:	Timer for async reading of reconfig results
 * @reconfig_in_progress_update:	Update FW is processing now (debug only)
 * @bar_lock:		vNIC config BAR access lock, protects: update,
 *			mailbox area, crypto TLV
 * @link_up:            Is the link up?
 * @link_status_lock:	Protects @link_* and ensures atomicity with BAR reading
 * @rx_coalesce_adapt_on:   Is RX interrupt moderation adaptive?
 * @tx_coalesce_adapt_on:   Is TX interrupt moderation adaptive?
 * @rx_coalesce_usecs:      RX interrupt moderation usecs delay parameter
 * @rx_coalesce_max_frames: RX interrupt moderation frame count parameter
 * @tx_coalesce_usecs:      TX interrupt moderation usecs delay parameter
 * @tx_coalesce_max_frames: TX interrupt moderation frame count parameter
 * @qcp_cfg:            Pointer to QCP queue used for configuration notification
 * @tx_bar:             Pointer to mapped TX queues
 * @rx_bar:             Pointer to mapped FL/RX queues
 * @xa_ipsec:           IPsec xarray SA data
 * @tlv_caps:		Parsed TLV capabilities
 * @ktls_tx_conn_cnt:	Number of offloaded kTLS TX connections
 * @ktls_rx_conn_cnt:	Number of offloaded kTLS RX connections
 * @ktls_conn_id_gen:	Trivial generator for kTLS connection ids (for TX)
 * @ktls_no_space:	Counter of firmware rejecting kTLS connection due to
 *			lack of space
 * @ktls_rx_resync_req:	Counter of TLS RX resync requested
 * @ktls_rx_resync_ign:	Counter of TLS RX resync requests ignored
 * @ktls_rx_resync_sent:    Counter of TLS RX resync completed
 * @mbox_cmsg:		Common Control Message via vNIC mailbox state
 * @mbox_cmsg.queue:	CCM mbox queue of pending messages
 * @mbox_cmsg.wq:	CCM mbox wait queue of waiting processes
 * @mbox_cmsg.workq:	CCM mbox work queue for @wait_work and @runq_work
 * @mbox_cmsg.wait_work:    CCM mbox posted msg reconfig wait work
 * @mbox_cmsg.runq_work:    CCM mbox posted msg queue runner work
 * @mbox_cmsg.tag:	CCM mbox message tag allocator
 * @debugfs_dir:	Device directory in debugfs
 * @vnic_list:		Entry on device vNIC list
 * @pdev:		Backpointer to PCI device
 * @app:		APP handle if available
 * @vnic_no_name:	For non-port PF vNIC make ndo_get_phys_port_name return
 *			-EOPNOTSUPP to keep backwards compatibility (set by app)
 * @port:		Pointer to nfp_port structure if vNIC is a port
 * @mbox_amsg:		Asynchronously processed message via mailbox
 * @mbox_amsg.lock:	Protect message list
 * @mbox_amsg.list:	List of message to process
 * @mbox_amsg.work:	Work to process message asynchronously
 * @fs:			Flow steering
 * @fs.count:		Flow count
 * @fs.list:		List of flows
 * @app_priv:		APP private data for this vNIC
 */
struct nfp_net {
	struct nfp_net_dp dp;

	const struct nfp_dev_info *dev_info;
	struct nfp_net_fw_version fw_ver;

	u32 id;

	u32 cap;
	u32 cap_w1;
	u32 max_mtu;

	u8 rss_hfunc;
	u32 rss_cfg;
	u8 rss_key[NFP_NET_CFG_RSS_KEY_SZ];
	u8 rss_itbl[NFP_NET_CFG_RSS_ITBL_SZ];

	struct xdp_attachment_info xdp;
	struct xdp_attachment_info xdp_hw;

	unsigned int max_tx_rings;
	unsigned int max_rx_rings;

	int stride_tx;
	int stride_rx;

	unsigned int max_r_vecs;
	struct nfp_net_r_vector r_vecs[NFP_NET_MAX_R_VECS];
	struct msix_entry irq_entries[NFP_NET_MAX_IRQS];

	irq_handler_t lsc_handler;
	char lsc_name[IFNAMSIZ + 8];

	irq_handler_t exn_handler;
	char exn_name[IFNAMSIZ + 8];

	irq_handler_t shared_handler;
	char shared_name[IFNAMSIZ + 8];

	bool link_up;
	spinlock_t link_status_lock;

	spinlock_t reconfig_lock;
	u32 reconfig_posted;
	bool reconfig_timer_active;
	bool reconfig_sync_present;
	struct timer_list reconfig_timer;
	u32 reconfig_in_progress_update;

	struct semaphore bar_lock;

	bool rx_coalesce_adapt_on;
	bool tx_coalesce_adapt_on;
	u32 rx_coalesce_usecs;
	u32 rx_coalesce_max_frames;
	u32 tx_coalesce_usecs;
	u32 tx_coalesce_max_frames;

	u8 __iomem *qcp_cfg;

	u8 __iomem *tx_bar;
	u8 __iomem *rx_bar;

#ifdef CONFIG_NFP_NET_IPSEC
	struct xarray xa_ipsec;
#endif

	struct nfp_net_tlv_caps tlv_caps;

	unsigned int ktls_tx_conn_cnt;
	unsigned int ktls_rx_conn_cnt;

	atomic64_t ktls_conn_id_gen;

	atomic_t ktls_no_space;
	atomic_t ktls_rx_resync_req;
	atomic_t ktls_rx_resync_ign;
	atomic_t ktls_rx_resync_sent;

	struct {
		struct sk_buff_head queue;
		wait_queue_head_t wq;
		struct workqueue_struct *workq;
		struct work_struct wait_work;
		struct work_struct runq_work;
		u16 tag;
	} mbox_cmsg;

	struct dentry *debugfs_dir;

	struct list_head vnic_list;

	struct pci_dev *pdev;
	struct nfp_app *app;

	bool vnic_no_name;

	struct nfp_port *port;

	struct {
		spinlock_t lock;
		struct list_head list;
		struct work_struct work;
	} mbox_amsg;

	struct {
		u16 count;
		struct list_head list;
	} fs;

	void *app_priv;
};

struct nfp_fs_entry {
	struct list_head node;
	u32 flow_type;
	u32 loc;
	struct {
		union {
			struct {
				__be32 sip4;
				__be32 dip4;
			};
			struct {
				__be32 sip6[4];
				__be32 dip6[4];
			};
		};
		union {
			__be16 l3_proto;
			u8 l4_proto;
		};
		__be16 sport;
		__be16 dport;
	} key, msk;
	u64 action;
};

struct nfp_mbox_amsg_entry {
	struct list_head list;
	int (*cfg)(struct nfp_net *nn, struct nfp_mbox_amsg_entry *entry);
	u32 cmd;
	char msg[];
};

int nfp_net_sched_mbox_amsg_work(struct nfp_net *nn, u32 cmd, const void *data, size_t len,
				 int (*cb)(struct nfp_net *, struct nfp_mbox_amsg_entry *));

/* Functions to read/write from/to a BAR
 * Performs any endian conversion necessary.
 */
static inline u16 nn_readb(struct nfp_net *nn, int off)
{
	return readb(nn->dp.ctrl_bar + off);
}

static inline void nn_writeb(struct nfp_net *nn, int off, u8 val)
{
	writeb(val, nn->dp.ctrl_bar + off);
}

static inline u16 nn_readw(struct nfp_net *nn, int off)
{
	return readw(nn->dp.ctrl_bar + off);
}

static inline void nn_writew(struct nfp_net *nn, int off, u16 val)
{
	writew(val, nn->dp.ctrl_bar + off);
}

static inline u32 nn_readl(struct nfp_net *nn, int off)
{
	return readl(nn->dp.ctrl_bar + off);
}

static inline void nn_writel(struct nfp_net *nn, int off, u32 val)
{
	writel(val, nn->dp.ctrl_bar + off);
}

static inline u64 nn_readq(struct nfp_net *nn, int off)
{
	return readq(nn->dp.ctrl_bar + off);
}

static inline void nn_writeq(struct nfp_net *nn, int off, u64 val)
{
	writeq(val, nn->dp.ctrl_bar + off);
}

/* Flush posted PCI writes by reading something without side effects */
static inline void nn_pci_flush(struct nfp_net *nn)
{
	nn_readl(nn, NFP_NET_CFG_VERSION);
}

/* Queue Controller Peripheral access functions and definitions.
 *
 * Some of the BARs of the NFP are mapped to portions of the Queue
 * Controller Peripheral (QCP) address space on the NFP.  A QCP queue
 * has a read and a write pointer (as well as a size and flags,
 * indicating overflow etc).  The QCP offers a number of different
 * operation on queue pointers, but here we only offer function to
 * either add to a pointer or to read the pointer value.
 */
#define NFP_QCP_QUEUE_ADDR_SZ			0x800
#define NFP_QCP_QUEUE_OFF(_x)			((_x) * NFP_QCP_QUEUE_ADDR_SZ)
#define NFP_QCP_QUEUE_ADD_RPTR			0x0000
#define NFP_QCP_QUEUE_ADD_WPTR			0x0004
#define NFP_QCP_QUEUE_STS_LO			0x0008
#define NFP_QCP_QUEUE_STS_LO_READPTR_mask	0x3ffff
#define NFP_QCP_QUEUE_STS_HI			0x000c
#define NFP_QCP_QUEUE_STS_HI_WRITEPTR_mask	0x3ffff

/* nfp_qcp_ptr - Read or Write Pointer of a queue */
enum nfp_qcp_ptr {
	NFP_QCP_READ_PTR = 0,
	NFP_QCP_WRITE_PTR
};

/**
 * nfp_qcp_rd_ptr_add() - Add the value to the read pointer of a queue
 *
 * @q:   Base address for queue structure
 * @val: Value to add to the queue pointer
 */
static inline void nfp_qcp_rd_ptr_add(u8 __iomem *q, u32 val)
{
	writel(val, q + NFP_QCP_QUEUE_ADD_RPTR);
}

/**
 * nfp_qcp_wr_ptr_add() - Add the value to the write pointer of a queue
 *
 * @q:   Base address for queue structure
 * @val: Value to add to the queue pointer
 */
static inline void nfp_qcp_wr_ptr_add(u8 __iomem *q, u32 val)
{
	writel(val, q + NFP_QCP_QUEUE_ADD_WPTR);
}

static inline u32 _nfp_qcp_read(u8 __iomem *q, enum nfp_qcp_ptr ptr)
{
	u32 off;
	u32 val;

	if (ptr == NFP_QCP_READ_PTR)
		off = NFP_QCP_QUEUE_STS_LO;
	else
		off = NFP_QCP_QUEUE_STS_HI;

	val = readl(q + off);

	if (ptr == NFP_QCP_READ_PTR)
		return val & NFP_QCP_QUEUE_STS_LO_READPTR_mask;
	else
		return val & NFP_QCP_QUEUE_STS_HI_WRITEPTR_mask;
}

/**
 * nfp_qcp_rd_ptr_read() - Read the current read pointer value for a queue
 * @q:  Base address for queue structure
 *
 * Return: Value read.
 */
static inline u32 nfp_qcp_rd_ptr_read(u8 __iomem *q)
{
	return _nfp_qcp_read(q, NFP_QCP_READ_PTR);
}

/**
 * nfp_qcp_wr_ptr_read() - Read the current write pointer value for a queue
 * @q:  Base address for queue structure
 *
 * Return: Value read.
 */
static inline u32 nfp_qcp_wr_ptr_read(u8 __iomem *q)
{
	return _nfp_qcp_read(q, NFP_QCP_WRITE_PTR);
}

u32 nfp_qcp_queue_offset(const struct nfp_dev_info *dev_info, u16 queue);

static inline bool nfp_net_is_data_vnic(struct nfp_net *nn)
{
	WARN_ON_ONCE(!nn->dp.netdev && nn->port);
	return !!nn->dp.netdev;
}

static inline bool nfp_net_running(struct nfp_net *nn)
{
	return nn->dp.ctrl & NFP_NET_CFG_CTRL_ENABLE;
}

static inline const char *nfp_net_name(struct nfp_net *nn)
{
	return nn->dp.netdev ? nn->dp.netdev->name : "ctrl";
}

static inline void nfp_ctrl_lock(struct nfp_net *nn)
	__acquires(&nn->r_vecs[0].lock)
{
	spin_lock_bh(&nn->r_vecs[0].lock);
}

static inline void nfp_ctrl_unlock(struct nfp_net *nn)
	__releases(&nn->r_vecs[0].lock)
{
	spin_unlock_bh(&nn->r_vecs[0].lock);
}

static inline void nn_ctrl_bar_lock(struct nfp_net *nn)
{
	down(&nn->bar_lock);
}

static inline bool nn_ctrl_bar_trylock(struct nfp_net *nn)
{
	return !down_trylock(&nn->bar_lock);
}

static inline void nn_ctrl_bar_unlock(struct nfp_net *nn)
{
	up(&nn->bar_lock);
}

/* Globals */
extern const char nfp_driver_version[];

extern const struct net_device_ops nfp_nfd3_netdev_ops;
extern const struct net_device_ops nfp_nfdk_netdev_ops;

static inline bool nfp_netdev_is_nfp_net(struct net_device *netdev)
{
	return netdev->netdev_ops == &nfp_nfd3_netdev_ops ||
	       netdev->netdev_ops == &nfp_nfdk_netdev_ops;
}

static inline int nfp_net_coalesce_para_check(u32 param)
{
	if (param >= ((1 << 16) - 1))
		return -EINVAL;

	return 0;
}

/* Prototypes */
void nfp_net_get_fw_version(struct nfp_net_fw_version *fw_ver,
			    void __iomem *ctrl_bar);

struct nfp_net *
nfp_net_alloc(struct pci_dev *pdev, const struct nfp_dev_info *dev_info,
	      void __iomem *ctrl_bar, bool needs_netdev,
	      unsigned int max_tx_rings, unsigned int max_rx_rings);
void nfp_net_free(struct nfp_net *nn);

int nfp_net_init(struct nfp_net *nn);
void nfp_net_clean(struct nfp_net *nn);

int nfp_ctrl_open(struct nfp_net *nn);
void nfp_ctrl_close(struct nfp_net *nn);

void nfp_net_set_ethtool_ops(struct net_device *netdev);
void nfp_net_info(struct nfp_net *nn);
int __nfp_net_reconfig(struct nfp_net *nn, u32 update);
int nfp_net_reconfig(struct nfp_net *nn, u32 update);
unsigned int nfp_net_rss_key_sz(struct nfp_net *nn);
void nfp_net_rss_write_itbl(struct nfp_net *nn);
void nfp_net_rss_write_key(struct nfp_net *nn);
void nfp_net_coalesce_write_cfg(struct nfp_net *nn);
int nfp_net_mbox_lock(struct nfp_net *nn, unsigned int data_size);
int nfp_net_mbox_reconfig(struct nfp_net *nn, u32 mbox_cmd);
int nfp_net_mbox_reconfig_and_unlock(struct nfp_net *nn, u32 mbox_cmd);
void nfp_net_mbox_reconfig_post(struct nfp_net *nn, u32 update);
int nfp_net_mbox_reconfig_wait_posted(struct nfp_net *nn);

unsigned int
nfp_net_irqs_alloc(struct pci_dev *pdev, struct msix_entry *irq_entries,
		   unsigned int min_irqs, unsigned int want_irqs);
void nfp_net_irqs_disable(struct pci_dev *pdev);
void
nfp_net_irqs_assign(struct nfp_net *nn, struct msix_entry *irq_entries,
		    unsigned int n);
struct sk_buff *
nfp_net_tls_tx(struct nfp_net_dp *dp, struct nfp_net_r_vector *r_vec,
	       struct sk_buff *skb, u64 *tls_handle, int *nr_frags);
void nfp_net_tls_tx_undo(struct sk_buff *skb, u64 tls_handle);

struct nfp_net_dp *nfp_net_clone_dp(struct nfp_net *nn);
int nfp_net_ring_reconfig(struct nfp_net *nn, struct nfp_net_dp *new,
			  struct netlink_ext_ack *extack);

int nfp_net_fs_add_hw(struct nfp_net *nn, struct nfp_fs_entry *entry);
int nfp_net_fs_del_hw(struct nfp_net *nn, struct nfp_fs_entry *entry);

#ifdef CONFIG_NFP_DEBUG
void nfp_net_debugfs_create(void);
void nfp_net_debugfs_destroy(void);
struct dentry *nfp_net_debugfs_device_add(struct pci_dev *pdev);
void nfp_net_debugfs_vnic_add(struct nfp_net *nn, struct dentry *ddir);
void nfp_net_debugfs_dir_clean(struct dentry **dir);
#else
static inline void nfp_net_debugfs_create(void)
{
}

static inline void nfp_net_debugfs_destroy(void)
{
}

static inline struct dentry *nfp_net_debugfs_device_add(struct pci_dev *pdev)
{
	return NULL;
}

static inline void
nfp_net_debugfs_vnic_add(struct nfp_net *nn, struct dentry *ddir)
{
}

static inline void nfp_net_debugfs_dir_clean(struct dentry **dir)
{
}
#endif /* CONFIG_NFP_DEBUG */

#endif /* _NFP_NET_H_ */