Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
0002 /* Copyright (c) 2015-2018 Mellanox Technologies. All rights reserved */
0003 
0004 #ifndef _MLXSW_CMD_H
0005 #define _MLXSW_CMD_H
0006 
0007 #include "item.h"
0008 
0009 #define MLXSW_CMD_MBOX_SIZE 4096
0010 
0011 static inline char *mlxsw_cmd_mbox_alloc(void)
0012 {
0013     return kzalloc(MLXSW_CMD_MBOX_SIZE, GFP_KERNEL);
0014 }
0015 
0016 static inline void mlxsw_cmd_mbox_free(char *mbox)
0017 {
0018     kfree(mbox);
0019 }
0020 
0021 static inline void mlxsw_cmd_mbox_zero(char *mbox)
0022 {
0023     memset(mbox, 0, MLXSW_CMD_MBOX_SIZE);
0024 }
0025 
0026 struct mlxsw_core;
0027 
0028 int mlxsw_cmd_exec(struct mlxsw_core *mlxsw_core, u16 opcode, u8 opcode_mod,
0029            u32 in_mod, bool out_mbox_direct, bool reset_ok,
0030            char *in_mbox, size_t in_mbox_size,
0031            char *out_mbox, size_t out_mbox_size);
0032 
0033 static inline int mlxsw_cmd_exec_in(struct mlxsw_core *mlxsw_core, u16 opcode,
0034                     u8 opcode_mod, u32 in_mod, char *in_mbox,
0035                     size_t in_mbox_size)
0036 {
0037     return mlxsw_cmd_exec(mlxsw_core, opcode, opcode_mod, in_mod, false,
0038                   false, in_mbox, in_mbox_size, NULL, 0);
0039 }
0040 
0041 static inline int mlxsw_cmd_exec_out(struct mlxsw_core *mlxsw_core, u16 opcode,
0042                      u8 opcode_mod, u32 in_mod,
0043                      bool out_mbox_direct,
0044                      char *out_mbox, size_t out_mbox_size)
0045 {
0046     return mlxsw_cmd_exec(mlxsw_core, opcode, opcode_mod, in_mod,
0047                   out_mbox_direct, false, NULL, 0,
0048                   out_mbox, out_mbox_size);
0049 }
0050 
0051 static inline int mlxsw_cmd_exec_none(struct mlxsw_core *mlxsw_core, u16 opcode,
0052                       u8 opcode_mod, u32 in_mod)
0053 {
0054     return mlxsw_cmd_exec(mlxsw_core, opcode, opcode_mod, in_mod, false,
0055                   false, NULL, 0, NULL, 0);
0056 }
0057 
0058 enum mlxsw_cmd_opcode {
0059     MLXSW_CMD_OPCODE_QUERY_FW       = 0x004,
0060     MLXSW_CMD_OPCODE_QUERY_BOARDINFO    = 0x006,
0061     MLXSW_CMD_OPCODE_QUERY_AQ_CAP       = 0x003,
0062     MLXSW_CMD_OPCODE_MAP_FA         = 0xFFF,
0063     MLXSW_CMD_OPCODE_UNMAP_FA       = 0xFFE,
0064     MLXSW_CMD_OPCODE_CONFIG_PROFILE     = 0x100,
0065     MLXSW_CMD_OPCODE_ACCESS_REG     = 0x040,
0066     MLXSW_CMD_OPCODE_SW2HW_DQ       = 0x201,
0067     MLXSW_CMD_OPCODE_HW2SW_DQ       = 0x202,
0068     MLXSW_CMD_OPCODE_2ERR_DQ        = 0x01E,
0069     MLXSW_CMD_OPCODE_QUERY_DQ       = 0x022,
0070     MLXSW_CMD_OPCODE_SW2HW_CQ       = 0x016,
0071     MLXSW_CMD_OPCODE_HW2SW_CQ       = 0x017,
0072     MLXSW_CMD_OPCODE_QUERY_CQ       = 0x018,
0073     MLXSW_CMD_OPCODE_SW2HW_EQ       = 0x013,
0074     MLXSW_CMD_OPCODE_HW2SW_EQ       = 0x014,
0075     MLXSW_CMD_OPCODE_QUERY_EQ       = 0x015,
0076     MLXSW_CMD_OPCODE_QUERY_RESOURCES    = 0x101,
0077 };
0078 
0079 static inline const char *mlxsw_cmd_opcode_str(u16 opcode)
0080 {
0081     switch (opcode) {
0082     case MLXSW_CMD_OPCODE_QUERY_FW:
0083         return "QUERY_FW";
0084     case MLXSW_CMD_OPCODE_QUERY_BOARDINFO:
0085         return "QUERY_BOARDINFO";
0086     case MLXSW_CMD_OPCODE_QUERY_AQ_CAP:
0087         return "QUERY_AQ_CAP";
0088     case MLXSW_CMD_OPCODE_MAP_FA:
0089         return "MAP_FA";
0090     case MLXSW_CMD_OPCODE_UNMAP_FA:
0091         return "UNMAP_FA";
0092     case MLXSW_CMD_OPCODE_CONFIG_PROFILE:
0093         return "CONFIG_PROFILE";
0094     case MLXSW_CMD_OPCODE_ACCESS_REG:
0095         return "ACCESS_REG";
0096     case MLXSW_CMD_OPCODE_SW2HW_DQ:
0097         return "SW2HW_DQ";
0098     case MLXSW_CMD_OPCODE_HW2SW_DQ:
0099         return "HW2SW_DQ";
0100     case MLXSW_CMD_OPCODE_2ERR_DQ:
0101         return "2ERR_DQ";
0102     case MLXSW_CMD_OPCODE_QUERY_DQ:
0103         return "QUERY_DQ";
0104     case MLXSW_CMD_OPCODE_SW2HW_CQ:
0105         return "SW2HW_CQ";
0106     case MLXSW_CMD_OPCODE_HW2SW_CQ:
0107         return "HW2SW_CQ";
0108     case MLXSW_CMD_OPCODE_QUERY_CQ:
0109         return "QUERY_CQ";
0110     case MLXSW_CMD_OPCODE_SW2HW_EQ:
0111         return "SW2HW_EQ";
0112     case MLXSW_CMD_OPCODE_HW2SW_EQ:
0113         return "HW2SW_EQ";
0114     case MLXSW_CMD_OPCODE_QUERY_EQ:
0115         return "QUERY_EQ";
0116     case MLXSW_CMD_OPCODE_QUERY_RESOURCES:
0117         return "QUERY_RESOURCES";
0118     default:
0119         return "*UNKNOWN*";
0120     }
0121 }
0122 
0123 enum mlxsw_cmd_status {
0124     /* Command execution succeeded. */
0125     MLXSW_CMD_STATUS_OK     = 0x00,
0126     /* Internal error (e.g. bus error) occurred while processing command. */
0127     MLXSW_CMD_STATUS_INTERNAL_ERR   = 0x01,
0128     /* Operation/command not supported or opcode modifier not supported. */
0129     MLXSW_CMD_STATUS_BAD_OP     = 0x02,
0130     /* Parameter not supported, parameter out of range. */
0131     MLXSW_CMD_STATUS_BAD_PARAM  = 0x03,
0132     /* System was not enabled or bad system state. */
0133     MLXSW_CMD_STATUS_BAD_SYS_STATE  = 0x04,
0134     /* Attempt to access reserved or unallocated resource, or resource in
0135      * inappropriate ownership.
0136      */
0137     MLXSW_CMD_STATUS_BAD_RESOURCE   = 0x05,
0138     /* Requested resource is currently executing a command. */
0139     MLXSW_CMD_STATUS_RESOURCE_BUSY  = 0x06,
0140     /* Required capability exceeds device limits. */
0141     MLXSW_CMD_STATUS_EXCEED_LIM = 0x08,
0142     /* Resource is not in the appropriate state or ownership. */
0143     MLXSW_CMD_STATUS_BAD_RES_STATE  = 0x09,
0144     /* Index out of range (might be beyond table size or attempt to
0145      * access a reserved resource).
0146      */
0147     MLXSW_CMD_STATUS_BAD_INDEX  = 0x0A,
0148     /* NVMEM checksum/CRC failed. */
0149     MLXSW_CMD_STATUS_BAD_NVMEM  = 0x0B,
0150     /* Device is currently running reset */
0151     MLXSW_CMD_STATUS_RUNNING_RESET  = 0x26,
0152     /* Bad management packet (silently discarded). */
0153     MLXSW_CMD_STATUS_BAD_PKT    = 0x30,
0154 };
0155 
0156 static inline const char *mlxsw_cmd_status_str(u8 status)
0157 {
0158     switch (status) {
0159     case MLXSW_CMD_STATUS_OK:
0160         return "OK";
0161     case MLXSW_CMD_STATUS_INTERNAL_ERR:
0162         return "INTERNAL_ERR";
0163     case MLXSW_CMD_STATUS_BAD_OP:
0164         return "BAD_OP";
0165     case MLXSW_CMD_STATUS_BAD_PARAM:
0166         return "BAD_PARAM";
0167     case MLXSW_CMD_STATUS_BAD_SYS_STATE:
0168         return "BAD_SYS_STATE";
0169     case MLXSW_CMD_STATUS_BAD_RESOURCE:
0170         return "BAD_RESOURCE";
0171     case MLXSW_CMD_STATUS_RESOURCE_BUSY:
0172         return "RESOURCE_BUSY";
0173     case MLXSW_CMD_STATUS_EXCEED_LIM:
0174         return "EXCEED_LIM";
0175     case MLXSW_CMD_STATUS_BAD_RES_STATE:
0176         return "BAD_RES_STATE";
0177     case MLXSW_CMD_STATUS_BAD_INDEX:
0178         return "BAD_INDEX";
0179     case MLXSW_CMD_STATUS_BAD_NVMEM:
0180         return "BAD_NVMEM";
0181     case MLXSW_CMD_STATUS_RUNNING_RESET:
0182         return "RUNNING_RESET";
0183     case MLXSW_CMD_STATUS_BAD_PKT:
0184         return "BAD_PKT";
0185     default:
0186         return "*UNKNOWN*";
0187     }
0188 }
0189 
0190 /* QUERY_FW - Query Firmware
0191  * -------------------------
0192  * OpMod == 0, INMmod == 0
0193  * -----------------------
0194  * The QUERY_FW command retrieves information related to firmware, command
0195  * interface version and the amount of resources that should be allocated to
0196  * the firmware.
0197  */
0198 
0199 static inline int mlxsw_cmd_query_fw(struct mlxsw_core *mlxsw_core,
0200                      char *out_mbox)
0201 {
0202     return mlxsw_cmd_exec_out(mlxsw_core, MLXSW_CMD_OPCODE_QUERY_FW,
0203                   0, 0, false, out_mbox, MLXSW_CMD_MBOX_SIZE);
0204 }
0205 
0206 /* cmd_mbox_query_fw_fw_pages
0207  * Amount of physical memory to be allocatedfor firmware usage in 4KB pages.
0208  */
0209 MLXSW_ITEM32(cmd_mbox, query_fw, fw_pages, 0x00, 16, 16);
0210 
0211 /* cmd_mbox_query_fw_fw_rev_major
0212  * Firmware Revision - Major
0213  */
0214 MLXSW_ITEM32(cmd_mbox, query_fw, fw_rev_major, 0x00, 0, 16);
0215 
0216 /* cmd_mbox_query_fw_fw_rev_subminor
0217  * Firmware Sub-minor version (Patch level)
0218  */
0219 MLXSW_ITEM32(cmd_mbox, query_fw, fw_rev_subminor, 0x04, 16, 16);
0220 
0221 /* cmd_mbox_query_fw_fw_rev_minor
0222  * Firmware Revision - Minor
0223  */
0224 MLXSW_ITEM32(cmd_mbox, query_fw, fw_rev_minor, 0x04, 0, 16);
0225 
0226 /* cmd_mbox_query_fw_core_clk
0227  * Internal Clock Frequency (in MHz)
0228  */
0229 MLXSW_ITEM32(cmd_mbox, query_fw, core_clk, 0x08, 16, 16);
0230 
0231 /* cmd_mbox_query_fw_cmd_interface_rev
0232  * Command Interface Interpreter Revision ID. This number is bumped up
0233  * every time a non-backward-compatible change is done for the command
0234  * interface. The current cmd_interface_rev is 1.
0235  */
0236 MLXSW_ITEM32(cmd_mbox, query_fw, cmd_interface_rev, 0x08, 0, 16);
0237 
0238 /* cmd_mbox_query_fw_dt
0239  * If set, Debug Trace is supported
0240  */
0241 MLXSW_ITEM32(cmd_mbox, query_fw, dt, 0x0C, 31, 1);
0242 
0243 /* cmd_mbox_query_fw_api_version
0244  * Indicates the version of the API, to enable software querying
0245  * for compatibility. The current api_version is 1.
0246  */
0247 MLXSW_ITEM32(cmd_mbox, query_fw, api_version, 0x0C, 0, 16);
0248 
0249 /* cmd_mbox_query_fw_fw_hour
0250  * Firmware timestamp - hour
0251  */
0252 MLXSW_ITEM32(cmd_mbox, query_fw, fw_hour, 0x10, 24, 8);
0253 
0254 /* cmd_mbox_query_fw_fw_minutes
0255  * Firmware timestamp - minutes
0256  */
0257 MLXSW_ITEM32(cmd_mbox, query_fw, fw_minutes, 0x10, 16, 8);
0258 
0259 /* cmd_mbox_query_fw_fw_seconds
0260  * Firmware timestamp - seconds
0261  */
0262 MLXSW_ITEM32(cmd_mbox, query_fw, fw_seconds, 0x10, 8, 8);
0263 
0264 /* cmd_mbox_query_fw_fw_year
0265  * Firmware timestamp - year
0266  */
0267 MLXSW_ITEM32(cmd_mbox, query_fw, fw_year, 0x14, 16, 16);
0268 
0269 /* cmd_mbox_query_fw_fw_month
0270  * Firmware timestamp - month
0271  */
0272 MLXSW_ITEM32(cmd_mbox, query_fw, fw_month, 0x14, 8, 8);
0273 
0274 /* cmd_mbox_query_fw_fw_day
0275  * Firmware timestamp - day
0276  */
0277 MLXSW_ITEM32(cmd_mbox, query_fw, fw_day, 0x14, 0, 8);
0278 
0279 /* cmd_mbox_query_fw_clr_int_base_offset
0280  * Clear Interrupt register's offset from clr_int_bar register
0281  * in PCI address space.
0282  */
0283 MLXSW_ITEM64(cmd_mbox, query_fw, clr_int_base_offset, 0x20, 0, 64);
0284 
0285 /* cmd_mbox_query_fw_clr_int_bar
0286  * PCI base address register (BAR) where clr_int register is located.
0287  * 00 - BAR 0-1 (64 bit BAR)
0288  */
0289 MLXSW_ITEM32(cmd_mbox, query_fw, clr_int_bar, 0x28, 30, 2);
0290 
0291 /* cmd_mbox_query_fw_error_buf_offset
0292  * Read Only buffer for internal error reports of offset
0293  * from error_buf_bar register in PCI address space).
0294  */
0295 MLXSW_ITEM64(cmd_mbox, query_fw, error_buf_offset, 0x30, 0, 64);
0296 
0297 /* cmd_mbox_query_fw_error_buf_size
0298  * Internal error buffer size in DWORDs
0299  */
0300 MLXSW_ITEM32(cmd_mbox, query_fw, error_buf_size, 0x38, 0, 32);
0301 
0302 /* cmd_mbox_query_fw_error_int_bar
0303  * PCI base address register (BAR) where error buffer
0304  * register is located.
0305  * 00 - BAR 0-1 (64 bit BAR)
0306  */
0307 MLXSW_ITEM32(cmd_mbox, query_fw, error_int_bar, 0x3C, 30, 2);
0308 
0309 /* cmd_mbox_query_fw_doorbell_page_offset
0310  * Offset of the doorbell page
0311  */
0312 MLXSW_ITEM64(cmd_mbox, query_fw, doorbell_page_offset, 0x40, 0, 64);
0313 
0314 /* cmd_mbox_query_fw_doorbell_page_bar
0315  * PCI base address register (BAR) of the doorbell page
0316  * 00 - BAR 0-1 (64 bit BAR)
0317  */
0318 MLXSW_ITEM32(cmd_mbox, query_fw, doorbell_page_bar, 0x48, 30, 2);
0319 
0320 /* cmd_mbox_query_fw_free_running_clock_offset
0321  * The offset of the free running clock page
0322  */
0323 MLXSW_ITEM64(cmd_mbox, query_fw, free_running_clock_offset, 0x50, 0, 64);
0324 
0325 /* cmd_mbox_query_fw_fr_rn_clk_bar
0326  * PCI base address register (BAR) of the free running clock page
0327  * 0: BAR 0
0328  * 1: 64 bit BAR
0329  */
0330 MLXSW_ITEM32(cmd_mbox, query_fw, fr_rn_clk_bar, 0x58, 30, 2);
0331 
0332 /* cmd_mbox_query_fw_utc_sec_offset
0333  * The offset of the UTC_Sec page
0334  */
0335 MLXSW_ITEM64(cmd_mbox, query_fw, utc_sec_offset, 0x70, 0, 64);
0336 
0337 /* cmd_mbox_query_fw_utc_sec_bar
0338  * PCI base address register (BAR) of the UTC_Sec page
0339  * 0: BAR 0
0340  * 1: 64 bit BAR
0341  * Reserved on SwitchX/-2, Switch-IB/2, Spectrum-1
0342  */
0343 MLXSW_ITEM32(cmd_mbox, query_fw, utc_sec_bar, 0x78, 30, 2);
0344 
0345 /* cmd_mbox_query_fw_utc_nsec_offset
0346  * The offset of the UTC_nSec page
0347  */
0348 MLXSW_ITEM64(cmd_mbox, query_fw, utc_nsec_offset, 0x80, 0, 64);
0349 
0350 /* cmd_mbox_query_fw_utc_nsec_bar
0351  * PCI base address register (BAR) of the UTC_nSec page
0352  * 0: BAR 0
0353  * 1: 64 bit BAR
0354  * Reserved on SwitchX/-2, Switch-IB/2, Spectrum-1
0355  */
0356 MLXSW_ITEM32(cmd_mbox, query_fw, utc_nsec_bar, 0x88, 30, 2);
0357 
0358 /* QUERY_BOARDINFO - Query Board Information
0359  * -----------------------------------------
0360  * OpMod == 0 (N/A), INMmod == 0 (N/A)
0361  * -----------------------------------
0362  * The QUERY_BOARDINFO command retrieves adapter specific parameters.
0363  */
0364 
0365 static inline int mlxsw_cmd_boardinfo(struct mlxsw_core *mlxsw_core,
0366                       char *out_mbox)
0367 {
0368     return mlxsw_cmd_exec_out(mlxsw_core, MLXSW_CMD_OPCODE_QUERY_BOARDINFO,
0369                   0, 0, false, out_mbox, MLXSW_CMD_MBOX_SIZE);
0370 }
0371 
0372 /* cmd_mbox_boardinfo_intapin
0373  * When PCIe interrupt messages are being used, this value is used for clearing
0374  * an interrupt. When using MSI-X, this register is not used.
0375  */
0376 MLXSW_ITEM32(cmd_mbox, boardinfo, intapin, 0x10, 24, 8);
0377 
0378 /* cmd_mbox_boardinfo_vsd_vendor_id
0379  * PCISIG Vendor ID (www.pcisig.com/membership/vid_search) of the vendor
0380  * specifying/formatting the VSD. The vsd_vendor_id identifies the management
0381  * domain of the VSD/PSID data. Different vendors may choose different VSD/PSID
0382  * format and encoding as long as they use their assigned vsd_vendor_id.
0383  */
0384 MLXSW_ITEM32(cmd_mbox, boardinfo, vsd_vendor_id, 0x1C, 0, 16);
0385 
0386 /* cmd_mbox_boardinfo_vsd
0387  * Vendor Specific Data. The VSD string that is burnt to the Flash
0388  * with the firmware.
0389  */
0390 #define MLXSW_CMD_BOARDINFO_VSD_LEN 208
0391 MLXSW_ITEM_BUF(cmd_mbox, boardinfo, vsd, 0x20, MLXSW_CMD_BOARDINFO_VSD_LEN);
0392 
0393 /* cmd_mbox_boardinfo_psid
0394  * The PSID field is a 16-ascii (byte) character string which acts as
0395  * the board ID. The PSID format is used in conjunction with
0396  * Mellanox vsd_vendor_id (15B3h).
0397  */
0398 #define MLXSW_CMD_BOARDINFO_PSID_LEN 16
0399 MLXSW_ITEM_BUF(cmd_mbox, boardinfo, psid, 0xF0, MLXSW_CMD_BOARDINFO_PSID_LEN);
0400 
0401 /* QUERY_AQ_CAP - Query Asynchronous Queues Capabilities
0402  * -----------------------------------------------------
0403  * OpMod == 0 (N/A), INMmod == 0 (N/A)
0404  * -----------------------------------
0405  * The QUERY_AQ_CAP command returns the device asynchronous queues
0406  * capabilities supported.
0407  */
0408 
0409 static inline int mlxsw_cmd_query_aq_cap(struct mlxsw_core *mlxsw_core,
0410                      char *out_mbox)
0411 {
0412     return mlxsw_cmd_exec_out(mlxsw_core, MLXSW_CMD_OPCODE_QUERY_AQ_CAP,
0413                   0, 0, false, out_mbox, MLXSW_CMD_MBOX_SIZE);
0414 }
0415 
0416 /* cmd_mbox_query_aq_cap_log_max_sdq_sz
0417  * Log (base 2) of max WQEs allowed on SDQ.
0418  */
0419 MLXSW_ITEM32(cmd_mbox, query_aq_cap, log_max_sdq_sz, 0x00, 24, 8);
0420 
0421 /* cmd_mbox_query_aq_cap_max_num_sdqs
0422  * Maximum number of SDQs.
0423  */
0424 MLXSW_ITEM32(cmd_mbox, query_aq_cap, max_num_sdqs, 0x00, 0, 8);
0425 
0426 /* cmd_mbox_query_aq_cap_log_max_rdq_sz
0427  * Log (base 2) of max WQEs allowed on RDQ.
0428  */
0429 MLXSW_ITEM32(cmd_mbox, query_aq_cap, log_max_rdq_sz, 0x04, 24, 8);
0430 
0431 /* cmd_mbox_query_aq_cap_max_num_rdqs
0432  * Maximum number of RDQs.
0433  */
0434 MLXSW_ITEM32(cmd_mbox, query_aq_cap, max_num_rdqs, 0x04, 0, 8);
0435 
0436 /* cmd_mbox_query_aq_cap_log_max_cq_sz
0437  * Log (base 2) of the Maximum CQEs allowed in a CQ for CQEv0 and CQEv1.
0438  */
0439 MLXSW_ITEM32(cmd_mbox, query_aq_cap, log_max_cq_sz, 0x08, 24, 8);
0440 
0441 /* cmd_mbox_query_aq_cap_log_max_cqv2_sz
0442  * Log (base 2) of the Maximum CQEs allowed in a CQ for CQEv2.
0443  */
0444 MLXSW_ITEM32(cmd_mbox, query_aq_cap, log_max_cqv2_sz, 0x08, 16, 8);
0445 
0446 /* cmd_mbox_query_aq_cap_max_num_cqs
0447  * Maximum number of CQs.
0448  */
0449 MLXSW_ITEM32(cmd_mbox, query_aq_cap, max_num_cqs, 0x08, 0, 8);
0450 
0451 /* cmd_mbox_query_aq_cap_log_max_eq_sz
0452  * Log (base 2) of max EQEs allowed on EQ.
0453  */
0454 MLXSW_ITEM32(cmd_mbox, query_aq_cap, log_max_eq_sz, 0x0C, 24, 8);
0455 
0456 /* cmd_mbox_query_aq_cap_max_num_eqs
0457  * Maximum number of EQs.
0458  */
0459 MLXSW_ITEM32(cmd_mbox, query_aq_cap, max_num_eqs, 0x0C, 0, 8);
0460 
0461 /* cmd_mbox_query_aq_cap_max_sg_sq
0462  * The maximum S/G list elements in an DSQ. DSQ must not contain
0463  * more S/G entries than indicated here.
0464  */
0465 MLXSW_ITEM32(cmd_mbox, query_aq_cap, max_sg_sq, 0x10, 8, 8);
0466 
0467 /* cmd_mbox_query_aq_cap_
0468  * The maximum S/G list elements in an DRQ. DRQ must not contain
0469  * more S/G entries than indicated here.
0470  */
0471 MLXSW_ITEM32(cmd_mbox, query_aq_cap, max_sg_rq, 0x10, 0, 8);
0472 
0473 /* MAP_FA - Map Firmware Area
0474  * --------------------------
0475  * OpMod == 0 (N/A), INMmod == Number of VPM entries
0476  * -------------------------------------------------
0477  * The MAP_FA command passes physical pages to the switch. These pages
0478  * are used to store the device firmware. MAP_FA can be executed multiple
0479  * times until all the firmware area is mapped (the size that should be
0480  * mapped is retrieved through the QUERY_FW command). All required pages
0481  * must be mapped to finish the initialization phase. Physical memory
0482  * passed in this command must be pinned.
0483  */
0484 
0485 #define MLXSW_CMD_MAP_FA_VPM_ENTRIES_MAX 32
0486 
0487 static inline int mlxsw_cmd_map_fa(struct mlxsw_core *mlxsw_core,
0488                    char *in_mbox, u32 vpm_entries_count)
0489 {
0490     return mlxsw_cmd_exec_in(mlxsw_core, MLXSW_CMD_OPCODE_MAP_FA,
0491                  0, vpm_entries_count,
0492                  in_mbox, MLXSW_CMD_MBOX_SIZE);
0493 }
0494 
0495 /* cmd_mbox_map_fa_pa
0496  * Physical Address.
0497  */
0498 MLXSW_ITEM64_INDEXED(cmd_mbox, map_fa, pa, 0x00, 12, 52, 0x08, 0x00, true);
0499 
0500 /* cmd_mbox_map_fa_log2size
0501  * Log (base 2) of the size in 4KB pages of the physical and contiguous memory
0502  * that starts at PA_L/H.
0503  */
0504 MLXSW_ITEM32_INDEXED(cmd_mbox, map_fa, log2size, 0x00, 0, 5, 0x08, 0x04, false);
0505 
0506 /* UNMAP_FA - Unmap Firmware Area
0507  * ------------------------------
0508  * OpMod == 0 (N/A), INMmod == 0 (N/A)
0509  * -----------------------------------
0510  * The UNMAP_FA command unload the firmware and unmaps all the
0511  * firmware area. After this command is completed the device will not access
0512  * the pages that were mapped to the firmware area. After executing UNMAP_FA
0513  * command, software reset must be done prior to execution of MAP_FW command.
0514  */
0515 
0516 static inline int mlxsw_cmd_unmap_fa(struct mlxsw_core *mlxsw_core)
0517 {
0518     return mlxsw_cmd_exec_none(mlxsw_core, MLXSW_CMD_OPCODE_UNMAP_FA, 0, 0);
0519 }
0520 
0521 /* QUERY_RESOURCES - Query chip resources
0522  * --------------------------------------
0523  * OpMod == 0 (N/A) , INMmod is index
0524  * ----------------------------------
0525  * The QUERY_RESOURCES command retrieves information related to chip resources
0526  * by resource ID. Every command returns 32 entries. INmod is being use as base.
0527  * for example, index 1 will return entries 32-63. When the tables end and there
0528  * are no more sources in the table, will return resource id 0xFFF to indicate
0529  * it.
0530  */
0531 
0532 #define MLXSW_CMD_QUERY_RESOURCES_TABLE_END_ID 0xffff
0533 #define MLXSW_CMD_QUERY_RESOURCES_MAX_QUERIES 100
0534 #define MLXSW_CMD_QUERY_RESOURCES_PER_QUERY 32
0535 
0536 static inline int mlxsw_cmd_query_resources(struct mlxsw_core *mlxsw_core,
0537                         char *out_mbox, int index)
0538 {
0539     return mlxsw_cmd_exec_out(mlxsw_core, MLXSW_CMD_OPCODE_QUERY_RESOURCES,
0540                   0, index, false, out_mbox,
0541                   MLXSW_CMD_MBOX_SIZE);
0542 }
0543 
0544 /* cmd_mbox_query_resource_id
0545  * The resource id. 0xFFFF indicates table's end.
0546  */
0547 MLXSW_ITEM32_INDEXED(cmd_mbox, query_resource, id, 0x00, 16, 16, 0x8, 0, false);
0548 
0549 /* cmd_mbox_query_resource_data
0550  * The resource
0551  */
0552 MLXSW_ITEM64_INDEXED(cmd_mbox, query_resource, data,
0553              0x00, 0, 40, 0x8, 0, false);
0554 
0555 /* CONFIG_PROFILE (Set) - Configure Switch Profile
0556  * ------------------------------
0557  * OpMod == 1 (Set), INMmod == 0 (N/A)
0558  * -----------------------------------
0559  * The CONFIG_PROFILE command sets the switch profile. The command can be
0560  * executed on the device only once at startup in order to allocate and
0561  * configure all switch resources and prepare it for operational mode.
0562  * It is not possible to change the device profile after the chip is
0563  * in operational mode.
0564  * Failure of the CONFIG_PROFILE command leaves the hardware in an indeterminate
0565  * state therefore it is required to perform software reset to the device
0566  * following an unsuccessful completion of the command. It is required
0567  * to perform software reset to the device to change an existing profile.
0568  */
0569 
0570 static inline int mlxsw_cmd_config_profile_set(struct mlxsw_core *mlxsw_core,
0571                            char *in_mbox)
0572 {
0573     return mlxsw_cmd_exec_in(mlxsw_core, MLXSW_CMD_OPCODE_CONFIG_PROFILE,
0574                  1, 0, in_mbox, MLXSW_CMD_MBOX_SIZE);
0575 }
0576 
0577 /* cmd_mbox_config_profile_set_max_vepa_channels
0578  * Capability bit. Setting a bit to 1 configures the profile
0579  * according to the mailbox contents.
0580  */
0581 MLXSW_ITEM32(cmd_mbox, config_profile, set_max_vepa_channels, 0x0C, 0, 1);
0582 
0583 /* cmd_mbox_config_profile_set_max_lag
0584  * Capability bit. Setting a bit to 1 configures the profile
0585  * according to the mailbox contents.
0586  */
0587 MLXSW_ITEM32(cmd_mbox, config_profile, set_max_lag, 0x0C, 1, 1);
0588 
0589 /* cmd_mbox_config_profile_set_max_port_per_lag
0590  * Capability bit. Setting a bit to 1 configures the profile
0591  * according to the mailbox contents.
0592  */
0593 MLXSW_ITEM32(cmd_mbox, config_profile, set_max_port_per_lag, 0x0C, 2, 1);
0594 
0595 /* cmd_mbox_config_profile_set_max_mid
0596  * Capability bit. Setting a bit to 1 configures the profile
0597  * according to the mailbox contents.
0598  */
0599 MLXSW_ITEM32(cmd_mbox, config_profile, set_max_mid, 0x0C, 3, 1);
0600 
0601 /* cmd_mbox_config_profile_set_max_pgt
0602  * Capability bit. Setting a bit to 1 configures the profile
0603  * according to the mailbox contents.
0604  */
0605 MLXSW_ITEM32(cmd_mbox, config_profile, set_max_pgt, 0x0C, 4, 1);
0606 
0607 /* cmd_mbox_config_profile_set_max_system_port
0608  * Capability bit. Setting a bit to 1 configures the profile
0609  * according to the mailbox contents.
0610  */
0611 MLXSW_ITEM32(cmd_mbox, config_profile, set_max_system_port, 0x0C, 5, 1);
0612 
0613 /* cmd_mbox_config_profile_set_max_vlan_groups
0614  * Capability bit. Setting a bit to 1 configures the profile
0615  * according to the mailbox contents.
0616  */
0617 MLXSW_ITEM32(cmd_mbox, config_profile, set_max_vlan_groups, 0x0C, 6, 1);
0618 
0619 /* cmd_mbox_config_profile_set_max_regions
0620  * Capability bit. Setting a bit to 1 configures the profile
0621  * according to the mailbox contents.
0622  */
0623 MLXSW_ITEM32(cmd_mbox, config_profile, set_max_regions, 0x0C, 7, 1);
0624 
0625 /* cmd_mbox_config_profile_set_flood_mode
0626  * Capability bit. Setting a bit to 1 configures the profile
0627  * according to the mailbox contents.
0628  */
0629 MLXSW_ITEM32(cmd_mbox, config_profile, set_flood_mode, 0x0C, 8, 1);
0630 
0631 /* cmd_mbox_config_profile_set_max_flood_tables
0632  * Capability bit. Setting a bit to 1 configures the profile
0633  * according to the mailbox contents.
0634  */
0635 MLXSW_ITEM32(cmd_mbox, config_profile, set_flood_tables, 0x0C, 9, 1);
0636 
0637 /* cmd_mbox_config_profile_set_max_ib_mc
0638  * Capability bit. Setting a bit to 1 configures the profile
0639  * according to the mailbox contents.
0640  */
0641 MLXSW_ITEM32(cmd_mbox, config_profile, set_max_ib_mc, 0x0C, 12, 1);
0642 
0643 /* cmd_mbox_config_profile_set_max_pkey
0644  * Capability bit. Setting a bit to 1 configures the profile
0645  * according to the mailbox contents.
0646  */
0647 MLXSW_ITEM32(cmd_mbox, config_profile, set_max_pkey, 0x0C, 13, 1);
0648 
0649 /* cmd_mbox_config_profile_set_adaptive_routing_group_cap
0650  * Capability bit. Setting a bit to 1 configures the profile
0651  * according to the mailbox contents.
0652  */
0653 MLXSW_ITEM32(cmd_mbox, config_profile,
0654          set_adaptive_routing_group_cap, 0x0C, 14, 1);
0655 
0656 /* cmd_mbox_config_profile_set_ar_sec
0657  * Capability bit. Setting a bit to 1 configures the profile
0658  * according to the mailbox contents.
0659  */
0660 MLXSW_ITEM32(cmd_mbox, config_profile, set_ar_sec, 0x0C, 15, 1);
0661 
0662 /* cmd_mbox_config_set_ubridge
0663  * Capability bit. Setting a bit to 1 configures the profile
0664  * according to the mailbox contents.
0665  */
0666 MLXSW_ITEM32(cmd_mbox, config_profile, set_ubridge, 0x0C, 22, 1);
0667 
0668 /* cmd_mbox_config_set_kvd_linear_size
0669  * Capability bit. Setting a bit to 1 configures the profile
0670  * according to the mailbox contents.
0671  */
0672 MLXSW_ITEM32(cmd_mbox, config_profile, set_kvd_linear_size, 0x0C, 24, 1);
0673 
0674 /* cmd_mbox_config_set_kvd_hash_single_size
0675  * Capability bit. Setting a bit to 1 configures the profile
0676  * according to the mailbox contents.
0677  */
0678 MLXSW_ITEM32(cmd_mbox, config_profile, set_kvd_hash_single_size, 0x0C, 25, 1);
0679 
0680 /* cmd_mbox_config_set_kvd_hash_double_size
0681  * Capability bit. Setting a bit to 1 configures the profile
0682  * according to the mailbox contents.
0683  */
0684 MLXSW_ITEM32(cmd_mbox, config_profile, set_kvd_hash_double_size, 0x0C, 26, 1);
0685 
0686 /* cmd_mbox_config_set_cqe_version
0687  * Capability bit. Setting a bit to 1 configures the profile
0688  * according to the mailbox contents.
0689  */
0690 MLXSW_ITEM32(cmd_mbox, config_profile, set_cqe_version, 0x08, 0, 1);
0691 
0692 /* cmd_mbox_config_set_cqe_time_stamp_type
0693  * Capability bit. Setting a bit to 1 configures the profile
0694  * according to the mailbox contents.
0695  */
0696 MLXSW_ITEM32(cmd_mbox, config_profile, set_cqe_time_stamp_type, 0x08, 2, 1);
0697 
0698 /* cmd_mbox_config_profile_max_vepa_channels
0699  * Maximum number of VEPA channels per port (0 through 16)
0700  * 0 - multi-channel VEPA is disabled
0701  */
0702 MLXSW_ITEM32(cmd_mbox, config_profile, max_vepa_channels, 0x10, 0, 8);
0703 
0704 /* cmd_mbox_config_profile_max_lag
0705  * Maximum number of LAG IDs requested.
0706  */
0707 MLXSW_ITEM32(cmd_mbox, config_profile, max_lag, 0x14, 0, 16);
0708 
0709 /* cmd_mbox_config_profile_max_port_per_lag
0710  * Maximum number of ports per LAG requested.
0711  */
0712 MLXSW_ITEM32(cmd_mbox, config_profile, max_port_per_lag, 0x18, 0, 16);
0713 
0714 /* cmd_mbox_config_profile_max_mid
0715  * Maximum Multicast IDs.
0716  * Multicast IDs are allocated from 0 to max_mid-1
0717  */
0718 MLXSW_ITEM32(cmd_mbox, config_profile, max_mid, 0x1C, 0, 16);
0719 
0720 /* cmd_mbox_config_profile_max_pgt
0721  * Maximum records in the Port Group Table per Switch Partition.
0722  * Port Group Table indexes are from 0 to max_pgt-1
0723  */
0724 MLXSW_ITEM32(cmd_mbox, config_profile, max_pgt, 0x20, 0, 16);
0725 
0726 /* cmd_mbox_config_profile_max_system_port
0727  * The maximum number of system ports that can be allocated.
0728  */
0729 MLXSW_ITEM32(cmd_mbox, config_profile, max_system_port, 0x24, 0, 16);
0730 
0731 /* cmd_mbox_config_profile_max_vlan_groups
0732  * Maximum number VLAN Groups for VLAN binding.
0733  */
0734 MLXSW_ITEM32(cmd_mbox, config_profile, max_vlan_groups, 0x28, 0, 12);
0735 
0736 /* cmd_mbox_config_profile_max_regions
0737  * Maximum number of TCAM Regions.
0738  */
0739 MLXSW_ITEM32(cmd_mbox, config_profile, max_regions, 0x2C, 0, 16);
0740 
0741 /* cmd_mbox_config_profile_max_flood_tables
0742  * Maximum number of single-entry flooding tables. Different flooding tables
0743  * can be associated with different packet types.
0744  */
0745 MLXSW_ITEM32(cmd_mbox, config_profile, max_flood_tables, 0x30, 16, 4);
0746 
0747 /* cmd_mbox_config_profile_max_vid_flood_tables
0748  * Maximum number of per-vid flooding tables. Flooding tables are associated
0749  * to the different packet types for the different switch partitions.
0750  * Table size is 4K entries covering all VID space.
0751  */
0752 MLXSW_ITEM32(cmd_mbox, config_profile, max_vid_flood_tables, 0x30, 8, 4);
0753 
0754 enum mlxsw_cmd_mbox_config_profile_flood_mode {
0755     /* Mixed mode, where:
0756      * max_flood_tables indicates the number of single-entry tables.
0757      * max_vid_flood_tables indicates the number of per-VID tables.
0758      * max_fid_offset_flood_tables indicates the number of FID-offset
0759      * tables. max_fid_flood_tables indicates the number of per-FID tables.
0760      * Reserved when unified bridge model is used.
0761      */
0762     MLXSW_CMD_MBOX_CONFIG_PROFILE_FLOOD_MODE_MIXED = 3,
0763     /* Controlled flood tables. Reserved when legacy bridge model is
0764      * used.
0765      */
0766     MLXSW_CMD_MBOX_CONFIG_PROFILE_FLOOD_MODE_CONTROLLED = 4,
0767 };
0768 
0769 /* cmd_mbox_config_profile_flood_mode
0770  * Flooding mode to use.
0771  */
0772 MLXSW_ITEM32(cmd_mbox, config_profile, flood_mode, 0x30, 0, 3);
0773 
0774 /* cmd_mbox_config_profile_max_fid_offset_flood_tables
0775  * Maximum number of FID-offset flooding tables.
0776  */
0777 MLXSW_ITEM32(cmd_mbox, config_profile,
0778          max_fid_offset_flood_tables, 0x34, 24, 4);
0779 
0780 /* cmd_mbox_config_profile_fid_offset_flood_table_size
0781  * The size (number of entries) of each FID-offset flood table.
0782  */
0783 MLXSW_ITEM32(cmd_mbox, config_profile,
0784          fid_offset_flood_table_size, 0x34, 0, 16);
0785 
0786 /* cmd_mbox_config_profile_max_fid_flood_tables
0787  * Maximum number of per-FID flooding tables.
0788  *
0789  * Note: This flooding tables cover special FIDs only (vFIDs), starting at
0790  * FID value 4K and higher.
0791  */
0792 MLXSW_ITEM32(cmd_mbox, config_profile, max_fid_flood_tables, 0x38, 24, 4);
0793 
0794 /* cmd_mbox_config_profile_fid_flood_table_size
0795  * The size (number of entries) of each per-FID table.
0796  */
0797 MLXSW_ITEM32(cmd_mbox, config_profile, fid_flood_table_size, 0x38, 0, 16);
0798 
0799 /* cmd_mbox_config_profile_max_ib_mc
0800  * Maximum number of multicast FDB records for InfiniBand
0801  * FDB (in 512 chunks) per InfiniBand switch partition.
0802  */
0803 MLXSW_ITEM32(cmd_mbox, config_profile, max_ib_mc, 0x40, 0, 15);
0804 
0805 /* cmd_mbox_config_profile_max_pkey
0806  * Maximum per port PKEY table size (for PKEY enforcement)
0807  */
0808 MLXSW_ITEM32(cmd_mbox, config_profile, max_pkey, 0x44, 0, 15);
0809 
0810 /* cmd_mbox_config_profile_ar_sec
0811  * Primary/secondary capability
0812  * Describes the number of adaptive routing sub-groups
0813  * 0 - disable primary/secondary (single group)
0814  * 1 - enable primary/secondary (2 sub-groups)
0815  * 2 - 3 sub-groups: Not supported in SwitchX, SwitchX-2
0816  * 3 - 4 sub-groups: Not supported in SwitchX, SwitchX-2
0817  */
0818 MLXSW_ITEM32(cmd_mbox, config_profile, ar_sec, 0x4C, 24, 2);
0819 
0820 /* cmd_mbox_config_profile_adaptive_routing_group_cap
0821  * Adaptive Routing Group Capability. Indicates the number of AR groups
0822  * supported. Note that when Primary/secondary is enabled, each
0823  * primary/secondary couple consumes 2 adaptive routing entries.
0824  */
0825 MLXSW_ITEM32(cmd_mbox, config_profile, adaptive_routing_group_cap, 0x4C, 0, 16);
0826 
0827 /* cmd_mbox_config_profile_arn
0828  * Adaptive Routing Notification Enable
0829  * Not supported in SwitchX, SwitchX-2
0830  */
0831 MLXSW_ITEM32(cmd_mbox, config_profile, arn, 0x50, 31, 1);
0832 
0833 /* cmd_mbox_config_profile_ubridge
0834  * Unified Bridge
0835  * 0 - non unified bridge
0836  * 1 - unified bridge
0837  */
0838 MLXSW_ITEM32(cmd_mbox, config_profile, ubridge, 0x50, 4, 1);
0839 
0840 /* cmd_mbox_config_kvd_linear_size
0841  * KVD Linear Size
0842  * Valid for Spectrum only
0843  * Allowed values are 128*N where N=0 or higher
0844  */
0845 MLXSW_ITEM32(cmd_mbox, config_profile, kvd_linear_size, 0x54, 0, 24);
0846 
0847 /* cmd_mbox_config_kvd_hash_single_size
0848  * KVD Hash single-entries size
0849  * Valid for Spectrum only
0850  * Allowed values are 128*N where N=0 or higher
0851  * Must be greater or equal to cap_min_kvd_hash_single_size
0852  * Must be smaller or equal to cap_kvd_size - kvd_linear_size
0853  */
0854 MLXSW_ITEM32(cmd_mbox, config_profile, kvd_hash_single_size, 0x58, 0, 24);
0855 
0856 /* cmd_mbox_config_kvd_hash_double_size
0857  * KVD Hash double-entries size (units of single-size entries)
0858  * Valid for Spectrum only
0859  * Allowed values are 128*N where N=0 or higher
0860  * Must be either 0 or greater or equal to cap_min_kvd_hash_double_size
0861  * Must be smaller or equal to cap_kvd_size - kvd_linear_size
0862  */
0863 MLXSW_ITEM32(cmd_mbox, config_profile, kvd_hash_double_size, 0x5C, 0, 24);
0864 
0865 /* cmd_mbox_config_profile_swid_config_mask
0866  * Modify Switch Partition Configuration mask. When set, the configu-
0867  * ration value for the Switch Partition are taken from the mailbox.
0868  * When clear, the current configuration values are used.
0869  * Bit 0 - set type
0870  * Bit 1 - properties
0871  * Other - reserved
0872  */
0873 MLXSW_ITEM32_INDEXED(cmd_mbox, config_profile, swid_config_mask,
0874              0x60, 24, 8, 0x08, 0x00, false);
0875 
0876 /* cmd_mbox_config_profile_swid_config_type
0877  * Switch Partition type.
0878  * 0000 - disabled (Switch Partition does not exist)
0879  * 0001 - InfiniBand
0880  * 0010 - Ethernet
0881  * 1000 - router port (SwitchX-2 only)
0882  * Other - reserved
0883  */
0884 MLXSW_ITEM32_INDEXED(cmd_mbox, config_profile, swid_config_type,
0885              0x60, 20, 4, 0x08, 0x00, false);
0886 
0887 /* cmd_mbox_config_profile_swid_config_properties
0888  * Switch Partition properties.
0889  */
0890 MLXSW_ITEM32_INDEXED(cmd_mbox, config_profile, swid_config_properties,
0891              0x60, 0, 8, 0x08, 0x00, false);
0892 
0893 enum mlxsw_cmd_mbox_config_profile_cqe_time_stamp_type {
0894     /* uSec - 1.024uSec (default). Only bits 15:0 are valid. */
0895     MLXSW_CMD_MBOX_CONFIG_PROFILE_CQE_TIME_STAMP_TYPE_USEC,
0896     /* FRC - Free Running Clock, units of 1nSec.
0897      * Reserved when SwitchX/-2, Switch-IB/2 and Spectrum-1.
0898      */
0899     MLXSW_CMD_MBOX_CONFIG_PROFILE_CQE_TIME_STAMP_TYPE_FRC,
0900     /* UTC. time_stamp[37:30] = Sec, time_stamp[29:0] = nSec.
0901      * Reserved when SwitchX/2, Switch-IB/2 and Spectrum-1.
0902      */
0903     MLXSW_CMD_MBOX_CONFIG_PROFILE_CQE_TIME_STAMP_TYPE_UTC,
0904 };
0905 
0906 /* cmd_mbox_config_profile_cqe_time_stamp_type
0907  * CQE time_stamp_type for non-mirror-packets.
0908  * Configured if set_cqe_time_stamp_type is set.
0909  * Reserved when SwitchX/-2, Switch-IB/2 and Spectrum-1.
0910  */
0911 MLXSW_ITEM32(cmd_mbox, config_profile, cqe_time_stamp_type, 0xB0, 8, 2);
0912 
0913 /* cmd_mbox_config_profile_cqe_version
0914  * CQE version:
0915  * 0: CQE version is 0
0916  * 1: CQE version is either 1 or 2
0917  * CQE ver 1 or 2 is configured by Completion Queue Context field cqe_ver.
0918  */
0919 MLXSW_ITEM32(cmd_mbox, config_profile, cqe_version, 0xB0, 0, 8);
0920 
0921 /* ACCESS_REG - Access EMAD Supported Register
0922  * ----------------------------------
0923  * OpMod == 0 (N/A), INMmod == 0 (N/A)
0924  * -------------------------------------
0925  * The ACCESS_REG command supports accessing device registers. This access
0926  * is mainly used for bootstrapping.
0927  */
0928 
0929 static inline int mlxsw_cmd_access_reg(struct mlxsw_core *mlxsw_core,
0930                        bool reset_ok,
0931                        char *in_mbox, char *out_mbox)
0932 {
0933     return mlxsw_cmd_exec(mlxsw_core, MLXSW_CMD_OPCODE_ACCESS_REG,
0934                   0, 0, false, reset_ok,
0935                   in_mbox, MLXSW_CMD_MBOX_SIZE,
0936                   out_mbox, MLXSW_CMD_MBOX_SIZE);
0937 }
0938 
0939 /* SW2HW_DQ - Software to Hardware DQ
0940  * ----------------------------------
0941  * OpMod == 0 (send DQ) / OpMod == 1 (receive DQ)
0942  * INMmod == DQ number
0943  * ----------------------------------------------
0944  * The SW2HW_DQ command transitions a descriptor queue from software to
0945  * hardware ownership. The command enables posting WQEs and ringing DoorBells
0946  * on the descriptor queue.
0947  */
0948 
0949 static inline int __mlxsw_cmd_sw2hw_dq(struct mlxsw_core *mlxsw_core,
0950                        char *in_mbox, u32 dq_number,
0951                        u8 opcode_mod)
0952 {
0953     return mlxsw_cmd_exec_in(mlxsw_core, MLXSW_CMD_OPCODE_SW2HW_DQ,
0954                  opcode_mod, dq_number,
0955                  in_mbox, MLXSW_CMD_MBOX_SIZE);
0956 }
0957 
0958 enum {
0959     MLXSW_CMD_OPCODE_MOD_SDQ = 0,
0960     MLXSW_CMD_OPCODE_MOD_RDQ = 1,
0961 };
0962 
0963 static inline int mlxsw_cmd_sw2hw_sdq(struct mlxsw_core *mlxsw_core,
0964                       char *in_mbox, u32 dq_number)
0965 {
0966     return __mlxsw_cmd_sw2hw_dq(mlxsw_core, in_mbox, dq_number,
0967                     MLXSW_CMD_OPCODE_MOD_SDQ);
0968 }
0969 
0970 static inline int mlxsw_cmd_sw2hw_rdq(struct mlxsw_core *mlxsw_core,
0971                       char *in_mbox, u32 dq_number)
0972 {
0973     return __mlxsw_cmd_sw2hw_dq(mlxsw_core, in_mbox, dq_number,
0974                     MLXSW_CMD_OPCODE_MOD_RDQ);
0975 }
0976 
0977 /* cmd_mbox_sw2hw_dq_cq
0978  * Number of the CQ that this Descriptor Queue reports completions to.
0979  */
0980 MLXSW_ITEM32(cmd_mbox, sw2hw_dq, cq, 0x00, 24, 8);
0981 
0982 enum mlxsw_cmd_mbox_sw2hw_dq_sdq_lp {
0983     MLXSW_CMD_MBOX_SW2HW_DQ_SDQ_LP_WQE,
0984     MLXSW_CMD_MBOX_SW2HW_DQ_SDQ_LP_IGNORE_WQE,
0985 };
0986 
0987 /* cmd_mbox_sw2hw_dq_sdq_lp
0988  * SDQ local Processing
0989  * 0: local processing by wqe.lp
0990  * 1: local processing (ignoring wqe.lp)
0991  */
0992 MLXSW_ITEM32(cmd_mbox, sw2hw_dq, sdq_lp, 0x00, 23, 1);
0993 
0994 /* cmd_mbox_sw2hw_dq_sdq_tclass
0995  * SDQ: CPU Egress TClass
0996  * RDQ: Reserved
0997  */
0998 MLXSW_ITEM32(cmd_mbox, sw2hw_dq, sdq_tclass, 0x00, 16, 6);
0999 
1000 /* cmd_mbox_sw2hw_dq_log2_dq_sz
1001  * Log (base 2) of the Descriptor Queue size in 4KB pages.
1002  */
1003 MLXSW_ITEM32(cmd_mbox, sw2hw_dq, log2_dq_sz, 0x00, 0, 6);
1004 
1005 /* cmd_mbox_sw2hw_dq_pa
1006  * Physical Address.
1007  */
1008 MLXSW_ITEM64_INDEXED(cmd_mbox, sw2hw_dq, pa, 0x10, 12, 52, 0x08, 0x00, true);
1009 
1010 /* HW2SW_DQ - Hardware to Software DQ
1011  * ----------------------------------
1012  * OpMod == 0 (send DQ) / OpMod == 1 (receive DQ)
1013  * INMmod == DQ number
1014  * ----------------------------------------------
1015  * The HW2SW_DQ command transitions a descriptor queue from hardware to
1016  * software ownership. Incoming packets on the DQ are silently discarded,
1017  * SW should not post descriptors on nonoperational DQs.
1018  */
1019 
1020 static inline int __mlxsw_cmd_hw2sw_dq(struct mlxsw_core *mlxsw_core,
1021                        u32 dq_number, u8 opcode_mod)
1022 {
1023     return mlxsw_cmd_exec_none(mlxsw_core, MLXSW_CMD_OPCODE_HW2SW_DQ,
1024                    opcode_mod, dq_number);
1025 }
1026 
1027 static inline int mlxsw_cmd_hw2sw_sdq(struct mlxsw_core *mlxsw_core,
1028                       u32 dq_number)
1029 {
1030     return __mlxsw_cmd_hw2sw_dq(mlxsw_core, dq_number,
1031                     MLXSW_CMD_OPCODE_MOD_SDQ);
1032 }
1033 
1034 static inline int mlxsw_cmd_hw2sw_rdq(struct mlxsw_core *mlxsw_core,
1035                       u32 dq_number)
1036 {
1037     return __mlxsw_cmd_hw2sw_dq(mlxsw_core, dq_number,
1038                     MLXSW_CMD_OPCODE_MOD_RDQ);
1039 }
1040 
1041 /* 2ERR_DQ - To Error DQ
1042  * ---------------------
1043  * OpMod == 0 (send DQ) / OpMod == 1 (receive DQ)
1044  * INMmod == DQ number
1045  * ----------------------------------------------
1046  * The 2ERR_DQ command transitions the DQ into the error state from the state
1047  * in which it has been. While the command is executed, some in-process
1048  * descriptors may complete. Once the DQ transitions into the error state,
1049  * if there are posted descriptors on the RDQ/SDQ, the hardware writes
1050  * a completion with error (flushed) for all descriptors posted in the RDQ/SDQ.
1051  * When the command is completed successfully, the DQ is already in
1052  * the error state.
1053  */
1054 
1055 static inline int __mlxsw_cmd_2err_dq(struct mlxsw_core *mlxsw_core,
1056                       u32 dq_number, u8 opcode_mod)
1057 {
1058     return mlxsw_cmd_exec_none(mlxsw_core, MLXSW_CMD_OPCODE_2ERR_DQ,
1059                    opcode_mod, dq_number);
1060 }
1061 
1062 static inline int mlxsw_cmd_2err_sdq(struct mlxsw_core *mlxsw_core,
1063                      u32 dq_number)
1064 {
1065     return __mlxsw_cmd_2err_dq(mlxsw_core, dq_number,
1066                    MLXSW_CMD_OPCODE_MOD_SDQ);
1067 }
1068 
1069 static inline int mlxsw_cmd_2err_rdq(struct mlxsw_core *mlxsw_core,
1070                      u32 dq_number)
1071 {
1072     return __mlxsw_cmd_2err_dq(mlxsw_core, dq_number,
1073                    MLXSW_CMD_OPCODE_MOD_RDQ);
1074 }
1075 
1076 /* QUERY_DQ - Query DQ
1077  * ---------------------
1078  * OpMod == 0 (send DQ) / OpMod == 1 (receive DQ)
1079  * INMmod == DQ number
1080  * ----------------------------------------------
1081  * The QUERY_DQ command retrieves a snapshot of DQ parameters from the hardware.
1082  *
1083  * Note: Output mailbox has the same format as SW2HW_DQ.
1084  */
1085 
1086 static inline int __mlxsw_cmd_query_dq(struct mlxsw_core *mlxsw_core,
1087                        char *out_mbox, u32 dq_number,
1088                        u8 opcode_mod)
1089 {
1090     return mlxsw_cmd_exec_out(mlxsw_core, MLXSW_CMD_OPCODE_2ERR_DQ,
1091                   opcode_mod, dq_number, false,
1092                   out_mbox, MLXSW_CMD_MBOX_SIZE);
1093 }
1094 
1095 static inline int mlxsw_cmd_query_sdq(struct mlxsw_core *mlxsw_core,
1096                       char *out_mbox, u32 dq_number)
1097 {
1098     return __mlxsw_cmd_query_dq(mlxsw_core, out_mbox, dq_number,
1099                     MLXSW_CMD_OPCODE_MOD_SDQ);
1100 }
1101 
1102 static inline int mlxsw_cmd_query_rdq(struct mlxsw_core *mlxsw_core,
1103                       char *out_mbox, u32 dq_number)
1104 {
1105     return __mlxsw_cmd_query_dq(mlxsw_core, out_mbox, dq_number,
1106                     MLXSW_CMD_OPCODE_MOD_RDQ);
1107 }
1108 
1109 /* SW2HW_CQ - Software to Hardware CQ
1110  * ----------------------------------
1111  * OpMod == 0 (N/A), INMmod == CQ number
1112  * -------------------------------------
1113  * The SW2HW_CQ command transfers ownership of a CQ context entry from software
1114  * to hardware. The command takes the CQ context entry from the input mailbox
1115  * and stores it in the CQC in the ownership of the hardware. The command fails
1116  * if the requested CQC entry is already in the ownership of the hardware.
1117  */
1118 
1119 static inline int mlxsw_cmd_sw2hw_cq(struct mlxsw_core *mlxsw_core,
1120                      char *in_mbox, u32 cq_number)
1121 {
1122     return mlxsw_cmd_exec_in(mlxsw_core, MLXSW_CMD_OPCODE_SW2HW_CQ,
1123                  0, cq_number, in_mbox, MLXSW_CMD_MBOX_SIZE);
1124 }
1125 
1126 enum mlxsw_cmd_mbox_sw2hw_cq_cqe_ver {
1127     MLXSW_CMD_MBOX_SW2HW_CQ_CQE_VER_1,
1128     MLXSW_CMD_MBOX_SW2HW_CQ_CQE_VER_2,
1129 };
1130 
1131 /* cmd_mbox_sw2hw_cq_cqe_ver
1132  * CQE Version.
1133  */
1134 MLXSW_ITEM32(cmd_mbox, sw2hw_cq, cqe_ver, 0x00, 28, 4);
1135 
1136 /* cmd_mbox_sw2hw_cq_c_eqn
1137  * Event Queue this CQ reports completion events to.
1138  */
1139 MLXSW_ITEM32(cmd_mbox, sw2hw_cq, c_eqn, 0x00, 24, 1);
1140 
1141 /* cmd_mbox_sw2hw_cq_st
1142  * Event delivery state machine
1143  * 0x0 - FIRED
1144  * 0x1 - ARMED (Request for Notification)
1145  */
1146 MLXSW_ITEM32(cmd_mbox, sw2hw_cq, st, 0x00, 8, 1);
1147 
1148 /* cmd_mbox_sw2hw_cq_log_cq_size
1149  * Log (base 2) of the CQ size (in entries).
1150  */
1151 MLXSW_ITEM32(cmd_mbox, sw2hw_cq, log_cq_size, 0x00, 0, 4);
1152 
1153 /* cmd_mbox_sw2hw_cq_producer_counter
1154  * Producer Counter. The counter is incremented for each CQE that is
1155  * written by the HW to the CQ.
1156  * Maintained by HW (valid for the QUERY_CQ command only)
1157  */
1158 MLXSW_ITEM32(cmd_mbox, sw2hw_cq, producer_counter, 0x04, 0, 16);
1159 
1160 /* cmd_mbox_sw2hw_cq_pa
1161  * Physical Address.
1162  */
1163 MLXSW_ITEM64_INDEXED(cmd_mbox, sw2hw_cq, pa, 0x10, 11, 53, 0x08, 0x00, true);
1164 
1165 /* HW2SW_CQ - Hardware to Software CQ
1166  * ----------------------------------
1167  * OpMod == 0 (N/A), INMmod == CQ number
1168  * -------------------------------------
1169  * The HW2SW_CQ command transfers ownership of a CQ context entry from hardware
1170  * to software. The CQC entry is invalidated as a result of this command.
1171  */
1172 
1173 static inline int mlxsw_cmd_hw2sw_cq(struct mlxsw_core *mlxsw_core,
1174                      u32 cq_number)
1175 {
1176     return mlxsw_cmd_exec_none(mlxsw_core, MLXSW_CMD_OPCODE_HW2SW_CQ,
1177                    0, cq_number);
1178 }
1179 
1180 /* QUERY_CQ - Query CQ
1181  * ----------------------------------
1182  * OpMod == 0 (N/A), INMmod == CQ number
1183  * -------------------------------------
1184  * The QUERY_CQ command retrieves a snapshot of the current CQ context entry.
1185  * The command stores the snapshot in the output mailbox in the software format.
1186  * Note that the CQ context state and values are not affected by the QUERY_CQ
1187  * command. The QUERY_CQ command is for debug purposes only.
1188  *
1189  * Note: Output mailbox has the same format as SW2HW_CQ.
1190  */
1191 
1192 static inline int mlxsw_cmd_query_cq(struct mlxsw_core *mlxsw_core,
1193                      char *out_mbox, u32 cq_number)
1194 {
1195     return mlxsw_cmd_exec_out(mlxsw_core, MLXSW_CMD_OPCODE_QUERY_CQ,
1196                   0, cq_number, false,
1197                   out_mbox, MLXSW_CMD_MBOX_SIZE);
1198 }
1199 
1200 /* SW2HW_EQ - Software to Hardware EQ
1201  * ----------------------------------
1202  * OpMod == 0 (N/A), INMmod == EQ number
1203  * -------------------------------------
1204  * The SW2HW_EQ command transfers ownership of an EQ context entry from software
1205  * to hardware. The command takes the EQ context entry from the input mailbox
1206  * and stores it in the EQC in the ownership of the hardware. The command fails
1207  * if the requested EQC entry is already in the ownership of the hardware.
1208  */
1209 
1210 static inline int mlxsw_cmd_sw2hw_eq(struct mlxsw_core *mlxsw_core,
1211                      char *in_mbox, u32 eq_number)
1212 {
1213     return mlxsw_cmd_exec_in(mlxsw_core, MLXSW_CMD_OPCODE_SW2HW_EQ,
1214                  0, eq_number, in_mbox, MLXSW_CMD_MBOX_SIZE);
1215 }
1216 
1217 /* cmd_mbox_sw2hw_eq_int_msix
1218  * When set, MSI-X cycles will be generated by this EQ.
1219  * When cleared, an interrupt will be generated by this EQ.
1220  */
1221 MLXSW_ITEM32(cmd_mbox, sw2hw_eq, int_msix, 0x00, 24, 1);
1222 
1223 /* cmd_mbox_sw2hw_eq_st
1224  * Event delivery state machine
1225  * 0x0 - FIRED
1226  * 0x1 - ARMED (Request for Notification)
1227  * 0x11 - Always ARMED
1228  * other - reserved
1229  */
1230 MLXSW_ITEM32(cmd_mbox, sw2hw_eq, st, 0x00, 8, 2);
1231 
1232 /* cmd_mbox_sw2hw_eq_log_eq_size
1233  * Log (base 2) of the EQ size (in entries).
1234  */
1235 MLXSW_ITEM32(cmd_mbox, sw2hw_eq, log_eq_size, 0x00, 0, 4);
1236 
1237 /* cmd_mbox_sw2hw_eq_producer_counter
1238  * Producer Counter. The counter is incremented for each EQE that is written
1239  * by the HW to the EQ.
1240  * Maintained by HW (valid for the QUERY_EQ command only)
1241  */
1242 MLXSW_ITEM32(cmd_mbox, sw2hw_eq, producer_counter, 0x04, 0, 16);
1243 
1244 /* cmd_mbox_sw2hw_eq_pa
1245  * Physical Address.
1246  */
1247 MLXSW_ITEM64_INDEXED(cmd_mbox, sw2hw_eq, pa, 0x10, 11, 53, 0x08, 0x00, true);
1248 
1249 /* HW2SW_EQ - Hardware to Software EQ
1250  * ----------------------------------
1251  * OpMod == 0 (N/A), INMmod == EQ number
1252  * -------------------------------------
1253  */
1254 
1255 static inline int mlxsw_cmd_hw2sw_eq(struct mlxsw_core *mlxsw_core,
1256                      u32 eq_number)
1257 {
1258     return mlxsw_cmd_exec_none(mlxsw_core, MLXSW_CMD_OPCODE_HW2SW_EQ,
1259                    0, eq_number);
1260 }
1261 
1262 /* QUERY_EQ - Query EQ
1263  * ----------------------------------
1264  * OpMod == 0 (N/A), INMmod == EQ number
1265  * -------------------------------------
1266  *
1267  * Note: Output mailbox has the same format as SW2HW_EQ.
1268  */
1269 
1270 static inline int mlxsw_cmd_query_eq(struct mlxsw_core *mlxsw_core,
1271                      char *out_mbox, u32 eq_number)
1272 {
1273     return mlxsw_cmd_exec_out(mlxsw_core, MLXSW_CMD_OPCODE_QUERY_EQ,
1274                   0, eq_number, false,
1275                   out_mbox, MLXSW_CMD_MBOX_SIZE);
1276 }
1277 
1278 #endif