aboutsummaryrefslogtreecommitdiff
path: root/include/pci_caps/px.h
blob: cd3c2f7dec82d89a46246ac05c08490b34380bfe (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
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
/*
 * Copyright (c) 2019 Nutanix Inc. All rights reserved.
 *
 * Authors: Thanos Makatos <thanos@nutanix.com>
 *          Swapnil Ingle <swapnil.ingle@nutanix.com>
 *          Felipe Franciosi <felipe@nutanix.com>
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *      * Redistributions of source code must retain the above copyright
 *        notice, this list of conditions and the following disclaimer.
 *      * Redistributions in binary form must reproduce the above copyright
 *        notice, this list of conditions and the following disclaimer in the
 *        documentation and/or other materials provided with the distribution.
 *      * Neither the name of Nutanix nor the names of its contributors may be
 *        used to endorse or promote products derived from this software without
 *        specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 *  ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 *  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 *  DAMAGE.
 *
 */

/*
 * PCI Express capability
 */

#ifndef LIB_VFIO_USER_PCI_CAPS_PX_H
#define LIB_VFIO_USER_PCI_CAPS_PX_H

#include "common.h"

#ifdef __cplusplus
extern "C" {
#endif

struct pxcaps {
    uint16_t ver:4;
    uint16_t dpt:4;
    uint16_t si:1;
    uint16_t imn:5;
    uint16_t res1:2;
} __attribute__((packed));
_Static_assert(sizeof(struct pxcaps) == 0x2, "bad PXCAPS size");

struct pxdcap {
    uint32_t mps:3;
    uint32_t pfs:2;
    uint32_t etfs:1;
    uint32_t l0sl:3;
    uint32_t l1l:3;
    uint32_t res1:3;
    uint32_t rer:1;
    uint32_t res2:2;
    uint32_t csplv:8;
    uint32_t cspls:2;
    uint32_t flrc:1;
    uint32_t res3:3;
} __attribute__((packed));
_Static_assert(sizeof(struct pxdcap) == 0x4, "bad PXDCAP size");

union pxdc {
    uint16_t raw;
    struct {
        uint16_t cere:1;
        uint16_t nfere:1;
        uint16_t fere:1;
        uint16_t urre:1;
        uint16_t ero:1;
        uint16_t mps:3;
        uint16_t ete:1;
        uint16_t pfe:1;
        uint16_t appme:1;
        uint16_t ens:1;
        uint16_t mrrs:3;
        uint16_t iflr:1;
     } __attribute__((packed));
} __attribute__((packed));
_Static_assert(sizeof(union pxdc) == 0x2, "bad PXDC size");

/* TODO not defining for now since all values are 0 for reset */
struct pxds {
    uint16_t stuff:16;
} __attribute__((packed));
_Static_assert(sizeof(struct pxds) == 0x2, "bad PXDS size");

struct pxlcap {
    uint32_t stuff:32;
} __attribute__((packed));
_Static_assert(sizeof(struct pxlcap) == 0x4, "bad PXLCAP size");

union pxlc {
    uint16_t raw;
    struct {
        uint16_t aspmc:2; /* Active State Power Management Control */
        uint16_t rsvdp1:1;
        uint16_t rcb:1; /* Read Completion Boundary */
        uint16_t ld:1; /* Link Disable */
        uint16_t rl:1; /* Retrain Link */
        uint16_t ccc:1; /* Common Clock Configuration */
        uint16_t es:1; /* Extended Synch */
        uint16_t clkreq_en:1; /* Enable Clock Power Management */
        uint16_t hawd:1; /* Hardware Autonomous Width Disable */
        uint16_t lbmie:1; /* Link Bandwidth Management Interrupt Enable */
        uint16_t labie:1; /* Link Autonomous Bandwidth Interrupt Enable */
        uint16_t rsvdp2:4;
    };
} __attribute__((packed));
_Static_assert(sizeof(union pxlc) == 0x2, "bad PXLC size");

struct pxls {
    uint16_t stuff:16;
} __attribute__((packed));
_Static_assert(sizeof(struct pxls) == 0x2, "bad PXLS size");

struct pxscap {
    uint32_t stuff:32;
} __attribute__((packed));
_Static_assert(sizeof(struct pxscap) == 0x4, "bad PXSCAP size");

struct pxsc {
    uint16_t stuff:16;
} __attribute__((packed));
_Static_assert(sizeof(struct pxsc) == 0x2, "bad PXSC size");

struct pxss {
    uint16_t stuff:16;
} __attribute__((packed));
_Static_assert(sizeof(struct pxss) == 0x2, "bad PXSS size");

struct pxrc {
    uint16_t stuff:16;
} __attribute__((packed));
_Static_assert(sizeof(struct pxrc) == 0x2, "bad PXRC size");

struct pxrcap {
    uint16_t stuff:16;
} __attribute__((packed));
_Static_assert(sizeof(struct pxrcap) == 0x2, "bad PXRCAP size");

struct pxrs {
    uint32_t stuff:32;
} __attribute__((packed));
_Static_assert(sizeof(struct pxrs) == 0x4, "bad PXRS size");

struct pxdcap2 {
    uint32_t ctrs:4;
    uint32_t ctds:1;
    uint32_t arifs:1;
    uint32_t aors:1;
    uint32_t aocs32:1;
    uint32_t aocs64:1;
    uint32_t ccs128:1;
    uint32_t nprpr:1;
    uint32_t ltrs:1;
    uint32_t tphcs:2;
    uint32_t obffs:2;
    uint32_t effs:1;
    uint32_t eetps:1;
    uint32_t meetp:2;
    uint32_t res1:8;
} __attribute__((packed));
_Static_assert(sizeof(struct pxdcap2) == 0x4, "bad PXDCAP2 size");

union pxdc2 {
    uint16_t raw;
    struct {
        uint32_t comp_timeout:4;
        uint32_t comp_timout_dis:1;
        uint32_t ari:1;
        uint32_t atomic_req:1;
        uint32_t atomic_egress_block:1;
        uint32_t ido_req_en:1;
        uint32_t ido_cmp_en:1;
        uint32_t ltr_en:1;
        uint32_t obff_en:2;
        uint32_t end_end_tlp_prefix_block:1;
    } __attribute__((packed));
} __attribute__((packed));
_Static_assert(sizeof(union pxdc2) == 0x2, "bad PXDC2 size");

struct pxds2 {
    uint16_t stuff:16;
} __attribute__((packed));
_Static_assert(sizeof(struct pxds2) == 0x2, "bad PXDS2 size");

struct pxlcap2 {
    uint32_t stuff:32;
} __attribute__((packed));
_Static_assert(sizeof(struct pxlcap2) == 0x4, "bad PXLCAP2 size");

struct pxlc2 {
    uint16_t stuff:16;
} __attribute__((packed));
_Static_assert(sizeof(struct pxlc2) == 0x2, "bad PXLC2 size");

struct pxls2 {
    uint16_t stuff:16;
} __attribute__((packed));
_Static_assert(sizeof(struct pxls2) == 0x2, "bad PXLS2 size");

struct pxscap2 {
    uint32_t stuff:32;
} __attribute__((packed));
_Static_assert(sizeof(struct pxscap2) == 0x4, "bad PXSCAP2 size");

struct pxsc2 {
    uint16_t stuff:16;
} __attribute__((packed));
_Static_assert(sizeof(struct pxsc2) == 0x2, "bad PXSC2 size");

struct pxss2 {
    uint16_t stuff:16;
} __attribute__((packed));
_Static_assert(sizeof(struct pxss2) == 0x2, "bad PXSS2 size");

/*
 * PCI_CAP_EXP_ENDPOINT_SIZEOF_V2 from pci_regs.h is a false friend: earlier
 * kernel versions defined the size as if the device was a Root Complex
 * Integrated Endpoint (size 0x2c).
 *
 * Regardless, we define the full structure anyway.
 */
#define VFIO_USER_PCI_CAP_EXP_SIZEOF (0x3c)

/*
 * PCI Express capability, defined in PCI Express 7.8.
 *
 * The relevant fields and size of this capability varies depending upon the
 * type. While we can expect, at least for now, all users to implement a PCI
 * Express Endpoint, we'll define the entire struct, on the presumption that
 * there is no issue with having additional space in the capability.
 */
struct pxcap {
    struct cap_hdr hdr;
    /* PCI Express Capabilities Register */
    struct pxcaps pxcaps;
    /* Device Capabilities */
    struct pxdcap pxdcap;
    /* Device Control */
    union pxdc pxdc;
    /* Device Status */
    struct pxds pxds;
    /* Link Capabilities */
    struct pxlcap pxlcap;
    /* Link Control */
    union pxlc pxlc;
    /* Link Status */
    struct pxls pxls;
    /* Slot Capabilities */
    struct pxscap pxscap;
    /* Slot Control */
    struct pxsc pxsc;
    /* Slot Status */
    struct pxss pxss;
    /* Root Control */
    struct pxrc pxrc;
    /* Root Capabilities */
    struct pxrcap pxrcap;
    /* Root Status */
    struct pxrs pxrs;
    /* Device Capabilities 2 */
    struct pxdcap2 pxdcap2;
    /* Device Control 2 */
    union pxdc2 pxdc2;
    /* Device Status 2 */
    struct pxds2 pxds2;
    /* Link Capabilities 2 */
    struct pxlcap2 pxlcap2;
    /* Link Control 2 */
    struct pxlc2 pxlc2;
    /* Link Status 2 */
    struct pxls2 pxls2;
    /* Slot Capabilities 2 */
    struct pxscap2 pxscap2;
    /* Slot Control 2 */
    struct pxsc2 pxsc2;
    /* Slot Status 2 */
    struct pxss2 pxss2;
} __attribute__((packed));
_Static_assert(sizeof(struct pxcap) == VFIO_USER_PCI_CAP_EXP_SIZEOF,
		"bad PCI Express Capability size");
_Static_assert(offsetof(struct pxcap, hdr) == 0, "bad offset");

#ifdef __cplusplus
}
#endif

#endif /* LIB_VFIO_USER_PCI_CAPS_PX_H */

/* ex: set tabstop=4 shiftwidth=4 softtabstop=4 expandtab: */