1 /* SPDX-License-Identifier: (GPL-2.0 OR Linux-OpenIB) OR BSD-2-Clause */ 2 /* Copyright(c) 2023 Advanced Micro Devices, Inc. */ 3 4 #ifndef _PDS_CORE_IF_H_ 5 #define _PDS_CORE_IF_H_ 6 7 #define PCI_VENDOR_ID_PENSANDO 0x1dd8 8 #define PCI_DEVICE_ID_PENSANDO_CORE_PF 0x100c 9 #define PCI_DEVICE_ID_VIRTIO_NET_TRANS 0x1000 10 #define PCI_DEVICE_ID_PENSANDO_IONIC_ETH_VF 0x1003 11 #define PCI_DEVICE_ID_PENSANDO_VDPA_VF 0x100b 12 #define PDS_CORE_BARS_MAX 4 13 #define PDS_CORE_PCI_BAR_DBELL 1 14 15 /* Bar0 */ 16 #define PDS_CORE_DEV_INFO_SIGNATURE 0x44455649 /* 'DEVI' */ 17 #define PDS_CORE_BAR0_SIZE 0x8000 18 #define PDS_CORE_BAR0_DEV_INFO_REGS_OFFSET 0x0000 19 #define PDS_CORE_BAR0_DEV_CMD_REGS_OFFSET 0x0800 20 #define PDS_CORE_BAR0_DEV_CMD_DATA_REGS_OFFSET 0x0c00 21 #define PDS_CORE_BAR0_INTR_STATUS_OFFSET 0x1000 22 #define PDS_CORE_BAR0_INTR_CTRL_OFFSET 0x2000 23 #define PDS_CORE_DEV_CMD_DONE 0x00000001 24 25 #define PDS_CORE_DEVCMD_TIMEOUT 5 26 27 #define PDS_CORE_CLIENT_ID 0 28 #define PDS_CORE_ASIC_TYPE_CAPRI 0 29 30 /* 31 * enum pds_core_cmd_opcode - Device commands 32 */ 33 enum pds_core_cmd_opcode { 34 /* Core init */ 35 PDS_CORE_CMD_NOP = 0, 36 PDS_CORE_CMD_IDENTIFY = 1, 37 PDS_CORE_CMD_RESET = 2, 38 PDS_CORE_CMD_INIT = 3, 39 40 PDS_CORE_CMD_FW_DOWNLOAD = 4, 41 PDS_CORE_CMD_FW_CONTROL = 5, 42 43 /* SR/IOV commands */ 44 PDS_CORE_CMD_VF_GETATTR = 60, 45 PDS_CORE_CMD_VF_SETATTR = 61, 46 PDS_CORE_CMD_VF_CTRL = 62, 47 48 /* Add commands before this line */ 49 PDS_CORE_CMD_MAX, 50 PDS_CORE_CMD_COUNT 51 }; 52 53 /* 54 * enum pds_core_status_code - Device command return codes 55 */ 56 enum pds_core_status_code { 57 PDS_RC_SUCCESS = 0, /* Success */ 58 PDS_RC_EVERSION = 1, /* Incorrect version for request */ 59 PDS_RC_EOPCODE = 2, /* Invalid cmd opcode */ 60 PDS_RC_EIO = 3, /* I/O error */ 61 PDS_RC_EPERM = 4, /* Permission denied */ 62 PDS_RC_EQID = 5, /* Bad qid */ 63 PDS_RC_EQTYPE = 6, /* Bad qtype */ 64 PDS_RC_ENOENT = 7, /* No such element */ 65 PDS_RC_EINTR = 8, /* operation interrupted */ 66 PDS_RC_EAGAIN = 9, /* Try again */ 67 PDS_RC_ENOMEM = 10, /* Out of memory */ 68 PDS_RC_EFAULT = 11, /* Bad address */ 69 PDS_RC_EBUSY = 12, /* Device or resource busy */ 70 PDS_RC_EEXIST = 13, /* object already exists */ 71 PDS_RC_EINVAL = 14, /* Invalid argument */ 72 PDS_RC_ENOSPC = 15, /* No space left or alloc failure */ 73 PDS_RC_ERANGE = 16, /* Parameter out of range */ 74 PDS_RC_BAD_ADDR = 17, /* Descriptor contains a bad ptr */ 75 PDS_RC_DEV_CMD = 18, /* Device cmd attempted on AdminQ */ 76 PDS_RC_ENOSUPP = 19, /* Operation not supported */ 77 PDS_RC_ERROR = 29, /* Generic error */ 78 PDS_RC_ERDMA = 30, /* Generic RDMA error */ 79 PDS_RC_EVFID = 31, /* VF ID does not exist */ 80 PDS_RC_BAD_FW = 32, /* FW file is invalid or corrupted */ 81 PDS_RC_ECLIENT = 33, /* No such client id */ 82 PDS_RC_BAD_PCI = 255, /* Broken PCI when reading status */ 83 }; 84 85 /** 86 * struct pds_core_drv_identity - Driver identity information 87 * @drv_type: Driver type (enum pds_core_driver_type) 88 * @os_dist: OS distribution, numeric format 89 * @os_dist_str: OS distribution, string format 90 * @kernel_ver: Kernel version, numeric format 91 * @kernel_ver_str: Kernel version, string format 92 * @driver_ver_str: Driver version, string format 93 */ 94 struct pds_core_drv_identity { 95 __le32 drv_type; 96 __le32 os_dist; 97 char os_dist_str[128]; 98 __le32 kernel_ver; 99 char kernel_ver_str[32]; 100 char driver_ver_str[32]; 101 }; 102 103 #define PDS_DEV_TYPE_MAX 16 104 /** 105 * struct pds_core_dev_identity - Device identity information 106 * @version: Version of device identify 107 * @type: Identify type (0 for now) 108 * @state: Device state 109 * @rsvd: Word boundary padding 110 * @nlifs: Number of LIFs provisioned 111 * @nintrs: Number of interrupts provisioned 112 * @ndbpgs_per_lif: Number of doorbell pages per LIF 113 * @intr_coal_mult: Interrupt coalescing multiplication factor 114 * Scale user-supplied interrupt coalescing 115 * value in usecs to device units using: 116 * device units = usecs * mult / div 117 * @intr_coal_div: Interrupt coalescing division factor 118 * Scale user-supplied interrupt coalescing 119 * value in usecs to device units using: 120 * device units = usecs * mult / div 121 * @vif_types: How many of each VIF device type is supported 122 */ 123 struct pds_core_dev_identity { 124 u8 version; 125 u8 type; 126 u8 state; 127 u8 rsvd; 128 __le32 nlifs; 129 __le32 nintrs; 130 __le32 ndbpgs_per_lif; 131 __le32 intr_coal_mult; 132 __le32 intr_coal_div; 133 __le16 vif_types[PDS_DEV_TYPE_MAX]; 134 }; 135 136 #define PDS_CORE_IDENTITY_VERSION_1 1 137 138 /** 139 * struct pds_core_dev_identify_cmd - Driver/device identify command 140 * @opcode: Opcode PDS_CORE_CMD_IDENTIFY 141 * @ver: Highest version of identify supported by driver 142 * 143 * Expects to find driver identification info (struct pds_core_drv_identity) 144 * in cmd_regs->data. Driver should keep the devcmd interface locked 145 * while preparing the driver info. 146 */ 147 struct pds_core_dev_identify_cmd { 148 u8 opcode; 149 u8 ver; 150 }; 151 152 /** 153 * struct pds_core_dev_identify_comp - Device identify command completion 154 * @status: Status of the command (enum pds_core_status_code) 155 * @ver: Version of identify returned by device 156 * 157 * Device identification info (struct pds_core_dev_identity) can be found 158 * in cmd_regs->data. Driver should keep the devcmd interface locked 159 * while reading the results. 160 */ 161 struct pds_core_dev_identify_comp { 162 u8 status; 163 u8 ver; 164 }; 165 166 /** 167 * struct pds_core_dev_reset_cmd - Device reset command 168 * @opcode: Opcode PDS_CORE_CMD_RESET 169 * 170 * Resets and clears all LIFs, VDevs, and VIFs on the device. 171 */ 172 struct pds_core_dev_reset_cmd { 173 u8 opcode; 174 }; 175 176 /** 177 * struct pds_core_dev_reset_comp - Reset command completion 178 * @status: Status of the command (enum pds_core_status_code) 179 */ 180 struct pds_core_dev_reset_comp { 181 u8 status; 182 }; 183 184 /* 185 * struct pds_core_dev_init_data - Pointers and info needed for the Core 186 * initialization PDS_CORE_CMD_INIT command. The in and out structs are 187 * overlays on the pds_core_dev_cmd_regs.data space for passing data down 188 * to the firmware on init, and then returning initialization results. 189 */ 190 struct pds_core_dev_init_data_in { 191 __le64 adminq_q_base; 192 __le64 adminq_cq_base; 193 __le64 notifyq_cq_base; 194 __le32 flags; 195 __le16 intr_index; 196 u8 adminq_ring_size; 197 u8 notifyq_ring_size; 198 }; 199 200 struct pds_core_dev_init_data_out { 201 __le32 core_hw_index; 202 __le32 adminq_hw_index; 203 __le32 notifyq_hw_index; 204 u8 adminq_hw_type; 205 u8 notifyq_hw_type; 206 }; 207 208 /** 209 * struct pds_core_dev_init_cmd - Core device initialize 210 * @opcode: opcode PDS_CORE_CMD_INIT 211 * 212 * Initializes the core device and sets up the AdminQ and NotifyQ. 213 * Expects to find initialization data (struct pds_core_dev_init_data_in) 214 * in cmd_regs->data. Driver should keep the devcmd interface locked 215 * while preparing the driver info. 216 */ 217 struct pds_core_dev_init_cmd { 218 u8 opcode; 219 }; 220 221 /** 222 * struct pds_core_dev_init_comp - Core init completion 223 * @status: Status of the command (enum pds_core_status_code) 224 * 225 * Initialization result data (struct pds_core_dev_init_data_in) 226 * is found in cmd_regs->data. 227 */ 228 struct pds_core_dev_init_comp { 229 u8 status; 230 }; 231 232 /** 233 * struct pds_core_fw_download_cmd - Firmware download command 234 * @opcode: opcode 235 * @rsvd: Word boundary padding 236 * @addr: DMA address of the firmware buffer 237 * @offset: offset of the firmware buffer within the full image 238 * @length: number of valid bytes in the firmware buffer 239 */ 240 struct pds_core_fw_download_cmd { 241 u8 opcode; 242 u8 rsvd[3]; 243 __le32 offset; 244 __le64 addr; 245 __le32 length; 246 }; 247 248 /** 249 * struct pds_core_fw_download_comp - Firmware download completion 250 * @status: Status of the command (enum pds_core_status_code) 251 */ 252 struct pds_core_fw_download_comp { 253 u8 status; 254 }; 255 256 /** 257 * enum pds_core_fw_control_oper - FW control operations 258 * @PDS_CORE_FW_INSTALL_ASYNC: Install firmware asynchronously 259 * @PDS_CORE_FW_INSTALL_STATUS: Firmware installation status 260 * @PDS_CORE_FW_ACTIVATE_ASYNC: Activate firmware asynchronously 261 * @PDS_CORE_FW_ACTIVATE_STATUS: Firmware activate status 262 * @PDS_CORE_FW_UPDATE_CLEANUP: Cleanup any firmware update leftovers 263 * @PDS_CORE_FW_GET_BOOT: Return current active firmware slot 264 * @PDS_CORE_FW_SET_BOOT: Set active firmware slot for next boot 265 * @PDS_CORE_FW_GET_LIST: Return list of installed firmware images 266 */ 267 enum pds_core_fw_control_oper { 268 PDS_CORE_FW_INSTALL_ASYNC = 0, 269 PDS_CORE_FW_INSTALL_STATUS = 1, 270 PDS_CORE_FW_ACTIVATE_ASYNC = 2, 271 PDS_CORE_FW_ACTIVATE_STATUS = 3, 272 PDS_CORE_FW_UPDATE_CLEANUP = 4, 273 PDS_CORE_FW_GET_BOOT = 5, 274 PDS_CORE_FW_SET_BOOT = 6, 275 PDS_CORE_FW_GET_LIST = 7, 276 }; 277 278 enum pds_core_fw_slot { 279 PDS_CORE_FW_SLOT_INVALID = 0, 280 PDS_CORE_FW_SLOT_A = 1, 281 PDS_CORE_FW_SLOT_B = 2, 282 PDS_CORE_FW_SLOT_GOLD = 3, 283 }; 284 285 /** 286 * struct pds_core_fw_control_cmd - Firmware control command 287 * @opcode: opcode 288 * @rsvd: Word boundary padding 289 * @oper: firmware control operation (enum pds_core_fw_control_oper) 290 * @slot: slot to operate on (enum pds_core_fw_slot) 291 */ 292 struct pds_core_fw_control_cmd { 293 u8 opcode; 294 u8 rsvd[3]; 295 u8 oper; 296 u8 slot; 297 }; 298 299 /** 300 * struct pds_core_fw_control_comp - Firmware control copletion 301 * @status: Status of the command (enum pds_core_status_code) 302 * @rsvd: Word alignment space 303 * @slot: Slot number (enum pds_core_fw_slot) 304 * @rsvd1: Struct padding 305 * @color: Color bit 306 */ 307 struct pds_core_fw_control_comp { 308 u8 status; 309 u8 rsvd[3]; 310 u8 slot; 311 u8 rsvd1[10]; 312 u8 color; 313 }; 314 315 struct pds_core_fw_name_info { 316 #define PDS_CORE_FWSLOT_BUFLEN 8 317 #define PDS_CORE_FWVERS_BUFLEN 32 318 char slotname[PDS_CORE_FWSLOT_BUFLEN]; 319 char fw_version[PDS_CORE_FWVERS_BUFLEN]; 320 }; 321 322 struct pds_core_fw_list_info { 323 #define PDS_CORE_FWVERS_LIST_LEN 16 324 u8 num_fw_slots; 325 struct pds_core_fw_name_info fw_names[PDS_CORE_FWVERS_LIST_LEN]; 326 } __packed; 327 328 enum pds_core_vf_attr { 329 PDS_CORE_VF_ATTR_SPOOFCHK = 1, 330 PDS_CORE_VF_ATTR_TRUST = 2, 331 PDS_CORE_VF_ATTR_MAC = 3, 332 PDS_CORE_VF_ATTR_LINKSTATE = 4, 333 PDS_CORE_VF_ATTR_VLAN = 5, 334 PDS_CORE_VF_ATTR_RATE = 6, 335 PDS_CORE_VF_ATTR_STATSADDR = 7, 336 }; 337 338 /** 339 * enum pds_core_vf_link_status - Virtual Function link status 340 * @PDS_CORE_VF_LINK_STATUS_AUTO: Use link state of the uplink 341 * @PDS_CORE_VF_LINK_STATUS_UP: Link always up 342 * @PDS_CORE_VF_LINK_STATUS_DOWN: Link always down 343 */ 344 enum pds_core_vf_link_status { 345 PDS_CORE_VF_LINK_STATUS_AUTO = 0, 346 PDS_CORE_VF_LINK_STATUS_UP = 1, 347 PDS_CORE_VF_LINK_STATUS_DOWN = 2, 348 }; 349 350 /** 351 * struct pds_core_vf_setattr_cmd - Set VF attributes on the NIC 352 * @opcode: Opcode 353 * @attr: Attribute type (enum pds_core_vf_attr) 354 * @vf_index: VF index 355 * @macaddr: mac address 356 * @vlanid: vlan ID 357 * @maxrate: max Tx rate in Mbps 358 * @spoofchk: enable address spoof checking 359 * @trust: enable VF trust 360 * @linkstate: set link up or down 361 * @stats: stats addr struct 362 * @stats.pa: set DMA address for VF stats 363 * @stats.len: length of VF stats space 364 * @pad: force union to specific size 365 */ 366 struct pds_core_vf_setattr_cmd { 367 u8 opcode; 368 u8 attr; 369 __le16 vf_index; 370 union { 371 u8 macaddr[6]; 372 __le16 vlanid; 373 __le32 maxrate; 374 u8 spoofchk; 375 u8 trust; 376 u8 linkstate; 377 struct { 378 __le64 pa; 379 __le32 len; 380 } stats; 381 u8 pad[60]; 382 } __packed; 383 }; 384 385 struct pds_core_vf_setattr_comp { 386 u8 status; 387 u8 attr; 388 __le16 vf_index; 389 __le16 comp_index; 390 u8 rsvd[9]; 391 u8 color; 392 }; 393 394 /** 395 * struct pds_core_vf_getattr_cmd - Get VF attributes from the NIC 396 * @opcode: Opcode 397 * @attr: Attribute type (enum pds_core_vf_attr) 398 * @vf_index: VF index 399 */ 400 struct pds_core_vf_getattr_cmd { 401 u8 opcode; 402 u8 attr; 403 __le16 vf_index; 404 }; 405 406 struct pds_core_vf_getattr_comp { 407 u8 status; 408 u8 attr; 409 __le16 vf_index; 410 union { 411 u8 macaddr[6]; 412 __le16 vlanid; 413 __le32 maxrate; 414 u8 spoofchk; 415 u8 trust; 416 u8 linkstate; 417 __le64 stats_pa; 418 u8 pad[11]; 419 } __packed; 420 u8 color; 421 }; 422 423 enum pds_core_vf_ctrl_opcode { 424 PDS_CORE_VF_CTRL_START_ALL = 0, 425 PDS_CORE_VF_CTRL_START = 1, 426 }; 427 428 /** 429 * struct pds_core_vf_ctrl_cmd - VF control command 430 * @opcode: Opcode for the command 431 * @ctrl_opcode: VF control operation type 432 * @vf_index: VF Index. It is unused if op START_ALL is used. 433 */ 434 435 struct pds_core_vf_ctrl_cmd { 436 u8 opcode; 437 u8 ctrl_opcode; 438 __le16 vf_index; 439 }; 440 441 /** 442 * struct pds_core_vf_ctrl_comp - VF_CTRL command completion. 443 * @status: Status of the command (enum pds_core_status_code) 444 */ 445 struct pds_core_vf_ctrl_comp { 446 u8 status; 447 }; 448 449 /* 450 * union pds_core_dev_cmd - Overlay of core device command structures 451 */ 452 union pds_core_dev_cmd { 453 u8 opcode; 454 u32 words[16]; 455 456 struct pds_core_dev_identify_cmd identify; 457 struct pds_core_dev_init_cmd init; 458 struct pds_core_dev_reset_cmd reset; 459 struct pds_core_fw_download_cmd fw_download; 460 struct pds_core_fw_control_cmd fw_control; 461 462 struct pds_core_vf_setattr_cmd vf_setattr; 463 struct pds_core_vf_getattr_cmd vf_getattr; 464 struct pds_core_vf_ctrl_cmd vf_ctrl; 465 }; 466 467 /* 468 * union pds_core_dev_comp - Overlay of core device completion structures 469 */ 470 union pds_core_dev_comp { 471 u8 status; 472 u8 bytes[16]; 473 474 struct pds_core_dev_identify_comp identify; 475 struct pds_core_dev_reset_comp reset; 476 struct pds_core_dev_init_comp init; 477 struct pds_core_fw_download_comp fw_download; 478 struct pds_core_fw_control_comp fw_control; 479 480 struct pds_core_vf_setattr_comp vf_setattr; 481 struct pds_core_vf_getattr_comp vf_getattr; 482 struct pds_core_vf_ctrl_comp vf_ctrl; 483 }; 484 485 /** 486 * struct pds_core_dev_hwstamp_regs - Hardware current timestamp registers 487 * @tick_low: Low 32 bits of hardware timestamp 488 * @tick_high: High 32 bits of hardware timestamp 489 */ 490 struct pds_core_dev_hwstamp_regs { 491 u32 tick_low; 492 u32 tick_high; 493 }; 494 495 /** 496 * struct pds_core_dev_info_regs - Device info register format (read-only) 497 * @signature: Signature value of 0x44455649 ('DEVI') 498 * @version: Current version of info 499 * @asic_type: Asic type 500 * @asic_rev: Asic revision 501 * @fw_status: Firmware status 502 * bit 0 - 1 = fw running 503 * bit 4-7 - 4 bit generation number, changes on fw restart 504 * @fw_heartbeat: Firmware heartbeat counter 505 * @serial_num: Serial number 506 * @fw_version: Firmware version 507 * @oprom_regs: oprom_regs to store oprom debug enable/disable and bmp 508 * @rsvd_pad1024: Struct padding 509 * @hwstamp: Hardware current timestamp registers 510 * @rsvd_pad2048: Struct padding 511 */ 512 struct pds_core_dev_info_regs { 513 #define PDS_CORE_DEVINFO_FWVERS_BUFLEN 32 514 #define PDS_CORE_DEVINFO_SERIAL_BUFLEN 32 515 u32 signature; 516 u8 version; 517 u8 asic_type; 518 u8 asic_rev; 519 #define PDS_CORE_FW_STS_F_STOPPED 0x00 520 #define PDS_CORE_FW_STS_F_RUNNING 0x01 521 #define PDS_CORE_FW_STS_F_GENERATION 0xF0 522 u8 fw_status; 523 __le32 fw_heartbeat; 524 char fw_version[PDS_CORE_DEVINFO_FWVERS_BUFLEN]; 525 char serial_num[PDS_CORE_DEVINFO_SERIAL_BUFLEN]; 526 u8 oprom_regs[32]; /* reserved */ 527 u8 rsvd_pad1024[916]; 528 struct pds_core_dev_hwstamp_regs hwstamp; /* on 1k boundary */ 529 u8 rsvd_pad2048[1016]; 530 } __packed; 531 532 /** 533 * struct pds_core_dev_cmd_regs - Device command register format (read-write) 534 * @doorbell: Device Cmd Doorbell, write-only 535 * Write a 1 to signal device to process cmd 536 * @done: Command completed indicator, poll for completion 537 * bit 0 == 1 when command is complete 538 * @cmd: Opcode-specific command bytes 539 * @comp: Opcode-specific response bytes 540 * @rsvd: Struct padding 541 * @data: Opcode-specific side-data 542 */ 543 struct pds_core_dev_cmd_regs { 544 u32 doorbell; 545 u32 done; 546 union pds_core_dev_cmd cmd; 547 union pds_core_dev_comp comp; 548 u8 rsvd[48]; 549 u32 data[478]; 550 } __packed; 551 552 /** 553 * struct pds_core_dev_regs - Device register format for bar 0 page 0 554 * @info: Device info registers 555 * @devcmd: Device command registers 556 */ 557 struct pds_core_dev_regs { 558 struct pds_core_dev_info_regs info; 559 struct pds_core_dev_cmd_regs devcmd; 560 } __packed; 561 562 #ifndef __CHECKER__ 563 static_assert(sizeof(struct pds_core_drv_identity) <= 1912); 564 static_assert(sizeof(struct pds_core_dev_identity) <= 1912); 565 static_assert(sizeof(union pds_core_dev_cmd) == 64); 566 static_assert(sizeof(union pds_core_dev_comp) == 16); 567 static_assert(sizeof(struct pds_core_dev_info_regs) == 2048); 568 static_assert(sizeof(struct pds_core_dev_cmd_regs) == 2048); 569 static_assert(sizeof(struct pds_core_dev_regs) == 4096); 570 #endif /* __CHECKER__ */ 571 572 #endif /* _PDS_CORE_IF_H_ */ 573