efct: Broadcom (Emulex) FC Target driver
Subsystems (2)
v3 cover efct: Broadcom (Emulex) FC Target driver
This patch set is a request to incorporate the new Broadcom (Emulex) FC target driver, efct, into the kernel source tree.
The driver source has been Announced a couple of times, the last version on 12/20/2019. The driver has been hosted on gitlab for review has had contributions from the community.
gitlab ([email protected]:jsmart/efct-Emulex_FC_Target.git)
The driver integrates into the source tree at the (new) drivers/scsi/elx subdirectory.
The driver consists of the following components:
- A libefc_sli subdirectory: This subdirectory contains a library that encapsulates common definitions and routines for an Emulex SLI-4 adapter.
- A libefc subdirectory: This subdirectory contains a library of common routines. Of major import is a number of routines that implement a FC Discovery engine for target mode.
- An efct subdirectory: This subdirectory contains the efct target mode device driver. The driver utilizes the above librarys and plugs into the SCSI LIO interfaces. The driver is SCSI only at this time.
The patches populate the libraries and device driver and can only be compiled as a complete set.
This driver is completely independent from the lpfc device driver and there is no overlap on PCI ID's.
The patches have been cut against the 5.7/scsi-queue branch.
Thank you to those that have contributed to the driver in the past.
Review comments welcome!
-- james
V2 modifications:
Contains the following modifications based on prior review comments:
Indentation/Alignment/Spacing changes
Comments: format cleanup; removed obvious or unnecessary comments;
Added comments for clarity.
Headers use #ifndef comparing for prior inclusion
Cleanup structure names (remove _s suffix)
Encapsulate use of macro arguments
Refactor to remove static function declarations for static local routines Removed unused variables
Fix SLI4_INTF_VALID_MASK for 32bits
Ensure no BIT() use
Use __ffs() in page count macro
Reorg to move field defines out of structure definition Commonize command building routines to reduce duplication
LIO interface:
Removed scsi initiator includes
Cleaned up interface defines
Removed lio WWN version attribute.
Expanded macros within logging macros
Cleaned up lio state setting macro
Remove __force use
Modularized session debugfs code so can be easily replaced. Cleaned up abort task handling. Return after initiating. Modularized where possible to reduce duplication
Convert from kthread to workqueue use
Remove unused macros
Add missing TARGET_CORE build attribute
Fix kbuild test robot warnings
Comments not addressed:
Use of __packed: not believed necessary
Session debugfs code remains. There is not yet a common lio
mechanism to replace with.
V3 modifications:
Changed anonymous enums to named enums
Split gaint enums into multiple enums
Use defines to spell out _MASK values directly
Changed multiple #defines to named enums and a few vice versa cases
for consistency
Added Link Speed support for up to 128G
Removed efc_assert define. Replaced with WARN_ON. Returned defined return values EFC_SUCCESS & EFC_FAIL Added return values for routines returning more than those 2 values Reduction of calling arguments in various routines. Expanded dump type and status handling
Fixed locking in discovery handling routines.
Fixed line formatting length and indentation issues. Removed code that was not used.
Removed Sparse Vector APIs and structures. Use xarray api instead. Changed node pool creation. Use mempool and allocate dma memory when
required
Bug Fix: Send LS_RJT for non FCP PRLIs
Removed Queue topology string and parsing routines and rework queue
creation. Adapter configuration is implicitly known by the driver
Used request_threaded_irq instead of using our thread Reworked efct_device_attach function to use if statements and gotos Changed efct_fw_reset, removed accessing other port Convert to used pci_alloc_irq_vectors api
Removed proc interface.
Changed assertion log messages.
Unified log message using cmd_name
Removed DIF related code which is not used
Removed SCSI get property
Incorporated LIO interface review comments
Reworked xxx_reg_vpi/vfi routines
Use SPDX license in elx/Makefile
Many more small changes.
James Smart (31):
elx: libefc_sli: SLI-4 register offsets and field definitions
elx: libefc_sli: SLI Descriptors and Queue entries
elx: libefc_sli: Data structures and defines for mbox commands
elx: libefc_sli: queue create/destroy/parse routines
elx: libefc_sli: Populate and post different WQEs
elx: libefc_sli: bmbx routines and SLI config commands
elx: libefc_sli: APIs to setup SLI library
elx: libefc: Generic state machine framework
elx: libefc: Emulex FC discovery library APIs and definitions
elx: libefc: FC Domain state machine interfaces
elx: libefc: SLI and FC PORT state machine interfaces
elx: libefc: Remote node state machine interfaces
elx: libefc: Fabric node state machine interfaces
elx: libefc: FC node ELS and state handling
elx: efct: Data structures and defines for hw operations
elx: efct: Driver initialization routines
elx: efct: Hardware queues creation and deletion
elx: efct: RQ buffer, memory pool allocation and deallocation APIs
elx: efct: Hardware IO and SGL initialization
elx: efct: Hardware queues processing
elx: efct: Unsolicited FC frame processing routines
elx: efct: Extended link Service IO handling
elx: efct: SCSI IO handling routines
elx: efct: LIO backend interface routines
elx: efct: Hardware IO submission routines
elx: efct: link statistics and SFP data
elx: efct: xport and hardware teardown routines
elx: efct: Firmware update, async link processing
elx: efct: scsi_transport_fc host interface support
elx: efct: Add Makefile and Kconfig for efct driver
elx: efct: Tie into kernel Kconfig and build process
MAINTAINERS | 8 + drivers/scsi/Kconfig | 2 + drivers/scsi/Makefile | 1 + drivers/scsi/elx/Kconfig | 9 + drivers/scsi/elx/Makefile | 18 + drivers/scsi/elx/efct/efct_driver.c | 856 +++++ drivers/scsi/elx/efct/efct_driver.h | 142 + drivers/scsi/elx/efct/efct_els.c | 1928 +++++++++++ drivers/scsi/elx/efct/efct_els.h | 133 + drivers/scsi/elx/efct/efct_hw.c | 5347 +++++++++++++++++++++++++++++++ drivers/scsi/elx/efct/efct_hw.h | 864 +++++ drivers/scsi/elx/efct/efct_hw_queues.c | 765 +++++ drivers/scsi/elx/efct/efct_io.c | 198 ++ drivers/scsi/elx/efct/efct_io.h | 191 ++ drivers/scsi/elx/efct/efct_lio.c | 1840 +++++++++++ drivers/scsi/elx/efct/efct_lio.h | 178 + drivers/scsi/elx/efct/efct_scsi.c | 1192 +++++++ drivers/scsi/elx/efct/efct_scsi.h | 235 ++ drivers/scsi/elx/efct/efct_unsol.c | 813 +++++ drivers/scsi/elx/efct/efct_unsol.h | 49 + drivers/scsi/elx/efct/efct_xport.c | 1310 ++++++++ drivers/scsi/elx/efct/efct_xport.h | 201 ++ drivers/scsi/elx/include/efc_common.h | 43 + drivers/scsi/elx/libefc/efc.h | 72 + drivers/scsi/elx/libefc/efc_device.c | 1672 ++++++++++ drivers/scsi/elx/libefc/efc_device.h | 72 + drivers/scsi/elx/libefc/efc_domain.c | 1109 +++++++ drivers/scsi/elx/libefc/efc_domain.h | 52 + drivers/scsi/elx/libefc/efc_fabric.c | 1759 ++++++++++ drivers/scsi/elx/libefc/efc_fabric.h | 116 + drivers/scsi/elx/libefc/efc_lib.c | 41 + drivers/scsi/elx/libefc/efc_node.c | 1196 +++++++ drivers/scsi/elx/libefc/efc_node.h | 183 ++ drivers/scsi/elx/libefc/efc_sm.c | 61 + drivers/scsi/elx/libefc/efc_sm.h | 209 ++ drivers/scsi/elx/libefc/efc_sport.c | 846 +++++ drivers/scsi/elx/libefc/efc_sport.h | 52 + drivers/scsi/elx/libefc/efclib.h | 640 ++++ drivers/scsi/elx/libefc_sli/sli4.c | 5523 ++++++++++++++++++++++++++++++++ drivers/scsi/elx/libefc_sli/sli4.h | 4133 ++++++++++++++++++++++++ 40 files changed, 34059 insertions(+) create mode 100644 drivers/scsi/elx/Kconfig create mode 100644 drivers/scsi/elx/Makefile create mode 100644 drivers/scsi/elx/efct/efct_driver.c create mode 100644 drivers/scsi/elx/efct/efct_driver.h create mode 100644 drivers/scsi/elx/efct/efct_els.c create mode 100644 drivers/scsi/elx/efct/efct_els.h create mode 100644 drivers/scsi/elx/efct/efct_hw.c create mode 100644 drivers/scsi/elx/efct/efct_hw.h create mode 100644 drivers/scsi/elx/efct/efct_hw_queues.c create mode 100644 drivers/scsi/elx/efct/efct_io.c create mode 100644 drivers/scsi/elx/efct/efct_io.h create mode 100644 drivers/scsi/elx/efct/efct_lio.c create mode 100644 drivers/scsi/elx/efct/efct_lio.h create mode 100644 drivers/scsi/elx/efct/efct_scsi.c create mode 100644 drivers/scsi/elx/efct/efct_scsi.h create mode 100644 drivers/scsi/elx/efct/efct_unsol.c create mode 100644 drivers/scsi/elx/efct/efct_unsol.h create mode 100644 drivers/scsi/elx/efct/efct_xport.c create mode 100644 drivers/scsi/elx/efct/efct_xport.h create mode 100644 drivers/scsi/elx/include/efc_common.h create mode 100644 drivers/scsi/elx/libefc/efc.h create mode 100644 drivers/scsi/elx/libefc/efc_device.c create mode 100644 drivers/scsi/elx/libefc/efc_device.h create mode 100644 drivers/scsi/elx/libefc/efc_domain.c create mode 100644 drivers/scsi/elx/libefc/efc_domain.h create mode 100644 drivers/scsi/elx/libefc/efc_fabric.c create mode 100644 drivers/scsi/elx/libefc/efc_fabric.h create mode 100644 drivers/scsi/elx/libefc/efc_lib.c create mode 100644 drivers/scsi/elx/libefc/efc_node.c create mode 100644 drivers/scsi/elx/libefc/efc_node.h create mode 100644 drivers/scsi/elx/libefc/efc_sm.c create mode 100644 drivers/scsi/elx/libefc/efc_sm.h create mode 100644 drivers/scsi/elx/libefc/efc_sport.c create mode 100644 drivers/scsi/elx/libefc/efc_sport.h create mode 100644 drivers/scsi/elx/libefc/efclib.h create mode 100644 drivers/scsi/elx/libefc_sli/sli4.c create mode 100644 drivers/scsi/elx/libefc_sli/sli4.h
Signature · 1 line
2.16.4
PATCH v3 1/31 elx: libefc_sli: SLI-4 register offsets and field definitions
This is the initial patch for the new Emulex target mode SCSI driver sources.
This patch:
- Creates the new Emulex source level directory drivers/scsi/elx and adds the directory to the MAINTAINERS file.
- Creates the first library subdirectory drivers/scsi/elx/libefc_sli. This library is a SLI-4 interface library.
- Starts the population of the libefc_sli library with definitions of SLI-4 hardware register offsets and definitions.
---
v3:
Changed anonymous enums to named.
SLI defines to spell out _MASK value directly. Changed multiple #defines to named enums for consistency. SLI4_REG_MAX to SLI4_REG_UNKNOWN
--- MAINTAINERS | 8 ++ drivers/scsi/elx/libefc_sli/sli4.c | 26 ++++ drivers/scsi/elx/libefc_sli/sli4.h | 252 +++++++++++++++++++++++++++++++++++++ 3 files changed, 286 insertions(+) create mode 100644 drivers/scsi/elx/libefc_sli/sli4.c create mode 100644 drivers/scsi/elx/libefc_sli/sli4.h
MAINTAINERS +8 -0
@@ -6223,6 +6223,14 @@ W: http://www.broadcom.com S: Supported F: drivers/scsi/lpfc/ +EMULEX/BROADCOM EFCT FC/FCOE SCSI TARGET DRIVER +M: James Smart <[email protected]> +M: Ram Vegesna <[email protected]> +L: [email protected] +W: http://www.broadcom.com +S: Supported +F: drivers/scsi/elx/ + ENE CB710 FLASH CARD READER DRIVER M: Michał Mirosław <[email protected]> S: Maintained
drivers/scsi/elx/libefc_sli/sli4.c new file +26 -0
@@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0 +/* +* Copyright (C) 2019 Broadcom. All Rights Reserved. The term +* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. +*/ + +/** +* All common (i.e. transport-independent) SLI-4 functions are implemented +* in this file. +*/ +#include "sli4.h" + +struct sli4_asic_entry_t { +u32 rev_id; +u32 family; +}; + +static struct sli4_asic_entry_t sli4_asic_table[] = { + {SLI4_ASIC_REV_B0 ,SLI4_ASIC_GEN_5 }, + {SLI4_ASIC_REV_D0 ,SLI4_ASIC_GEN_5 }, + {SLI4_ASIC_REV_A3 ,SLI4_ASIC_GEN_6 }, + {SLI4_ASIC_REV_A0 ,SLI4_ASIC_GEN_6 }, + {SLI4_ASIC_REV_A1 ,SLI4_ASIC_GEN_6 }, + {SLI4_ASIC_REV_A3 ,SLI4_ASIC_GEN_6 }, + {SLI4_ASIC_REV_A1 ,SLI4_ASIC_GEN_7 }, +};
drivers/scsi/elx/libefc_sli/sli4.h new file +252 -0
252 lines not on this page · raw message
Signature · 1 line
2.16.4
Re: [PATCH v3 01/31] elx: libefc_sli: SLI-4 register offsets and field definitions
Hi James,
Quoted 6 lines · James Smart
This is the initial patch for the new Emulex target mode SCSI driver sources.
This patch:
- Creates the new Emulex source level directorydrivers/scsi/elxand adds the directory to theMAINTAINERSfile.
I would drop this. It's clear from the diff stat.
Quoted 2 lines
- Creates the first library subdirectory
drivers/scsi/elx/libefc_sli. This library is a SLI-4 interface library.
Instead saying what this patch does, it would be better the explain why it structured this way.
Quoted 45 lines
- Starts the population of the
libefc_slilibrary with definitions of SLI-4 hardware register offsets and definitions.Signed-off-by Ram Vegesna <[email protected]>Signed-off-by James Smart <[email protected]>---
v3:
Changed anonymous enums to named.
SLI defines to spell out_MASKvalue directly. Changed multiple #defines to named enums for consistency.SLI4_REG_MAXtoSLI4_REG_UNKNOWN--- MAINTAINERS | 8 ++ drivers/scsi/elx/libefc_sli/sli4.c | 26 ++++ drivers/scsi/elx/libefc_sli/sli4.h | 252 +++++++++++++++++++++++++++++++++++++ 3 files changed, 286 insertions(+) create mode 100644 drivers/scsi/elx/libefc_sli/sli4.c create mode 100644 drivers/scsi/elx/libefc_sli/sli4.hMAINTAINERS +8
-0@@ -6223,6 +6223,14 @@ W: http://www.broadcom.com S: Supported F: drivers/scsi/lpfc/ +EMULEX/BROADCOM EFCT FC/FCOE SCSI TARGET DRIVER +M: James Smart <[email protected]> +M: Ram Vegesna <[email protected]> +L: [email protected] +W: http://www.broadcom.com +S: Supported +F: drivers/scsi/elx/ + ENE CB710 FLASH CARD READER DRIVER M: Michał Mirosław <[email protected]> S: Maintaineddrivers/scsi/elx/libefc_sli/sli4.c new file +0
-0
drivers/scsi/elx/libefc_sli/sli4.c line 3
Quoted 3 lines
drivers/scsi/elx/libefc_sli/sli4.c new file +3
-0@@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0 +/* +* Copyright (C) 2019 Broadcom. All Rights Reserved. The term
2020? (and all later copyright headers)
Quoted 100 lines
drivers/scsi/elx/libefc_sli/sli4.c new file +23
-0+* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. +*/ + +/** +* All common (i.e. transport-independent) SLI-4 functions are implemented +* in this file. +*/ +#include "sli4.h" + +struct sli4_asic_entry_t { +u32 rev_id; +u32 family; +}; + +static struct sli4_asic_entry_t sli4_asic_table[] = { + {SLI4_ASIC_REV_B0 ,SLI4_ASIC_GEN_5 }, + {SLI4_ASIC_REV_D0 ,SLI4_ASIC_GEN_5 }, + {SLI4_ASIC_REV_A3 ,SLI4_ASIC_GEN_6 }, + {SLI4_ASIC_REV_A0 ,SLI4_ASIC_GEN_6 }, + {SLI4_ASIC_REV_A1 ,SLI4_ASIC_GEN_6 }, + {SLI4_ASIC_REV_A3 ,SLI4_ASIC_GEN_6 }, + {SLI4_ASIC_REV_A1 ,SLI4_ASIC_GEN_7 }, +};drivers/scsi/elx/libefc_sli/sli4.h new file +71
-0@@ -0,0 +1,252 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* +* Copyright (C) 2019 Broadcom. All Rights Reserved. The term +* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. +* +*/ + +/* +* All common SLI-4 structures and function prototypes. +*/ + +#ifndef _SLI4_H +#define _SLI4_H + +#include <linux/pci.h> +#include <linux/delay.h> +#include "scsi/fc/fc_els.h" +#include "scsi/fc/fc_fs.h" +#include "../include/efc_common.h" + +/************************************************************************* +* Common SLI-4 register offsets and field definitions +*/ + +/* SLI_INTF - SLI Interface Definition Register */ +#define SLI4_INTF_REG 0x0058 +enum sli4_intf { +SLI4_INTF_REV_SHIFT =4 , +SLI4_INTF_REV_MASK =0xF0 , + +SLI4_INTF_REV_S3 =0x30 , +SLI4_INTF_REV_S4 =0x40 , + +SLI4_INTF_FAMILY_SHIFT =8 , +SLI4_INTF_FAMILY_MASK =0x0F00 , + +SLI4_FAMILY_CHECK_ASIC_TYPE =0x0F00 , + +SLI4_INTF_IF_TYPE_SHIFT =12 , +SLI4_INTF_IF_TYPE_MASK =0xF000 , + +SLI4_INTF_IF_TYPE_2 =0x2000 , +SLI4_INTF_IF_TYPE_6 =0x6000 , + +SLI4_INTF_VALID_SHIFT =29 , +SLI4_INTF_VALID_MASK =0xE0000000 , + +SLI4_INTF_VALID_VALUE =0xC0000000 , +}; + +/* ASIC_ID - SLI ASIC Type and Revision Register */ +#define SLI4_ASIC_ID_REG 0x009c +enum sli4_asic { +SLI4_ASIC_GEN_SHIFT =8 , +SLI4_ASIC_GEN_MASK =0xFF00 , +SLI4_ASIC_GEN_5 =0x0B00 , +SLI4_ASIC_GEN_6 =0x0C00 , +SLI4_ASIC_GEN_7 =0x0D00 , +}; + +enum sli4_acic_revisions { +SLI4_ASIC_REV_A0 =0x00 , +SLI4_ASIC_REV_A1 =0x01 , +SLI4_ASIC_REV_A2 =0x02 , +SLI4_ASIC_REV_A3 =0x03 , +SLI4_ASIC_REV_B0 =0x10 , +SLI4_ASIC_REV_B1 =0x11 , +SLI4_ASIC_REV_B2 =0x12 , +SLI4_ASIC_REV_C0 =0x20 , +SLI4_ASIC_REV_C1 =0x21 , + SLI4_ASIC_REV_C2 = 0x22,
drivers/scsi/elx/libefc_sli/sli4.h line 81
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h new file +10
-0+ SLI4_ASIC_REV_D0 = 0x30, +}; + +/* BMBX - Bootstrap Mailbox Register */ +#define SLI4_BMBX_REG 0x0160 +enum sli4_bmbx { +SLI4_BMBX_MASK_HI =0x3 , +SLI4_BMBX_MASK_LO =0xf , +SLI4_BMBX_RDY = (1 <<0 ), +SLI4_BMBX_HI = (1 <<1 ),
Are the brakets nessary for enum defitions? I would leave away.
drivers/scsi/elx/libefc_sli/sli4.h line 89
Quoted 8 lines
drivers/scsi/elx/libefc_sli/sli4.h new file +8
-0+ SLI4_BMBX_SIZE = 256, +}; + +#define SLI4_BMBX_WRITE_HI (r) \ + ((upper_32_bits(r) & ~SLI4_BMBX_MASK_HI) | SLI4_BMBX_HI) +#define SLI4_BMBX_WRITE_LO (r) \ + (((upper_32_bits(r) & SLI4_BMBX_MASK_HI) << 30) | \ + (((r) & ~SLI4_BMBX_MASK_LO) >> 2))
I am wondering if these macros should be an inline function instead. Certainly bike shedding territory.
BTW, why is it called SLI4_BMBX_WRITE_HI and not just SLI4_BMBX_HI? Because below with the doorbell registers there is a different pattern.
Quoted 35 lines
drivers/scsi/elx/libefc_sli/sli4.h new file +35
-0+ +/* SLIPORT_CONTROL - SLI Port Control Register */ +#define SLI4_PORT_CTRL_REG 0x0408 +enum sli4_port_ctrl { +SLI4_PORT_CTRL_IP = (1 <<27 ), +SLI4_PORT_CTRL_IDIS = (1 <<22 ), +SLI4_PORT_CTRL_FDD = (1 <<31 ), +}; + +/* SLI4_SLIPORT_ERROR - SLI Port Error Register */ +#define SLI4_PORT_ERROR1 0x040c +#define SLI4_PORT_ERROR2 0x0410 + +/* EQCQ_DOORBELL - EQ and CQ Doorbell Register */ +#define SLI4_EQCQ_DB_REG 0x120 +enum sli4_eqcq_e { +SLI4_EQ_ID_LO_MASK =0x01FF , + +SLI4_CQ_ID_LO_MASK =0x03FF , + +SLI4_EQCQ_CI_EQ =0x0200 , + +SLI4_EQCQ_QT_EQ =0x00000400 , +SLI4_EQCQ_QT_CQ =0x00000000 , + +SLI4_EQCQ_ID_HI_SHIFT =11 , +SLI4_EQCQ_ID_HI_MASK =0xF800 , + +SLI4_EQCQ_NUM_SHIFT =16 , +SLI4_EQCQ_NUM_MASK =0x1FFF0000 , + +SLI4_EQCQ_ARM =0x20000000 , +SLI4_EQCQ_UNARM =0x00000000 , +}; +
drivers/scsi/elx/libefc_sli/sli4.h line 134
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h new file +10
-0+#define SLI4_EQ_DOORBELL (n, id, a) \ + (((id) & SLI4_EQ_ID_LO_MASK) | SLI4_EQCQ_QT_EQ | \ + ((((id) >> 9) << SLI4_EQCQ_ID_HI_SHIFT) & SLI4_EQCQ_ID_HI_MASK) | \ + (((n) << SLI4_EQCQ_NUM_SHIFT) & SLI4_EQCQ_NUM_MASK) | \ + (a) | SLI4_EQCQ_CI_EQ) + +#define SLI4_CQ_DOORBELL (n, id, a) \ + (((id) & SLI4_CQ_ID_LO_MASK) | SLI4_EQCQ_QT_CQ | \ + ((((id) >> 10) << SLI4_EQCQ_ID_HI_SHIFT) & SLI4_EQCQ_ID_HI_MASK) | \ + (((n) << SLI4_EQCQ_NUM_SHIFT) & SLI4_EQCQ_NUM_MASK) | (a))
Well, I find it a bit hard to digest. What do those two defines do? Maybe it would be more readable as inline function with a comment or so. Just saying :)
Quoted 29 lines
drivers/scsi/elx/libefc_sli/sli4.h new file +29
-0+/* EQ_DOORBELL - EQ Doorbell Register for IF_TYPE = 6*/ +#define SLI4_IF6_EQ_DB_REG 0x120 +enum sli4_eq_e { +SLI4_IF6_EQ_ID_MASK =0x0FFF , + +SLI4_IF6_EQ_NUM_SHIFT =16 , +SLI4_IF6_EQ_NUM_MASK =0x1FFF0000 , +}; + +#define SLI4_IF6_EQ_DOORBELL (n, id, a) \ + (((id) & SLI4_IF6_EQ_ID_MASK) | \ + (((n) << SLI4_IF6_EQ_NUM_SHIFT) & SLI4_IF6_EQ_NUM_MASK) | (a)) + +/* CQ_DOORBELL - CQ Doorbell Register for IF_TYPE = 6 */ +#define SLI4_IF6_CQ_DB_REG 0xC0 +enum sli4_cq_e { +SLI4_IF6_CQ_ID_MASK =0xFFFF , + +SLI4_IF6_CQ_NUM_SHIFT =16 , +SLI4_IF6_CQ_NUM_MASK =0x1FFF0000 , +}; + +#define SLI4_IF6_CQ_DOORBELL (n, id, a) \ + (((id) & SLI4_IF6_CQ_ID_MASK) | \ + (((n) << SLI4_IF6_CQ_NUM_SHIFT) & SLI4_IF6_CQ_NUM_MASK) | (a)) + +/* MQ_DOORBELL - MQ Doorbell Register */ +#define SLI4_MQ_DB_REG 0x0140 +#define SLI4_IF6_MQ_DB_REG 0x0160
drivers/scsi/elx/libefc_sli/sli4.h line 174
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h new file +10
-0+enum sli4_mq_e { +SLI4_MQ_ID_MASK =0xFFFF , + +SLI4_MQ_NUM_SHIFT =16 , +SLI4_MQ_NUM_MASK =0x3FFF0000 , +}; + +#define SLI4_MQ_DOORBELL (n, i) \ + (((i) & SLI4_MQ_ID_MASK) | \ + (((n) << SLI4_MQ_NUM_SHIFT) & SLI4_MQ_NUM_MASK))
s/i/id/
And just because I like patterns: why no 'a'?
drivers/scsi/elx/libefc_sli/sli4.h line 188
Quoted 13 lines
drivers/scsi/elx/libefc_sli/sli4.h new file +13
-0+/* RQ_DOORBELL - RQ Doorbell Register */ +#define SLI4_RQ_DB_REG 0x0a0 +#define SLI4_IF6_RQ_DB_REG 0x0080 +enum sli4_rq_e { +SLI4_RQ_DB_ID_MASK =0xFFFF , + +SLI4_RQ_DB_NUM_SHIFT =16 , +SLI4_RQ_DB_NUM_MASK =0x3FFF0000 , +}; + +#define SLI4_RQ_DOORBELL (n, i) \ + (((i) & SLI4_RQ_DB_ID_MASK) | \ + (((n) << SLI4_RQ_DB_NUM_SHIFT) & SLI4_RQ_DB_NUM_MASK))
s/i/id/
Quoted 8 lines
drivers/scsi/elx/libefc_sli/sli4.h new file +8
-0+ +/* WQ_DOORBELL - WQ Doorbell Register */ +#define SLI4_IO_WQ_DB_REG 0x040 +#define SLI4_IF6_WQ_DB_REG 0x040 +enum sli4_wq_e { +SLI4_WQ_ID_MASK =0xFFFF , + +SLI4_WQ_IDX_SHIFT =16 ,
drivers/scsi/elx/libefc_sli/sli4.h line 206
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h new file +10
-0+SLI4_WQ_IDX_MASK =0xFF0000 , + +SLI4_WQ_NUM_SHIFT =24 , + SLI4_WQ_NUM_MASK = 0x0FF00000, +}; + +#define SLI4_WQ_DOORBELL (n, x, i) \ + (((i) & SLI4_WQ_ID_MASK) | \ + (((x) << SLI4_WQ_IDX_SHIFT) & SLI4_WQ_IDX_MASK) | \ + (((n) << SLI4_WQ_NUM_SHIFT) & SLI4_WQ_NUM_MASK))
s/i/id/
And why is id not the second argument? What is x?
Quoted 49 lines
drivers/scsi/elx/libefc_sli/sli4.h new file +46
-0+ +/* SLIPORT_SEMAPHORE - SLI Port Host and Port Status Register */ +#define SLI4_PORT_SEMP_REG 0x0400 +enum sli4_port_sem_e { +SLI4_PORT_SEMP_ERR_MASK =0xF000 , +SLI4_PORT_SEMP_UNRECOV_ERR =0xF000 , +}; + +/* SLIPORT_STATUS - SLI Port Status Register */ +#define SLI4_PORT_STATUS_REGOFF 0x0404 +enum sli4_port_status { +SLI4_PORT_STATUS_FDP = (1 <<21 ), +SLI4_PORT_STATUS_RDY = (1 <<23 ), +SLI4_PORT_STATUS_RN = (1 <<24 ), +SLI4_PORT_STATUS_DIP = (1 <<25 ), +SLI4_PORT_STATUS_OTI = (1 <<29 ), +SLI4_PORT_STATUS_ERR = (1 <<31 ), +}; + +#define SLI4_PHYDEV_CTRL_REG 0x0414 +#define SLI4_PHYDEV_CTRL_FRST (1 << 1) +#define SLI4_PHYDEV_CTRL_DD (1 << 2) + +/* Register name enums */ +enum sli4_regname_en { +SLI4_REG_BMBX , +SLI4_REG_EQ_DOORBELL , +SLI4_REG_CQ_DOORBELL , +SLI4_REG_RQ_DOORBELL , +SLI4_REG_IO_WQ_DOORBELL , +SLI4_REG_MQ_DOORBELL , +SLI4_REG_PHYSDEV_CONTROL , +SLI4_REG_PORT_CONTROL , +SLI4_REG_PORT_ERROR1 , +SLI4_REG_PORT_ERROR2 , +SLI4_REG_PORT_SEMAPHORE , +SLI4_REG_PORT_STATUS , +SLI4_REG_UNKWOWN /* must be last */ +}; + +struct sli4_reg { +u32 rset; +u32 off; +}; + +#endif /* !_SLI4_H */ Signature · 1 line
2.16.4
Thanks,
Daniel
Re: [PATCH v3 01/31] elx: libefc_sli: SLI-4 register offsets and field definitions
Quoted 10 lines · Daniel Wagner
Hi James,
Quoted 6 lines · James Smart
This is the initial patch for the new Emulex target mode SCSI driver sources.
This patch:
- Creates the new Emulex source level directorydrivers/scsi/elxand adds the directory to theMAINTAINERSfile.
Quoted 7 lines
I would drop this. It's clear from the diff stat.
Quoted 2 lines
- Creates the first library subdirectory
drivers/scsi/elx/libefc_sli. This library is a SLI-4 interface library.Instead saying what this patch does, it would be better the explain why it structured this way.
Ok. I will see what I can come up with.
Quoted 1 line
...
Quoted 3 lines
BTW, why is it called
SLI4_BMBX_WRITE_HIand not justSLI4_BMBX_HI? Because below with the doorbell registers there is a different pattern.
Because the semantics of the BMBX register involve writing it (as a u32) once for the high address bits and a second time for the low address bits. The format is slightly different on each write.
I'll see how to comment this and clarify. inlines will help.
Agree with the rest of the comments and will clarify
-- james
Re: [PATCH v3 01/31] elx: libefc_sli: SLI-4 register offsets and field definitions
In reply to James SmartQuoted 11 lines · James Smart
This is the initial patch for the new Emulex target mode SCSI driver sources.
This patch:
- Creates the new Emulex source level directorydrivers/scsi/elxand adds the directory to theMAINTAINERSfile.
- Creates the first library subdirectorydrivers/scsi/elx/libefc_sli. This library is a SLI-4 interface library.
- Starts the population of thelibefc_slilibrary with definitions of SLI-4 hardware register offsets and definitions.
Quoted 3 lines
Signed-off-by Ram Vegesna <[email protected]>Signed-off-by James Smart <[email protected]>
Cheers,
Hannes
Signature · 4 lines
Dr. Hannes Reinecke Teamlead Storage & Networking [email protected] +49 911 74053 688 SUSE Software Solutions GmbH, Maxfeldstr. 5, 90409 Nürnberg HRB 36809 (AG Nürnberg), Geschäftsführer: Felix Imendörffer
Re: [PATCH v3 01/31] elx: libefc_sli: SLI-4 register offsets and field definitions
In reply to James SmartQuoted 33 lines · James Smart
This is the initial patch for the new Emulex target mode SCSI driver sources.
This patch:
- Creates the new Emulex source level directorydrivers/scsi/elxand adds the directory to theMAINTAINERSfile.
- Creates the first library subdirectorydrivers/scsi/elx/libefc_sli. This library is a SLI-4 interface library.
- Starts the population of thelibefc_slilibrary with definitions of SLI-4 hardware register offsets and definitions.Signed-off-by Ram Vegesna <[email protected]>Signed-off-by James Smart <[email protected]>---
v3:
Changed anonymous enums to named.
SLI defines to spell out_MASKvalue directly. Changed multiple #defines to named enums for consistency.SLI4_REG_MAXtoSLI4_REG_UNKNOWN--- MAINTAINERS | 8 ++ drivers/scsi/elx/libefc_sli/sli4.c | 26 ++++ drivers/scsi/elx/libefc_sli/sli4.h | 252 +++++++++++++++++++++++++++++++++++++ 3 files changed, 286 insertions(+) create mode 100644 drivers/scsi/elx/libefc_sli/sli4.c create mode 100644 drivers/scsi/elx/libefc_sli/sli4.hMAINTAINERS +0
-0
MAINTAINERS W: http://www.broadcom.com · line 6229
Quoted 7 lines
MAINTAINERS +4
-0@@ -6223,6 +6223,14 @@ W: http://www.broadcom.com S: Supported F: drivers/scsi/lpfc/ +EMULEX/BROADCOM EFCT FC/FCOE SCSI TARGET DRIVER +M: James Smart <[email protected]> +M: Ram Vegesna <[email protected]> +L: [email protected]
Hi James,
Perhaps [email protected] can be added too
Thanks,
Roman
Quoted 300 lines
MAINTAINERS +4
-0+W: http://www.broadcom.com +S: Supported +F: drivers/scsi/elx/ + ENE CB710 FLASH CARD READER DRIVER M: Michał Mirosław <[email protected]> S: Maintaineddrivers/scsi/elx/libefc_sli/sli4.c new file +26
-0@@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0 +/* +* Copyright (C) 2019 Broadcom. All Rights Reserved. The term +* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. +*/ + +/** +* All common (i.e. transport-independent) SLI-4 functions are implemented +* in this file. +*/ +#include "sli4.h" + +struct sli4_asic_entry_t { +u32 rev_id; +u32 family; +}; + +static struct sli4_asic_entry_t sli4_asic_table[] = { + {SLI4_ASIC_REV_B0 ,SLI4_ASIC_GEN_5 }, + {SLI4_ASIC_REV_D0 ,SLI4_ASIC_GEN_5 }, + {SLI4_ASIC_REV_A3 ,SLI4_ASIC_GEN_6 }, + {SLI4_ASIC_REV_A0 ,SLI4_ASIC_GEN_6 }, + {SLI4_ASIC_REV_A1 ,SLI4_ASIC_GEN_6 }, + {SLI4_ASIC_REV_A3 ,SLI4_ASIC_GEN_6 }, + {SLI4_ASIC_REV_A1 ,SLI4_ASIC_GEN_7 }, +};drivers/scsi/elx/libefc_sli/sli4.h new file +252
-0@@ -0,0 +1,252 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* +* Copyright (C) 2019 Broadcom. All Rights Reserved. The term +* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. +* +*/ + +/* +* All common SLI-4 structures and function prototypes. +*/ + +#ifndef _SLI4_H +#define _SLI4_H + +#include <linux/pci.h> +#include <linux/delay.h> +#include "scsi/fc/fc_els.h" +#include "scsi/fc/fc_fs.h" +#include "../include/efc_common.h" + +/************************************************************************* +* Common SLI-4 register offsets and field definitions +*/ + +/* SLI_INTF - SLI Interface Definition Register */ +#define SLI4_INTF_REG 0x0058 +enum sli4_intf { +SLI4_INTF_REV_SHIFT =4 , +SLI4_INTF_REV_MASK =0xF0 , + +SLI4_INTF_REV_S3 =0x30 , +SLI4_INTF_REV_S4 =0x40 , + +SLI4_INTF_FAMILY_SHIFT =8 , +SLI4_INTF_FAMILY_MASK =0x0F00 , + +SLI4_FAMILY_CHECK_ASIC_TYPE =0x0F00 , + +SLI4_INTF_IF_TYPE_SHIFT =12 , +SLI4_INTF_IF_TYPE_MASK =0xF000 , + +SLI4_INTF_IF_TYPE_2 =0x2000 , +SLI4_INTF_IF_TYPE_6 =0x6000 , + +SLI4_INTF_VALID_SHIFT =29 , +SLI4_INTF_VALID_MASK =0xE0000000 , + +SLI4_INTF_VALID_VALUE =0xC0000000 , +}; + +/* ASIC_ID - SLI ASIC Type and Revision Register */ +#define SLI4_ASIC_ID_REG 0x009c +enum sli4_asic { +SLI4_ASIC_GEN_SHIFT =8 , +SLI4_ASIC_GEN_MASK =0xFF00 , +SLI4_ASIC_GEN_5 =0x0B00 , +SLI4_ASIC_GEN_6 =0x0C00 , +SLI4_ASIC_GEN_7 =0x0D00 , +}; + +enum sli4_acic_revisions { +SLI4_ASIC_REV_A0 =0x00 , +SLI4_ASIC_REV_A1 =0x01 , +SLI4_ASIC_REV_A2 =0x02 , +SLI4_ASIC_REV_A3 =0x03 , +SLI4_ASIC_REV_B0 =0x10 , +SLI4_ASIC_REV_B1 =0x11 , +SLI4_ASIC_REV_B2 =0x12 , +SLI4_ASIC_REV_C0 =0x20 , +SLI4_ASIC_REV_C1 =0x21 , +SLI4_ASIC_REV_C2 =0x22 , +SLI4_ASIC_REV_D0 =0x30 , +}; + +/* BMBX - Bootstrap Mailbox Register */ +#define SLI4_BMBX_REG 0x0160 +enum sli4_bmbx { +SLI4_BMBX_MASK_HI =0x3 , +SLI4_BMBX_MASK_LO =0xf , +SLI4_BMBX_RDY = (1 <<0 ), +SLI4_BMBX_HI = (1 <<1 ), +SLI4_BMBX_SIZE =256 , +}; + +#define SLI4_BMBX_WRITE_HI (r) \ + ((upper_32_bits(r) & ~SLI4_BMBX_MASK_HI) | SLI4_BMBX_HI) +#define SLI4_BMBX_WRITE_LO (r) \ + (((upper_32_bits(r) & SLI4_BMBX_MASK_HI) << 30) | \ + (((r) & ~SLI4_BMBX_MASK_LO) >> 2)) + +/* SLIPORT_CONTROL - SLI Port Control Register */ +#define SLI4_PORT_CTRL_REG 0x0408 +enum sli4_port_ctrl { +SLI4_PORT_CTRL_IP = (1 <<27 ), +SLI4_PORT_CTRL_IDIS = (1 <<22 ), +SLI4_PORT_CTRL_FDD = (1 <<31 ), +}; + +/* SLI4_SLIPORT_ERROR - SLI Port Error Register */ +#define SLI4_PORT_ERROR1 0x040c +#define SLI4_PORT_ERROR2 0x0410 + +/* EQCQ_DOORBELL - EQ and CQ Doorbell Register */ +#define SLI4_EQCQ_DB_REG 0x120 +enum sli4_eqcq_e { +SLI4_EQ_ID_LO_MASK =0x01FF , + +SLI4_CQ_ID_LO_MASK =0x03FF , + +SLI4_EQCQ_CI_EQ =0x0200 , + +SLI4_EQCQ_QT_EQ =0x00000400 , +SLI4_EQCQ_QT_CQ =0x00000000 , + +SLI4_EQCQ_ID_HI_SHIFT =11 , +SLI4_EQCQ_ID_HI_MASK =0xF800 , + +SLI4_EQCQ_NUM_SHIFT =16 , +SLI4_EQCQ_NUM_MASK =0x1FFF0000 , + +SLI4_EQCQ_ARM =0x20000000 , +SLI4_EQCQ_UNARM =0x00000000 , +}; + +#define SLI4_EQ_DOORBELL (n, id, a) \ + (((id) & SLI4_EQ_ID_LO_MASK) | SLI4_EQCQ_QT_EQ | \ + ((((id) >> 9) << SLI4_EQCQ_ID_HI_SHIFT) & SLI4_EQCQ_ID_HI_MASK) | \ + (((n) << SLI4_EQCQ_NUM_SHIFT) & SLI4_EQCQ_NUM_MASK) | \ + (a) | SLI4_EQCQ_CI_EQ) + +#define SLI4_CQ_DOORBELL (n, id, a) \ + (((id) & SLI4_CQ_ID_LO_MASK) | SLI4_EQCQ_QT_CQ | \ + ((((id) >> 10) << SLI4_EQCQ_ID_HI_SHIFT) & SLI4_EQCQ_ID_HI_MASK) | \ + (((n) << SLI4_EQCQ_NUM_SHIFT) & SLI4_EQCQ_NUM_MASK) | (a)) + +/* EQ_DOORBELL - EQ Doorbell Register for IF_TYPE = 6*/ +#define SLI4_IF6_EQ_DB_REG 0x120 +enum sli4_eq_e { +SLI4_IF6_EQ_ID_MASK =0x0FFF , + +SLI4_IF6_EQ_NUM_SHIFT =16 , +SLI4_IF6_EQ_NUM_MASK =0x1FFF0000 , +}; + +#define SLI4_IF6_EQ_DOORBELL (n, id, a) \ + (((id) & SLI4_IF6_EQ_ID_MASK) | \ + (((n) << SLI4_IF6_EQ_NUM_SHIFT) & SLI4_IF6_EQ_NUM_MASK) | (a)) + +/* CQ_DOORBELL - CQ Doorbell Register for IF_TYPE = 6 */ +#define SLI4_IF6_CQ_DB_REG 0xC0 +enum sli4_cq_e { +SLI4_IF6_CQ_ID_MASK =0xFFFF , + +SLI4_IF6_CQ_NUM_SHIFT =16 , +SLI4_IF6_CQ_NUM_MASK =0x1FFF0000 , +}; + +#define SLI4_IF6_CQ_DOORBELL (n, id, a) \ + (((id) & SLI4_IF6_CQ_ID_MASK) | \ + (((n) << SLI4_IF6_CQ_NUM_SHIFT) & SLI4_IF6_CQ_NUM_MASK) | (a)) + +/* MQ_DOORBELL - MQ Doorbell Register */ +#define SLI4_MQ_DB_REG 0x0140 +#define SLI4_IF6_MQ_DB_REG 0x0160 +enum sli4_mq_e { +SLI4_MQ_ID_MASK =0xFFFF , + +SLI4_MQ_NUM_SHIFT =16 , +SLI4_MQ_NUM_MASK =0x3FFF0000 , +}; + +#define SLI4_MQ_DOORBELL (n, i) \ + (((i) & SLI4_MQ_ID_MASK) | \ + (((n) << SLI4_MQ_NUM_SHIFT) & SLI4_MQ_NUM_MASK)) + +/* RQ_DOORBELL - RQ Doorbell Register */ +#define SLI4_RQ_DB_REG 0x0a0 +#define SLI4_IF6_RQ_DB_REG 0x0080 +enum sli4_rq_e { +SLI4_RQ_DB_ID_MASK =0xFFFF , + +SLI4_RQ_DB_NUM_SHIFT =16 , +SLI4_RQ_DB_NUM_MASK =0x3FFF0000 , +}; + +#define SLI4_RQ_DOORBELL (n, i) \ + (((i) & SLI4_RQ_DB_ID_MASK) | \ + (((n) << SLI4_RQ_DB_NUM_SHIFT) & SLI4_RQ_DB_NUM_MASK)) + +/* WQ_DOORBELL - WQ Doorbell Register */ +#define SLI4_IO_WQ_DB_REG 0x040 +#define SLI4_IF6_WQ_DB_REG 0x040 +enum sli4_wq_e { +SLI4_WQ_ID_MASK =0xFFFF , + +SLI4_WQ_IDX_SHIFT =16 , +SLI4_WQ_IDX_MASK =0xFF0000 , + +SLI4_WQ_NUM_SHIFT =24 , +SLI4_WQ_NUM_MASK =0x0FF00000 , +}; + +#define SLI4_WQ_DOORBELL (n, x, i) \ + (((i) & SLI4_WQ_ID_MASK) | \ + (((x) << SLI4_WQ_IDX_SHIFT) & SLI4_WQ_IDX_MASK) | \ + (((n) << SLI4_WQ_NUM_SHIFT) & SLI4_WQ_NUM_MASK)) + +/* SLIPORT_SEMAPHORE - SLI Port Host and Port Status Register */ +#define SLI4_PORT_SEMP_REG 0x0400 +enum sli4_port_sem_e { +SLI4_PORT_SEMP_ERR_MASK =0xF000 , +SLI4_PORT_SEMP_UNRECOV_ERR =0xF000 , +}; + +/* SLIPORT_STATUS - SLI Port Status Register */ +#define SLI4_PORT_STATUS_REGOFF 0x0404 +enum sli4_port_status { +SLI4_PORT_STATUS_FDP = (1 <<21 ), +SLI4_PORT_STATUS_RDY = (1 <<23 ), +SLI4_PORT_STATUS_RN = (1 <<24 ), +SLI4_PORT_STATUS_DIP = (1 <<25 ), +SLI4_PORT_STATUS_OTI = (1 <<29 ), +SLI4_PORT_STATUS_ERR = (1 <<31 ), +}; + +#define SLI4_PHYDEV_CTRL_REG 0x0414 +#define SLI4_PHYDEV_CTRL_FRST (1 << 1) +#define SLI4_PHYDEV_CTRL_DD (1 << 2) + +/* Register name enums */ +enum sli4_regname_en { +SLI4_REG_BMBX , +SLI4_REG_EQ_DOORBELL , +SLI4_REG_CQ_DOORBELL , +SLI4_REG_RQ_DOORBELL , +SLI4_REG_IO_WQ_DOORBELL , +SLI4_REG_MQ_DOORBELL , +SLI4_REG_PHYSDEV_CONTROL , +SLI4_REG_PORT_CONTROL , +SLI4_REG_PORT_ERROR1 , +SLI4_REG_PORT_ERROR2 , +SLI4_REG_PORT_SEMAPHORE , +SLI4_REG_PORT_STATUS , +SLI4_REG_UNKWOWN /* must be last */ +}; + +struct sli4_reg { +u32 rset; +u32 off; +}; + +#endif /* !_SLI4_H */ Signature · 1 line
2.16.4
PATCH v3 2/31 elx: libefc_sli: SLI Descriptors and Queue entries
In reply to James SmartThis patch continues the libefc_sli SLI-4 library population.
This patch add SLI-4 Data structures and defines for:
- Buffer Descriptors (BDEs)
- Scatter/Gather List elements (SGEs)
- Queues and their Entry Descriptions for:
Event Queues (EQs), Completion Queues (CQs), Receive Queues (RQs), and the Mailbox Queue (MQ).
---
v3:
Changed anonymous enums to named.
SLI defines to spell out _MASK value directly. Change multiple defines to named Enums for consistency. Single Enum to #define.
--- drivers/scsi/elx/include/efc_common.h | 25 + drivers/scsi/elx/libefc_sli/sli4.h | 1761 +++++++++++++++++++++++++++++++++ 2 files changed, 1786 insertions(+) create mode 100644 drivers/scsi/elx/include/efc_common.h
drivers/scsi/elx/include/efc_common.h new file +25 -0
@@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* +* Copyright (C) 2019 Broadcom. All Rights Reserved. The term +* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. +*/ + +#ifndef __EFC_COMMON_H__ +#define __EFC_COMMON_H__ + +#include <linux/pci.h> + +#define EFC_SUCCESS 0 +#define EFC_FAIL 1 + +struct efc_dma { +void *virt; +void *alloc; +dma_addr_t phys; + +size_t size; +size_t len; +struct pci_dev *pdev; +}; + +#endif /* __EFC_COMMON_H__ */
drivers/scsi/elx/libefc_sli/sli4.h +1761 -0
1,765 lines not on this page · raw message
Signature · 1 line
2.16.4
Re: [PATCH v3 02/31] elx: libefc_sli: SLI Descriptors and Queue entries
Hi,
Quoted 8 lines · James Smart
This patch continues the
libefc_sliSLI-4 library population.This patch add SLI-4 Data structures and defines for:
- Buffer Descriptors (BDEs)
- Scatter/Gather List elements (SGEs)
- Queues and their Entry Descriptions for:
Event Queues (EQs), Completion Queues (CQs), Receive Queues (RQs), and the Mailbox Queue (MQ).
There are a definitions which are not used at all, e.g. DISEED_SGE_OP_RX_VALUE, sli4_acqe_e, sli4_acqe_event_code, etc. What are the plans with those?
Quoted 51 lines
Signed-off-by Ram Vegesna <[email protected]>Signed-off-by James Smart <[email protected]>---
v3:
Changed anonymous enums to named.
SLI defines to spell out_MASKvalue directly. Change multiple defines to named Enums for consistency. Single Enum to #define.--- drivers/scsi/elx/include/efc_common.h | 25 + drivers/scsi/elx/libefc_sli/sli4.h | 1761 +++++++++++++++++++++++++++++++++ 2 files changed, 1786 insertions(+) create mode 100644 drivers/scsi/elx/include/efc_common.hdrivers/scsi/elx/include/efc_common.h new file +25
-0@@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* +* Copyright (C) 2019 Broadcom. All Rights Reserved. The term +* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. +*/ + +#ifndef __EFC_COMMON_H__ +#define __EFC_COMMON_H__ + +#include <linux/pci.h> + +#define EFC_SUCCESS 0 +#define EFC_FAIL 1 + +struct efc_dma { +void *virt; +void *alloc; +dma_addr_t phys; + +size_t size; +size_t len; +struct pci_dev *pdev; +}; + +#endif /* __EFC_COMMON_H__ */ drivers/scsi/elx/libefc_sli/sli4.h +0
-0
drivers/scsi/elx/libefc_sli/sli4.h struct sli4_reg { · line 257
Quoted 9 lines
drivers/scsi/elx/libefc_sli/sli4.h +6
-0@@ -249,4 +249,1765 @@ struct sli4_reg {u32 off; }; +struct sli4_dmaaddr { +__le32 low; +__le32 high; +}; + +/* a 3-word BDE with address 1st 2 words, length last word */
Maybe expand BDE here as it is the first time the acrynom is used. Please 'with address 1st 2 words,....' since this is redunant.
drivers/scsi/elx/libefc_sli/sli4.h struct sli4_reg { · line 267
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h +10
-0+struct sli4_bufptr { +struct sli4_dmaaddr addr; +__le32 length; +}; + +/* a 3-word BDE with length as first word, address last 2 words */ +struct sli4_bufptr_len1st { +__le32 length0; +struct sli4_dmaaddr addr; +};
This struct is unused. Remove it please.
Quoted 23 lines
drivers/scsi/elx/libefc_sli/sli4.h +23
-0+ +/* Buffer Descriptor Entry (BDE) */ +enum sli4_bde_e { +SLI4_BDE_MASK_BUFFER_LEN =0x00ffffff , +SLI4_BDE_MASK_BDE_TYPE =0xff000000 , +}; + +struct sli4_bde { +__le32 bde_type_buflen; +union { +struct sli4_dmaaddr data; +struct { +__le32 offset; +__le32 rsvd2; + } imm; +struct sli4_dmaaddr blp; + } u; +}; + +/* Buffer Descriptors */ +enum sli4_bde_type { +BDE_TYPE_SHIFT =24 , +BDE_TYPE_BDE_64 =0x00 ,/* Generic 64-bit data */
drivers/scsi/elx/libefc_sli/sli4.h struct sli4_reg { · line 300
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h +10
-0+BDE_TYPE_BDE_IMM =0x01 ,/* Immediate data */ + BDE_TYPE_BLP = 0x40, /* Buffer List Pointer */ +}; + +/* Scatter-Gather Entry (SGE) */ +#define SLI4_SGE_MAX_RESERVED 3 + +enum sli4_sge_type { +/* DW2 */ + SLI4_SGE_DATA_OFFSET_MASK = 0x07FFFFFF,
Nitpick: some of the hex values are in small letters some as here use large letters.
Quoted 66 lines
drivers/scsi/elx/libefc_sli/sli4.h +66
-0+/*DW2W1*/ +SLI4_SGE_TYPE_SHIFT =27 , +SLI4_SGE_TYPE_MASK =0x78000000 , +/*SGE Types*/ +SLI4_SGE_TYPE_DATA =0x00 , +SLI4_SGE_TYPE_DIF =0x04 ,/* Data Integrity Field */ +SLI4_SGE_TYPE_LSP =0x05 ,/* List Segment Pointer */ +SLI4_SGE_TYPE_PEDIF =0x06 ,/* Post Encryption Engine DIF */ +SLI4_SGE_TYPE_PESEED =0x07 ,/* Post Encryption DIF Seed */ +SLI4_SGE_TYPE_DISEED =0x08 ,/* DIF Seed */ +SLI4_SGE_TYPE_ENC =0x09 ,/* Encryption */ +SLI4_SGE_TYPE_ATM =0x0a ,/* DIF Application Tag Mask */ +SLI4_SGE_TYPE_SKIP =0x0c ,/* SKIP */ + + SLI4_SGE_LAST = (1 << 31), +}; + +struct sli4_sge { +__le32 buffer_address_high; +__le32 buffer_address_low; +__le32 dw2_flags; +__le32 buffer_length; +}; + +/* T10 DIF Scatter-Gather Entry (SGE) */ +struct sli4_dif_sge { +__le32 buffer_address_high; +__le32 buffer_address_low; +__le32 dw2_flags; +__le32 rsvd12; +}; + +/* Data Integrity Seed (DISEED) SGE */ +enum sli4_diseed_sge_flags { +/* DW2W1 */ +DISEED_SGE_HS = (1 <<2 ), +DISEED_SGE_WS = (1 <<3 ), +DISEED_SGE_IC = (1 <<4 ), +DISEED_SGE_ICS = (1 <<5 ), +DISEED_SGE_ATRT = (1 <<6 ), +DISEED_SGE_AT = (1 <<7 ), +DISEED_SGE_FAT = (1 <<8 ), +DISEED_SGE_NA = (1 <<9 ), +DISEED_SGE_HI = (1 <<10 ), + +/* DW3W1 */ +DISEED_SGE_BS_MASK =0x0007 , +DISEED_SGE_AI = (1 <<3 ), +DISEED_SGE_ME = (1 <<4 ), +DISEED_SGE_RE = (1 <<5 ), +DISEED_SGE_CE = (1 <<6 ), +DISEED_SGE_NR = (1 <<7 ), + +DISEED_SGE_OP_RX_SHIFT =8 , +DISEED_SGE_OP_RX_MASK =0x0F00 , +DISEED_SGE_OP_TX_SHIFT =12 , +DISEED_SGE_OP_TX_MASK =0xF000 , +}; + +/* Opcode values */ +enum sli4_diseed_sge_opcodes { +DISEED_SGE_OP_IN_NODIF_OUT_CRC , +DISEED_SGE_OP_IN_CRC_OUT_NODIF , +DISEED_SGE_OP_IN_NODIF_OUT_CSUM , +DISEED_SGE_OP_IN_CSUM_OUT_NODIF , + DISEED_SGE_OP_IN_CRC_OUT_CRC,
drivers/scsi/elx/libefc_sli/sli4.h struct sli4_reg { · line 376
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h +10
-0+DISEED_SGE_OP_IN_CSUM_OUT_CSUM , +DISEED_SGE_OP_IN_CRC_OUT_CSUM , +DISEED_SGE_OP_IN_CSUM_OUT_CRC , + DISEED_SGE_OP_IN_RAW_OUT_RAW, +}; + +#define DISEED_SGE_OP_RX_VALUE (stype) \ + (DISEED_SGE_OP_##stype << DISEED_SGE_OP_RX_SHIFT) +#define DISEED_SGE_OP_TX_VALUE (stype) \ + (DISEED_SGE_OP_##stype << DISEED_SGE_OP_TX_SHIFT)
empty line
Quoted 104 lines
drivers/scsi/elx/libefc_sli/sli4.h +104
-0+struct sli4_diseed_sge { +__le32 ref_tag_cmp; +__le32 ref_tag_repl; +__le16 app_tag_repl; +__le16 dw2w1_flags; +__le16 app_tag_cmp; +__le16 dw3w1_flags; +}; + +/* List Segment Pointer Scatter-Gather Entry (SGE) */ +#define SLI4_LSP_SGE_SEGLEN 0x00ffffff + +struct sli4_lsp_sge { +__le32 buffer_address_high; +__le32 buffer_address_low; +__le32 dw2_flags; +__le32 dw3_seglen; +}; + +enum sli4_eqe_e { +SLI4_EQE_VALID =1 , +SLI4_EQE_MJCODE =0xe , +SLI4_EQE_MNCODE =0xfff0 , +}; + +struct sli4_eqe { +__le16 dw0w0_flags; +__le16 resource_id; +}; + +#define SLI4_MAJOR_CODE_STANDARD 0 +#define SLI4_MAJOR_CODE_SENTINEL 1 + +/* Sentinel EQE indicating the EQ is full */ +#define SLI4_EQE_STATUS_EQ_FULL 2 + +enum sli4_mcqe_e { +SLI4_MCQE_CONSUMED = (1 <<27 ), +SLI4_MCQE_COMPLETED = (1 <<28 ), +SLI4_MCQE_AE = (1 <<30 ), +SLI4_MCQE_VALID = (1 <<31 ), +}; + +/* Entry was consumed but not completed */ +#define SLI4_MCQE_STATUS_NOT_COMPLETED -2 + +struct sli4_mcqe { +__le16 completion_status; +__le16 extended_status; +__le32 mqe_tag_low; +__le32 mqe_tag_high; +__le32 dw3_flags; +}; + +enum sli4_acqe_e { +SLI4_ACQE_AE = (1 <<6 ),/* async event - this is an ACQE */ +SLI4_ACQE_VAL = (1 <<7 ),/* valid - contents of CQE are valid */ +}; + +struct sli4_acqe { +__le32 event_data[3 ]; +u8 rsvd12; +u8 event_code; +u8 event_type; +u8 ae_val; +}; + +enum sli4_acqe_event_code { +SLI4_ACQE_EVENT_CODE_LINK_STATE =0x01 , +SLI4_ACQE_EVENT_CODE_FIP =0x02 , +SLI4_ACQE_EVENT_CODE_DCBX =0x03 , +SLI4_ACQE_EVENT_CODE_ISCSI =0x04 , +SLI4_ACQE_EVENT_CODE_GRP_5 =0x05 , +SLI4_ACQE_EVENT_CODE_FC_LINK_EVENT =0x10 , +SLI4_ACQE_EVENT_CODE_SLI_PORT_EVENT =0x11 , +SLI4_ACQE_EVENT_CODE_VF_EVENT =0x12 , +SLI4_ACQE_EVENT_CODE_MR_EVENT =0x13 , +}; + +enum sli4_qtype { +SLI_QTYPE_EQ , +SLI_QTYPE_CQ , +SLI_QTYPE_MQ , +SLI_QTYPE_WQ , +SLI_QTYPE_RQ , +SLI_QTYPE_MAX ,/* must be last */ +}; + +#define SLI_USER_MQ_COUNT 1 +#define SLI_MAX_CQ_SET_COUNT 16 +#define SLI_MAX_RQ_SET_COUNT 16 + +enum sli4_qentry { +SLI_QENTRY_ASYNC , +SLI_QENTRY_MQ , +SLI_QENTRY_RQ , +SLI_QENTRY_WQ , +SLI_QENTRY_WQ_RELEASE , +SLI_QENTRY_OPT_WRITE_CMD , +SLI_QENTRY_OPT_WRITE_DATA , +SLI_QENTRY_XABT , +SLI_QENTRY_MAX /* must be last */ +}; +
drivers/scsi/elx/libefc_sli/sli4.h struct sli4_reg { · line 491
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h +10
-0+enum sli4_queue_flags { +/* CQ has MQ/Async completion */ +SLI4_QUEUE_FLAG_MQ = (1 <<0 ), + +/* RQ for packet headers */ +SLI4_QUEUE_FLAG_HDR = (1 <<1 ), + +/* RQ index increment by 8 */ +SLI4_QUEUE_FLAG_RQBATCH = (1 <<2 ), +};
There are several styles of documention and comments in this header. I suggest to streamline them all and use kernel doc style?
drivers/scsi/elx/libefc_sli/sli4.h struct sli4_reg { · line 496
Quoted 4 lines
drivers/scsi/elx/libefc_sli/sli4.h +4
-0+struct sli4_queue { +/* Common to all queue types */ +struct efc_dma dma; +spinlock_t lock;/* protect the queue operations */
I really would love the have some documentation on the locking concept of the driver. From my very limited experience so far with the FC drivers, this is one of the areas which are hard to review if there is no documentation on the design and rules. For example 'protect the queue operations' is pretty much an useless comment.
drivers/scsi/elx/libefc_sli/sli4.h struct sli4_reg { · line 509
Quoted 13 lines
drivers/scsi/elx/libefc_sli/sli4.h +13
-0+u32 index;/* current host entry index */ +u16 size;/* entry size */ +u16 length;/* number of entries */ +u16 n_posted;/* number entries posted */ +u16 id;/* Port assigned xQ_ID */ +u16 ulp;/* ULP assigned to this queue */ +void __iomem *db_regaddr;/* register address for the doorbell */ +u8 type;/* queue type ie EQ, CQ, ... */ +u32 proc_limit;/* limit CQE processed per iteration */ +u32 posted_limit;/* CQE/EQE process before ring doorbel */ +u32 max_num_processed; +time_t max_process_time; +u16 phase;/* For if_type = 6, this value toggle
^^^^^^^
Is this the type member? What does the value 6 mean?
drivers/scsi/elx/libefc_sli/sli4.h struct sli4_reg { · line 519
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h +10
-0+* for each iteration of the queue, +* a queue entry is valid when a cqe +* valid bit matches this value +*/ + +union { +u32 r_idx;/* "read" index (MQ only) */ +struct { +u32 dword; + } flag;
Is this struct really neccessary?
Quoted 215 lines
drivers/scsi/elx/libefc_sli/sli4.h +215
-0+ } u; +}; + +/* Generic Command Request header */ +enum sli4_cmd_version { +CMD_V0 , +CMD_V1 , +CMD_V2 , +}; + +struct sli4_rqst_hdr { +u8 opcode; +u8 subsystem; +__le16 rsvd2; +__le32 timeout; +__le32 request_length; +__le32 dw3_version; +}; + +/* Generic Command Response header */ +struct sli4_rsp_hdr { +u8 opcode; +u8 subsystem; +__le16 rsvd2; +u8 status; +u8 additional_status; +__le16 rsvd6; +__le32 response_length; +__le32 actual_response_length; +}; + +#define SLI4_QUEUE_RQ_BATCH 8 + +#define CFG_RQST_CMDSZ (stype) sizeof(struct sli4_rqst_##stype) + +#define CFG_RQST_PYLD_LEN (stype) \ + cpu_to_le32(sizeof(struct sli4_rqst_##stype) - \ + sizeof(struct sli4_rqst_hdr)) + +#define CFG_RQST_PYLD_LEN_VAR (stype, varpyld) \ + cpu_to_le32((sizeof(struct sli4_rqst_##stype) + \ + varpyld) - sizeof(struct sli4_rqst_hdr)) + +#define SZ_DMAADDR sizeof(struct sli4_dmaaddr) + +#define SLI_CONFIG_PYLD_LENGTH (stype) \ + max(sizeof(struct sli4_rqst_##stype), \ + sizeof(struct sli4_rsp_##stype)) + +enum sli4_create_cqv2_e { +/* DW5_flags values*/ +CREATE_CQV2_CLSWM_MASK =0x00003000 , +CREATE_CQV2_NODELAY =0x00004000 , +CREATE_CQV2_AUTOVALID =0x00008000 , +CREATE_CQV2_CQECNT_MASK =0x18000000 , +CREATE_CQV2_VALID =0x20000000 , +CREATE_CQV2_EVT =0x80000000 , +/* DW6W1_flags values*/ +CREATE_CQV2_ARM =0x8000 , +}; + +struct sli4_rqst_cmn_create_cq_v2 { +struct sli4_rqst_hdr hdr; +__le16 num_pages; +u8 page_size; +u8 rsvd19; +__le32 dw5_flags; +__le16 eq_id; +__le16 dw6w1_arm; +__le16 cqe_count; +__le16 rsvd30; +__le32 rsvd32; +struct sli4_dmaaddr page_phys_addr[0 ]; +}; + +enum sli4_create_cqset_e { +/* DW5_flags values*/ +CREATE_CQSETV0_CLSWM_MASK =0x00003000 , +CREATE_CQSETV0_NODELAY =0x00004000 , +CREATE_CQSETV0_AUTOVALID =0x00008000 , +CREATE_CQSETV0_CQECNT_MASK =0x18000000 , +CREATE_CQSETV0_VALID =0x20000000 , +CREATE_CQSETV0_EVT =0x80000000 , +/* DW5W1_flags values */ +CREATE_CQSETV0_CQE_COUNT =0x7fff , +CREATE_CQSETV0_ARM =0x8000 , +}; + +struct sli4_rqst_cmn_create_cq_set_v0 { +struct sli4_rqst_hdr hdr; +__le16 num_pages; +u8 page_size; +u8 rsvd19; +__le32 dw5_flags; +__le16 num_cq_req; +__le16 dw6w1_flags; +__le16 eq_id[16 ]; +struct sli4_dmaaddr page_phys_addr[0 ]; +}; + +/* CQE count */ +enum sli4_cq_cnt { +CQ_CNT_256 , +CQ_CNT_512 , +CQ_CNT_1024 , +CQ_CNT_LARGE , +}; + +#define CQ_CNT_SHIFT 27 +#define CQ_CNT_VAL (type) (CQ_CNT_##type << CQ_CNT_SHIFT) + +#define SLI4_CQE_BYTES (4 * sizeof(u32)) + +#define SLI4_CMN_CREATE_CQ_V2_MAX_PAGES 8 + +/* Generic Common Create EQ/CQ/MQ/WQ/RQ Queue completion */ +struct sli4_rsp_cmn_create_queue { +struct sli4_rsp_hdr hdr; +__le16 q_id; +u8 rsvd18; +u8 ulp; +__le32 db_offset; +__le16 db_rs; +__le16 db_fmt; +}; + +struct sli4_rsp_cmn_create_queue_set { +struct sli4_rsp_hdr hdr; +__le16 q_id; +__le16 num_q_allocated; +}; + +/* Common Destroy Queue */ +struct sli4_rqst_cmn_destroy_q { +struct sli4_rqst_hdr hdr; +__le16 q_id; +__le16 rsvd; +}; + +struct sli4_rsp_cmn_destroy_q { +struct sli4_rsp_hdr hdr; +}; + +/* Modify the delay multiplier for EQs */ +struct sli4_rqst_cmn_modify_eq_delay { +struct sli4_rqst_hdr hdr; +__le32 num_eq; +struct { +__le32 eq_id; +__le32 phase; +__le32 delay_multiplier; + } eq_delay_record[8 ]; +}; + +struct sli4_rsp_cmn_modify_eq_delay { +struct sli4_rsp_hdr hdr; +}; + +enum sli4_create_cq_e { +/* DW5 */ +CREATE_EQ_AUTOVALID = (1 <<28 ), +CREATE_EQ_VALID = (1 <<29 ), +CREATE_EQ_EQESZ = (1 <<31 ), +/* DW6 */ +CREATE_EQ_COUNT = (7 <<26 ), +CREATE_EQ_ARM = (1 <<31 ), +/* DW7 */ +CREATE_EQ_DELAYMULTI_SHIFT =13 , +CREATE_EQ_DELAYMULTI_MASK =0x007FE000 , +CREATE_EQ_DELAYMULTI =0x00040000 , +}; + +struct sli4_rqst_cmn_create_eq { +struct sli4_rqst_hdr hdr; +__le16 num_pages; +__le16 rsvd18; +__le32 dw5_flags; +__le32 dw6_flags; +__le32 dw7_delaymulti; +__le32 rsvd32; +struct sli4_dmaaddr page_address[8 ]; +}; + +struct sli4_rsp_cmn_create_eq { +struct sli4_rsp_cmn_create_queue q_rsp; +}; + +/* EQ count */ +enum sli4_eq_cnt { +EQ_CNT_256 , +EQ_CNT_512 , +EQ_CNT_1024 , +EQ_CNT_2048 , +EQ_CNT_4096 =3 , +}; + +#define EQ_CNT_SHIFT 26 +#define EQ_CNT_VAL (type) (EQ_CNT_##type << EQ_CNT_SHIFT) + +#define SLI4_EQE_SIZE_4 0 +#define SLI4_EQE_SIZE_16 1 + +/* Create a Mailbox Queue; accommodate v0 and v1 forms. */ +enum sli4_create_mq_flags { +/* DW6W1 */ +CREATE_MQEXT_RINGSIZE =0xf , +CREATE_MQEXT_CQID_SHIFT =6 , +CREATE_MQEXT_CQIDV0_MASK =0xffc0 , +/* DW7 */ +CREATE_MQEXT_VAL = (1 <<31 ), +/* DW8 */ +CREATE_MQEXT_ACQV = (1 <<0 ), +CREATE_MQEXT_ASYNC_CQIDV0 =0x7fe , +}; +
drivers/scsi/elx/libefc_sli/sli4.h struct sli4_reg { · line 744
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h +10
-0+struct sli4_rqst_cmn_create_mq_ext { +struct sli4_rqst_hdr hdr; +__le16 num_pages; +__le16 cq_id_v1; +__le32 async_event_bitmap; +__le16 async_cq_id_v1; +__le16 dw6w1_flags; +__le32 dw7_val; +__le32 dw8_flags; +__le32 rsvd36;
Nitpick: The code intentions for all these definitions are not consistent. For example above struct sli4_rqst_cmn_create_eq uses a different pattern. Please pick one and stick to it.
Quoted 121 lines
drivers/scsi/elx/libefc_sli/sli4.h +121
-0+struct sli4_dmaaddr page_phys_addr[0 ]; +}; + +struct sli4_rsp_cmn_create_mq_ext { +struct sli4_rsp_cmn_create_queue q_rsp; +}; + +enum sli4_mqe_size { +SLI4_MQE_SIZE_16 =0x05 , +SLI4_MQE_SIZE_32 , +SLI4_MQE_SIZE_64 , +SLI4_MQE_SIZE_128 , +}; + +enum sli4_async_evt { +SLI4_ASYNC_EVT_LINK_STATE = (1 <<1 ), +SLI4_ASYNC_EVT_FIP = (1 <<2 ), +SLI4_ASYNC_EVT_GRP5 = (1 <<5 ), +SLI4_ASYNC_EVT_FC = (1 <<16 ), +SLI4_ASYNC_EVT_SLI_PORT = (1 <<17 ), +}; + +#define SLI4_ASYNC_EVT_FC_ALL \ + (SLI4_ASYNC_EVT_LINK_STATE | \ + SLI4_ASYNC_EVT_FIP | \ + SLI4_ASYNC_EVT_GRP5 | \ + SLI4_ASYNC_EVT_FC | \ + SLI4_ASYNC_EVT_SLI_PORT) + +/* Create a Completion Queue. */ +struct sli4_rqst_cmn_create_cq_v0 { +struct sli4_rqst_hdr hdr; +__le16 num_pages; +__le16 rsvd18; +__le32 dw5_flags; +__le32 dw6_flags; +__le32 rsvd28; +__le32 rsvd32; +struct sli4_dmaaddr page_phys_addr[0 ]; +}; + +enum sli4_create_rq_e { +SLI4_RQ_CREATE_DUA =0x1 , +SLI4_RQ_CREATE_BQU =0x2 , + +SLI4_RQE_SIZE =8 , +SLI4_RQE_SIZE_8 =0x2 , +SLI4_RQE_SIZE_16 =0x3 , +SLI4_RQE_SIZE_32 =0x4 , +SLI4_RQE_SIZE_64 =0x5 , +SLI4_RQE_SIZE_128 =0x6 , + +SLI4_RQ_PAGE_SIZE_4096 =0x1 , +SLI4_RQ_PAGE_SIZE_8192 =0x2 , +SLI4_RQ_PAGE_SIZE_16384 =0x4 , +SLI4_RQ_PAGE_SIZE_32768 =0x8 , +SLI4_RQ_PAGE_SIZE_64536 =0x10 , + +SLI4_RQ_CREATE_V0_MAX_PAGES =8 , +SLI4_RQ_CREATE_V0_MIN_BUF_SIZE =128 , +SLI4_RQ_CREATE_V0_MAX_BUF_SIZE =2048 , +}; + +struct sli4_rqst_rq_create { +struct sli4_rqst_hdr hdr; +__le16 num_pages; +u8 dua_bqu_byte; +u8 ulp; +__le16 rsvd16; +u8 rqe_count_byte; +u8 rsvd19; +__le32 rsvd20; +__le16 buffer_size; +__le16 cq_id; +__le32 rsvd28; +struct sli4_dmaaddr page_phys_addr[SLI4_RQ_CREATE_V0_MAX_PAGES ]; +}; + +struct sli4_rsp_rq_create { +struct sli4_rsp_cmn_create_queue rsp; +}; + +enum sli4_create_rqv1_e { +SLI4_RQ_CREATE_V1_DNB =0x80 , +SLI4_RQ_CREATE_V1_MAX_PAGES =8 , +SLI4_RQ_CREATE_V1_MIN_BUF_SIZE =64 , +SLI4_RQ_CREATE_V1_MAX_BUF_SIZE =2048 , +}; + +struct sli4_rqst_rq_create_v1 { +struct sli4_rqst_hdr hdr; +__le16 num_pages; +u8 rsvd14; +u8 dim_dfd_dnb; +u8 page_size; +u8 rqe_size_byte; +__le16 rqe_count; +__le32 rsvd20; +__le16 rsvd24; +__le16 cq_id; +__le32 buffer_size; +struct sli4_dmaaddr page_phys_addr[SLI4_RQ_CREATE_V1_MAX_PAGES ]; +}; + +struct sli4_rsp_rq_create_v1 { +struct sli4_rsp_cmn_create_queue rsp; +}; + +#define SLI4_RQCREATEV2_DNB 0x80 + +struct sli4_rqst_rq_create_v2 { +struct sli4_rqst_hdr hdr; +__le16 num_pages; +u8 rq_count; +u8 dim_dfd_dnb; +u8 page_size; +u8 rqe_size_byte; +__le16 rqe_count; +__le16 hdr_buffer_size; +__le16 payload_buffer_size; +__le16 base_cq_id;
drivers/scsi/elx/libefc_sli/sli4.h struct sli4_reg { · line 875
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h +10
-0+__le16 rsvd26; +__le32 rsvd42; +struct sli4_dmaaddr page_phys_addr[0 ]; +}; + +struct sli4_rsp_rq_create_v2 { +struct sli4_rsp_cmn_create_queue rsp; +}; + +#define SLI4_CQE_CODE_OFFSET 14
empty line
Quoted 1,047 lines
drivers/scsi/elx/libefc_sli/sli4.h +1047
-0+enum sli4_cqe_code { +SLI4_CQE_CODE_WORK_REQUEST_COMPLETION =0x01 , +SLI4_CQE_CODE_RELEASE_WQE , +SLI4_CQE_CODE_RSVD , +SLI4_CQE_CODE_RQ_ASYNC , +SLI4_CQE_CODE_XRI_ABORTED , +SLI4_CQE_CODE_RQ_COALESCING , +SLI4_CQE_CODE_RQ_CONSUMPTION , +SLI4_CQE_CODE_MEASUREMENT_REPORTING , +SLI4_CQE_CODE_RQ_ASYNC_V1 , +SLI4_CQE_CODE_RQ_COALESCING_V1 , +SLI4_CQE_CODE_OPTIMIZED_WRITE_CMD , +SLI4_CQE_CODE_OPTIMIZED_WRITE_DATA , +}; + +#define SLI4_WQ_CREATE_MAX_PAGES 8 +struct sli4_rqst_wq_create { +struct sli4_rqst_hdr hdr; +__le16 num_pages; +__le16 cq_id; +u8 page_size; +u8 wqe_size_byte; +__le16 wqe_count; +__le32 rsvd; +struct sli4_dmaaddr + page_phys_addr[SLI4_WQ_CREATE_MAX_PAGES ]; +}; + +struct sli4_rsp_wq_create { +struct sli4_rsp_cmn_create_queue rsp; +}; + +enum sli4_link_attention_flags { +LINK_ATTN_TYPE_LINK_UP =0x01 , +LINK_ATTN_TYPE_LINK_DOWN =0x02 , +LINK_ATTN_TYPE_NO_HARD_ALPA =0x03 , + +LINK_ATTN_P2P =0x01 , +LINK_ATTN_FC_AL =0x02 , +LINK_ATTN_INTERNAL_LOOPBACK =0x03 , +LINK_ATTN_SERDES_LOOPBACK =0x04 , + +LINK_ATTN_1G =0x01 , +LINK_ATTN_2G =0x02 , +LINK_ATTN_4G =0x04 , +LINK_ATTN_8G =0x08 , +LINK_ATTN_10G =0x0a , +LINK_ATTN_16G =0x10 , +}; + +struct sli4_link_attention { +u8 link_number; +u8 attn_type; +u8 topology; +u8 port_speed; +u8 port_fault; +u8 shared_link_status; +__le16 logical_link_speed; +__le32 event_tag; +u8 rsvd12; +u8 event_code; +u8 event_type; +u8 flags; +}; + +enum sli4_link_event_type { +FC_EVENT_LINK_ATTENTION =0x01 , +FC_EVENT_SHARED_LINK_ATTENTION =0x02 , +}; + +enum sli4_wcqe_flags { +SLI4_WCQE_XB =0x10 , +SLI4_WCQE_QX =0x80 , +}; + +struct sli4_fc_wcqe { +u8 hw_status; +u8 status; +__le16 request_tag; +__le32 wqe_specific_1; +__le32 wqe_specific_2; +u8 rsvd12; +u8 qx_byte; +u8 code; +u8 flags; +}; + +/* FC WQ consumed CQ queue entry */ +struct sli4_fc_wqec { +__le32 rsvd0; +__le32 rsvd1; +__le16 wqe_index; +__le16 wq_id; +__le16 rsvd12; +u8 code; +u8 vld_byte; +}; + +/* FC Completion Status Codes. */ +enum sli4_wcqe_status { +SLI4_FC_WCQE_STATUS_SUCCESS , +SLI4_FC_WCQE_STATUS_FCP_RSP_FAILURE , +SLI4_FC_WCQE_STATUS_REMOTE_STOP , +SLI4_FC_WCQE_STATUS_LOCAL_REJECT , +SLI4_FC_WCQE_STATUS_NPORT_RJT , +SLI4_FC_WCQE_STATUS_FABRIC_RJT , +SLI4_FC_WCQE_STATUS_NPORT_BSY , +SLI4_FC_WCQE_STATUS_FABRIC_BSY , +SLI4_FC_WCQE_STATUS_RSVD , +SLI4_FC_WCQE_STATUS_LS_RJT , +SLI4_FC_WCQE_STATUS_RX_BUF_OVERRUN , +SLI4_FC_WCQE_STATUS_CMD_REJECT , +SLI4_FC_WCQE_STATUS_FCP_TGT_LENCHECK , +SLI4_FC_WCQE_STATUS_RSVD1 , +SLI4_FC_WCQE_STATUS_ELS_CMPLT_NO_AUTOREG , +SLI4_FC_WCQE_STATUS_RSVD2 , +SLI4_FC_WCQE_STATUS_RQ_SUCCESS ,//0x10 +SLI4_FC_WCQE_STATUS_RQ_BUF_LEN_EXCEEDED , +SLI4_FC_WCQE_STATUS_RQ_INSUFF_BUF_NEEDED , +SLI4_FC_WCQE_STATUS_RQ_INSUFF_FRM_DISC , +SLI4_FC_WCQE_STATUS_RQ_DMA_FAILURE , +SLI4_FC_WCQE_STATUS_FCP_RSP_TRUNCATE , +SLI4_FC_WCQE_STATUS_DI_ERROR , +SLI4_FC_WCQE_STATUS_BA_RJT , +SLI4_FC_WCQE_STATUS_RQ_INSUFF_XRI_NEEDED , +SLI4_FC_WCQE_STATUS_RQ_INSUFF_XRI_DISC , +SLI4_FC_WCQE_STATUS_RX_ERROR_DETECT , +SLI4_FC_WCQE_STATUS_RX_ABORT_REQUEST , + +/* driver generated status codes */ +SLI4_FC_WCQE_STATUS_DISPATCH_ERROR =0xfd , +SLI4_FC_WCQE_STATUS_SHUTDOWN =0xfe , +SLI4_FC_WCQE_STATUS_TARGET_WQE_TIMEOUT =0xff , +}; + +/* DI_ERROR Extended Status */ +enum sli4_fc_di_error_status { +SLI4_FC_DI_ERROR_GE = (1 <<0 ), +SLI4_FC_DI_ERROR_AE = (1 <<1 ), +SLI4_FC_DI_ERROR_RE = (1 <<2 ), +SLI4_FC_DI_ERROR_TDPV = (1 <<3 ), +SLI4_FC_DI_ERROR_UDB = (1 <<4 ), +SLI4_FC_DI_ERROR_EDIR = (1 <<5 ), +}; + +/* WQE DIF field contents */ +enum sli4_dif_fields { +SLI4_DIF_DISABLED , +SLI4_DIF_PASS_THROUGH , +SLI4_DIF_STRIP , +SLI4_DIF_INSERT , +}; + +/* Work Queue Entry (WQE) types */ +enum sli4_wqe_types { +SLI4_WQE_ABORT =0x0f , +SLI4_WQE_ELS_REQUEST64 =0x8a , +SLI4_WQE_FCP_IBIDIR64 =0xac , +SLI4_WQE_FCP_IREAD64 =0x9a , +SLI4_WQE_FCP_IWRITE64 =0x98 , +SLI4_WQE_FCP_ICMND64 =0x9c , +SLI4_WQE_FCP_TRECEIVE64 =0xa1 , +SLI4_WQE_FCP_CONT_TRECEIVE64 =0xe5 , +SLI4_WQE_FCP_TRSP64 =0xa3 , +SLI4_WQE_FCP_TSEND64 =0x9f , +SLI4_WQE_GEN_REQUEST64 =0xc2 , +SLI4_WQE_SEND_FRAME =0xe1 , +SLI4_WQE_XMIT_BCAST64 =0x84 , +SLI4_WQE_XMIT_BLS_RSP =0x97 , +SLI4_WQE_ELS_RSP64 =0x95 , +SLI4_WQE_XMIT_SEQUENCE64 =0x82 , +SLI4_WQE_REQUEUE_XRI =0x93 , +}; + +/* WQE command types */ +enum sli4_wqe_cmds { +SLI4_CMD_FCP_IREAD64_WQE =0x00 , +SLI4_CMD_FCP_ICMND64_WQE =0x00 , +SLI4_CMD_FCP_IWRITE64_WQE =0x01 , +SLI4_CMD_FCP_TRECEIVE64_WQE =0x02 , +SLI4_CMD_FCP_TRSP64_WQE =0x03 , +SLI4_CMD_FCP_TSEND64_WQE =0x07 , +SLI4_CMD_GEN_REQUEST64_WQE =0x08 , +SLI4_CMD_XMIT_BCAST64_WQE =0x08 , +SLI4_CMD_XMIT_BLS_RSP64_WQE =0x08 , +SLI4_CMD_ABORT_WQE =0x08 , +SLI4_CMD_XMIT_SEQUENCE64_WQE =0x08 , +SLI4_CMD_REQUEUE_XRI_WQE =0x0A , +SLI4_CMD_SEND_FRAME_WQE =0x0a , +}; + +#define SLI4_WQE_SIZE 0x05 +#define SLI4_WQE_EXT_SIZE 0x06 + +#define SLI4_WQE_BYTES (16 * sizeof(u32)) +#define SLI4_WQE_EXT_BYTES (32 * sizeof(u32)) + +/* Mask for ccp (CS_CTL) */ +#define SLI4_MASK_CCP 0xfe + +/* Generic WQE */ +enum sli4_gen_wqe_flags { +SLI4_GEN_WQE_EBDECNT = (0xf <<0 ), +SLI4_GEN_WQE_LEN_LOC = (0x3 <<7 ), +SLI4_GEN_WQE_QOSD = (1 <<9 ), +SLI4_GEN_WQE_XBL = (1 <<11 ), +SLI4_GEN_WQE_HLM = (1 <<12 ), +SLI4_GEN_WQE_IOD = (1 <<13 ), +SLI4_GEN_WQE_DBDE = (1 <<14 ), +SLI4_GEN_WQE_WQES = (1 <<15 ), + +SLI4_GEN_WQE_PRI = (0x7 ), +SLI4_GEN_WQE_PV = (1 <<3 ), +SLI4_GEN_WQE_EAT = (1 <<4 ), +SLI4_GEN_WQE_XC = (1 <<5 ), +SLI4_GEN_WQE_CCPE = (1 <<7 ), + +SLI4_GEN_WQE_CMDTYPE = (0xf ), +SLI4_GEN_WQE_WQEC = (1 <<7 ), +}; + +struct sli4_generic_wqe { +__le32 cmd_spec0_5[6 ]; +__le16 xri_tag; +__le16 context_tag; +u8 ct_byte; +u8 command; +u8 class_byte; +u8 timer; +__le32 abort_tag; +__le16 request_tag; +__le16 rsvd34; +__le16 dw10w0_flags; +u8 eat_xc_ccpe; +u8 ccp; +u8 cmdtype_wqec_byte; +u8 rsvd41; +__le16 cq_id; +}; + +/* WQE used to abort exchanges. */ +enum sli4_abort_wqe_flags { +SLI4_ABRT_WQE_IR =0x02 , + +SLI4_ABRT_WQE_EBDECNT = (0xf <<0 ), +SLI4_ABRT_WQE_LEN_LOC = (0x3 <<7 ), +SLI4_ABRT_WQE_QOSD = (1 <<9 ), +SLI4_ABRT_WQE_XBL = (1 <<11 ), +SLI4_ABRT_WQE_IOD = (1 <<13 ), +SLI4_ABRT_WQE_DBDE = (1 <<14 ), +SLI4_ABRT_WQE_WQES = (1 <<15 ), + +SLI4_ABRT_WQE_PRI = (0x7 ), +SLI4_ABRT_WQE_PV = (1 <<3 ), +SLI4_ABRT_WQE_EAT = (1 <<4 ), +SLI4_ABRT_WQE_XC = (1 <<5 ), +SLI4_ABRT_WQE_CCPE = (1 <<7 ), + +SLI4_ABRT_WQE_CMDTYPE = (0xf ), +SLI4_ABRT_WQE_WQEC = (1 <<7 ), +}; + +struct sli4_abort_wqe { +__le32 rsvd0; +__le32 rsvd4; +__le32 ext_t_tag; +u8 ia_ir_byte; +u8 criteria; +__le16 rsvd10; +__le32 ext_t_mask; +__le32 t_mask; +__le16 xri_tag; +__le16 context_tag; +u8 ct_byte; +u8 command; +u8 class_byte; +u8 timer; +__le32 t_tag; +__le16 request_tag; +__le16 rsvd34; +__le16 dw10w0_flags; +u8 eat_xc_ccpe; +u8 ccp; +u8 cmdtype_wqec_byte; +u8 rsvd41; +__le16 cq_id; +}; + +enum sli4_abort_criteria { +SLI4_ABORT_CRITERIA_XRI_TAG =0x01 , +SLI4_ABORT_CRITERIA_ABORT_TAG , +SLI4_ABORT_CRITERIA_REQUEST_TAG , +SLI4_ABORT_CRITERIA_EXT_ABORT_TAG , +}; + +enum sli4_abort_type { +SLI_ABORT_XRI , +SLI_ABORT_ABORT_ID , +SLI_ABORT_REQUEST_ID , +SLI_ABORT_MAX ,/* must be last */ +}; + +/* WQE used to create an ELS request. */ +enum sli4_els_req_wqe_flags { +SLI4_REQ_WQE_QOSD =0x2 , +SLI4_REQ_WQE_DBDE =0x40 , +SLI4_REQ_WQE_XBL =0x8 , +SLI4_REQ_WQE_XC =0x20 , +SLI4_REQ_WQE_IOD =0x20 , +SLI4_REQ_WQE_HLM =0x10 , +SLI4_REQ_WQE_CCPE =0x80 , +SLI4_REQ_WQE_EAT =0x10 , +SLI4_REQ_WQE_WQES =0x80 , +SLI4_REQ_WQE_PU_SHFT =4 , +SLI4_REQ_WQE_CT_SHFT =2 , +SLI4_REQ_WQE_CT =0xc , +SLI4_REQ_WQE_ELSID_SHFT =4 , +SLI4_REQ_WQE_SP_SHFT =24 , +SLI4_REQ_WQE_LEN_LOC_BIT1 =0x80 , +SLI4_REQ_WQE_LEN_LOC_BIT2 =0x1 , +}; + +struct sli4_els_request64_wqe { +struct sli4_bde els_request_payload; +__le32 els_request_payload_length; +__le32 sid_sp_dword; +__le32 remote_id_dword; +__le16 xri_tag; +__le16 context_tag; +u8 ct_byte; +u8 command; +u8 class_byte; +u8 timer; +__le32 abort_tag; +__le16 request_tag; +__le16 temporary_rpi; +u8 len_loc1_byte; +u8 qosd_xbl_hlm_iod_dbde_wqes; +u8 eat_xc_ccpe; +u8 ccp; +u8 cmdtype_elsid_byte; +u8 rsvd41; +__le16 cq_id; +struct sli4_bde els_response_payload_bde; +__le32 max_response_payload_length; +}; + +/* WQE used to create an FCP initiator no data command. */ +enum sli4_icmd_wqe_flags { +SLI4_ICMD_WQE_DBDE =0x40 , +SLI4_ICMD_WQE_XBL =0x8 , +SLI4_ICMD_WQE_XC =0x20 , +SLI4_ICMD_WQE_IOD =0x20 , +SLI4_ICMD_WQE_HLM =0x10 , +SLI4_ICMD_WQE_CCPE =0x80 , +SLI4_ICMD_WQE_EAT =0x10 , +SLI4_ICMD_WQE_APPID =0x10 , +SLI4_ICMD_WQE_WQES =0x80 , +SLI4_ICMD_WQE_PU_SHFT =4 , +SLI4_ICMD_WQE_CT_SHFT =2 , +SLI4_ICMD_WQE_BS_SHFT =4 , +SLI4_ICMD_WQE_LEN_LOC_BIT1 =0x80 , +SLI4_ICMD_WQE_LEN_LOC_BIT2 =0x1 , +}; + +struct sli4_fcp_icmnd64_wqe { +struct sli4_bde bde; +__le16 payload_offset_length; +__le16 fcp_cmd_buffer_length; +__le32 rsvd12; +__le32 remote_n_port_id_dword; +__le16 xri_tag; +__le16 context_tag; +u8 dif_ct_bs_byte; +u8 command; +u8 class_pu_byte; +u8 timer; +__le32 abort_tag; +__le16 request_tag; +__le16 rsvd34; +u8 len_loc1_byte; +u8 qosd_xbl_hlm_iod_dbde_wqes; +u8 eat_xc_ccpe; +u8 ccp; +u8 cmd_type_byte; +u8 rsvd41; +__le16 cq_id; +__le32 rsvd44; +__le32 rsvd48; +__le32 rsvd52; +__le32 rsvd56; +}; + +/* WQE used to create an FCP initiator read. */ +enum sli4_ir_wqe_flags { +SLI4_IR_WQE_DBDE =0x40 , +SLI4_IR_WQE_XBL =0x8 , +SLI4_IR_WQE_XC =0x20 , +SLI4_IR_WQE_IOD =0x20 , +SLI4_IR_WQE_HLM =0x10 , +SLI4_IR_WQE_CCPE =0x80 , +SLI4_IR_WQE_EAT =0x10 , +SLI4_IR_WQE_APPID =0x10 , +SLI4_IR_WQE_WQES =0x80 , +SLI4_IR_WQE_PU_SHFT =4 , +SLI4_IR_WQE_CT_SHFT =2 , +SLI4_IR_WQE_BS_SHFT =4 , +SLI4_IR_WQE_LEN_LOC_BIT1 =0x80 , +SLI4_IR_WQE_LEN_LOC_BIT2 =0x1 , +}; + +struct sli4_fcp_iread64_wqe { +struct sli4_bde bde; +__le16 payload_offset_length; +__le16 fcp_cmd_buffer_length; + +__le32 total_transfer_length; + +__le32 remote_n_port_id_dword; + +__le16 xri_tag; +__le16 context_tag; + +u8 dif_ct_bs_byte; +u8 command; +u8 class_pu_byte; +u8 timer; + +__le32 abort_tag; + +__le16 request_tag; +__le16 rsvd34; + +u8 len_loc1_byte; +u8 qosd_xbl_hlm_iod_dbde_wqes; +u8 eat_xc_ccpe; +u8 ccp; + +u8 cmd_type_byte; +u8 rsvd41; +__le16 cq_id; + +__le32 rsvd44; +struct sli4_bde first_data_bde; +}; + +/* WQE used to create an FCP initiator write. */ +enum sli4_iwr_wqe_flags { +SLI4_IWR_WQE_DBDE =0x40 , +SLI4_IWR_WQE_XBL =0x8 , +SLI4_IWR_WQE_XC =0x20 , +SLI4_IWR_WQE_IOD =0x20 , +SLI4_IWR_WQE_HLM =0x10 , +SLI4_IWR_WQE_DNRX =0x10 , +SLI4_IWR_WQE_CCPE =0x80 , +SLI4_IWR_WQE_EAT =0x10 , +SLI4_IWR_WQE_APPID =0x10 , +SLI4_IWR_WQE_WQES =0x80 , +SLI4_IWR_WQE_PU_SHFT =4 , +SLI4_IWR_WQE_CT_SHFT =2 , +SLI4_IWR_WQE_BS_SHFT =4 , +SLI4_IWR_WQE_LEN_LOC_BIT1 =0x80 , +SLI4_IWR_WQE_LEN_LOC_BIT2 =0x1 , +}; + +struct sli4_fcp_iwrite64_wqe { +struct sli4_bde bde; +__le16 payload_offset_length; +__le16 fcp_cmd_buffer_length; +__le16 total_transfer_length; +__le16 initial_transfer_length; +__le16 xri_tag; +__le16 context_tag; +u8 dif_ct_bs_byte; +u8 command; +u8 class_pu_byte; +u8 timer; +__le32 abort_tag; +__le16 request_tag; +__le16 rsvd34; +u8 len_loc1_byte; +u8 qosd_xbl_hlm_iod_dbde_wqes; +u8 eat_xc_ccpe; +u8 ccp; +u8 cmd_type_byte; +u8 rsvd41; +__le16 cq_id; +__le32 remote_n_port_id_dword; +struct sli4_bde first_data_bde; +}; + +struct sli4_fcp_128byte_wqe { +u32 dw[32 ]; +}; + +/* WQE used to create an FCP target receive */ +enum sli4_trcv_wqe_flags { +SLI4_TRCV_WQE_DBDE =0x40 , +SLI4_TRCV_WQE_XBL =0x8 , +SLI4_TRCV_WQE_AR =0x8 , +SLI4_TRCV_WQE_XC =0x20 , +SLI4_TRCV_WQE_IOD =0x20 , +SLI4_TRCV_WQE_HLM =0x10 , +SLI4_TRCV_WQE_DNRX =0x10 , +SLI4_TRCV_WQE_CCPE =0x80 , +SLI4_TRCV_WQE_EAT =0x10 , +SLI4_TRCV_WQE_APPID =0x10 , +SLI4_TRCV_WQE_WQES =0x80 , +SLI4_TRCV_WQE_PU_SHFT =4 , +SLI4_TRCV_WQE_CT_SHFT =2 , +SLI4_TRCV_WQE_BS_SHFT =4 , +SLI4_TRCV_WQE_LEN_LOC_BIT2 =0x1 , +}; + +struct sli4_fcp_treceive64_wqe { +struct sli4_bde bde; +__le32 payload_offset_length; +__le32 relative_offset; +union { +__le16 sec_xri_tag; +__le16 rsvd; +__le32 dword; + } dword5; +__le16 xri_tag; +__le16 context_tag; +u8 dif_ct_bs_byte; +u8 command; +u8 class_ar_pu_byte; +u8 timer; +__le32 abort_tag; +__le16 request_tag; +__le16 remote_xid; +u8 lloc1_appid; +u8 qosd_xbl_hlm_iod_dbde_wqes; +u8 eat_xc_ccpe; +u8 ccp; +u8 cmd_type_byte; +u8 rsvd41; +__le16 cq_id; +__le32 fcp_data_receive_length; +struct sli4_bde first_data_bde; +}; + +/* WQE used to create an FCP target response */ +enum sli4_trsp_wqe_flags { +SLI4_TRSP_WQE_AG =0x8 , +SLI4_TRSP_WQE_DBDE =0x40 , +SLI4_TRSP_WQE_XBL =0x8 , +SLI4_TRSP_WQE_XC =0x20 , +SLI4_TRSP_WQE_HLM =0x10 , +SLI4_TRSP_WQE_DNRX =0x10 , +SLI4_TRSP_WQE_CCPE =0x80 , +SLI4_TRSP_WQE_EAT =0x10 , +SLI4_TRSP_WQE_APPID =0x10 , +SLI4_TRSP_WQE_WQES =0x80 , +}; + +struct sli4_fcp_trsp64_wqe { +struct sli4_bde bde; +__le32 fcp_response_length; +__le32 rsvd12; +__le32 dword5; +__le16 xri_tag; +__le16 rpi; +u8 ct_dnrx_byte; +u8 command; +u8 class_ag_byte; +u8 timer; +__le32 abort_tag; +__le16 request_tag; +__le16 remote_xid; +u8 lloc1_appid; +u8 qosd_xbl_hlm_dbde_wqes; +u8 eat_xc_ccpe; +u8 ccp; +u8 cmd_type_byte; +u8 rsvd41; +__le16 cq_id; +__le32 rsvd44; +__le32 rsvd48; +__le32 rsvd52; +__le32 rsvd56; +}; + +/* WQE used to create an FCP target send (DATA IN). */ +enum sli4_tsend_wqe_flags { +SLI4_TSEND_WQE_XBL =0x8 , +SLI4_TSEND_WQE_DBDE =0x40 , +SLI4_TSEND_WQE_IOD =0x20 , +SLI4_TSEND_WQE_QOSD =0x2 , +SLI4_TSEND_WQE_HLM =0x10 , +SLI4_TSEND_WQE_PU_SHFT =4 , +SLI4_TSEND_WQE_AR =0x8 , +SLI4_TSEND_CT_SHFT =2 , +SLI4_TSEND_BS_SHFT =4 , +SLI4_TSEND_LEN_LOC_BIT2 =0x1 , +SLI4_TSEND_CCPE =0x80 , +SLI4_TSEND_APPID_VALID =0x20 , +SLI4_TSEND_WQES =0x80 , +SLI4_TSEND_XC =0x20 , +SLI4_TSEND_EAT =0x10 , +}; + +struct sli4_fcp_tsend64_wqe { +struct sli4_bde bde; +__le32 payload_offset_length; +__le32 relative_offset; +__le32 dword5; +__le16 xri_tag; +__le16 rpi; +u8 ct_byte; +u8 command; +u8 class_pu_ar_byte; +u8 timer; +__le32 abort_tag; +__le16 request_tag; +__le16 remote_xid; +u8 dw10byte0; +u8 ll_qd_xbl_hlm_iod_dbde; +u8 dw10byte2; +u8 ccp; +u8 cmd_type_byte; +u8 rsvd45; +__le16 cq_id; +__le32 fcp_data_transmit_length; +struct sli4_bde first_data_bde; +}; + +/* WQE used to create a general request. */ +enum sli4_gen_req_wqe_flags { +SLI4_GEN_REQ64_WQE_XBL =0x8 , +SLI4_GEN_REQ64_WQE_DBDE =0x40 , +SLI4_GEN_REQ64_WQE_IOD =0x20 , +SLI4_GEN_REQ64_WQE_QOSD =0x2 , +SLI4_GEN_REQ64_WQE_HLM =0x10 , +SLI4_GEN_REQ64_CT_SHFT =2 , +}; + +struct sli4_gen_request64_wqe { +struct sli4_bde bde; +__le32 request_payload_length; +__le32 relative_offset; +u8 rsvd17; +u8 df_ctl; +u8 type; +u8 r_ctl; +__le16 xri_tag; +__le16 context_tag; +u8 ct_byte; +u8 command; +u8 class_byte; +u8 timer; +__le32 abort_tag; +__le16 request_tag; +__le16 rsvd34; +u8 dw10flags0; +u8 dw10flags1; +u8 dw10flags2; +u8 ccp; +u8 cmd_type_byte; +u8 rsvd41; +__le16 cq_id; +__le32 remote_n_port_id_dword; +__le32 rsvd48; +__le32 rsvd52; +__le32 max_response_payload_length; +}; + +/* WQE used to create a send frame request */ +enum sli4_sf_wqe_flags { +SLI4_SF_WQE_DBDE =0x40 , +SLI4_SF_PU =0x30 , +SLI4_SF_CT =0xc , +SLI4_SF_QOSD =0x2 , +SLI4_SF_LEN_LOC_BIT1 =0x80 , +SLI4_SF_LEN_LOC_BIT2 =0x1 , +SLI4_SF_XC =0x20 , +SLI4_SF_XBL =0x8 , +}; + +struct sli4_send_frame_wqe { +struct sli4_bde bde; +__le32 frame_length; +__le32 fc_header_0_1[2 ]; +__le16 xri_tag; +__le16 context_tag; +u8 ct_byte; +u8 command; +u8 dw7flags0; +u8 timer; +__le32 abort_tag; +__le16 request_tag; +u8 eof; +u8 sof; +u8 dw10flags0; +u8 dw10flags1; +u8 dw10flags2; +u8 ccp; +u8 cmd_type_byte; +u8 rsvd41; +__le16 cq_id; +__le32 fc_header_2_5[4 ]; +}; + +/* WQE used to create a transmit sequence */ +enum sli4_seq_wqe_flags { +SLI4_SEQ_WQE_DBDE =0x4000 , +SLI4_SEQ_WQE_XBL =0x800 , +SLI4_SEQ_WQE_SI =0x4 , +SLI4_SEQ_WQE_FT =0x8 , +SLI4_SEQ_WQE_XO =0x40 , +SLI4_SEQ_WQE_LS =0x80 , +SLI4_SEQ_WQE_DIF =0x3 , +SLI4_SEQ_WQE_BS =0x70 , +SLI4_SEQ_WQE_PU =0x30 , +SLI4_SEQ_WQE_HLM =0x1000 , +SLI4_SEQ_WQE_IOD_SHIFT =13 , +SLI4_SEQ_WQE_CT_SHIFT =2 , +SLI4_SEQ_WQE_LEN_LOC_SHIFT =7 , +}; + +struct sli4_xmit_sequence64_wqe { +struct sli4_bde bde; +__le32 remote_n_port_id_dword; +__le32 relative_offset; +u8 dw5flags0; +u8 df_ctl; +u8 type; +u8 r_ctl; +__le16 xri_tag; +__le16 context_tag; +u8 dw7flags0; +u8 command; +u8 dw7flags1; +u8 timer; +__le32 abort_tag; +__le16 request_tag; +__le16 remote_xid; +__le16 dw10w0; +u8 dw10flags0; +u8 ccp; +u8 cmd_type_wqec_byte; +u8 rsvd45; +__le16 cq_id; +__le32 sequence_payload_len; +__le32 rsvd48; +__le32 rsvd52; +__le32 rsvd56; +}; + +/* +* WQE used unblock the specified XRI and to release +* it to the SLI Port's free pool. +*/ +enum sli4_requeue_wqe_flags { +SLI4_REQU_XRI_WQE_XC =0x20 , +SLI4_REQU_XRI_WQE_QOSD =0x2 , +}; + +struct sli4_requeue_xri_wqe { +__le32 rsvd0; +__le32 rsvd4; +__le32 rsvd8; +__le32 rsvd12; +__le32 rsvd16; +__le32 rsvd20; +__le16 xri_tag; +__le16 context_tag; +u8 ct_byte; +u8 command; +u8 class_byte; +u8 timer; +__le32 rsvd32; +__le16 request_tag; +__le16 rsvd34; +__le16 flags0; +__le16 flags1; +__le16 flags2; +u8 ccp; +u8 cmd_type_wqec_byte; +u8 rsvd42; +__le16 cq_id; +__le32 rsvd44; +__le32 rsvd48; +__le32 rsvd52; +__le32 rsvd56; +}; + +/* WQE used to create a BLS response */ +enum sli4_bls_rsp_wqe_flags { +SLI4_BLS_RSP_RID =0xffffff , +SLI4_BLS_RSP_WQE_AR =0x40000000 , +SLI4_BLS_RSP_WQE_CT_SHFT =2 , +SLI4_BLS_RSP_WQE_QOSD =0x2 , +SLI4_BLS_RSP_WQE_HLM =0x10 , +}; + +struct sli4_xmit_bls_rsp_wqe { +__le32 payload_word0; +__le16 rx_id; +__le16 ox_id; +__le16 high_seq_cnt; +__le16 low_seq_cnt; +__le32 rsvd12; +__le32 local_n_port_id_dword; +__le32 remote_id_dword; +__le16 xri_tag; +__le16 context_tag; +u8 dw8flags0; +u8 command; +u8 dw8flags1; +u8 timer; +__le32 abort_tag; +__le16 request_tag; +__le16 rsvd38; +u8 dw11flags0; +u8 dw11flags1; +u8 dw11flags2; +u8 ccp; +u8 dw12flags0; +u8 rsvd45; +__le16 cq_id; +__le16 temporary_rpi; +u8 rsvd50; +u8 rsvd51; +__le32 rsvd52; +__le32 rsvd56; +__le32 rsvd60; +}; + +enum sli_bls_type { +SLI4_SLI_BLS_ACC , +SLI4_SLI_BLS_RJT , +SLI4_SLI_BLS_MAX +}; + +struct sli_bls_payload { +enum sli_bls_type type; +__le16 ox_id; +__le16 rx_id; +union { +struct { +u8 seq_id_validity; +u8 seq_id_last; +u8 rsvd2; +u8 rsvd3; +u16 ox_id; +u16 rx_id; +__le16 low_seq_cnt; +__le16 high_seq_cnt; + } acc; +struct { +u8 vendor_unique; +u8 reason_explanation; +u8 reason_code; +u8 rsvd3; + } rjt; + } u; +}; + +/* WQE used to create an ELS response */ + +enum sli4_els_rsp_flags { +SLI4_ELS_SID =0xffffff , +SLI4_ELS_RID =0xffffff , +SLI4_ELS_DBDE =0x40 , +SLI4_ELS_XBL =0x8 , +SLI4_ELS_IOD =0x20 , +SLI4_ELS_QOSD =0x2 , +SLI4_ELS_XC =0x20 , +SLI4_ELS_CT_OFFSET =0X2 , +SLI4_ELS_SP =0X1000000 , +SLI4_ELS_HLM =0X10 , +}; + +struct sli4_xmit_els_rsp64_wqe { +struct sli4_bde els_response_payload; +__le32 els_response_payload_length; +__le32 sid_dw; +__le32 rid_dw; +__le16 xri_tag; +__le16 context_tag; +u8 ct_byte; +u8 command; +u8 class_byte; +u8 timer; +__le32 abort_tag; +__le16 request_tag; +__le16 ox_id; +u8 flags1; +u8 flags2; +u8 flags3; +u8 flags4; +u8 cmd_type_wqec; +u8 rsvd34; +__le16 cq_id; +__le16 temporary_rpi; +__le16 rsvd38; +u32 rsvd40; +u32 rsvd44; +u32 rsvd48; +}; + +/* Prameters used to populate WQE*/ +struct sli_bls_params { +u32 s_id; +u16 ox_id; +u16 rx_id; +u8 payload[12 ]; +}; + +struct sli_els_params { +u32 s_id; +u16 ox_id; +u8 timeout; +}; + +struct sli_ct_params { +u8 r_ctl; +u8 type; +u8 df_ctl; +u8 timeout; +u16 ox_id; +}; + +struct sli_fcp_tgt_params { +u32 offset; +u16 ox_id; +u16 flags; +u8 cs_ctl; +u8 timeout; +u32 app_id; +}; + +/* Local Reject Reason Codes */ +enum sli4_fc_local_rej_codes { +SLI4_FC_LOCAL_REJECT_UNKNOWN , +SLI4_FC_LOCAL_REJECT_MISSING_CONTINUE , +SLI4_FC_LOCAL_REJECT_SEQUENCE_TIMEOUT , +SLI4_FC_LOCAL_REJECT_INTERNAL_ERROR , +SLI4_FC_LOCAL_REJECT_INVALID_RPI , +SLI4_FC_LOCAL_REJECT_NO_XRI , +SLI4_FC_LOCAL_REJECT_ILLEGAL_COMMAND , +SLI4_FC_LOCAL_REJECT_XCHG_DROPPED , +SLI4_FC_LOCAL_REJECT_ILLEGAL_FIELD , +SLI4_FC_LOCAL_REJECT_RPI_SUSPENDED , +SLI4_FC_LOCAL_REJECT_RSVD , +SLI4_FC_LOCAL_REJECT_RSVD1 , +SLI4_FC_LOCAL_REJECT_NO_ABORT_MATCH , +SLI4_FC_LOCAL_REJECT_TX_DMA_FAILED , +SLI4_FC_LOCAL_REJECT_RX_DMA_FAILED , +SLI4_FC_LOCAL_REJECT_ILLEGAL_FRAME , +SLI4_FC_LOCAL_REJECT_RSVD2 , +SLI4_FC_LOCAL_REJECT_NO_RESOURCES ,//0x11 +SLI4_FC_LOCAL_REJECT_FCP_CONF_FAILURE , +SLI4_FC_LOCAL_REJECT_ILLEGAL_LENGTH , +SLI4_FC_LOCAL_REJECT_UNSUPPORTED_FEATURE , +SLI4_FC_LOCAL_REJECT_ABORT_IN_PROGRESS , +SLI4_FC_LOCAL_REJECT_ABORT_REQUESTED , +SLI4_FC_LOCAL_REJECT_RCV_BUFFER_TIMEOUT , +SLI4_FC_LOCAL_REJECT_LOOP_OPEN_FAILURE , +SLI4_FC_LOCAL_REJECT_RSVD3 , +SLI4_FC_LOCAL_REJECT_LINK_DOWN , +SLI4_FC_LOCAL_REJECT_CORRUPTED_DATA , +SLI4_FC_LOCAL_REJECT_CORRUPTED_RPI , +SLI4_FC_LOCAL_REJECT_OUTOFORDER_DATA , +SLI4_FC_LOCAL_REJECT_OUTOFORDER_ACK , +SLI4_FC_LOCAL_REJECT_DUP_FRAME , +SLI4_FC_LOCAL_REJECT_LINK_CONTROL_FRAME ,//0x20 +SLI4_FC_LOCAL_REJECT_BAD_HOST_ADDRESS , +SLI4_FC_LOCAL_REJECT_RSVD4 , +SLI4_FC_LOCAL_REJECT_MISSING_HDR_BUFFER , +SLI4_FC_LOCAL_REJECT_MSEQ_CHAIN_CORRUPTED , +SLI4_FC_LOCAL_REJECT_ABORTMULT_REQUESTED , +SLI4_FC_LOCAL_REJECT_BUFFER_SHORTAGE =0x28 , +SLI4_FC_LOCAL_REJECT_RCV_XRIBUF_WAITING , +SLI4_FC_LOCAL_REJECT_INVALID_VPI =0x2e , +SLI4_FC_LOCAL_REJECT_NO_FPORT_DETECTED , +SLI4_FC_LOCAL_REJECT_MISSING_XRIBUF , +SLI4_FC_LOCAL_REJECT_RSVD5 , +SLI4_FC_LOCAL_REJECT_INVALID_XRI , +SLI4_FC_LOCAL_REJECT_INVALID_RELOFFSET =0x40 , +SLI4_FC_LOCAL_REJECT_MISSING_RELOFFSET , +SLI4_FC_LOCAL_REJECT_INSUFF_BUFFERSPACE , +SLI4_FC_LOCAL_REJECT_MISSING_SI , +SLI4_FC_LOCAL_REJECT_MISSING_ES , +SLI4_FC_LOCAL_REJECT_INCOMPLETE_XFER , +SLI4_FC_LOCAL_REJECT_SLER_FAILURE , +SLI4_FC_LOCAL_REJECT_SLER_CMD_RCV_FAILURE , +SLI4_FC_LOCAL_REJECT_SLER_REC_RJT_ERR , +SLI4_FC_LOCAL_REJECT_SLER_REC_SRR_RETRY_ERR , +SLI4_FC_LOCAL_REJECT_SLER_SRR_RJT_ERR , +SLI4_FC_LOCAL_REJECT_RSVD6 , +SLI4_FC_LOCAL_REJECT_SLER_RRQ_RJT_ERR , +SLI4_FC_LOCAL_REJECT_SLER_RRQ_RETRY_ERR , +SLI4_FC_LOCAL_REJECT_SLER_ABTS_ERR , +}; + +enum sli4_async_rcqe_flags { +SLI4_RACQE_RQ_EL_INDX =0xfff , +SLI4_RACQE_FCFI =0x3f , +SLI4_RACQE_HDPL =0x3f , +SLI4_RACQE_RQ_ID =0xffc0 , +}; + +struct sli4_fc_async_rcqe { +u8 rsvd0; +u8 status; +__le16 rq_elmt_indx_word; +__le32 rsvd4; +__le16 fcfi_rq_id_word; +__le16 data_placement_length; +u8 sof_byte; +u8 eof_byte; +u8 code; +u8 hdpl_byte; +}; + +struct sli4_fc_async_rcqe_v1 { +u8 rsvd0; +u8 status; +__le16 rq_elmt_indx_word; +u8 fcfi_byte; +u8 rsvd5; +__le16 rsvd6; +__le16 rq_id; +__le16 data_placement_length; +u8 sof_byte; +u8 eof_byte; +u8 code; +u8 hdpl_byte; +}; + +enum sli4_fc_async_rq_status { +SLI4_FC_ASYNC_RQ_SUCCESS =0x10 , +SLI4_FC_ASYNC_RQ_BUF_LEN_EXCEEDED , +SLI4_FC_ASYNC_RQ_INSUFF_BUF_NEEDED , +SLI4_FC_ASYNC_RQ_INSUFF_BUF_FRM_DISC , +SLI4_FC_ASYNC_RQ_DMA_FAILURE , +}; + +#define SLI4_RCQE_RQ_EL_INDX 0xfff + +struct sli4_fc_coalescing_rcqe { +u8 rsvd0; +u8 status; +__le16 rq_elmt_indx_word;
drivers/scsi/elx/libefc_sli/sli4.h struct sli4_reg { · line 1932
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h +10
-0+__le32 rsvd4; +__le16 rq_id; +__le16 sequence_reporting_placement_length; +__le16 rsvd14; +u8 code; +u8 vld_byte; +}; + +#define SLI4_FC_COALESCE_RQ_SUCCESS 0x10 +#define SLI4_FC_COALESCE_RQ_INSUFF_XRI_NEEDED 0x18
empty line missing
drivers/scsi/elx/libefc_sli/sli4.h struct sli4_reg { · line 1938
Quoted 6 lines
drivers/scsi/elx/libefc_sli/sli4.h +6
-0+/* +* @SLI4_OCQE_RQ_EL_INDX: bits 0 to 15 in word1 +* @SLI4_OCQE_FCFI: bits 0 to 6 in dw1 +* @SLI4_OCQE_OOX: bit 15 in dw1 +* @SLI4_OCQE_AGXR: bit 16 in dw1 +*/
Maybe make a proper kernel doc out of this?
drivers/scsi/elx/libefc_sli/sli4.h struct sli4_reg { · line 1944
Quoted 6 lines
drivers/scsi/elx/libefc_sli/sli4.h +6
-0+enum sli4_optimized_write_cmd_cqe_flags { +SLI4_OCQE_RQ_EL_INDX =0x7f , +SLI4_OCQE_FCFI =0x3f , +SLI4_OCQE_OOX = (1 <<6 ), +SLI4_OCQE_AGXR = (1 <<7 ), +SLI4_OCQE_HDPL =0x3f ,
Code aligment is not consistent with the rest.
Quoted 73 lines
drivers/scsi/elx/libefc_sli/sli4.h +68
-0+}; + +struct sli4_fc_optimized_write_cmd_cqe { +u8 rsvd0; +u8 status; +__le16 w1; +u8 flags0; +u8 flags1; +__le16 xri; +__le16 rq_id; +__le16 data_placement_length; +__le16 rpi; +u8 code; +u8 hdpl_vld; +}; + +#define SLI4_OCQE_XB 0x10 + +struct sli4_fc_optimized_write_data_cqe { +u8 hw_status; +u8 status; +__le16 xri; +__le32 total_data_placed; +__le32 extended_status; +__le16 rsvd12; +u8 code; +u8 flags; +}; + +struct sli4_fc_xri_aborted_cqe { +u8 rsvd0; +u8 status; +__le16 rsvd2; +__le32 extended_status; +__le16 xri; +__le16 remote_xid; +__le16 rsvd12; +u8 code; +u8 flags; +}; + +enum sli4_generic_ctx { +SLI4_GENERIC_CONTEXT_RPI , +SLI4_GENERIC_CONTEXT_VPI , +SLI4_GENERIC_CONTEXT_VFI , +SLI4_GENERIC_CONTEXT_FCFI , +}; + +#define SLI4_GENERIC_CLASS_CLASS_2 0x1 +#define SLI4_GENERIC_CLASS_CLASS_3 0x2 + +#define SLI4_ELS_REQUEST64_DIR_WRITE 0x0 +#define SLI4_ELS_REQUEST64_DIR_READ 0x1 + +enum sli4_els_request { +SLI4_ELS_REQUEST64_OTHER , +SLI4_ELS_REQUEST64_LOGO , +SLI4_ELS_REQUEST64_FDISC , +SLI4_ELS_REQUEST64_FLOGIN , +SLI4_ELS_REQUEST64_PLOGI , +}; + +enum sli4_els_cmd_type { +SLI4_ELS_REQUEST64_CMD_GEN =0x08 , +SLI4_ELS_REQUEST64_CMD_NON_FABRIC =0x0c , +SLI4_ELS_REQUEST64_CMD_FABRIC =0x0d , +}; +#endif /* !_SLI4_H */ Signature · 1 line
2.16.4
Thanks,
Daniel
Re: [PATCH v3 02/31] elx: libefc_sli: SLI Descriptors and Queue entries
Quoted 12 lines · Daniel Wagner
Hi,
Quoted 8 lines · James Smart
This patch continues the
libefc_sliSLI-4 library population.This patch add SLI-4 Data structures and defines for:
- Buffer Descriptors (BDEs)
- Scatter/Gather List elements (SGEs)
- Queues and their Entry Descriptions for:
Event Queues (EQs), Completion Queues (CQs), Receive Queues (RQs), and the Mailbox Queue (MQ).
Quoted 4 lines
There are a definitions which are not used at all, e.g.
DISEED_SGE_OP_RX_VALUE,sli4_acqe_e,sli4_acqe_event_code, etc. What are the plans with those?
When defining adapter interfaces, the interface is usually defined in its entirety, whether fully used or not. Not only is it not always clear what will be used when first added, but it seems cleaner to review for correctness (comparing 1:1 with a hw spec vs 1sy-2sy vs N in spec). In the case of several of the items, there will be future features (DIF support) folded in that will utilize most of the definitions.
I know it's not as clean as "only define what is used", but I would prefer to handle hw this way.
Agree with the rest of the comments and will address.
-- james
Re: [PATCH v3 02/31] elx: libefc_sli: SLI Descriptors and Queue entries
In reply to James SmartQuoted 306 lines · James Smart
This patch continues the
libefc_sliSLI-4 library population.This patch add SLI-4 Data structures and defines for:
- Buffer Descriptors (BDEs)
- Scatter/Gather List elements (SGEs)
- Queues and their Entry Descriptions for:
Event Queues (EQs), Completion Queues (CQs), Receive Queues (RQs), and the Mailbox Queue (MQ).Signed-off-by Ram Vegesna <[email protected]>Signed-off-by James Smart <[email protected]>---
v3:
Changed anonymous enums to named.
SLI defines to spell out_MASKvalue directly. Change multiple defines to named Enums for consistency. Single Enum to #define.--- drivers/scsi/elx/include/efc_common.h | 25 + drivers/scsi/elx/libefc_sli/sli4.h | 1761 +++++++++++++++++++++++++++++++++ 2 files changed, 1786 insertions(+)create mode 100644
drivers/scsi/elx/include/efc_common.hdrivers/scsi/elx/include/efc_common.h new file +25
-0@@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* +* Copyright (C) 2019 Broadcom. All Rights Reserved. The term +* “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. +*/ + +#ifndef __EFC_COMMON_H__ +#define __EFC_COMMON_H__ + +#include <linux/pci.h> + +#define EFC_SUCCESS 0 +#define EFC_FAIL 1 + +struct efc_dma { +void *virt; +void *alloc; +dma_addr_t phys; + +size_t size; +size_t len; +struct pci_dev *pdev; +}; + +#endif /* __EFC_COMMON_H__ */ drivers/scsi/elx/libefc_sli/sli4.h +243
-0@@ -249,4 +249,1765 @@ struct sli4_reg {u32 off; }; +struct sli4_dmaaddr { +__le32 low; +__le32 high; +}; + +/* a 3-word BDE with address 1st 2 words, length last word */ +struct sli4_bufptr { +struct sli4_dmaaddr addr; +__le32 length; +}; + +/* a 3-word BDE with length as first word, address last 2 words */ +struct sli4_bufptr_len1st { +__le32 length0; +struct sli4_dmaaddr addr; +}; + +/* Buffer Descriptor Entry (BDE) */ +enum sli4_bde_e { +SLI4_BDE_MASK_BUFFER_LEN =0x00ffffff , +SLI4_BDE_MASK_BDE_TYPE =0xff000000 , +}; + +struct sli4_bde { +__le32 bde_type_buflen; +union { +struct sli4_dmaaddr data; +struct { +__le32 offset; +__le32 rsvd2; + } imm; +struct sli4_dmaaddr blp; + } u; +}; + +/* Buffer Descriptors */ +enum sli4_bde_type { +BDE_TYPE_SHIFT =24 , +BDE_TYPE_BDE_64 =0x00 ,/* Generic 64-bit data */ +BDE_TYPE_BDE_IMM =0x01 ,/* Immediate data */ +BDE_TYPE_BLP =0x40 ,/* Buffer List Pointer */ +}; + +/* Scatter-Gather Entry (SGE) */ +#define SLI4_SGE_MAX_RESERVED 3 + +enum sli4_sge_type { +/* DW2 */ +SLI4_SGE_DATA_OFFSET_MASK =0x07FFFFFF , +/*DW2W1*/ +SLI4_SGE_TYPE_SHIFT =27 , +SLI4_SGE_TYPE_MASK =0x78000000 , +/*SGE Types*/ +SLI4_SGE_TYPE_DATA =0x00 , +SLI4_SGE_TYPE_DIF =0x04 ,/* Data Integrity Field */ +SLI4_SGE_TYPE_LSP =0x05 ,/* List Segment Pointer */ +SLI4_SGE_TYPE_PEDIF =0x06 ,/* Post Encryption Engine DIF */ +SLI4_SGE_TYPE_PESEED =0x07 ,/* Post Encryption DIF Seed */ +SLI4_SGE_TYPE_DISEED =0x08 ,/* DIF Seed */ +SLI4_SGE_TYPE_ENC =0x09 ,/* Encryption */ +SLI4_SGE_TYPE_ATM =0x0a ,/* DIF Application Tag Mask */ +SLI4_SGE_TYPE_SKIP =0x0c ,/* SKIP */ + +SLI4_SGE_LAST = (1 <<31 ), +}; + +struct sli4_sge { +__le32 buffer_address_high; +__le32 buffer_address_low; +__le32 dw2_flags; +__le32 buffer_length; +}; + +/* T10 DIF Scatter-Gather Entry (SGE) */ +struct sli4_dif_sge { +__le32 buffer_address_high; +__le32 buffer_address_low; +__le32 dw2_flags; +__le32 rsvd12; +}; + +/* Data Integrity Seed (DISEED) SGE */ +enum sli4_diseed_sge_flags { +/* DW2W1 */ +DISEED_SGE_HS = (1 <<2 ), +DISEED_SGE_WS = (1 <<3 ), +DISEED_SGE_IC = (1 <<4 ), +DISEED_SGE_ICS = (1 <<5 ), +DISEED_SGE_ATRT = (1 <<6 ), +DISEED_SGE_AT = (1 <<7 ), +DISEED_SGE_FAT = (1 <<8 ), +DISEED_SGE_NA = (1 <<9 ), +DISEED_SGE_HI = (1 <<10 ), + +/* DW3W1 */ +DISEED_SGE_BS_MASK =0x0007 , +DISEED_SGE_AI = (1 <<3 ), +DISEED_SGE_ME = (1 <<4 ), +DISEED_SGE_RE = (1 <<5 ), +DISEED_SGE_CE = (1 <<6 ), +DISEED_SGE_NR = (1 <<7 ), + +DISEED_SGE_OP_RX_SHIFT =8 , +DISEED_SGE_OP_RX_MASK =0x0F00 , +DISEED_SGE_OP_TX_SHIFT =12 , +DISEED_SGE_OP_TX_MASK =0xF000 , +}; + +/* Opcode values */ +enum sli4_diseed_sge_opcodes { +DISEED_SGE_OP_IN_NODIF_OUT_CRC , +DISEED_SGE_OP_IN_CRC_OUT_NODIF , +DISEED_SGE_OP_IN_NODIF_OUT_CSUM , +DISEED_SGE_OP_IN_CSUM_OUT_NODIF , +DISEED_SGE_OP_IN_CRC_OUT_CRC , +DISEED_SGE_OP_IN_CSUM_OUT_CSUM , +DISEED_SGE_OP_IN_CRC_OUT_CSUM , +DISEED_SGE_OP_IN_CSUM_OUT_CRC , +DISEED_SGE_OP_IN_RAW_OUT_RAW , +}; + +#define DISEED_SGE_OP_RX_VALUE (stype) \ + (DISEED_SGE_OP_##stype << DISEED_SGE_OP_RX_SHIFT) +#define DISEED_SGE_OP_TX_VALUE (stype) \ + (DISEED_SGE_OP_##stype << DISEED_SGE_OP_TX_SHIFT) + +struct sli4_diseed_sge { +__le32 ref_tag_cmp; +__le32 ref_tag_repl; +__le16 app_tag_repl; +__le16 dw2w1_flags; +__le16 app_tag_cmp; +__le16 dw3w1_flags; +}; + +/* List Segment Pointer Scatter-Gather Entry (SGE) */ +#define SLI4_LSP_SGE_SEGLEN 0x00ffffff + +struct sli4_lsp_sge { +__le32 buffer_address_high; +__le32 buffer_address_low; +__le32 dw2_flags; +__le32 dw3_seglen; +}; + +enum sli4_eqe_e { +SLI4_EQE_VALID =1 , +SLI4_EQE_MJCODE =0xe , +SLI4_EQE_MNCODE =0xfff0 , +}; + +struct sli4_eqe { +__le16 dw0w0_flags; +__le16 resource_id; +}; + +#define SLI4_MAJOR_CODE_STANDARD 0 +#define SLI4_MAJOR_CODE_SENTINEL 1 + +/* Sentinel EQE indicating the EQ is full */ +#define SLI4_EQE_STATUS_EQ_FULL 2 + +enum sli4_mcqe_e { +SLI4_MCQE_CONSUMED = (1 <<27 ), +SLI4_MCQE_COMPLETED = (1 <<28 ), +SLI4_MCQE_AE = (1 <<30 ), +SLI4_MCQE_VALID = (1 <<31 ), +}; + +/* Entry was consumed but not completed */ +#define SLI4_MCQE_STATUS_NOT_COMPLETED -2 + +struct sli4_mcqe { +__le16 completion_status; +__le16 extended_status; +__le32 mqe_tag_low; +__le32 mqe_tag_high; +__le32 dw3_flags; +}; + +enum sli4_acqe_e { +SLI4_ACQE_AE = (1 <<6 ),/* async event - this is an ACQE */ +SLI4_ACQE_VAL = (1 <<7 ),/* valid - contents of CQE are valid */ +}; + +struct sli4_acqe { +__le32 event_data[3 ]; +u8 rsvd12; +u8 event_code; +u8 event_type; +u8 ae_val; +}; + +enum sli4_acqe_event_code { +SLI4_ACQE_EVENT_CODE_LINK_STATE =0x01 , +SLI4_ACQE_EVENT_CODE_FIP =0x02 , +SLI4_ACQE_EVENT_CODE_DCBX =0x03 , +SLI4_ACQE_EVENT_CODE_ISCSI =0x04 , +SLI4_ACQE_EVENT_CODE_GRP_5 =0x05 , +SLI4_ACQE_EVENT_CODE_FC_LINK_EVENT =0x10 , +SLI4_ACQE_EVENT_CODE_SLI_PORT_EVENT =0x11 , +SLI4_ACQE_EVENT_CODE_VF_EVENT =0x12 , +SLI4_ACQE_EVENT_CODE_MR_EVENT =0x13 , +}; + +enum sli4_qtype { +SLI_QTYPE_EQ , +SLI_QTYPE_CQ , +SLI_QTYPE_MQ , +SLI_QTYPE_WQ , +SLI_QTYPE_RQ , +SLI_QTYPE_MAX ,/* must be last */ +}; + +#define SLI_USER_MQ_COUNT 1 +#define SLI_MAX_CQ_SET_COUNT 16 +#define SLI_MAX_RQ_SET_COUNT 16 + +enum sli4_qentry { +SLI_QENTRY_ASYNC , +SLI_QENTRY_MQ , +SLI_QENTRY_RQ , +SLI_QENTRY_WQ , +SLI_QENTRY_WQ_RELEASE , +SLI_QENTRY_OPT_WRITE_CMD , +SLI_QENTRY_OPT_WRITE_DATA , +SLI_QENTRY_XABT , +SLI_QENTRY_MAX /* must be last */ +}; + +enum sli4_queue_flags { +/* CQ has MQ/Async completion */ +SLI4_QUEUE_FLAG_MQ = (1 <<0 ), + +/* RQ for packet headers */ +SLI4_QUEUE_FLAG_HDR = (1 <<1 ), + +/* RQ index increment by 8 */ +SLI4_QUEUE_FLAG_RQBATCH = (1 <<2 ), +}; + +struct sli4_queue { +/* Common to all queue types */
drivers/scsi/elx/libefc_sli/sli4.h struct sli4_reg { · line 504
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h +10
-0+struct efc_dma dma; +spinlock_t lock;/* protect the queue operations */ +u32 index;/* current host entry index */ +u16 size;/* entry size */ +u16 length;/* number of entries */ +u16 n_posted;/* number entries posted */ +u16 id;/* Port assigned xQ_ID */ +u16 ulp;/* ULP assigned to this queue */ +void __iomem *db_regaddr;/* register address for the doorbell */ +u8 type;/* queue type ie EQ, CQ, ... */
Alignment?
Having an u8 following a pointer is a guaranteed misalignment for the remaining entries. Also, consider casting it to the above qtype enum.
drivers/scsi/elx/libefc_sli/sli4.h struct sli4_reg { · line 514
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h +10
-0+u32 proc_limit;/* limit CQE processed per iteration */ +u32 posted_limit;/* CQE/EQE process before ring doorbel */ +u32 max_num_processed; +time_t max_process_time; +u16 phase;/* For if_type = 6, this value toggle +* for each iteration of the queue, +* a queue entry is valid when a cqe +* valid bit matches this value +*/ +
Same here. u16 between u32 is not making the cachline happy.
drivers/scsi/elx/libefc_sli/sli4.h struct sli4_reg { · line 523
Quoted 9 lines
drivers/scsi/elx/libefc_sli/sli4.h +9
-0+union { +u32 r_idx;/* "read" index (MQ only) */ +struct { +u32 dword; + } flag; + } u; +}; + +/* Generic Command Request header */
And the remainder seems to be all hardware-dependent structures.
Would it be possible to rearrange stuff so that hardware/SLI related structures are being kept separate from the software/driver dependent ones? Just so that one is clear which structures can or must mot be changed.
Cheers,
Hannes
Signature · 4 lines
Dr. Hannes Reinecke Teamlead Storage & Networking [email protected] +49 911 74053 688 SUSE Software Solutions GmbH, Maxfeldstr. 5, 90409 Nürnberg HRB 36809 (AG Nürnberg), Geschäftsführer: Felix Imendörffer
James Bottomley
maintainerRe: [PATCH v3 02/31] elx: libefc_sli: SLI Descriptors and Queue entries
Quoted 1 line · Hannes Reinecke
On 4/12/20 5:32 AM, James Smart wrote:
[...]
Quoted 13 lines
Quoted 13 lines
drivers/scsi/elx/libefc_sli/sli4.h +4
-0+struct sli4_queue { +/* Common to all queue types */ +struct efc_dma dma; +spinlock_t lock;/* protect the queue operations */
(quoted diff) +1
-0+ u32 index; /* current host entryindex */
drivers/scsi/elx/libefc_sli/sli4.h +5
-0+u16 size;/* entry size */ +u16 length;/* number of entries */ +u16 n_posted;/* number entries posted */ +u16 id;/* Port assigned xQ_ID */ +u16 ulp;/* ULP assigned to this queue */
Quoted 8 lines
Quoted 4 lines
(quoted diff) +1
-0+ void __iomem *db_regaddr; /* register addressfor the doorbell */
(quoted diff) +1
-0+ u8 type; /* queue type ieEQ, CQ, ... */
Alignment?
Having an u8 following a pointer is a guaranteed misalignment for the remaining entries.
Only for a packed structure, which this isn't.
In an ordinary structure, everything is padded to the required aligment, so you're going to waste 3 bytes here but it isn't going to be misaligned.
James
Re: [PATCH v3 02/31] elx: libefc_sli: SLI Descriptors and Queue entries
In reply to Hannes ReineckeQuoted 9 lines
And the remainder seems to be all hardware-dependent structures.
Would it be possible to rearrange stuff so that hardware/SLI related structures are being kept separate from the software/driver dependent ones? Just so that one is clear which structures can or must mot be changed.Cheers,
Hannes
Agree with the comments and will address. Will look at the header split as well.
-- james
PATCH v3 3/31 elx: libefc_sli: Data structures and defines for mbox commands
In reply to James SmartThis patch continues the libefc_sli SLI-4 library population.
This patch adds definitions for SLI-4 mailbox commands and responses.
---
v3:
Changed anonymous enums to named.
Split gaint enums into multiple enums.
Single Enum to #define
Added Link Speed defines to accommodate upto 128G SLI defines to spell out _MASK value directly. Changed multiple defines to named Enums for consistency.
--- drivers/scsi/elx/libefc_sli/sli4.h | 1677 ++++++++++++++++++++++++++++++++++++ 1 file changed, 1677 insertions(+)
drivers/scsi/elx/libefc_sli/sli4.h +1677 -0
@@ -2010,4 +2010,1681 @@ enum sli4_els_cmd_type { SLI4_ELS_REQUEST64_CMD_FABRIC = 0x0d, }; +#define SLI_PAGE_SIZE (1 << 12)/* 4096 */ +#define SLI_SUB_PAGE_MASK (SLI_PAGE_SIZE - 1) +#define SLI_ROUND_PAGE (b) (((b) + SLI_SUB_PAGE_MASK) & ~SLI_SUB_PAGE_MASK) + +#define SLI4_BMBX_TIMEOUT_MSEC 30000 +#define SLI4_FW_READY_TIMEOUT_MSEC 30000 + +#define SLI4_BMBX_DELAY_US 1000/* 1 ms */ +#define SLI4_INIT_PORT_DELAY_US 10000/* 10 ms */ + +static inline u32 +sli_page_count (size_t bytes,u32 page_size) +{ +if (!page_size) +return 0 ; + +return (bytes + (page_size -1 )) >>__ffs (page_size); +} + +/************************************************************************* +* SLI-4 mailbox command formats and definitions +*/ + +struct sli4_mbox_command_header { +u8 resvd0; +u8 command; +__le16 status;/* Port writes to indicate success/fail */ +}; + +enum sli4_mbx_cmd_value { +MBX_CMD_CONFIG_LINK =0x07 , +MBX_CMD_DUMP =0x17 , +MBX_CMD_DOWN_LINK =0x06 , +MBX_CMD_INIT_LINK =0x05 , +MBX_CMD_INIT_VFI =0xa3 , +MBX_CMD_INIT_VPI =0xa4 , +MBX_CMD_POST_XRI =0xa7 , +MBX_CMD_RELEASE_XRI =0xac , +MBX_CMD_READ_CONFIG =0x0b , +MBX_CMD_READ_STATUS =0x0e , +MBX_CMD_READ_NVPARMS =0x02 , +MBX_CMD_READ_REV =0x11 , +MBX_CMD_READ_LNK_STAT =0x12 , +MBX_CMD_READ_SPARM64 =0x8d , +MBX_CMD_READ_TOPOLOGY =0x95 , +MBX_CMD_REG_FCFI =0xa0 , +MBX_CMD_REG_FCFI_MRQ =0xaf , +MBX_CMD_REG_RPI =0x93 , +MBX_CMD_REG_RX_RQ =0xa6 , +MBX_CMD_REG_VFI =0x9f , +MBX_CMD_REG_VPI =0x96 , +MBX_CMD_RQST_FEATURES =0x9d , +MBX_CMD_SLI_CONFIG =0x9b , +MBX_CMD_UNREG_FCFI =0xa2 , +MBX_CMD_UNREG_RPI =0x14 , +MBX_CMD_UNREG_VFI =0xa1 , +MBX_CMD_UNREG_VPI =0x97 , +MBX_CMD_WRITE_NVPARMS =0x03 , +MBX_CMD_CFG_AUTO_XFER_RDY =0xAD , +}; + +enum sli4_mbx_status { +MBX_STATUS_SUCCESS =0x0000 , +MBX_STATUS_FAILURE =0x0001 , +MBX_STATUS_RPI_NOT_REG =0x1400 , +}; + +/* CONFIG_LINK */ +enum sli4_cmd_config_link_flags { +SLI4_CFG_LINK_BBSCN =0xf00 , +SLI4_CFG_LINK_CSCN =0x1000 , +}; + +struct sli4_cmd_config_link { +struct sli4_mbox_command_header hdr; +u8 maxbbc; +u8 rsvd5; +u8 rsvd6; +u8 rsvd7; +u8 alpa; +__le16 n_port_id; +u8 rsvd11; +__le32 rsvd12; +__le32 e_d_tov; +__le32 lp_tov; +__le32 r_a_tov; +__le32 r_t_tov; +__le32 al_tov; +__le32 rsvd36; +__le32 bbscn_dword; +}; + +#define SLI4_DUMP4_TYPE 0xf + +#define SLI4_WKI_TAG_SAT_TEM 0x1040 + +struct sli4_cmd_dump4 { +struct sli4_mbox_command_header hdr; +__le32 type_dword; +__le16 wki_selection; +__le16 rsvd10; +__le32 rsvd12; +__le32 returned_byte_cnt; +__le32 resp_data[59 ]; +}; + +/* INIT_LINK - initialize the link for a FC port */ +enum sli4_init_link_flags { +SLI4_INIT_LINK_F_LOOPBACK = (1 <<0 ), + +SLI4_INIT_LINK_F_P2P_ONLY = (1 <<1 ), +SLI4_INIT_LINK_F_FCAL_ONLY = (2 <<1 ), +SLI4_INIT_LINK_F_FCAL_FAIL_OVER = (0 <<1 ), +SLI4_INIT_LINK_F_P2P_FAIL_OVER = (1 <<1 ), + +SLI4_INIT_LINK_F_UNFAIR = (1 <<6 ), +SLI4_INIT_LINK_F_NO_LIRP = (1 <<7 ), +SLI4_INIT_LINK_F_LOOP_VALID_CHK = (1 <<8 ), +SLI4_INIT_LINK_F_NO_LISA = (1 <<9 ), +SLI4_INIT_LINK_F_FAIL_OVER = (1 <<10 ), +SLI4_INIT_LINK_F_FIXED_SPEED = (1 <<11 ), +SLI4_INIT_LINK_F_PICK_HI_ALPA = (1 <<15 ), + +}; + +enum sli4_fc_link_speed { +FC_LINK_SPEED_1G =1 , +FC_LINK_SPEED_2G , +FC_LINK_SPEED_AUTO_1_2 , +FC_LINK_SPEED_4G , +FC_LINK_SPEED_AUTO_4_1 , +FC_LINK_SPEED_AUTO_4_2 , +FC_LINK_SPEED_AUTO_4_2_1 , +FC_LINK_SPEED_8G , +FC_LINK_SPEED_AUTO_8_1 , +FC_LINK_SPEED_AUTO_8_2 , +FC_LINK_SPEED_AUTO_8_2_1 , +FC_LINK_SPEED_AUTO_8_4 , +FC_LINK_SPEED_AUTO_8_4_1 , +FC_LINK_SPEED_AUTO_8_4_2 , +FC_LINK_SPEED_10G , +FC_LINK_SPEED_16G , +FC_LINK_SPEED_AUTO_16_8_4 , +FC_LINK_SPEED_AUTO_16_8 , +FC_LINK_SPEED_32G , +FC_LINK_SPEED_AUTO_32_16_8 , +FC_LINK_SPEED_AUTO_32_16 , +FC_LINK_SPEED_64G , +FC_LINK_SPEED_AUTO_64_32_16 , +FC_LINK_SPEED_AUTO_64_32 , +FC_LINK_SPEED_128G , +FC_LINK_SPEED_AUTO_128_64_32 , +FC_LINK_SPEED_AUTO_128_64 , +}; + +struct sli4_cmd_init_link { +struct sli4_mbox_command_header hdr; +__le32 sel_reset_al_pa_dword; +__le32 flags0; +__le32 link_speed_sel_code; +}; + +/* INIT_VFI - initialize the VFI resource */ +enum sli4_init_vfi_flags { +SLI4_INIT_VFI_FLAG_VP =0x1000 , +SLI4_INIT_VFI_FLAG_VF =0x2000 , +SLI4_INIT_VFI_FLAG_VT =0x4000 , +SLI4_INIT_VFI_FLAG_VR =0x8000 , + +SLI4_INIT_VFI_VFID =0x1fff , +SLI4_INIT_VFI_PRI =0xe000 , + +SLI4_INIT_VFI_HOP_COUNT =0xff000000 , +}; + +struct sli4_cmd_init_vfi { +struct sli4_mbox_command_header hdr; +__le16 vfi; +__le16 flags0_word; +__le16 fcfi; +__le16 vpi; +__le32 vf_id_pri_dword; +__le32 hop_cnt_dword; +}; + +/* INIT_VPI - initialize the VPI resource */ +struct sli4_cmd_init_vpi { +struct sli4_mbox_command_header hdr; +__le16 vpi; +__le16 vfi; +}; + +/* POST_XRI - post XRI resources to the SLI Port */ +enum sli4_post_xri_flags { +SLI4_POST_XRI_COUNT =0xfff , +SLI4_POST_XRI_FLAG_ENX =0x1000 , +SLI4_POST_XRI_FLAG_DL =0x2000 , +SLI4_POST_XRI_FLAG_DI =0x4000 , +SLI4_POST_XRI_FLAG_VAL =0x8000 , +}; + +struct sli4_cmd_post_xri { +struct sli4_mbox_command_header hdr; +__le16 xri_base; +__le16 xri_count_flags; +}; + +/* RELEASE_XRI - Release XRI resources from the SLI Port */ +enum sli4_release_xri_flags { +SLI4_RELEASE_XRI_REL_XRI_CNT =0x1f , +SLI4_RELEASE_XRI_COUNT =0x1f , +}; + +struct sli4_cmd_release_xri { +struct sli4_mbox_command_header hdr; +__le16 rel_xri_count_word; +__le16 xri_count_word; + +struct { +__le16 xri_tag0; +__le16 xri_tag1; + } xri_tbl[62 ]; +}; + +/* READ_CONFIG - read SLI port configuration parameters */ +struct sli4_cmd_read_config { +struct sli4_mbox_command_header hdr; +}; + +enum sli4_read_cfg_resp_flags { +SLI4_READ_CFG_RESP_RESOURCE_EXT =0x80000000 ,/* DW1 */ +SLI4_READ_CFG_RESP_TOPOLOGY =0xff000000 ,/* DW2 */ +}; + +enum sli4_read_cfg_topo { +SLI4_READ_CFG_TOPO_FC =0x1 ,/* FC topology unknown */ +SLI4_READ_CFG_TOPO_FC_DA =0x2 ,/* FC Direct Attach */ +SLI4_READ_CFG_TOPO_FC_AL =0x3 ,/* FC-AL topology */ +}; + +struct sli4_rsp_read_config { +struct sli4_mbox_command_header hdr; +__le32 ext_dword; +__le32 topology_dword; +__le32 resvd8; +__le16 e_d_tov; +__le16 resvd14; +__le32 resvd16; +__le16 r_a_tov; +__le16 resvd22; +__le32 resvd24; +__le32 resvd28; +__le16 lmt; +__le16 resvd34; +__le32 resvd36; +__le32 resvd40; +__le16 xri_base; +__le16 xri_count; +__le16 rpi_base; +__le16 rpi_count; +__le16 vpi_base; +__le16 vpi_count; +__le16 vfi_base; +__le16 vfi_count; +__le16 resvd60; +__le16 fcfi_count; +__le16 rq_count; +__le16 eq_count; +__le16 wq_count; +__le16 cq_count; +__le32 pad[45 ]; +}; + +/* READ_NVPARMS - read SLI port configuration parameters */ +enum sli4_read_nvparms_flags { +SLI4_READ_NVPARAMS_HARD_ALPA =0xff , +SLI4_READ_NVPARAMS_PREFERRED_D_ID =0xffffff00 , +}; + +struct sli4_cmd_read_nvparms { +struct sli4_mbox_command_header hdr; +__le32 resvd0; +__le32 resvd4; +__le32 resvd8; +__le32 resvd12; +u8 wwpn[8 ]; +u8 wwnn[8 ]; +__le32 hard_alpa_d_id; +}; + +/* WRITE_NVPARMS - write SLI port configuration parameters */ +struct sli4_cmd_write_nvparms { +struct sli4_mbox_command_header hdr; +__le32 resvd0; +__le32 resvd4; +__le32 resvd8; +__le32 resvd12; +u8 wwpn[8 ]; +u8 wwnn[8 ]; +__le32 hard_alpa_d_id; +}; + +/* READ_REV - read the Port revision levels */ +enum { +SLI4_READ_REV_FLAG_SLI_LEVEL =0xf , +SLI4_READ_REV_FLAG_FCOEM =0x10 , +SLI4_READ_REV_FLAG_CEEV =0x60 , +SLI4_READ_REV_FLAG_VPD =0x2000 , + +SLI4_READ_REV_AVAILABLE_LENGTH =0xffffff , +}; + +struct sli4_cmd_read_rev { +struct sli4_mbox_command_header hdr; +__le16 resvd0; +__le16 flags0_word; +__le32 first_hw_rev; +__le32 second_hw_rev; +__le32 resvd12; +__le32 third_hw_rev; +u8 fc_ph_low; +u8 fc_ph_high; +u8 feature_level_low; +u8 feature_level_high; +__le32 resvd24; +__le32 first_fw_id; +u8 first_fw_name[16 ]; +__le32 second_fw_id; +u8 second_fw_name[16 ]; +__le32 rsvd18[30 ]; +__le32 available_length_dword; +struct sli4_dmaaddr hostbuf; +__le32 returned_vpd_length; +__le32 actual_vpd_length; +}; + +/* READ_SPARM64 - read the Port service parameters */ +#define SLI4_READ_SPARM64_WWPN_OFFSET (4 * sizeof(u32)) +#define SLI4_READ_SPARM64_WWNN_OFFSET (6 * sizeof(u32)) + +struct sli4_cmd_read_sparm64 { +struct sli4_mbox_command_header hdr; +__le32 resvd0; +__le32 resvd4; +struct sli4_bde bde_64; +__le16 vpi; +__le16 resvd22; +__le16 port_name_start; +__le16 port_name_len; +__le16 node_name_start; +__le16 node_name_len; +}; + +/* READ_TOPOLOGY - read the link event information */ +enum sli4_read_topo_e { +SLI4_READTOPO_ATTEN_TYPE =0xff , +SLI4_READTOPO_FLAG_IL =0x100 , +SLI4_READTOPO_FLAG_PB_RECVD =0x200 , + +SLI4_READTOPO_LINKSTATE_RECV =0x3 , +SLI4_READTOPO_LINKSTATE_TRANS =0xc , +SLI4_READTOPO_LINKSTATE_MACHINE =0xf0 , +SLI4_READTOPO_LINKSTATE_SPEED =0xff00 , +SLI4_READTOPO_LINKSTATE_TF =0x40000000 , +SLI4_READTOPO_LINKSTATE_LU =0x80000000 , + +SLI4_READTOPO_SCN_BBSCN =0xf , +SLI4_READTOPO_SCN_CBBSCN =0xf0 , + +SLI4_READTOPO_R_T_TOV =0x1ff , +SLI4_READTOPO_AL_TOV =0xf000 , + +SLI4_READTOPO_PB_FLAG =0x80 , + +SLI4_READTOPO_INIT_N_PORTID =0xffffff , +}; + +#define SLI4_MIN_LOOP_MAP_BYTES 128 + +struct sli4_cmd_read_topology { +struct sli4_mbox_command_header hdr; +__le32 event_tag; +__le32 dw2_attentype; +u8 topology; +u8 lip_type; +u8 lip_al_ps; +u8 al_pa_granted; +struct sli4_bde bde_loop_map; +__le32 linkdown_state; +__le32 currlink_state; +u8 max_bbc; +u8 init_bbc; +u8 scn_flags; +u8 rsvd39; +__le16 dw10w0_al_rt_tov; +__le16 lp_tov; +u8 acquired_al_pa; +u8 pb_flags; +__le16 specified_al_pa; +__le32 dw12_init_n_port_id; +}; + +enum sli4_read_topo_link { +SLI4_READ_TOPOLOGY_LINK_UP =0x1 , +SLI4_READ_TOPOLOGY_LINK_DOWN , +SLI4_READ_TOPOLOGY_LINK_NO_ALPA , +}; + +enum sli4_read_topo { +SLI4_READ_TOPOLOGY_UNKNOWN =0x0 , +SLI4_READ_TOPOLOGY_NPORT , +SLI4_READ_TOPOLOGY_FC_AL , +}; + +enum sli4_read_topo_speed { +SLI4_READ_TOPOLOGY_SPEED_NONE =0x00 , +SLI4_READ_TOPOLOGY_SPEED_1G =0x04 , +SLI4_READ_TOPOLOGY_SPEED_2G =0x08 , +SLI4_READ_TOPOLOGY_SPEED_4G =0x10 , +SLI4_READ_TOPOLOGY_SPEED_8G =0x20 , +SLI4_READ_TOPOLOGY_SPEED_10G =0x40 , +SLI4_READ_TOPOLOGY_SPEED_16G =0x80 , +SLI4_READ_TOPOLOGY_SPEED_32G =0x90 , +}; + +/* REG_FCFI - activate a FC Forwarder */ +struct sli4_cmd_reg_fcfi_rq_cfg { +u8 r_ctl_mask; +u8 r_ctl_match; +u8 type_mask; +u8 type_match; +}; + +enum sli4_regfcfi_tag { +SLI4_REGFCFI_VLAN_TAG =0xfff , +SLI4_REGFCFI_VLANTAG_VALID =0x1000 , +}; + +#define SLI4_CMD_REG_FCFI_NUM_RQ_CFG 4 +struct sli4_cmd_reg_fcfi { +struct sli4_mbox_command_header hdr; +__le16 fcf_index; +__le16 fcfi; +__le16 rqid1; +__le16 rqid0; +__le16 rqid3; +__le16 rqid2; +struct sli4_cmd_reg_fcfi_rq_cfg + rq_cfg[SLI4_CMD_REG_FCFI_NUM_RQ_CFG ]; +__le32 dw8_vlan; +}; + +#define SLI4_CMD_REG_FCFI_MRQ_NUM_RQ_CFG 4 +#define SLI4_CMD_REG_FCFI_MRQ_MAX_NUM_RQ 32 +#define SLI4_CMD_REG_FCFI_SET_FCFI_MODE 0 +#define SLI4_CMD_REG_FCFI_SET_MRQ_MODE 1 + +enum sli4_reg_fcfi_mrq { +SLI4_REGFCFI_MRQ_VLAN_TAG =0xfff , +SLI4_REGFCFI_MRQ_VLANTAG_VALID =0x1000 , +SLI4_REGFCFI_MRQ_MODE =0x2000 , + +SLI4_REGFCFI_MRQ_MASK_NUM_PAIRS =0xff , +SLI4_REGFCFI_MRQ_FILTER_BITMASK =0xf00 , +SLI4_REGFCFI_MRQ_RQ_SEL_POLICY =0xf000 , +}; + +struct sli4_cmd_reg_fcfi_mrq { +struct sli4_mbox_command_header hdr; +__le16 fcf_index; +__le16 fcfi; +__le16 rqid1; +__le16 rqid0; +__le16 rqid3; +__le16 rqid2; +struct sli4_cmd_reg_fcfi_rq_cfg + rq_cfg[SLI4_CMD_REG_FCFI_MRQ_NUM_RQ_CFG ]; +__le32 dw8_vlan; +__le32 dw9_mrqflags; +}; + +struct sli4_cmd_rq_cfg { +__le16 rq_id; +u8 r_ctl_mask; +u8 r_ctl_match; +u8 type_mask; +u8 type_match; +}; + +/* REG_RPI - register a Remote Port Indicator */ +enum sli4_reg_rpi { +SLI4_REGRPI_REMOTE_N_PORTID =0xffffff ,/* DW2 */ +SLI4_REGRPI_UPD =0x1000000 , +SLI4_REGRPI_ETOW =0x8000000 , +SLI4_REGRPI_TERP =0x20000000 , +SLI4_REGRPI_CI =0x80000000 , +}; + +struct sli4_cmd_reg_rpi { +struct sli4_mbox_command_header hdr; +__le16 rpi; +__le16 rsvd2; +__le32 dw2_rportid_flags; +struct sli4_bde bde_64; +__le16 vpi; +__le16 rsvd26; +}; + +#define SLI4_REG_RPI_BUF_LEN 0x70 + +/* REG_VFI - register a Virtual Fabric Indicator */ +enum sli_reg_vfi { +SLI4_REGVFI_VP =0x1000 ,/* DW1 */ +SLI4_REGVFI_UPD =0x2000 , + +SLI4_REGVFI_LOCAL_N_PORTID =0xffffff ,/* DW10 */ +}; + +struct sli4_cmd_reg_vfi { +struct sli4_mbox_command_header hdr; +__le16 vfi; +__le16 dw0w1_flags; +__le16 fcfi; +__le16 vpi; +u8 wwpn[8 ]; +struct sli4_bde sparm; +__le32 e_d_tov; +__le32 r_a_tov; +__le32 dw10_lportid_flags; +}; + +/* REG_VPI - register a Virtual Port Indicator */ +enum sli4_reg_vpi { +SLI4_REGVPI_LOCAL_N_PORTID =0xffffff , +SLI4_REGVPI_UPD =0x1000000 , +}; + +struct sli4_cmd_reg_vpi { +struct sli4_mbox_command_header hdr; +__le32 rsvd0; +__le32 dw2_lportid_flags; +u8 wwpn[8 ]; +__le32 rsvd12; +__le16 vpi; +__le16 vfi; +}; + +/* REQUEST_FEATURES - request / query SLI features */ +enum sli4_req_features_flags { +SLI4_REQFEAT_QRY =0x1 ,/* Dw1 */ + +SLI4_REQFEAT_IAAB = (1 <<0 ),/* DW2 & DW3 */ +SLI4_REQFEAT_NPIV = (1 <<1 ), +SLI4_REQFEAT_DIF = (1 <<2 ), +SLI4_REQFEAT_VF = (1 <<3 ), +SLI4_REQFEAT_FCPI = (1 <<4 ), +SLI4_REQFEAT_FCPT = (1 <<5 ), +SLI4_REQFEAT_FCPC = (1 <<6 ), +SLI4_REQFEAT_RSVD = (1 <<7 ), +SLI4_REQFEAT_RQD = (1 <<8 ), +SLI4_REQFEAT_IAAR = (1 <<9 ), +SLI4_REQFEAT_HLM = (1 <<10 ), +SLI4_REQFEAT_PERFH = (1 <<11 ), +SLI4_REQFEAT_RXSEQ = (1 <<12 ), +SLI4_REQFEAT_RXRI = (1 <<13 ), +SLI4_REQFEAT_DCL2 = (1 <<14 ), +SLI4_REQFEAT_RSCO = (1 <<15 ), +SLI4_REQFEAT_MRQP = (1 <<16 ), +}; + +struct sli4_cmd_request_features { +struct sli4_mbox_command_header hdr; +__le32 dw1_qry; +__le32 cmd; +__le32 resp; +}; + +/* +* SLI_CONFIG - submit a configuration command to Port +* +* Command is either embedded as part of the payload (embed) or located +* in a separate memory buffer (mem) +*/ +enum sli4_sli_config { +SLI4_SLICONF_EMB =0x1 ,/* DW1 */ +SLI4_SLICONF_PMDCMD_SHIFT =3 , +SLI4_SLICONF_PMDCMD_MASK =0xF8 , +SLI4_SLICONF_PMDCMD_VAL_1 =8 , +SLI4_SLICONF_PMDCNT =0xF8 , + +SLI4_SLICONFIG_PMD_LEN =0x00ffffff , +}; + +struct sli4_cmd_sli_config { +struct sli4_mbox_command_header hdr; +__le32 dw1_flags; +__le32 payload_len; +__le32 rsvd12[3 ]; +union { +u8 embed[58 *sizeof (u32)]; +struct sli4_bufptr mem; + } payload; +}; + +/* READ_STATUS - read tx/rx status of a particular port */ +#define SLI4_READSTATUS_CLEAR_COUNTERS 0x1 + +struct sli4_cmd_read_status { +struct sli4_mbox_command_header hdr; +__le32 dw1_flags; +__le32 rsvd4; +__le32 trans_kbyte_cnt; +__le32 recv_kbyte_cnt; +__le32 trans_frame_cnt; +__le32 recv_frame_cnt; +__le32 trans_seq_cnt; +__le32 recv_seq_cnt; +__le32 tot_exchanges_orig; +__le32 tot_exchanges_resp; +__le32 recv_p_bsy_cnt; +__le32 recv_f_bsy_cnt; +__le32 no_rq_buf_dropped_frames_cnt; +__le32 empty_rq_timeout_cnt; +__le32 no_xri_dropped_frames_cnt; +__le32 empty_xri_pool_cnt; +}; + +/* READ_LNK_STAT - read link status of a particular port */ +enum sli4_read_link_stats_flags { +SLI4_READ_LNKSTAT_REC = (1 <<0 ), +SLI4_READ_LNKSTAT_GEC = (1 <<1 ), +SLI4_READ_LNKSTAT_W02OF = (1 <<2 ), +SLI4_READ_LNKSTAT_W03OF = (1 <<3 ), +SLI4_READ_LNKSTAT_W04OF = (1 <<4 ), +SLI4_READ_LNKSTAT_W05OF = (1 <<5 ), +SLI4_READ_LNKSTAT_W06OF = (1 <<6 ), +SLI4_READ_LNKSTAT_W07OF = (1 <<7 ), +SLI4_READ_LNKSTAT_W08OF = (1 <<8 ), +SLI4_READ_LNKSTAT_W09OF = (1 <<9 ), +SLI4_READ_LNKSTAT_W10OF = (1 <<10 ), +SLI4_READ_LNKSTAT_W11OF = (1 <<11 ), +SLI4_READ_LNKSTAT_W12OF = (1 <<12 ), +SLI4_READ_LNKSTAT_W13OF = (1 <<13 ), +SLI4_READ_LNKSTAT_W14OF = (1 <<14 ), +SLI4_READ_LNKSTAT_W15OF = (1 <<15 ), +SLI4_READ_LNKSTAT_W16OF = (1 <<16 ), +SLI4_READ_LNKSTAT_W17OF = (1 <<17 ), +SLI4_READ_LNKSTAT_W18OF = (1 <<18 ), +SLI4_READ_LNKSTAT_W19OF = (1 <<19 ), +SLI4_READ_LNKSTAT_W20OF = (1 <<20 ), +SLI4_READ_LNKSTAT_W21OF = (1 <<21 ), +SLI4_READ_LNKSTAT_CLRC = (1 <<30 ), +SLI4_READ_LNKSTAT_CLOF = (1 <<31 ), +}; + +struct sli4_cmd_read_link_stats { +struct sli4_mbox_command_header hdr; +__le32 dw1_flags; +__le32 linkfail_errcnt; +__le32 losssync_errcnt; +__le32 losssignal_errcnt; +__le32 primseq_errcnt; +__le32 inval_txword_errcnt; +__le32 crc_errcnt; +__le32 primseq_eventtimeout_cnt; +__le32 elastic_bufoverrun_errcnt; +__le32 arbit_fc_al_timeout_cnt; +__le32 adv_rx_buftor_to_buf_credit; +__le32 curr_rx_buf_to_buf_credit; +__le32 adv_tx_buf_to_buf_credit; +__le32 curr_tx_buf_to_buf_credit; +__le32 rx_eofa_cnt; +__le32 rx_eofdti_cnt; +__le32 rx_eofni_cnt; +__le32 rx_soff_cnt; +__le32 rx_dropped_no_aer_cnt; +__le32 rx_dropped_no_avail_rpi_rescnt; +__le32 rx_dropped_no_avail_xri_rescnt; +}; + +/* Format a WQE with WQ_ID Association performance hint */ +static inline void +sli_set_wq_id_association (void *entry,u16 q_id) +{ +u32 *wqe = entry; + +/* +* Set Word 10, bit 0 to zero +* Set Word 10, bits 15:1 to the WQ ID +*/ + wqe[10 ] &= ~0xffff ; + wqe[10 ] |= q_id <<1 ; +} + +/* UNREG_FCFI - unregister a FCFI */ +struct sli4_cmd_unreg_fcfi { +struct sli4_mbox_command_header hdr; +__le32 rsvd0; +__le16 fcfi; +__le16 rsvd6; +}; + +/* UNREG_RPI - unregister one or more RPI */ +enum sli4_unreg_rpi { +UNREG_RPI_DP =0x2000 , +UNREG_RPI_II_SHIFT =14 , +UNREG_RPI_II_MASK =0xC000 , +UNREG_RPI_II_RPI =0x0000 , +UNREG_RPI_II_VPI =0x4000 , +UNREG_RPI_II_VFI =0x8000 , +UNREG_RPI_II_FCFI =0xC000 , + +UNREG_RPI_DEST_N_PORTID_MASK =0x00ffffff , +}; + +struct sli4_cmd_unreg_rpi { +struct sli4_mbox_command_header hdr; +__le16 index; +__le16 dw1w1_flags; +__le32 dw2_dest_n_portid; +}; + +/* UNREG_VFI - unregister one or more VFI */ +enum sli4_unreg_vfi { +UNREG_VFI_II_SHIFT =14 , +UNREG_VFI_II_MASK =0xC000 , +UNREG_VFI_II_VFI =0x0000 , +UNREG_VFI_II_FCFI =0xC000 , +}; + +struct sli4_cmd_unreg_vfi { +struct sli4_mbox_command_header hdr; +__le32 rsvd0; +__le16 index; +__le16 dw2_flags; +}; + +enum sli4_unreg_type { +SLI4_UNREG_TYPE_PORT , +SLI4_UNREG_TYPE_DOMAIN , +SLI4_UNREG_TYPE_FCF , +SLI4_UNREG_TYPE_ALL +}; + +/* UNREG_VPI - unregister one or more VPI */ +enum sli4_unreg_vpi { +UNREG_VPI_II_SHIFT =14 , +UNREG_VPI_II_MASK =0xC000 , +UNREG_VPI_II_VPI =0x0000 , +UNREG_VPI_II_VFI =0x8000 , +UNREG_VPI_II_FCFI =0xC000 , +}; + +struct sli4_cmd_unreg_vpi { +struct sli4_mbox_command_header hdr; +__le32 rsvd0; +__le16 index; +__le16 dw2w0_flags; +}; + +/* AUTO_XFER_RDY - Configure the auto-generate XFER-RDY feature */ +struct sli4_cmd_config_auto_xfer_rdy { +struct sli4_mbox_command_header hdr; +__le32 rsvd0; +__le32 max_burst_len; +}; + +#define SLI4_CONFIG_AUTO_XFERRDY_BLKSIZE 0xffff + +struct sli4_cmd_config_auto_xfer_rdy_hp { +struct sli4_mbox_command_header hdr; +__le32 rsvd0; +__le32 max_burst_len; +__le32 dw3_esoc_flags; +__le16 block_size; +__le16 rsvd14; +}; + +/************************************************************************* +* SLI-4 common configuration command formats and definitions +*/ + +/* +* Subsystem values. +*/ +enum sli4_subsystem { +SLI4_SUBSYSTEM_COMMON =0x01 , +SLI4_SUBSYSTEM_LOWLEVEL =0x0B , +SLI4_SUBSYSTEM_FC =0x0C , +SLI4_SUBSYSTEM_DMTF =0x11 , +}; + +#define SLI4_OPC_LOWLEVEL_SET_WATCHDOG 0X36 + +/* +* Common opcode (OPC) values. +*/ +enum sli4_cmn_opcode { +CMN_FUNCTION_RESET =0x3d , +CMN_CREATE_CQ =0x0c , +CMN_CREATE_CQ_SET =0x1d , +CMN_DESTROY_CQ =0x36 , +CMN_MODIFY_EQ_DELAY =0x29 , +CMN_CREATE_EQ =0x0d , +CMN_DESTROY_EQ =0x37 , +CMN_CREATE_MQ_EXT =0x5a , +CMN_DESTROY_MQ =0x35 , +CMN_GET_CNTL_ATTRIBUTES =0x20 , +CMN_NOP =0x21 , +CMN_GET_RSC_EXTENT_INFO =0x9a , +CMN_GET_SLI4_PARAMS =0xb5 , +CMN_QUERY_FW_CONFIG =0x3a , +CMN_GET_PORT_NAME =0x4d , + +CMN_WRITE_FLASHROM =0x07 , +/* TRANSCEIVER Data */ +CMN_READ_TRANS_DATA =0x49 , +CMN_GET_CNTL_ADDL_ATTRS =0x79 , +CMN_GET_FUNCTION_CFG =0xa0 , +CMN_GET_PROFILE_CFG =0xa4 , +CMN_SET_PROFILE_CFG =0xa5 , +CMN_GET_PROFILE_LIST =0xa6 , +CMN_GET_ACTIVE_PROFILE =0xa7 , +CMN_SET_ACTIVE_PROFILE =0xa8 , +CMN_READ_OBJECT =0xab , +CMN_WRITE_OBJECT =0xac , +CMN_DELETE_OBJECT =0xae , +CMN_READ_OBJECT_LIST =0xad , +CMN_SET_DUMP_LOCATION =0xb8 , +CMN_SET_FEATURES =0xbf , +CMN_GET_RECFG_LINK_INFO =0xc9 , +CMN_SET_RECNG_LINK_ID =0xca , +}; + +/* DMTF opcode (OPC) values */ +#define DMTF_EXEC_CLP_CMD 0x01 + +/* +* COMMON_FUNCTION_RESET +* +* Resets the Port, returning it to a power-on state. This configuration +* command does not have a payload and should set/expect the lengths to +* be zero. +*/ +struct sli4_rqst_cmn_function_reset { +struct sli4_rqst_hdr hdr; +}; + +struct sli4_rsp_cmn_function_reset { +struct sli4_rsp_hdr hdr; +}; + + +/* +* COMMON_GET_CNTL_ATTRIBUTES +* +* Query for information about the SLI Port +*/ +enum sli4_cntrl_attr_flags { +SLI4_CNTL_ATTR_PORTNUM =0x3f , +SLI4_CNTL_ATTR_PORTTYPE =0xc0 , +}; + +struct sli4_rsp_cmn_get_cntl_attributes { +struct sli4_rsp_hdr hdr; +u8 version_str[32 ]; +u8 manufacturer_name[32 ]; +__le32 supported_modes; +u8 eprom_version_lo; +u8 eprom_version_hi; +__le16 rsvd17; +__le32 mbx_ds_version; +__le32 ep_fw_ds_version; +u8 ncsi_version_str[12 ]; +__le32 def_extended_timeout; +u8 model_number[32 ]; +u8 description[64 ]; +u8 serial_number[32 ]; +u8 ip_version_str[32 ]; +u8 fw_version_str[32 ]; +u8 bios_version_str[32 ]; +u8 redboot_version_str[32 ]; +u8 driver_version_str[32 ]; +u8 fw_on_flash_version_str[32 ]; +__le32 functionalities_supported; +__le16 max_cdb_length; +u8 asic_revision; +u8 generational_guid0; +__le32 generational_guid1_12[3 ]; +__le16 generational_guid13_14; +u8 generational_guid15; +u8 hba_port_count; +__le16 default_link_down_timeout; +u8 iscsi_version_min_max; +u8 multifunctional_device; +u8 cache_valid; +u8 hba_status; +u8 max_domains_supported; +u8 port_num_type_flags; +__le32 firmware_post_status; +__le32 hba_mtu; +u8 iscsi_features; +u8 rsvd121[3 ]; +__le16 pci_vendor_id; +__le16 pci_device_id; +__le16 pci_sub_vendor_id; +__le16 pci_sub_system_id; +u8 pci_bus_number; +u8 pci_device_number; +u8 pci_function_number; +u8 interface_type; +__le64 unique_identifier; +u8 number_of_netfilters; +u8 rsvd122[3 ]; +}; + +/* +* COMMON_GET_CNTL_ATTRIBUTES +* +* This command queries the controller information from the Flash ROM. +*/ +struct sli4_rqst_cmn_get_cntl_addl_attributes { +struct sli4_rqst_hdr hdr; +}; + +struct sli4_rsp_cmn_get_cntl_addl_attributes { +struct sli4_rsp_hdr hdr; +__le16 ipl_file_number; +u8 ipl_file_version; +u8 rsvd4; +u8 on_die_temperature; +u8 rsvd5[3 ]; +__le32 driver_advanced_features_supported; +__le32 rsvd7[4 ]; +char universal_bios_version[32 ]; +char x86_bios_version[32 ]; +char efi_bios_version[32 ]; +char fcode_version[32 ]; +char uefi_bios_version[32 ]; +char uefi_nic_version[32 ]; +char uefi_fcode_version[32 ]; +char uefi_iscsi_version[32 ]; +char iscsi_x86_bios_version[32 ]; +char pxe_x86_bios_version[32 ]; +u8 default_wwpn[8 ]; +u8 ext_phy_version[32 ]; +u8 fc_universal_bios_version[32 ]; +u8 fc_x86_bios_version[32 ]; +u8 fc_efi_bios_version[32 ]; +u8 fc_fcode_version[32 ]; +u8 ext_phy_crc_label[8 ]; +u8 ipl_file_name[16 ]; +u8 rsvd139[72 ]; +}; + +/* +* COMMON_NOP +* +* This command does not do anything; it only returns +* the payload in the completion. +*/ +struct sli4_rqst_cmn_nop { +struct sli4_rqst_hdr hdr; +__le32 context[2 ]; +}; + +struct sli4_rsp_cmn_nop { +struct sli4_rsp_hdr hdr; +__le32 context[2 ]; +}; + +struct sli4_rqst_cmn_get_resource_extent_info { +struct sli4_rqst_hdr hdr; +__le16 resource_type; +__le16 rsvd16; +}; + +enum sli4_rsc_type { +SLI4_RSC_TYPE_VFI =0x20 , +SLI4_RSC_TYPE_VPI =0x21 , +SLI4_RSC_TYPE_RPI =0x22 , +SLI4_RSC_TYPE_XRI =0x23 , +}; + +struct sli4_rsp_cmn_get_resource_extent_info { +struct sli4_rsp_hdr hdr; +__le16 resource_extent_count; +__le16 resource_extent_size; +}; + +#define SLI4_128BYTE_WQE_SUPPORT 0x02 + +#define GET_Q_CNT_METHOD (m) \ + (((m) & RSP_GET_PARAM_Q_CNT_MTHD_MASK) >> RSP_GET_PARAM_Q_CNT_MTHD_SHFT) +#define GET_Q_CREATE_VERSION (v) \ + (((v) & RSP_GET_PARAM_QV_MASK) >> RSP_GET_PARAM_QV_SHIFT) + +enum sli4_rsp_get_params_e { +/*GENERIC*/ +RSP_GET_PARAM_Q_CNT_MTHD_SHFT =24 , +RSP_GET_PARAM_Q_CNT_MTHD_MASK = (0xF <<24 ), +RSP_GET_PARAM_QV_SHIFT =14 , +RSP_GET_PARAM_QV_MASK = (3 <<14 ), + +/* DW4 */ +RSP_GET_PARAM_PROTO_TYPE_MASK =0xFF , +/* DW5 */ +RSP_GET_PARAM_FT = (1 <<0 ), +RSP_GET_PARAM_SLI_REV_MASK = (0xF <<4 ), +RSP_GET_PARAM_SLI_FAM_MASK = (0xF <<8 ), +RSP_GET_PARAM_IF_TYPE_MASK = (0xF <<12 ), +RSP_GET_PARAM_SLI_HINT1_MASK = (0xFF <<16 ), +RSP_GET_PARAM_SLI_HINT2_MASK = (0x1F <<24 ), +/* DW6 */ +RSP_GET_PARAM_EQ_PAGE_CNT_MASK = (0xF <<0 ), +RSP_GET_PARAM_EQE_SZS_MASK = (0xF <<8 ), +RSP_GET_PARAM_EQ_PAGE_SZS_MASK = (0xFF <<16 ), +/* DW8 */ +RSP_GET_PARAM_CQ_PAGE_CNT_MASK = (0xF <<0 ), +RSP_GET_PARAM_CQE_SZS_MASK = (0xF <<8 ), +RSP_GET_PARAM_CQ_PAGE_SZS_MASK = (0xFF <<16 ), +/* DW10 */ +RSP_GET_PARAM_MQ_PAGE_CNT_MASK = (0xF <<0 ), +RSP_GET_PARAM_MQ_PAGE_SZS_MASK = (0xFF <<16 ), +/* DW12 */ +RSP_GET_PARAM_WQ_PAGE_CNT_MASK = (0xF <<0 ), +RSP_GET_PARAM_WQE_SZS_MASK = (0xF <<8 ), +RSP_GET_PARAM_WQ_PAGE_SZS_MASK = (0xFF <<16 ), +/* DW14 */ +RSP_GET_PARAM_RQ_PAGE_CNT_MASK = (0xF <<0 ), +RSP_GET_PARAM_RQE_SZS_MASK = (0xF <<8 ), +RSP_GET_PARAM_RQ_PAGE_SZS_MASK = (0xFF <<16 ), +/* DW15W1*/ +RSP_GET_PARAM_RQ_DB_WINDOW_MASK =0xF000 , +/* DW16 */ +RSP_GET_PARAM_FC = (1 <<0 ), +RSP_GET_PARAM_EXT = (1 <<1 ), +RSP_GET_PARAM_HDRR = (1 <<2 ), +RSP_GET_PARAM_SGLR = (1 <<3 ), +RSP_GET_PARAM_FBRR = (1 <<4 ), +RSP_GET_PARAM_AREG = (1 <<5 ), +RSP_GET_PARAM_TGT = (1 <<6 ), +RSP_GET_PARAM_TERP = (1 <<7 ), +RSP_GET_PARAM_ASSI = (1 <<8 ), +RSP_GET_PARAM_WCHN = (1 <<9 ), +RSP_GET_PARAM_TCCA = (1 <<10 ), +RSP_GET_PARAM_TRTY = (1 <<11 ), +RSP_GET_PARAM_TRIR = (1 <<12 ), +RSP_GET_PARAM_PHOFF = (1 <<13 ), +RSP_GET_PARAM_PHON = (1 <<14 ), +RSP_GET_PARAM_PHWQ = (1 <<15 ), +RSP_GET_PARAM_BOUND_4GA = (1 <<16 ), +RSP_GET_PARAM_RXC = (1 <<17 ), +RSP_GET_PARAM_HLM = (1 <<18 ), +RSP_GET_PARAM_IPR = (1 <<19 ), +RSP_GET_PARAM_RXRI = (1 <<20 ), +RSP_GET_PARAM_SGLC = (1 <<21 ), +RSP_GET_PARAM_TIMM = (1 <<22 ), +RSP_GET_PARAM_TSMM = (1 <<23 ), +RSP_GET_PARAM_OAS = (1 <<25 ), +RSP_GET_PARAM_LC = (1 <<26 ), +RSP_GET_PARAM_AGXF = (1 <<27 ), +RSP_GET_PARAM_LOOPBACK_MASK = (0xF <<28 ), +/* DW18 */ +RSP_GET_PARAM_SGL_PAGE_CNT_MASK = (0xF <<0 ), +RSP_GET_PARAM_SGL_PAGE_SZS_MASK = (0xFF <<8 ), +RSP_GET_PARAM_SGL_PP_ALIGN_MASK = (0xFF <<16 ), +}; + +struct sli4_rqst_cmn_get_sli4_params { +struct sli4_rqst_hdr hdr; +}; + +struct sli4_rsp_cmn_get_sli4_params { +struct sli4_rsp_hdr hdr; +__le32 dw4_protocol_type; +__le32 dw5_sli; +__le32 dw6_eq_page_cnt; +__le16 eqe_count_mask; +__le16 rsvd26; +__le32 dw8_cq_page_cnt; +__le16 cqe_count_mask; +__le16 rsvd34; +__le32 dw10_mq_page_cnt; +__le16 mqe_count_mask; +__le16 rsvd42; +__le32 dw12_wq_page_cnt; +__le16 wqe_count_mask; +__le16 rsvd50; +__le32 dw14_rq_page_cnt; +__le16 rqe_count_mask; +__le16 dw15w1_rq_db_window; +__le32 dw16_loopback_scope; +__le32 sge_supported_length; +__le32 dw18_sgl_page_cnt; +__le16 min_rq_buffer_size; +__le16 rsvd75; +__le32 max_rq_buffer_size; +__le16 physical_xri_max; +__le16 physical_rpi_max; +__le16 physical_vpi_max; +__le16 physical_vfi_max; +__le32 rsvd88; +__le16 frag_num_field_offset; +__le16 frag_num_field_size; +__le16 sgl_index_field_offset; +__le16 sgl_index_field_size; +__le32 chain_sge_initial_value_lo; +__le32 chain_sge_initial_value_hi; +}; + +/* +* COMMON_QUERY_FW_CONFIG +* +* This command retrieves firmware configuration parameters and adapter +* resources available to the driver. +*/ +struct sli4_rqst_cmn_query_fw_config { +struct sli4_rqst_hdr hdr; +}; + +struct sli4_rsp_cmn_query_fw_config { +struct sli4_rsp_hdr hdr; +__le32 config_number; +__le32 asic_rev; +__le32 physical_port; +__le32 function_mode; +__le32 ulp0_mode; +__le32 ulp0_nic_wqid_base; +__le32 ulp0_nic_wq_total;/* DW10 */ +__le32 ulp0_toe_wqid_base; +__le32 ulp0_toe_wq_total; +__le32 ulp0_toe_rqid_base; +__le32 ulp0_toe_rq_total; +__le32 ulp0_toe_defrqid_base; +__le32 ulp0_toe_defrq_total; +__le32 ulp0_lro_rqid_base; +__le32 ulp0_lro_rq_total; +__le32 ulp0_iscsi_icd_base; +__le32 ulp0_iscsi_icd_total;/* DW20 */ +__le32 ulp1_mode; +__le32 ulp1_nic_wqid_base; +__le32 ulp1_nic_wq_total; +__le32 ulp1_toe_wqid_base; +__le32 ulp1_toe_wq_total; +__le32 ulp1_toe_rqid_base; +__le32 ulp1_toe_rq_total; +__le32 ulp1_toe_defrqid_base; +__le32 ulp1_toe_defrq_total; +__le32 ulp1_lro_rqid_base;/* DW30 */ +__le32 ulp1_lro_rq_total; +__le32 ulp1_iscsi_icd_base; +__le32 ulp1_iscsi_icd_total; +__le32 function_capabilities; +__le32 ulp0_cq_base; +__le32 ulp0_cq_total; +__le32 ulp0_eq_base; +__le32 ulp0_eq_total; +__le32 ulp0_iscsi_chain_icd_base; +__le32 ulp0_iscsi_chain_icd_total;/* DW40 */ +__le32 ulp1_iscsi_chain_icd_base; +__le32 ulp1_iscsi_chain_icd_total; +}; + +/*Port Types*/ +enum sli4_port_types { +PORT_TYPE_ETH =0 , +PORT_TYPE_FC =1 , +}; + +struct sli4_rqst_cmn_get_port_name { +struct sli4_rqst_hdr hdr; +u8 port_type; +u8 rsvd4[3 ]; +}; + +struct sli4_rsp_cmn_get_port_name { +struct sli4_rsp_hdr hdr; +char port_name[4 ]; +}; + +struct sli4_rqst_cmn_write_flashrom { +struct sli4_rqst_hdr hdr; +__le32 flash_rom_access_opcode; +__le32 flash_rom_access_operation_type; +__le32 data_buffer_size; +__le32 offset; +u8 data_buffer[4 ]; +}; + +/* +* COMMON_READ_TRANSCEIVER_DATA +* +* This command reads SFF transceiver data(Format is defined +* by the SFF-8472 specification). +*/ +struct sli4_rqst_cmn_read_transceiver_data { +struct sli4_rqst_hdr hdr; +__le32 page_number; +__le32 port; +}; + +struct sli4_rsp_cmn_read_transceiver_data { +struct sli4_rsp_hdr hdr; +__le32 page_number; +__le32 port; +u8 page_data[128 ]; +u8 page_data_2[128 ]; +}; + +#define SLI4_REQ_DESIRE_READLEN 0xFFFFFF + +struct sli4_rqst_cmn_read_object { +struct sli4_rqst_hdr hdr; +__le32 desired_read_length_dword; +__le32 read_offset; +u8 object_name[104 ]; +__le32 host_buffer_descriptor_count; +struct sli4_bde host_buffer_descriptor[0 ]; +}; + +#define RSP_COM_READ_OBJ_EOF 0x80000000 + +struct sli4_rsp_cmn_read_object { +struct sli4_rsp_hdr hdr; +__le32 actual_read_length; +__le32 eof_dword; +}; + +enum sli4_rqst_write_object_flags { +SLI4_RQ_DES_WRITE_LEN =0xFFFFFF , +SLI4_RQ_DES_WRITE_LEN_NOC =0x40000000 , +SLI4_RQ_DES_WRITE_LEN_EOF =0x80000000 , +}; + +struct sli4_rqst_cmn_write_object { +struct sli4_rqst_hdr hdr; +__le32 desired_write_len_dword; +__le32 write_offset; +u8 object_name[104 ]; +__le32 host_buffer_descriptor_count; +struct sli4_bde host_buffer_descriptor[0 ]; +}; + +#define RSP_CHANGE_STATUS 0xFF + +struct sli4_rsp_cmn_write_object { +struct sli4_rsp_hdr hdr; +__le32 actual_write_length; +__le32 change_status_dword; +}; + +struct sli4_rqst_cmn_delete_object { +struct sli4_rqst_hdr hdr; +__le32 rsvd4; +__le32 rsvd5; +u8 object_name[104 ]; +}; + +#define SLI4_RQ_OBJ_LIST_READ_LEN 0xFFFFFF + +struct sli4_rqst_cmn_read_object_list { +struct sli4_rqst_hdr hdr; +__le32 desired_read_length_dword; +__le32 read_offset; +u8 object_name[104 ]; +__le32 host_buffer_descriptor_count; +struct sli4_bde host_buffer_descriptor[0 ]; +}; + +enum sli4_rqst_set_dump_flags { +SLI4_CMN_SET_DUMP_BUFFER_LEN =0xFFFFFF , +SLI4_CMN_SET_DUMP_FDB =0x20000000 , +SLI4_CMN_SET_DUMP_BLP =0x40000000 , +SLI4_CMN_SET_DUMP_QRY =0x80000000 , +}; + +struct sli4_rqst_cmn_set_dump_location { +struct sli4_rqst_hdr hdr; +__le32 buffer_length_dword; +__le32 buf_addr_low; +__le32 buf_addr_high; +}; + +struct sli4_rsp_cmn_set_dump_location { +struct sli4_rsp_hdr hdr; +__le32 buffer_length_dword; +}; + +enum sli4_dump_level { +SLI4_DUMP_LEVEL_NONE , +SLI4_CHIP_LEVEL_DUMP , +SLI4_FUNC_DESC_DUMP , +}; + +enum sli4_dump_state { +SLI4_DUMP_STATE_NONE , +SLI4_CHIP_DUMP_STATE_VALID , +SLI4_FUNC_DUMP_STATE_VALID , +}; + +enum sli4_dump_status { +SLI4_DUMP_READY_STATUS_NOT_READY , +SLI4_DUMP_READY_STATUS_DD_PRESENT , +SLI4_DUMP_READY_STATUS_FDB_PRESENT , +SLI4_DUMP_READY_STATUS_SKIP_DUMP , +SLI4_DUMP_READY_STATUS_FAILED =-1 , +}; + +enum sli4_set_features { +SLI4_SET_FEATURES_DIF_SEED =0x01 , +SLI4_SET_FEATURES_XRI_TIMER =0x03 , +SLI4_SET_FEATURES_MAX_PCIE_SPEED =0x04 , +SLI4_SET_FEATURES_FCTL_CHECK =0x05 , +SLI4_SET_FEATURES_FEC =0x06 , +SLI4_SET_FEATURES_PCIE_RECV_DETECT =0x07 , +SLI4_SET_FEATURES_DIF_MEMORY_MODE =0x08 , +SLI4_SET_FEATURES_DISABLE_SLI_PORT_PAUSE_STATE =0x09 , +SLI4_SET_FEATURES_ENABLE_PCIE_OPTIONS =0x0A , +SLI4_SET_FEAT_CFG_AUTO_XFER_RDY_T10PI =0x0C , +SLI4_SET_FEATURES_ENABLE_MULTI_RECEIVE_QUEUE =0x0D , +SLI4_SET_FEATURES_SET_FTD_XFER_HINT =0x0F , +SLI4_SET_FEATURES_SLI_PORT_HEALTH_CHECK =0x11 , +}; + +struct sli4_rqst_cmn_set_features { +struct sli4_rqst_hdr hdr; +__le32 feature; +__le32 param_len; +__le32 params[8 ]; +}; + +struct sli4_rqst_cmn_set_features_dif_seed { +__le16 seed; +__le16 rsvd16; +}; + +enum sli4_rqst_set_mrq_features { +SLI4_RQ_MULTIRQ_ISR =0x1 , +SLI4_RQ_MULTIRQ_AUTOGEN_XFER_RDY =0x2 , + +SLI4_RQ_MULTIRQ_NUM_RQS =0xFF , +SLI4_RQ_MULTIRQ_RQ_SELECT =0xF00 , +}; + +struct sli4_rqst_cmn_set_features_multirq { +__le32 auto_gen_xfer_dword; +__le32 num_rqs_dword; +}; + +enum sli4_rqst_health_check_flags { +SLI4_RQ_HEALTH_CHECK_ENABLE =0x1 , +SLI4_RQ_HEALTH_CHECK_QUERY =0x2 , +}; + +struct sli4_rqst_cmn_set_features_health_check { +__le32 health_check_dword; +}; + +struct sli4_rqst_cmn_set_features_set_fdt_xfer_hint { +__le32 fdt_xfer_hint; +}; + +struct sli4_rqst_dmtf_exec_clp_cmd { +struct sli4_rqst_hdr hdr; +__le32 cmd_buf_length; +__le32 resp_buf_length; +__le32 cmd_buf_addr_low; +__le32 cmd_buf_addr_high; +__le32 resp_buf_addr_low; +__le32 resp_buf_addr_high; +}; + +struct sli4_rsp_dmtf_exec_clp_cmd { +struct sli4_rsp_hdr hdr; +__le32 rsvd4; +__le32 resp_length; +__le32 rsvd6; +__le32 rsvd7; +__le32 rsvd8; +__le32 rsvd9; +__le32 clp_status; +__le32 clp_detailed_status; +}; + +#define SLI4_PROTOCOL_FC 0x10 +#define SLI4_PROTOCOL_DEFAULT 0xff + +struct sli4_rspource_descriptor_v1 { +u8 descriptor_type; +u8 descriptor_length; +__le16 rsvd16; +__le32 type_specific[0 ]; +}; + +enum sli4_pcie_desc_flags { +SLI4_PCIE_DESC_IMM =0x4000 , +SLI4_PCIE_DESC_NOSV =0x8000 , + +SLI4_PCIE_DESC_PF_NO =0x3FF0000 , + +SLI4_PCIE_DESC_MISSN_ROLE =0xFF , +SLI4_PCIE_DESC_PCHG =0x8000000 , +SLI4_PCIE_DESC_SCHG =0x10000000 , +SLI4_PCIE_DESC_XCHG =0x20000000 , +SLI4_PCIE_DESC_XROM =0xC0000000 +}; + +struct sli4_pcie_resource_descriptor_v1 { +u8 descriptor_type; +u8 descriptor_length; +__le16 imm_nosv_dword; +__le32 pf_number_dword; +__le32 rsvd3; +u8 sriov_state; +u8 pf_state; +u8 pf_type; +u8 rsvd4; +__le16 number_of_vfs; +__le16 rsvd5; +__le32 mission_roles_dword; +__le32 rsvd7[16 ]; +}; + +struct sli4_rqst_cmn_get_function_config { +struct sli4_rqst_hdr hdr; +}; + +struct sli4_rsp_cmn_get_function_config { +struct sli4_rsp_hdr hdr; +__le32 desc_count; +__le32 desc[54 ]; +}; + +/* Link Config Descriptor for link config functions */ +struct sli4_link_config_descriptor { +u8 link_config_id; +u8 rsvd1[3 ]; +__le32 config_description[8 ]; +}; + +#define MAX_LINK_DES 10 + +struct sli4_rqst_cmn_get_reconfig_link_info { +struct sli4_rqst_hdr hdr; +}; + +struct sli4_rsp_cmn_get_reconfig_link_info { +struct sli4_rsp_hdr hdr; +u8 active_link_config_id; +u8 rsvd17; +u8 next_link_config_id; +u8 rsvd19; +__le32 link_configuration_descriptor_count; +struct sli4_link_config_descriptor + desc[MAX_LINK_DES ]; +}; + +enum sli4_set_reconfig_link_flags { +SLI4_SET_RECONFIG_LINKID_NEXT =0xff , +SLI4_SET_RECONFIG_LINKID_FD = (1 <<31 ), +}; + +struct sli4_rqst_cmn_set_reconfig_link_id { +struct sli4_rqst_hdr hdr; +__le32 dw4_flags; +}; + +struct sli4_rsp_cmn_set_reconfig_link_id { +struct sli4_rsp_hdr hdr; +}; + +struct sli4_rqst_lowlevel_set_watchdog { +struct sli4_rqst_hdr hdr; +__le16 watchdog_timeout; +__le16 rsvd18; +}; + +struct sli4_rsp_lowlevel_set_watchdog { +struct sli4_rsp_hdr hdr; +__le32 rsvd; +}; + +/* FC opcode (OPC) values */ +enum sli4_fc_opcodes { +SLI4_OPC_WQ_CREATE =0x1 , +SLI4_OPC_WQ_DESTROY =0x2 , +SLI4_OPC_POST_SGL_PAGES =0x3 , +SLI4_OPC_RQ_CREATE =0x5 , +SLI4_OPC_RQ_DESTROY =0x6 , +SLI4_OPC_READ_FCF_TABLE =0x8 , +SLI4_OPC_POST_HDR_TEMPLATES =0xb , +SLI4_OPC_REDISCOVER_FCF =0x10 , +}; + +/* Use the default CQ associated with the WQ */ +#define SLI4_CQ_DEFAULT 0xffff + +/* +* POST_SGL_PAGES +* +* Register the scatter gather list (SGL) memory and +* associate it with an XRI. +*/ +struct sli4_rqst_post_sgl_pages { +struct sli4_rqst_hdr hdr; +__le16 xri_start; +__le16 xri_count; +struct { +__le32 page0_low; +__le32 page0_high; +__le32 page1_low; +__le32 page1_high; + } page_set[10 ]; +}; + +struct sli4_rsp_post_sgl_pages { +struct sli4_rsp_hdr hdr; +}; + +struct sli4_rqst_post_hdr_templates { +struct sli4_rqst_hdr hdr; +__le16 rpi_offset; +__le16 page_count; +struct sli4_dmaaddr page_descriptor[0 ]; +}; + +#define SLI4_HDR_TEMPLATE_SIZE 64 + +enum sli4_io_flags { +/* The XRI associated with this IO is already active */ +SLI4_IO_CONTINUATION = (1 <<0 ), +/* Automatically generate a good RSP frame */ +SLI4_IO_AUTO_GOOD_RESPONSE = (1 <<1 ), +SLI4_IO_NO_ABORT = (1 <<2 ), +/* Set the DNRX bit because no auto xref rdy buffer is posted */ +SLI4_IO_DNRX = (1 <<3 ), +}; + +enum sli4_callback { +SLI4_CB_LINK , +SLI4_CB_MAX , +}; + +enum sli4_link_status { +SLI_LINK_STATUS_UP , +SLI_LINK_STATUS_DOWN , +SLI_LINK_STATUS_NO_ALPA , +SLI_LINK_STATUS_MAX , +}; + +enum sli4_link_topology { +SLI_LINK_TOPO_NPORT =1 , +SLI_LINK_TOPO_LOOP , +SLI_LINK_TOPO_LOOPBACK_INTERNAL , +SLI_LINK_TOPO_LOOPBACK_EXTERNAL , +SLI_LINK_TOPO_NONE , +SLI_LINK_TOPO_MAX , +}; + +enum sli4_link_medium { +SLI_LINK_MEDIUM_ETHERNET , +SLI_LINK_MEDIUM_FC , +SLI_LINK_MEDIUM_MAX , +}; + +/*Driver specific structures*/ + +struct sli4_link_event { +enum sli4_link_status status; +enum sli4_link_topology topology; +enum sli4_link_medium medium; +u32 speed; +u8 *loop_map; +u32 fc_id; +}; + +enum sli4_resource { +SLI_RSRC_VFI , +SLI_RSRC_VPI , +SLI_RSRC_RPI , +SLI_RSRC_XRI , +SLI_RSRC_FCFI , +SLI_RSRC_MAX , +}; + +struct sli4_extent { +u32 number; +u32 size; +u32 n_alloc; +u32 *base; +unsigned long *use_map; +u32 map_size; +}; + +struct sli4_queue_info { +u16 max_qcount[SLI_QTYPE_MAX ]; +u32 max_qentries[SLI_QTYPE_MAX ]; +u16 count_mask[SLI_QTYPE_MAX ]; +u16 count_method[SLI_QTYPE_MAX ]; +u32 qpage_count[SLI_QTYPE_MAX ]; +}; + +#define SLI_PCI_MAX_REGS 6 +struct sli4 { +void *os; +struct pci_dev *pcidev; +void __iomem *reg[SLI_PCI_MAX_REGS ]; + +u32 sli_rev; +u32 sli_family; +u32 if_type; + +u16 asic_type; +u16 asic_rev; + +u16 e_d_tov; +u16 r_a_tov; +struct sli4_queue_info qinfo; +u16 link_module_type; +u8 rq_batch; +u16 rq_min_buf_size; +u32 rq_max_buf_size; +u8 topology; +u8 wwpn[8 ]; +u8 wwnn[8 ]; +u32 fw_rev[2 ]; +u8 fw_name[2 ][16 ]; +char ipl_name[16 ]; +u32 hw_rev[3 ]; +u8 port_number; +char port_name[2 ]; +char modeldesc[64 ]; +char bios_version_string[32 ]; +/* +* Tracks the port resources using extents metaphor. For +* devices that don't implement extents (i.e. +* has_extents == FALSE), the code models each resource as +* a single large extent. +*/ +struct sli4_extent extent[SLI_RSRC_MAX ]; +u32 features; +u32 has_extents:1 , + auto_reg:1 , + auto_xfer_rdy:1 , + hdr_template_req:1 , + perf_hint:1 , + perf_wq_id_association:1 , + cq_create_version:2 , + mq_create_version:2 , + high_login_mode:1 , + sgl_pre_registered:1 , + sgl_pre_registration_required:1 , + t10_dif_inline_capable:1 , + t10_dif_separate_capable:1 ; +u32 sge_supported_length; +u32 sgl_page_sizes; +u32 max_sgl_pages; +u32 wqe_size; + +/* +* Callback functions +*/ +int (*link)(void *ctx,void *event); +void *link_arg; + +struct efc_dma bmbx; + +/* Save pointer to physical memory descriptor for non-embedded +* SLI_CONFIG commands for BMBX dumping purposes +*/ +struct efc_dma *bmbx_non_emb_pmd; + +struct efc_dma vpd_data; +u32 vpd_length; +}; +#endif /* !_SLI4_H */
Signature · 1 line
2.16.4
Re: [PATCH v3 03/31] elx: libefc_sli: Data structures and defines for mbox commands
Hi,
Quoted 25 lines · James Smart
This patch continues the
libefc_sliSLI-4 library population.This patch adds definitions for SLI-4 mailbox commands and responses.
Signed-off-by Ram Vegesna <[email protected]>Signed-off-by James Smart <[email protected]>---
v3:
Changed anonymous enums to named.
Split gaint enums into multiple enums.
Single Enum to #define
Added Link Speed defines to accommodate upto 128G SLI defines to spell out_MASKvalue directly. Changed multiple defines to named Enums for consistency.--- drivers/scsi/elx/libefc_sli/sli4.h | 1677 ++++++++++++++++++++++++++++++++++++ 1 file changed, 1677 insertions(+)drivers/scsi/elx/libefc_sli/sli4.h +0
-0
drivers/scsi/elx/libefc_sli/sli4.h enum sli4_els_cmd_type { · line 2013
Quoted 4 lines
drivers/scsi/elx/libefc_sli/sli4.h +1
-0@@ -2010,4 +2010,1681 @@ enum sli4_els_cmd_type { SLI4_ELS_REQUEST64_CMD_FABRIC = 0x0d, }; +#define SLI_PAGE_SIZE (1 << 12)/* 4096 */
Could you add a comment why you need this definitionw and why it's not PAGE_SIZE? From starring at the code I think it has someting todo with SLI4_RQ_PAGE_SIZE_4096, but it's definitly not obvious for me how those address calculation work.
drivers/scsi/elx/libefc_sli/sli4.h enum sli4_els_cmd_type { · line 2015
Quoted 2 lines
drivers/scsi/elx/libefc_sli/sli4.h +2
-0+#define SLI_SUB_PAGE_MASK (SLI_PAGE_SIZE - 1) +#define SLI_ROUND_PAGE (b) (((b) + SLI_SUB_PAGE_MASK) & ~SLI_SUB_PAGE_MASK)
Couldn't you use round_up() instead defining SLI_SUB_PAGE_MASK and SLI_ROUND_PAGE?
Quoted 45 lines
drivers/scsi/elx/libefc_sli/sli4.h +45
-0+#define SLI4_BMBX_TIMEOUT_MSEC 30000 +#define SLI4_FW_READY_TIMEOUT_MSEC 30000 + +#define SLI4_BMBX_DELAY_US 1000/* 1 ms */ +#define SLI4_INIT_PORT_DELAY_US 10000/* 10 ms */ + +static inline u32 +sli_page_count (size_t bytes,u32 page_size) +{ +if (!page_size) +return 0 ; + +return (bytes + (page_size -1 )) >>__ffs (page_size); +} + +/************************************************************************* +* SLI-4 mailbox command formats and definitions +*/ + +struct sli4_mbox_command_header { +u8 resvd0; +u8 command; +__le16 status;/* Port writes to indicate success/fail */ +}; + +enum sli4_mbx_cmd_value { +MBX_CMD_CONFIG_LINK =0x07 , +MBX_CMD_DUMP =0x17 , +MBX_CMD_DOWN_LINK =0x06 , +MBX_CMD_INIT_LINK =0x05 , +MBX_CMD_INIT_VFI =0xa3 , +MBX_CMD_INIT_VPI =0xa4 , +MBX_CMD_POST_XRI =0xa7 , +MBX_CMD_RELEASE_XRI =0xac , +MBX_CMD_READ_CONFIG =0x0b , +MBX_CMD_READ_STATUS =0x0e , +MBX_CMD_READ_NVPARMS =0x02 , +MBX_CMD_READ_REV =0x11 , +MBX_CMD_READ_LNK_STAT =0x12 , +MBX_CMD_READ_SPARM64 =0x8d , +MBX_CMD_READ_TOPOLOGY =0x95 , +MBX_CMD_REG_FCFI =0xa0 , +MBX_CMD_REG_FCFI_MRQ =0xaf , +MBX_CMD_REG_RPI =0x93 , +MBX_CMD_REG_RX_RQ =0xa6 ,
drivers/scsi/elx/libefc_sli/sli4.h enum sli4_els_cmd_type { · line 2071
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h +10
-0+MBX_CMD_REG_VFI =0x9f , +MBX_CMD_REG_VPI =0x96 , +MBX_CMD_RQST_FEATURES =0x9d , +MBX_CMD_SLI_CONFIG =0x9b , +MBX_CMD_UNREG_FCFI =0xa2 , +MBX_CMD_UNREG_RPI =0x14 , +MBX_CMD_UNREG_VFI =0xa1 , +MBX_CMD_UNREG_VPI =0x97 , +MBX_CMD_WRITE_NVPARMS =0x03 , + MBX_CMD_CFG_AUTO_XFER_RDY = 0xAD,
s/0xAD/0xad/
drivers/scsi/elx/libefc_sli/sli4.h enum sli4_els_cmd_type { · line 2080
Quoted 9 lines
drivers/scsi/elx/libefc_sli/sli4.h +9
-0+}; + +enum sli4_mbx_status { +MBX_STATUS_SUCCESS =0x0000 , +MBX_STATUS_FAILURE =0x0001 , +MBX_STATUS_RPI_NOT_REG =0x1400 , +}; + +/* CONFIG_LINK */
This is not a Kconfig CONFIG flag, correct? Maybe make the comment a bit more verbose explaining what it means.
Quoted 267 lines
drivers/scsi/elx/libefc_sli/sli4.h +267
-0+enum sli4_cmd_config_link_flags { +SLI4_CFG_LINK_BBSCN =0xf00 , +SLI4_CFG_LINK_CSCN =0x1000 , +}; + +struct sli4_cmd_config_link { +struct sli4_mbox_command_header hdr; +u8 maxbbc; +u8 rsvd5; +u8 rsvd6; +u8 rsvd7; +u8 alpa; +__le16 n_port_id; +u8 rsvd11; +__le32 rsvd12; +__le32 e_d_tov; +__le32 lp_tov; +__le32 r_a_tov; +__le32 r_t_tov; +__le32 al_tov; +__le32 rsvd36; +__le32 bbscn_dword; +}; + +#define SLI4_DUMP4_TYPE 0xf + +#define SLI4_WKI_TAG_SAT_TEM 0x1040 + +struct sli4_cmd_dump4 { +struct sli4_mbox_command_header hdr; +__le32 type_dword; +__le16 wki_selection; +__le16 rsvd10; +__le32 rsvd12; +__le32 returned_byte_cnt; +__le32 resp_data[59 ]; +}; + +/* INIT_LINK - initialize the link for a FC port */ +enum sli4_init_link_flags { +SLI4_INIT_LINK_F_LOOPBACK = (1 <<0 ), + +SLI4_INIT_LINK_F_P2P_ONLY = (1 <<1 ), +SLI4_INIT_LINK_F_FCAL_ONLY = (2 <<1 ), +SLI4_INIT_LINK_F_FCAL_FAIL_OVER = (0 <<1 ), +SLI4_INIT_LINK_F_P2P_FAIL_OVER = (1 <<1 ), + +SLI4_INIT_LINK_F_UNFAIR = (1 <<6 ), +SLI4_INIT_LINK_F_NO_LIRP = (1 <<7 ), +SLI4_INIT_LINK_F_LOOP_VALID_CHK = (1 <<8 ), +SLI4_INIT_LINK_F_NO_LISA = (1 <<9 ), +SLI4_INIT_LINK_F_FAIL_OVER = (1 <<10 ), +SLI4_INIT_LINK_F_FIXED_SPEED = (1 <<11 ), +SLI4_INIT_LINK_F_PICK_HI_ALPA = (1 <<15 ), + +}; + +enum sli4_fc_link_speed { +FC_LINK_SPEED_1G =1 , +FC_LINK_SPEED_2G , +FC_LINK_SPEED_AUTO_1_2 , +FC_LINK_SPEED_4G , +FC_LINK_SPEED_AUTO_4_1 , +FC_LINK_SPEED_AUTO_4_2 , +FC_LINK_SPEED_AUTO_4_2_1 , +FC_LINK_SPEED_8G , +FC_LINK_SPEED_AUTO_8_1 , +FC_LINK_SPEED_AUTO_8_2 , +FC_LINK_SPEED_AUTO_8_2_1 , +FC_LINK_SPEED_AUTO_8_4 , +FC_LINK_SPEED_AUTO_8_4_1 , +FC_LINK_SPEED_AUTO_8_4_2 , +FC_LINK_SPEED_10G , +FC_LINK_SPEED_16G , +FC_LINK_SPEED_AUTO_16_8_4 , +FC_LINK_SPEED_AUTO_16_8 , +FC_LINK_SPEED_32G , +FC_LINK_SPEED_AUTO_32_16_8 , +FC_LINK_SPEED_AUTO_32_16 , +FC_LINK_SPEED_64G , +FC_LINK_SPEED_AUTO_64_32_16 , +FC_LINK_SPEED_AUTO_64_32 , +FC_LINK_SPEED_128G , +FC_LINK_SPEED_AUTO_128_64_32 , +FC_LINK_SPEED_AUTO_128_64 , +}; + +struct sli4_cmd_init_link { +struct sli4_mbox_command_header hdr; +__le32 sel_reset_al_pa_dword; +__le32 flags0; +__le32 link_speed_sel_code; +}; + +/* INIT_VFI - initialize the VFI resource */ +enum sli4_init_vfi_flags { +SLI4_INIT_VFI_FLAG_VP =0x1000 , +SLI4_INIT_VFI_FLAG_VF =0x2000 , +SLI4_INIT_VFI_FLAG_VT =0x4000 , +SLI4_INIT_VFI_FLAG_VR =0x8000 , + +SLI4_INIT_VFI_VFID =0x1fff , +SLI4_INIT_VFI_PRI =0xe000 , + +SLI4_INIT_VFI_HOP_COUNT =0xff000000 , +}; + +struct sli4_cmd_init_vfi { +struct sli4_mbox_command_header hdr; +__le16 vfi; +__le16 flags0_word; +__le16 fcfi; +__le16 vpi; +__le32 vf_id_pri_dword; +__le32 hop_cnt_dword; +}; + +/* INIT_VPI - initialize the VPI resource */ +struct sli4_cmd_init_vpi { +struct sli4_mbox_command_header hdr; +__le16 vpi; +__le16 vfi; +}; + +/* POST_XRI - post XRI resources to the SLI Port */ +enum sli4_post_xri_flags { +SLI4_POST_XRI_COUNT =0xfff , +SLI4_POST_XRI_FLAG_ENX =0x1000 , +SLI4_POST_XRI_FLAG_DL =0x2000 , +SLI4_POST_XRI_FLAG_DI =0x4000 , +SLI4_POST_XRI_FLAG_VAL =0x8000 , +}; + +struct sli4_cmd_post_xri { +struct sli4_mbox_command_header hdr; +__le16 xri_base; +__le16 xri_count_flags; +}; + +/* RELEASE_XRI - Release XRI resources from the SLI Port */ +enum sli4_release_xri_flags { +SLI4_RELEASE_XRI_REL_XRI_CNT =0x1f , +SLI4_RELEASE_XRI_COUNT =0x1f , +}; + +struct sli4_cmd_release_xri { +struct sli4_mbox_command_header hdr; +__le16 rel_xri_count_word; +__le16 xri_count_word; + +struct { +__le16 xri_tag0; +__le16 xri_tag1; + } xri_tbl[62 ]; +}; + +/* READ_CONFIG - read SLI port configuration parameters */ +struct sli4_cmd_read_config { +struct sli4_mbox_command_header hdr; +}; + +enum sli4_read_cfg_resp_flags { +SLI4_READ_CFG_RESP_RESOURCE_EXT =0x80000000 ,/* DW1 */ +SLI4_READ_CFG_RESP_TOPOLOGY =0xff000000 ,/* DW2 */ +}; + +enum sli4_read_cfg_topo { +SLI4_READ_CFG_TOPO_FC =0x1 ,/* FC topology unknown */ +SLI4_READ_CFG_TOPO_FC_DA =0x2 ,/* FC Direct Attach */ +SLI4_READ_CFG_TOPO_FC_AL =0x3 ,/* FC-AL topology */ +}; + +struct sli4_rsp_read_config { +struct sli4_mbox_command_header hdr; +__le32 ext_dword; +__le32 topology_dword; +__le32 resvd8; +__le16 e_d_tov; +__le16 resvd14; +__le32 resvd16; +__le16 r_a_tov; +__le16 resvd22; +__le32 resvd24; +__le32 resvd28; +__le16 lmt; +__le16 resvd34; +__le32 resvd36; +__le32 resvd40; +__le16 xri_base; +__le16 xri_count; +__le16 rpi_base; +__le16 rpi_count; +__le16 vpi_base; +__le16 vpi_count; +__le16 vfi_base; +__le16 vfi_count; +__le16 resvd60; +__le16 fcfi_count; +__le16 rq_count; +__le16 eq_count; +__le16 wq_count; +__le16 cq_count; +__le32 pad[45 ]; +}; + +/* READ_NVPARMS - read SLI port configuration parameters */ +enum sli4_read_nvparms_flags { +SLI4_READ_NVPARAMS_HARD_ALPA =0xff , +SLI4_READ_NVPARAMS_PREFERRED_D_ID =0xffffff00 , +}; + +struct sli4_cmd_read_nvparms { +struct sli4_mbox_command_header hdr; +__le32 resvd0; +__le32 resvd4; +__le32 resvd8; +__le32 resvd12; +u8 wwpn[8 ]; +u8 wwnn[8 ]; +__le32 hard_alpa_d_id; +}; + +/* WRITE_NVPARMS - write SLI port configuration parameters */ +struct sli4_cmd_write_nvparms { +struct sli4_mbox_command_header hdr; +__le32 resvd0; +__le32 resvd4; +__le32 resvd8; +__le32 resvd12; +u8 wwpn[8 ]; +u8 wwnn[8 ]; +__le32 hard_alpa_d_id; +}; + +/* READ_REV - read the Port revision levels */ +enum { +SLI4_READ_REV_FLAG_SLI_LEVEL =0xf , +SLI4_READ_REV_FLAG_FCOEM =0x10 , +SLI4_READ_REV_FLAG_CEEV =0x60 , +SLI4_READ_REV_FLAG_VPD =0x2000 , + +SLI4_READ_REV_AVAILABLE_LENGTH =0xffffff , +}; + +struct sli4_cmd_read_rev { +struct sli4_mbox_command_header hdr; +__le16 resvd0; +__le16 flags0_word; +__le32 first_hw_rev; +__le32 second_hw_rev; +__le32 resvd12; +__le32 third_hw_rev; +u8 fc_ph_low; +u8 fc_ph_high; +u8 feature_level_low; +u8 feature_level_high; +__le32 resvd24; +__le32 first_fw_id; +u8 first_fw_name[16 ]; +__le32 second_fw_id; +u8 second_fw_name[16 ]; +__le32 rsvd18[30 ]; +__le32 available_length_dword; +struct sli4_dmaaddr hostbuf; +__le32 returned_vpd_length; +__le32 actual_vpd_length; +};
drivers/scsi/elx/libefc_sli/sli4.h enum sli4_els_cmd_type { · line 2357
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h +10
-0+ +/* READ_SPARM64 - read the Port service parameters */ +#define SLI4_READ_SPARM64_WWPN_OFFSET (4 * sizeof(u32)) +#define SLI4_READ_SPARM64_WWNN_OFFSET (6 * sizeof(u32)) + +struct sli4_cmd_read_sparm64 { +struct sli4_mbox_command_header hdr; +__le32 resvd0; +__le32 resvd4; +struct sli4_bde bde_64;
I find these kind of strange code indention pattern unnecessary. I assume bde_64 is not indenteded as resvd4 because it is a struct.
Quoted 33 lines
drivers/scsi/elx/libefc_sli/sli4.h +33
-0+__le16 vpi; +__le16 resvd22; +__le16 port_name_start; +__le16 port_name_len; +__le16 node_name_start; +__le16 node_name_len; +}; + +/* READ_TOPOLOGY - read the link event information */ +enum sli4_read_topo_e { +SLI4_READTOPO_ATTEN_TYPE =0xff , +SLI4_READTOPO_FLAG_IL =0x100 , +SLI4_READTOPO_FLAG_PB_RECVD =0x200 , + +SLI4_READTOPO_LINKSTATE_RECV =0x3 , +SLI4_READTOPO_LINKSTATE_TRANS =0xc , +SLI4_READTOPO_LINKSTATE_MACHINE =0xf0 , +SLI4_READTOPO_LINKSTATE_SPEED =0xff00 , +SLI4_READTOPO_LINKSTATE_TF =0x40000000 , +SLI4_READTOPO_LINKSTATE_LU =0x80000000 , + +SLI4_READTOPO_SCN_BBSCN =0xf , +SLI4_READTOPO_SCN_CBBSCN =0xf0 , + +SLI4_READTOPO_R_T_TOV =0x1ff , +SLI4_READTOPO_AL_TOV =0xf000 , + +SLI4_READTOPO_PB_FLAG =0x80 , + +SLI4_READTOPO_INIT_N_PORTID =0xffffff , +}; + +#define SLI4_MIN_LOOP_MAP_BYTES 128
drivers/scsi/elx/libefc_sli/sli4.h enum sli4_els_cmd_type { · line 2400
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h +10
-0+ +struct sli4_cmd_read_topology { +struct sli4_mbox_command_header hdr; +__le32 event_tag; +__le32 dw2_attentype; +u8 topology; +u8 lip_type; +u8 lip_al_ps; +u8 al_pa_granted; +struct sli4_bde bde_loop_map;
and here again
Quoted 51 lines
drivers/scsi/elx/libefc_sli/sli4.h +51
-0+__le32 linkdown_state; +__le32 currlink_state; +u8 max_bbc; +u8 init_bbc; +u8 scn_flags; +u8 rsvd39; +__le16 dw10w0_al_rt_tov; +__le16 lp_tov; +u8 acquired_al_pa; +u8 pb_flags; +__le16 specified_al_pa; +__le32 dw12_init_n_port_id; +}; + +enum sli4_read_topo_link { +SLI4_READ_TOPOLOGY_LINK_UP =0x1 , +SLI4_READ_TOPOLOGY_LINK_DOWN , +SLI4_READ_TOPOLOGY_LINK_NO_ALPA , +}; + +enum sli4_read_topo { +SLI4_READ_TOPOLOGY_UNKNOWN =0x0 , +SLI4_READ_TOPOLOGY_NPORT , +SLI4_READ_TOPOLOGY_FC_AL , +}; + +enum sli4_read_topo_speed { +SLI4_READ_TOPOLOGY_SPEED_NONE =0x00 , +SLI4_READ_TOPOLOGY_SPEED_1G =0x04 , +SLI4_READ_TOPOLOGY_SPEED_2G =0x08 , +SLI4_READ_TOPOLOGY_SPEED_4G =0x10 , +SLI4_READ_TOPOLOGY_SPEED_8G =0x20 , +SLI4_READ_TOPOLOGY_SPEED_10G =0x40 , +SLI4_READ_TOPOLOGY_SPEED_16G =0x80 , +SLI4_READ_TOPOLOGY_SPEED_32G =0x90 , +}; + +/* REG_FCFI - activate a FC Forwarder */ +struct sli4_cmd_reg_fcfi_rq_cfg { +u8 r_ctl_mask; +u8 r_ctl_match; +u8 type_mask; +u8 type_match; +}; + +enum sli4_regfcfi_tag { +SLI4_REGFCFI_VLAN_TAG =0xfff , +SLI4_REGFCFI_VLANTAG_VALID =0x1000 , +}; + +#define SLI4_CMD_REG_FCFI_NUM_RQ_CFG 4
drivers/scsi/elx/libefc_sli/sli4.h enum sli4_els_cmd_type { · line 2461
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h +10
-0+struct sli4_cmd_reg_fcfi { +struct sli4_mbox_command_header hdr; +__le16 fcf_index; +__le16 fcfi; +__le16 rqid1; +__le16 rqid0; +__le16 rqid3; +__le16 rqid2; +struct sli4_cmd_reg_fcfi_rq_cfg + rq_cfg[SLI4_CMD_REG_FCFI_NUM_RQ_CFG ];
and here it rq_cfg is aligned.
Quoted 1,112 lines
drivers/scsi/elx/libefc_sli/sli4.h +1112
-0+__le32 dw8_vlan; +}; + +#define SLI4_CMD_REG_FCFI_MRQ_NUM_RQ_CFG 4 +#define SLI4_CMD_REG_FCFI_MRQ_MAX_NUM_RQ 32 +#define SLI4_CMD_REG_FCFI_SET_FCFI_MODE 0 +#define SLI4_CMD_REG_FCFI_SET_MRQ_MODE 1 + +enum sli4_reg_fcfi_mrq { +SLI4_REGFCFI_MRQ_VLAN_TAG =0xfff , +SLI4_REGFCFI_MRQ_VLANTAG_VALID =0x1000 , +SLI4_REGFCFI_MRQ_MODE =0x2000 , + +SLI4_REGFCFI_MRQ_MASK_NUM_PAIRS =0xff , +SLI4_REGFCFI_MRQ_FILTER_BITMASK =0xf00 , +SLI4_REGFCFI_MRQ_RQ_SEL_POLICY =0xf000 , +}; + +struct sli4_cmd_reg_fcfi_mrq { +struct sli4_mbox_command_header hdr; +__le16 fcf_index; +__le16 fcfi; +__le16 rqid1; +__le16 rqid0; +__le16 rqid3; +__le16 rqid2; +struct sli4_cmd_reg_fcfi_rq_cfg + rq_cfg[SLI4_CMD_REG_FCFI_MRQ_NUM_RQ_CFG ]; +__le32 dw8_vlan; +__le32 dw9_mrqflags; +}; + +struct sli4_cmd_rq_cfg { +__le16 rq_id; +u8 r_ctl_mask; +u8 r_ctl_match; +u8 type_mask; +u8 type_match; +}; + +/* REG_RPI - register a Remote Port Indicator */ +enum sli4_reg_rpi { +SLI4_REGRPI_REMOTE_N_PORTID =0xffffff ,/* DW2 */ +SLI4_REGRPI_UPD =0x1000000 , +SLI4_REGRPI_ETOW =0x8000000 , +SLI4_REGRPI_TERP =0x20000000 , +SLI4_REGRPI_CI =0x80000000 , +}; + +struct sli4_cmd_reg_rpi { +struct sli4_mbox_command_header hdr; +__le16 rpi; +__le16 rsvd2; +__le32 dw2_rportid_flags; +struct sli4_bde bde_64; +__le16 vpi; +__le16 rsvd26; +}; + +#define SLI4_REG_RPI_BUF_LEN 0x70 + +/* REG_VFI - register a Virtual Fabric Indicator */ +enum sli_reg_vfi { +SLI4_REGVFI_VP =0x1000 ,/* DW1 */ +SLI4_REGVFI_UPD =0x2000 , + +SLI4_REGVFI_LOCAL_N_PORTID =0xffffff ,/* DW10 */ +}; + +struct sli4_cmd_reg_vfi { +struct sli4_mbox_command_header hdr; +__le16 vfi; +__le16 dw0w1_flags; +__le16 fcfi; +__le16 vpi; +u8 wwpn[8 ]; +struct sli4_bde sparm; +__le32 e_d_tov; +__le32 r_a_tov; +__le32 dw10_lportid_flags; +}; + +/* REG_VPI - register a Virtual Port Indicator */ +enum sli4_reg_vpi { +SLI4_REGVPI_LOCAL_N_PORTID =0xffffff , +SLI4_REGVPI_UPD =0x1000000 , +}; + +struct sli4_cmd_reg_vpi { +struct sli4_mbox_command_header hdr; +__le32 rsvd0; +__le32 dw2_lportid_flags; +u8 wwpn[8 ]; +__le32 rsvd12; +__le16 vpi; +__le16 vfi; +}; + +/* REQUEST_FEATURES - request / query SLI features */ +enum sli4_req_features_flags { +SLI4_REQFEAT_QRY =0x1 ,/* Dw1 */ + +SLI4_REQFEAT_IAAB = (1 <<0 ),/* DW2 & DW3 */ +SLI4_REQFEAT_NPIV = (1 <<1 ), +SLI4_REQFEAT_DIF = (1 <<2 ), +SLI4_REQFEAT_VF = (1 <<3 ), +SLI4_REQFEAT_FCPI = (1 <<4 ), +SLI4_REQFEAT_FCPT = (1 <<5 ), +SLI4_REQFEAT_FCPC = (1 <<6 ), +SLI4_REQFEAT_RSVD = (1 <<7 ), +SLI4_REQFEAT_RQD = (1 <<8 ), +SLI4_REQFEAT_IAAR = (1 <<9 ), +SLI4_REQFEAT_HLM = (1 <<10 ), +SLI4_REQFEAT_PERFH = (1 <<11 ), +SLI4_REQFEAT_RXSEQ = (1 <<12 ), +SLI4_REQFEAT_RXRI = (1 <<13 ), +SLI4_REQFEAT_DCL2 = (1 <<14 ), +SLI4_REQFEAT_RSCO = (1 <<15 ), +SLI4_REQFEAT_MRQP = (1 <<16 ), +}; + +struct sli4_cmd_request_features { +struct sli4_mbox_command_header hdr; +__le32 dw1_qry; +__le32 cmd; +__le32 resp; +}; + +/* +* SLI_CONFIG - submit a configuration command to Port +* +* Command is either embedded as part of the payload (embed) or located +* in a separate memory buffer (mem) +*/ +enum sli4_sli_config { +SLI4_SLICONF_EMB =0x1 ,/* DW1 */ +SLI4_SLICONF_PMDCMD_SHIFT =3 , +SLI4_SLICONF_PMDCMD_MASK =0xF8 , +SLI4_SLICONF_PMDCMD_VAL_1 =8 , +SLI4_SLICONF_PMDCNT =0xF8 , + +SLI4_SLICONFIG_PMD_LEN =0x00ffffff , +}; + +struct sli4_cmd_sli_config { +struct sli4_mbox_command_header hdr; +__le32 dw1_flags; +__le32 payload_len; +__le32 rsvd12[3 ]; +union { +u8 embed[58 *sizeof (u32)]; +struct sli4_bufptr mem; + } payload; +}; + +/* READ_STATUS - read tx/rx status of a particular port */ +#define SLI4_READSTATUS_CLEAR_COUNTERS 0x1 + +struct sli4_cmd_read_status { +struct sli4_mbox_command_header hdr; +__le32 dw1_flags; +__le32 rsvd4; +__le32 trans_kbyte_cnt; +__le32 recv_kbyte_cnt; +__le32 trans_frame_cnt; +__le32 recv_frame_cnt; +__le32 trans_seq_cnt; +__le32 recv_seq_cnt; +__le32 tot_exchanges_orig; +__le32 tot_exchanges_resp; +__le32 recv_p_bsy_cnt; +__le32 recv_f_bsy_cnt; +__le32 no_rq_buf_dropped_frames_cnt; +__le32 empty_rq_timeout_cnt; +__le32 no_xri_dropped_frames_cnt; +__le32 empty_xri_pool_cnt; +}; + +/* READ_LNK_STAT - read link status of a particular port */ +enum sli4_read_link_stats_flags { +SLI4_READ_LNKSTAT_REC = (1 <<0 ), +SLI4_READ_LNKSTAT_GEC = (1 <<1 ), +SLI4_READ_LNKSTAT_W02OF = (1 <<2 ), +SLI4_READ_LNKSTAT_W03OF = (1 <<3 ), +SLI4_READ_LNKSTAT_W04OF = (1 <<4 ), +SLI4_READ_LNKSTAT_W05OF = (1 <<5 ), +SLI4_READ_LNKSTAT_W06OF = (1 <<6 ), +SLI4_READ_LNKSTAT_W07OF = (1 <<7 ), +SLI4_READ_LNKSTAT_W08OF = (1 <<8 ), +SLI4_READ_LNKSTAT_W09OF = (1 <<9 ), +SLI4_READ_LNKSTAT_W10OF = (1 <<10 ), +SLI4_READ_LNKSTAT_W11OF = (1 <<11 ), +SLI4_READ_LNKSTAT_W12OF = (1 <<12 ), +SLI4_READ_LNKSTAT_W13OF = (1 <<13 ), +SLI4_READ_LNKSTAT_W14OF = (1 <<14 ), +SLI4_READ_LNKSTAT_W15OF = (1 <<15 ), +SLI4_READ_LNKSTAT_W16OF = (1 <<16 ), +SLI4_READ_LNKSTAT_W17OF = (1 <<17 ), +SLI4_READ_LNKSTAT_W18OF = (1 <<18 ), +SLI4_READ_LNKSTAT_W19OF = (1 <<19 ), +SLI4_READ_LNKSTAT_W20OF = (1 <<20 ), +SLI4_READ_LNKSTAT_W21OF = (1 <<21 ), +SLI4_READ_LNKSTAT_CLRC = (1 <<30 ), +SLI4_READ_LNKSTAT_CLOF = (1 <<31 ), +}; + +struct sli4_cmd_read_link_stats { +struct sli4_mbox_command_header hdr; +__le32 dw1_flags; +__le32 linkfail_errcnt; +__le32 losssync_errcnt; +__le32 losssignal_errcnt; +__le32 primseq_errcnt; +__le32 inval_txword_errcnt; +__le32 crc_errcnt; +__le32 primseq_eventtimeout_cnt; +__le32 elastic_bufoverrun_errcnt; +__le32 arbit_fc_al_timeout_cnt; +__le32 adv_rx_buftor_to_buf_credit; +__le32 curr_rx_buf_to_buf_credit; +__le32 adv_tx_buf_to_buf_credit; +__le32 curr_tx_buf_to_buf_credit; +__le32 rx_eofa_cnt; +__le32 rx_eofdti_cnt; +__le32 rx_eofni_cnt; +__le32 rx_soff_cnt; +__le32 rx_dropped_no_aer_cnt; +__le32 rx_dropped_no_avail_rpi_rescnt; +__le32 rx_dropped_no_avail_xri_rescnt; +}; + +/* Format a WQE with WQ_ID Association performance hint */ +static inline void +sli_set_wq_id_association (void *entry,u16 q_id) +{ +u32 *wqe = entry; + +/* +* Set Word 10, bit 0 to zero +* Set Word 10, bits 15:1 to the WQ ID +*/ + wqe[10 ] &= ~0xffff ; + wqe[10 ] |= q_id <<1 ; +} + +/* UNREG_FCFI - unregister a FCFI */ +struct sli4_cmd_unreg_fcfi { +struct sli4_mbox_command_header hdr; +__le32 rsvd0; +__le16 fcfi; +__le16 rsvd6; +}; + +/* UNREG_RPI - unregister one or more RPI */ +enum sli4_unreg_rpi { +UNREG_RPI_DP =0x2000 , +UNREG_RPI_II_SHIFT =14 , +UNREG_RPI_II_MASK =0xC000 , +UNREG_RPI_II_RPI =0x0000 , +UNREG_RPI_II_VPI =0x4000 , +UNREG_RPI_II_VFI =0x8000 , +UNREG_RPI_II_FCFI =0xC000 , + +UNREG_RPI_DEST_N_PORTID_MASK =0x00ffffff , +}; + +struct sli4_cmd_unreg_rpi { +struct sli4_mbox_command_header hdr; +__le16 index; +__le16 dw1w1_flags; +__le32 dw2_dest_n_portid; +}; + +/* UNREG_VFI - unregister one or more VFI */ +enum sli4_unreg_vfi { +UNREG_VFI_II_SHIFT =14 , +UNREG_VFI_II_MASK =0xC000 , +UNREG_VFI_II_VFI =0x0000 , +UNREG_VFI_II_FCFI =0xC000 , +}; + +struct sli4_cmd_unreg_vfi { +struct sli4_mbox_command_header hdr; +__le32 rsvd0; +__le16 index; +__le16 dw2_flags; +}; + +enum sli4_unreg_type { +SLI4_UNREG_TYPE_PORT , +SLI4_UNREG_TYPE_DOMAIN , +SLI4_UNREG_TYPE_FCF , +SLI4_UNREG_TYPE_ALL +}; + +/* UNREG_VPI - unregister one or more VPI */ +enum sli4_unreg_vpi { +UNREG_VPI_II_SHIFT =14 , +UNREG_VPI_II_MASK =0xC000 , +UNREG_VPI_II_VPI =0x0000 , +UNREG_VPI_II_VFI =0x8000 , +UNREG_VPI_II_FCFI =0xC000 , +}; + +struct sli4_cmd_unreg_vpi { +struct sli4_mbox_command_header hdr; +__le32 rsvd0; +__le16 index; +__le16 dw2w0_flags; +}; + +/* AUTO_XFER_RDY - Configure the auto-generate XFER-RDY feature */ +struct sli4_cmd_config_auto_xfer_rdy { +struct sli4_mbox_command_header hdr; +__le32 rsvd0; +__le32 max_burst_len; +}; + +#define SLI4_CONFIG_AUTO_XFERRDY_BLKSIZE 0xffff + +struct sli4_cmd_config_auto_xfer_rdy_hp { +struct sli4_mbox_command_header hdr; +__le32 rsvd0; +__le32 max_burst_len; +__le32 dw3_esoc_flags; +__le16 block_size; +__le16 rsvd14; +}; + +/************************************************************************* +* SLI-4 common configuration command formats and definitions +*/ + +/* +* Subsystem values. +*/ +enum sli4_subsystem { +SLI4_SUBSYSTEM_COMMON =0x01 , +SLI4_SUBSYSTEM_LOWLEVEL =0x0B , +SLI4_SUBSYSTEM_FC =0x0C , +SLI4_SUBSYSTEM_DMTF =0x11 , +}; + +#define SLI4_OPC_LOWLEVEL_SET_WATCHDOG 0X36 + +/* +* Common opcode (OPC) values. +*/ +enum sli4_cmn_opcode { +CMN_FUNCTION_RESET =0x3d , +CMN_CREATE_CQ =0x0c , +CMN_CREATE_CQ_SET =0x1d , +CMN_DESTROY_CQ =0x36 , +CMN_MODIFY_EQ_DELAY =0x29 , +CMN_CREATE_EQ =0x0d , +CMN_DESTROY_EQ =0x37 , +CMN_CREATE_MQ_EXT =0x5a , +CMN_DESTROY_MQ =0x35 , +CMN_GET_CNTL_ATTRIBUTES =0x20 , +CMN_NOP =0x21 , +CMN_GET_RSC_EXTENT_INFO =0x9a , +CMN_GET_SLI4_PARAMS =0xb5 , +CMN_QUERY_FW_CONFIG =0x3a , +CMN_GET_PORT_NAME =0x4d , + +CMN_WRITE_FLASHROM =0x07 , +/* TRANSCEIVER Data */ +CMN_READ_TRANS_DATA =0x49 , +CMN_GET_CNTL_ADDL_ATTRS =0x79 , +CMN_GET_FUNCTION_CFG =0xa0 , +CMN_GET_PROFILE_CFG =0xa4 , +CMN_SET_PROFILE_CFG =0xa5 , +CMN_GET_PROFILE_LIST =0xa6 , +CMN_GET_ACTIVE_PROFILE =0xa7 , +CMN_SET_ACTIVE_PROFILE =0xa8 , +CMN_READ_OBJECT =0xab , +CMN_WRITE_OBJECT =0xac , +CMN_DELETE_OBJECT =0xae , +CMN_READ_OBJECT_LIST =0xad , +CMN_SET_DUMP_LOCATION =0xb8 , +CMN_SET_FEATURES =0xbf , +CMN_GET_RECFG_LINK_INFO =0xc9 , +CMN_SET_RECNG_LINK_ID =0xca , +}; + +/* DMTF opcode (OPC) values */ +#define DMTF_EXEC_CLP_CMD 0x01 + +/* +* COMMON_FUNCTION_RESET +* +* Resets the Port, returning it to a power-on state. This configuration +* command does not have a payload and should set/expect the lengths to +* be zero. +*/ +struct sli4_rqst_cmn_function_reset { +struct sli4_rqst_hdr hdr; +}; + +struct sli4_rsp_cmn_function_reset { +struct sli4_rsp_hdr hdr; +}; + + +/* +* COMMON_GET_CNTL_ATTRIBUTES +* +* Query for information about the SLI Port +*/ +enum sli4_cntrl_attr_flags { +SLI4_CNTL_ATTR_PORTNUM =0x3f , +SLI4_CNTL_ATTR_PORTTYPE =0xc0 , +}; + +struct sli4_rsp_cmn_get_cntl_attributes { +struct sli4_rsp_hdr hdr; +u8 version_str[32 ]; +u8 manufacturer_name[32 ]; +__le32 supported_modes; +u8 eprom_version_lo; +u8 eprom_version_hi; +__le16 rsvd17; +__le32 mbx_ds_version; +__le32 ep_fw_ds_version; +u8 ncsi_version_str[12 ]; +__le32 def_extended_timeout; +u8 model_number[32 ]; +u8 description[64 ]; +u8 serial_number[32 ]; +u8 ip_version_str[32 ]; +u8 fw_version_str[32 ]; +u8 bios_version_str[32 ]; +u8 redboot_version_str[32 ]; +u8 driver_version_str[32 ]; +u8 fw_on_flash_version_str[32 ]; +__le32 functionalities_supported; +__le16 max_cdb_length; +u8 asic_revision; +u8 generational_guid0; +__le32 generational_guid1_12[3 ]; +__le16 generational_guid13_14; +u8 generational_guid15; +u8 hba_port_count; +__le16 default_link_down_timeout; +u8 iscsi_version_min_max; +u8 multifunctional_device; +u8 cache_valid; +u8 hba_status; +u8 max_domains_supported; +u8 port_num_type_flags; +__le32 firmware_post_status; +__le32 hba_mtu; +u8 iscsi_features; +u8 rsvd121[3 ]; +__le16 pci_vendor_id; +__le16 pci_device_id; +__le16 pci_sub_vendor_id; +__le16 pci_sub_system_id; +u8 pci_bus_number; +u8 pci_device_number; +u8 pci_function_number; +u8 interface_type; +__le64 unique_identifier; +u8 number_of_netfilters; +u8 rsvd122[3 ]; +}; + +/* +* COMMON_GET_CNTL_ATTRIBUTES +* +* This command queries the controller information from the Flash ROM. +*/ +struct sli4_rqst_cmn_get_cntl_addl_attributes { +struct sli4_rqst_hdr hdr; +}; + +struct sli4_rsp_cmn_get_cntl_addl_attributes { +struct sli4_rsp_hdr hdr; +__le16 ipl_file_number; +u8 ipl_file_version; +u8 rsvd4; +u8 on_die_temperature; +u8 rsvd5[3 ]; +__le32 driver_advanced_features_supported; +__le32 rsvd7[4 ]; +char universal_bios_version[32 ]; +char x86_bios_version[32 ]; +char efi_bios_version[32 ]; +char fcode_version[32 ]; +char uefi_bios_version[32 ]; +char uefi_nic_version[32 ]; +char uefi_fcode_version[32 ]; +char uefi_iscsi_version[32 ]; +char iscsi_x86_bios_version[32 ]; +char pxe_x86_bios_version[32 ]; +u8 default_wwpn[8 ]; +u8 ext_phy_version[32 ]; +u8 fc_universal_bios_version[32 ]; +u8 fc_x86_bios_version[32 ]; +u8 fc_efi_bios_version[32 ]; +u8 fc_fcode_version[32 ]; +u8 ext_phy_crc_label[8 ]; +u8 ipl_file_name[16 ]; +u8 rsvd139[72 ]; +}; + +/* +* COMMON_NOP +* +* This command does not do anything; it only returns +* the payload in the completion. +*/ +struct sli4_rqst_cmn_nop { +struct sli4_rqst_hdr hdr; +__le32 context[2 ]; +}; + +struct sli4_rsp_cmn_nop { +struct sli4_rsp_hdr hdr; +__le32 context[2 ]; +}; + +struct sli4_rqst_cmn_get_resource_extent_info { +struct sli4_rqst_hdr hdr; +__le16 resource_type; +__le16 rsvd16; +}; + +enum sli4_rsc_type { +SLI4_RSC_TYPE_VFI =0x20 , +SLI4_RSC_TYPE_VPI =0x21 , +SLI4_RSC_TYPE_RPI =0x22 , +SLI4_RSC_TYPE_XRI =0x23 , +}; + +struct sli4_rsp_cmn_get_resource_extent_info { +struct sli4_rsp_hdr hdr; +__le16 resource_extent_count; +__le16 resource_extent_size; +}; + +#define SLI4_128BYTE_WQE_SUPPORT 0x02 + +#define GET_Q_CNT_METHOD (m) \ + (((m) & RSP_GET_PARAM_Q_CNT_MTHD_MASK) >> RSP_GET_PARAM_Q_CNT_MTHD_SHFT) +#define GET_Q_CREATE_VERSION (v) \ + (((v) & RSP_GET_PARAM_QV_MASK) >> RSP_GET_PARAM_QV_SHIFT) + +enum sli4_rsp_get_params_e { +/*GENERIC*/ +RSP_GET_PARAM_Q_CNT_MTHD_SHFT =24 , +RSP_GET_PARAM_Q_CNT_MTHD_MASK = (0xF <<24 ), +RSP_GET_PARAM_QV_SHIFT =14 , +RSP_GET_PARAM_QV_MASK = (3 <<14 ), + +/* DW4 */ +RSP_GET_PARAM_PROTO_TYPE_MASK =0xFF , +/* DW5 */ +RSP_GET_PARAM_FT = (1 <<0 ), +RSP_GET_PARAM_SLI_REV_MASK = (0xF <<4 ), +RSP_GET_PARAM_SLI_FAM_MASK = (0xF <<8 ), +RSP_GET_PARAM_IF_TYPE_MASK = (0xF <<12 ), +RSP_GET_PARAM_SLI_HINT1_MASK = (0xFF <<16 ), +RSP_GET_PARAM_SLI_HINT2_MASK = (0x1F <<24 ), +/* DW6 */ +RSP_GET_PARAM_EQ_PAGE_CNT_MASK = (0xF <<0 ), +RSP_GET_PARAM_EQE_SZS_MASK = (0xF <<8 ), +RSP_GET_PARAM_EQ_PAGE_SZS_MASK = (0xFF <<16 ), +/* DW8 */ +RSP_GET_PARAM_CQ_PAGE_CNT_MASK = (0xF <<0 ), +RSP_GET_PARAM_CQE_SZS_MASK = (0xF <<8 ), +RSP_GET_PARAM_CQ_PAGE_SZS_MASK = (0xFF <<16 ), +/* DW10 */ +RSP_GET_PARAM_MQ_PAGE_CNT_MASK = (0xF <<0 ), +RSP_GET_PARAM_MQ_PAGE_SZS_MASK = (0xFF <<16 ), +/* DW12 */ +RSP_GET_PARAM_WQ_PAGE_CNT_MASK = (0xF <<0 ), +RSP_GET_PARAM_WQE_SZS_MASK = (0xF <<8 ), +RSP_GET_PARAM_WQ_PAGE_SZS_MASK = (0xFF <<16 ), +/* DW14 */ +RSP_GET_PARAM_RQ_PAGE_CNT_MASK = (0xF <<0 ), +RSP_GET_PARAM_RQE_SZS_MASK = (0xF <<8 ), +RSP_GET_PARAM_RQ_PAGE_SZS_MASK = (0xFF <<16 ), +/* DW15W1*/ +RSP_GET_PARAM_RQ_DB_WINDOW_MASK =0xF000 , +/* DW16 */ +RSP_GET_PARAM_FC = (1 <<0 ), +RSP_GET_PARAM_EXT = (1 <<1 ), +RSP_GET_PARAM_HDRR = (1 <<2 ), +RSP_GET_PARAM_SGLR = (1 <<3 ), +RSP_GET_PARAM_FBRR = (1 <<4 ), +RSP_GET_PARAM_AREG = (1 <<5 ), +RSP_GET_PARAM_TGT = (1 <<6 ), +RSP_GET_PARAM_TERP = (1 <<7 ), +RSP_GET_PARAM_ASSI = (1 <<8 ), +RSP_GET_PARAM_WCHN = (1 <<9 ), +RSP_GET_PARAM_TCCA = (1 <<10 ), +RSP_GET_PARAM_TRTY = (1 <<11 ), +RSP_GET_PARAM_TRIR = (1 <<12 ), +RSP_GET_PARAM_PHOFF = (1 <<13 ), +RSP_GET_PARAM_PHON = (1 <<14 ), +RSP_GET_PARAM_PHWQ = (1 <<15 ), +RSP_GET_PARAM_BOUND_4GA = (1 <<16 ), +RSP_GET_PARAM_RXC = (1 <<17 ), +RSP_GET_PARAM_HLM = (1 <<18 ), +RSP_GET_PARAM_IPR = (1 <<19 ), +RSP_GET_PARAM_RXRI = (1 <<20 ), +RSP_GET_PARAM_SGLC = (1 <<21 ), +RSP_GET_PARAM_TIMM = (1 <<22 ), +RSP_GET_PARAM_TSMM = (1 <<23 ), +RSP_GET_PARAM_OAS = (1 <<25 ), +RSP_GET_PARAM_LC = (1 <<26 ), +RSP_GET_PARAM_AGXF = (1 <<27 ), +RSP_GET_PARAM_LOOPBACK_MASK = (0xF <<28 ), +/* DW18 */ +RSP_GET_PARAM_SGL_PAGE_CNT_MASK = (0xF <<0 ), +RSP_GET_PARAM_SGL_PAGE_SZS_MASK = (0xFF <<8 ), +RSP_GET_PARAM_SGL_PP_ALIGN_MASK = (0xFF <<16 ), +}; + +struct sli4_rqst_cmn_get_sli4_params { +struct sli4_rqst_hdr hdr; +}; + +struct sli4_rsp_cmn_get_sli4_params { +struct sli4_rsp_hdr hdr; +__le32 dw4_protocol_type; +__le32 dw5_sli; +__le32 dw6_eq_page_cnt; +__le16 eqe_count_mask; +__le16 rsvd26; +__le32 dw8_cq_page_cnt; +__le16 cqe_count_mask; +__le16 rsvd34; +__le32 dw10_mq_page_cnt; +__le16 mqe_count_mask; +__le16 rsvd42; +__le32 dw12_wq_page_cnt; +__le16 wqe_count_mask; +__le16 rsvd50; +__le32 dw14_rq_page_cnt; +__le16 rqe_count_mask; +__le16 dw15w1_rq_db_window; +__le32 dw16_loopback_scope; +__le32 sge_supported_length; +__le32 dw18_sgl_page_cnt; +__le16 min_rq_buffer_size; +__le16 rsvd75; +__le32 max_rq_buffer_size; +__le16 physical_xri_max; +__le16 physical_rpi_max; +__le16 physical_vpi_max; +__le16 physical_vfi_max; +__le32 rsvd88; +__le16 frag_num_field_offset; +__le16 frag_num_field_size; +__le16 sgl_index_field_offset; +__le16 sgl_index_field_size; +__le32 chain_sge_initial_value_lo; +__le32 chain_sge_initial_value_hi; +}; + +/* +* COMMON_QUERY_FW_CONFIG +* +* This command retrieves firmware configuration parameters and adapter +* resources available to the driver. +*/ +struct sli4_rqst_cmn_query_fw_config { +struct sli4_rqst_hdr hdr; +}; + +struct sli4_rsp_cmn_query_fw_config { +struct sli4_rsp_hdr hdr; +__le32 config_number; +__le32 asic_rev; +__le32 physical_port; +__le32 function_mode; +__le32 ulp0_mode; +__le32 ulp0_nic_wqid_base; +__le32 ulp0_nic_wq_total;/* DW10 */ +__le32 ulp0_toe_wqid_base; +__le32 ulp0_toe_wq_total; +__le32 ulp0_toe_rqid_base; +__le32 ulp0_toe_rq_total; +__le32 ulp0_toe_defrqid_base; +__le32 ulp0_toe_defrq_total; +__le32 ulp0_lro_rqid_base; +__le32 ulp0_lro_rq_total; +__le32 ulp0_iscsi_icd_base; +__le32 ulp0_iscsi_icd_total;/* DW20 */ +__le32 ulp1_mode; +__le32 ulp1_nic_wqid_base; +__le32 ulp1_nic_wq_total; +__le32 ulp1_toe_wqid_base; +__le32 ulp1_toe_wq_total; +__le32 ulp1_toe_rqid_base; +__le32 ulp1_toe_rq_total; +__le32 ulp1_toe_defrqid_base; +__le32 ulp1_toe_defrq_total; +__le32 ulp1_lro_rqid_base;/* DW30 */ +__le32 ulp1_lro_rq_total; +__le32 ulp1_iscsi_icd_base; +__le32 ulp1_iscsi_icd_total; +__le32 function_capabilities; +__le32 ulp0_cq_base; +__le32 ulp0_cq_total; +__le32 ulp0_eq_base; +__le32 ulp0_eq_total; +__le32 ulp0_iscsi_chain_icd_base; +__le32 ulp0_iscsi_chain_icd_total;/* DW40 */ +__le32 ulp1_iscsi_chain_icd_base; +__le32 ulp1_iscsi_chain_icd_total; +}; + +/*Port Types*/ +enum sli4_port_types { +PORT_TYPE_ETH =0 , +PORT_TYPE_FC =1 , +}; + +struct sli4_rqst_cmn_get_port_name { +struct sli4_rqst_hdr hdr; +u8 port_type; +u8 rsvd4[3 ]; +}; + +struct sli4_rsp_cmn_get_port_name { +struct sli4_rsp_hdr hdr; +char port_name[4 ]; +}; + +struct sli4_rqst_cmn_write_flashrom { +struct sli4_rqst_hdr hdr; +__le32 flash_rom_access_opcode; +__le32 flash_rom_access_operation_type; +__le32 data_buffer_size; +__le32 offset; +u8 data_buffer[4 ]; +}; + +/* +* COMMON_READ_TRANSCEIVER_DATA +* +* This command reads SFF transceiver data(Format is defined +* by the SFF-8472 specification). +*/ +struct sli4_rqst_cmn_read_transceiver_data { +struct sli4_rqst_hdr hdr; +__le32 page_number; +__le32 port; +}; + +struct sli4_rsp_cmn_read_transceiver_data { +struct sli4_rsp_hdr hdr; +__le32 page_number; +__le32 port; +u8 page_data[128 ]; +u8 page_data_2[128 ]; +}; + +#define SLI4_REQ_DESIRE_READLEN 0xFFFFFF + +struct sli4_rqst_cmn_read_object { +struct sli4_rqst_hdr hdr; +__le32 desired_read_length_dword; +__le32 read_offset; +u8 object_name[104 ]; +__le32 host_buffer_descriptor_count; +struct sli4_bde host_buffer_descriptor[0 ]; +}; + +#define RSP_COM_READ_OBJ_EOF 0x80000000 + +struct sli4_rsp_cmn_read_object { +struct sli4_rsp_hdr hdr; +__le32 actual_read_length; +__le32 eof_dword; +}; + +enum sli4_rqst_write_object_flags { +SLI4_RQ_DES_WRITE_LEN =0xFFFFFF , +SLI4_RQ_DES_WRITE_LEN_NOC =0x40000000 , +SLI4_RQ_DES_WRITE_LEN_EOF =0x80000000 , +}; + +struct sli4_rqst_cmn_write_object { +struct sli4_rqst_hdr hdr; +__le32 desired_write_len_dword; +__le32 write_offset; +u8 object_name[104 ]; +__le32 host_buffer_descriptor_count; +struct sli4_bde host_buffer_descriptor[0 ]; +}; + +#define RSP_CHANGE_STATUS 0xFF + +struct sli4_rsp_cmn_write_object { +struct sli4_rsp_hdr hdr; +__le32 actual_write_length; +__le32 change_status_dword; +}; + +struct sli4_rqst_cmn_delete_object { +struct sli4_rqst_hdr hdr; +__le32 rsvd4; +__le32 rsvd5; +u8 object_name[104 ]; +}; + +#define SLI4_RQ_OBJ_LIST_READ_LEN 0xFFFFFF + +struct sli4_rqst_cmn_read_object_list { +struct sli4_rqst_hdr hdr; +__le32 desired_read_length_dword; +__le32 read_offset; +u8 object_name[104 ]; +__le32 host_buffer_descriptor_count; +struct sli4_bde host_buffer_descriptor[0 ]; +}; + +enum sli4_rqst_set_dump_flags { +SLI4_CMN_SET_DUMP_BUFFER_LEN =0xFFFFFF , +SLI4_CMN_SET_DUMP_FDB =0x20000000 , +SLI4_CMN_SET_DUMP_BLP =0x40000000 , +SLI4_CMN_SET_DUMP_QRY =0x80000000 , +}; + +struct sli4_rqst_cmn_set_dump_location { +struct sli4_rqst_hdr hdr; +__le32 buffer_length_dword; +__le32 buf_addr_low; +__le32 buf_addr_high; +}; + +struct sli4_rsp_cmn_set_dump_location { +struct sli4_rsp_hdr hdr; +__le32 buffer_length_dword; +}; + +enum sli4_dump_level { +SLI4_DUMP_LEVEL_NONE , +SLI4_CHIP_LEVEL_DUMP , +SLI4_FUNC_DESC_DUMP , +}; + +enum sli4_dump_state { +SLI4_DUMP_STATE_NONE , +SLI4_CHIP_DUMP_STATE_VALID , +SLI4_FUNC_DUMP_STATE_VALID , +}; + +enum sli4_dump_status { +SLI4_DUMP_READY_STATUS_NOT_READY , +SLI4_DUMP_READY_STATUS_DD_PRESENT , +SLI4_DUMP_READY_STATUS_FDB_PRESENT , +SLI4_DUMP_READY_STATUS_SKIP_DUMP , +SLI4_DUMP_READY_STATUS_FAILED =-1 , +}; + +enum sli4_set_features { +SLI4_SET_FEATURES_DIF_SEED =0x01 , +SLI4_SET_FEATURES_XRI_TIMER =0x03 , +SLI4_SET_FEATURES_MAX_PCIE_SPEED =0x04 , +SLI4_SET_FEATURES_FCTL_CHECK =0x05 , +SLI4_SET_FEATURES_FEC =0x06 , +SLI4_SET_FEATURES_PCIE_RECV_DETECT =0x07 , +SLI4_SET_FEATURES_DIF_MEMORY_MODE =0x08 , +SLI4_SET_FEATURES_DISABLE_SLI_PORT_PAUSE_STATE =0x09 , +SLI4_SET_FEATURES_ENABLE_PCIE_OPTIONS =0x0A , +SLI4_SET_FEAT_CFG_AUTO_XFER_RDY_T10PI =0x0C , +SLI4_SET_FEATURES_ENABLE_MULTI_RECEIVE_QUEUE =0x0D , +SLI4_SET_FEATURES_SET_FTD_XFER_HINT =0x0F , +SLI4_SET_FEATURES_SLI_PORT_HEALTH_CHECK =0x11 , +}; + +struct sli4_rqst_cmn_set_features { +struct sli4_rqst_hdr hdr; +__le32 feature; +__le32 param_len; +__le32 params[8 ]; +}; + +struct sli4_rqst_cmn_set_features_dif_seed { +__le16 seed; +__le16 rsvd16; +}; + +enum sli4_rqst_set_mrq_features { +SLI4_RQ_MULTIRQ_ISR =0x1 , +SLI4_RQ_MULTIRQ_AUTOGEN_XFER_RDY =0x2 , + +SLI4_RQ_MULTIRQ_NUM_RQS =0xFF , +SLI4_RQ_MULTIRQ_RQ_SELECT =0xF00 , +}; + +struct sli4_rqst_cmn_set_features_multirq { +__le32 auto_gen_xfer_dword; +__le32 num_rqs_dword; +}; + +enum sli4_rqst_health_check_flags { +SLI4_RQ_HEALTH_CHECK_ENABLE =0x1 , +SLI4_RQ_HEALTH_CHECK_QUERY =0x2 , +}; + +struct sli4_rqst_cmn_set_features_health_check { +__le32 health_check_dword; +}; + +struct sli4_rqst_cmn_set_features_set_fdt_xfer_hint { +__le32 fdt_xfer_hint; +}; + +struct sli4_rqst_dmtf_exec_clp_cmd { +struct sli4_rqst_hdr hdr; +__le32 cmd_buf_length; +__le32 resp_buf_length; +__le32 cmd_buf_addr_low; +__le32 cmd_buf_addr_high; +__le32 resp_buf_addr_low; +__le32 resp_buf_addr_high; +}; + +struct sli4_rsp_dmtf_exec_clp_cmd { +struct sli4_rsp_hdr hdr; +__le32 rsvd4; +__le32 resp_length; +__le32 rsvd6; +__le32 rsvd7; +__le32 rsvd8; +__le32 rsvd9; +__le32 clp_status; +__le32 clp_detailed_status; +}; + +#define SLI4_PROTOCOL_FC 0x10 +#define SLI4_PROTOCOL_DEFAULT 0xff + +struct sli4_rspource_descriptor_v1 { +u8 descriptor_type; +u8 descriptor_length; +__le16 rsvd16; +__le32 type_specific[0 ]; +}; + +enum sli4_pcie_desc_flags { +SLI4_PCIE_DESC_IMM =0x4000 , +SLI4_PCIE_DESC_NOSV =0x8000 , + +SLI4_PCIE_DESC_PF_NO =0x3FF0000 , + +SLI4_PCIE_DESC_MISSN_ROLE =0xFF , +SLI4_PCIE_DESC_PCHG =0x8000000 , +SLI4_PCIE_DESC_SCHG =0x10000000 , +SLI4_PCIE_DESC_XCHG =0x20000000 , +SLI4_PCIE_DESC_XROM =0xC0000000 +}; + +struct sli4_pcie_resource_descriptor_v1 { +u8 descriptor_type; +u8 descriptor_length; +__le16 imm_nosv_dword; +__le32 pf_number_dword; +__le32 rsvd3; +u8 sriov_state; +u8 pf_state; +u8 pf_type; +u8 rsvd4; +__le16 number_of_vfs; +__le16 rsvd5; +__le32 mission_roles_dword; +__le32 rsvd7[16 ]; +}; + +struct sli4_rqst_cmn_get_function_config { +struct sli4_rqst_hdr hdr; +}; + +struct sli4_rsp_cmn_get_function_config { +struct sli4_rsp_hdr hdr; +__le32 desc_count; +__le32 desc[54 ]; +}; + +/* Link Config Descriptor for link config functions */ +struct sli4_link_config_descriptor { +u8 link_config_id; +u8 rsvd1[3 ]; +__le32 config_description[8 ]; +}; + +#define MAX_LINK_DES 10 + +struct sli4_rqst_cmn_get_reconfig_link_info { +struct sli4_rqst_hdr hdr; +}; + +struct sli4_rsp_cmn_get_reconfig_link_info { +struct sli4_rsp_hdr hdr; +u8 active_link_config_id; +u8 rsvd17; +u8 next_link_config_id; +u8 rsvd19; +__le32 link_configuration_descriptor_count; +struct sli4_link_config_descriptor + desc[MAX_LINK_DES ]; +}; + +enum sli4_set_reconfig_link_flags { +SLI4_SET_RECONFIG_LINKID_NEXT =0xff , +SLI4_SET_RECONFIG_LINKID_FD = (1 <<31 ), +}; + +struct sli4_rqst_cmn_set_reconfig_link_id { +struct sli4_rqst_hdr hdr; +__le32 dw4_flags; +}; + +struct sli4_rsp_cmn_set_reconfig_link_id { +struct sli4_rsp_hdr hdr; +}; + +struct sli4_rqst_lowlevel_set_watchdog { +struct sli4_rqst_hdr hdr; +__le16 watchdog_timeout; +__le16 rsvd18; +}; + +struct sli4_rsp_lowlevel_set_watchdog { +struct sli4_rsp_hdr hdr; +__le32 rsvd; +}; + +/* FC opcode (OPC) values */ +enum sli4_fc_opcodes { +SLI4_OPC_WQ_CREATE =0x1 , +SLI4_OPC_WQ_DESTROY =0x2 , +SLI4_OPC_POST_SGL_PAGES =0x3 , +SLI4_OPC_RQ_CREATE =0x5 , +SLI4_OPC_RQ_DESTROY =0x6 , +SLI4_OPC_READ_FCF_TABLE =0x8 , +SLI4_OPC_POST_HDR_TEMPLATES =0xb , +SLI4_OPC_REDISCOVER_FCF =0x10 , +}; + +/* Use the default CQ associated with the WQ */ +#define SLI4_CQ_DEFAULT 0xffff + +/* +* POST_SGL_PAGES +* +* Register the scatter gather list (SGL) memory and +* associate it with an XRI. +*/ +struct sli4_rqst_post_sgl_pages { +struct sli4_rqst_hdr hdr; +__le16 xri_start; +__le16 xri_count; +struct { +__le32 page0_low; +__le32 page0_high; +__le32 page1_low; +__le32 page1_high; + } page_set[10 ]; +}; + +struct sli4_rsp_post_sgl_pages { +struct sli4_rsp_hdr hdr; +}; + +struct sli4_rqst_post_hdr_templates { +struct sli4_rqst_hdr hdr; +__le16 rpi_offset; +__le16 page_count; +struct sli4_dmaaddr page_descriptor[0 ]; +}; + +#define SLI4_HDR_TEMPLATE_SIZE 64 + +enum sli4_io_flags { +/* The XRI associated with this IO is already active */ +SLI4_IO_CONTINUATION = (1 <<0 ), +/* Automatically generate a good RSP frame */ +SLI4_IO_AUTO_GOOD_RESPONSE = (1 <<1 ), +SLI4_IO_NO_ABORT = (1 <<2 ), +/* Set the DNRX bit because no auto xref rdy buffer is posted */ +SLI4_IO_DNRX = (1 <<3 ), +}; + +enum sli4_callback { +SLI4_CB_LINK , +SLI4_CB_MAX , +}; + +enum sli4_link_status { +SLI_LINK_STATUS_UP , +SLI_LINK_STATUS_DOWN , +SLI_LINK_STATUS_NO_ALPA , +SLI_LINK_STATUS_MAX , +}; + +enum sli4_link_topology { +SLI_LINK_TOPO_NPORT =1 , +SLI_LINK_TOPO_LOOP , +SLI_LINK_TOPO_LOOPBACK_INTERNAL , +SLI_LINK_TOPO_LOOPBACK_EXTERNAL , +SLI_LINK_TOPO_NONE , +SLI_LINK_TOPO_MAX , +}; + +enum sli4_link_medium {
drivers/scsi/elx/libefc_sli/sli4.h enum sli4_els_cmd_type { · line 3583
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h +10
-0+SLI_LINK_MEDIUM_ETHERNET , +SLI_LINK_MEDIUM_FC , + SLI_LINK_MEDIUM_MAX, +}; + +/*Driver specific structures*/ + +struct sli4_link_event { +enum sli4_link_status status; +enum sli4_link_topology topology;
Code idention
Quoted 23 lines
drivers/scsi/elx/libefc_sli/sli4.h +23
-0+enum sli4_link_medium medium; +u32 speed; +u8 *loop_map; +u32 fc_id; +}; + +enum sli4_resource { +SLI_RSRC_VFI , +SLI_RSRC_VPI , +SLI_RSRC_RPI , +SLI_RSRC_XRI , +SLI_RSRC_FCFI , +SLI_RSRC_MAX , +}; + +struct sli4_extent { +u32 number; +u32 size; +u32 n_alloc; +u32 *base; +unsigned long *use_map; +u32 map_size; +};
drivers/scsi/elx/libefc_sli/sli4.h enum sli4_els_cmd_type { · line 3616
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h +10
-0+ +struct sli4_queue_info { +u16 max_qcount[SLI_QTYPE_MAX ]; +u32 max_qentries[SLI_QTYPE_MAX ]; +u16 count_mask[SLI_QTYPE_MAX ]; +u16 count_method[SLI_QTYPE_MAX ]; +u32 qpage_count[SLI_QTYPE_MAX ]; +}; + +#define SLI_PCI_MAX_REGS 6
PCI_STD_NUM_BARS ?
drivers/scsi/elx/libefc_sli/sli4.h enum sli4_els_cmd_type { · line 3619
Quoted 3 lines
drivers/scsi/elx/libefc_sli/sli4.h +3
-0+struct sli4 { +void *os; +struct pci_dev *pcidev;
s/pcidev/pci/ as this seems to be a more common pattern.
drivers/scsi/elx/libefc_sli/sli4.h enum sli4_els_cmd_type { · line 3624
Quoted 5 lines
drivers/scsi/elx/libefc_sli/sli4.h +5
-0+void __iomem *reg[SLI_PCI_MAX_REGS ]; + +u32 sli_rev; +u32 sli_family; +u32 if_type;
ahhh the if_type member from the other comment
drivers/scsi/elx/libefc_sli/sli4.h enum sli4_els_cmd_type { · line 3631
Quoted 7 lines
drivers/scsi/elx/libefc_sli/sli4.h +7
-0+ +u16 asic_type; +u16 asic_rev; + +u16 e_d_tov; +u16 r_a_tov; +struct sli4_queue_info qinfo;
Please align it with the rest.
Quoted 26 lines
drivers/scsi/elx/libefc_sli/sli4.h +26
-0+u16 link_module_type; +u8 rq_batch; +u16 rq_min_buf_size; +u32 rq_max_buf_size; +u8 topology; +u8 wwpn[8 ]; +u8 wwnn[8 ]; +u32 fw_rev[2 ]; +u8 fw_name[2 ][16 ]; +char ipl_name[16 ]; +u32 hw_rev[3 ]; +u8 port_number; +char port_name[2 ]; +char modeldesc[64 ]; +char bios_version_string[32 ]; +/* +* Tracks the port resources using extents metaphor. For +* devices that don't implement extents (i.e. +* has_extents == FALSE), the code models each resource as +* a single large extent. +*/ +struct sli4_extent extent[SLI_RSRC_MAX ]; +u32 features; + u32 has_extents:1, + auto_reg:1, + auto_xfer_rdy:1,
drivers/scsi/elx/libefc_sli/sli4.h enum sli4_els_cmd_type { · line 3667
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h +10
-0+ hdr_template_req:1, + perf_hint:1, + perf_wq_id_association:1, + cq_create_version:2, + mq_create_version:2, + high_login_mode:1, + sgl_pre_registered:1, + sgl_pre_registration_required:1, + t10_dif_inline_capable:1, + t10_dif_separate_capable:1;
Why features and the bitfields?
Quoted 25 lines
drivers/scsi/elx/libefc_sli/sli4.h +22
-0+u32 sge_supported_length; +u32 sgl_page_sizes; +u32 max_sgl_pages; +u32 wqe_size; + +/* +* Callback functions +*/ +int (*link)(void *ctx,void *event); +void *link_arg; + +struct efc_dma bmbx; + +/* Save pointer to physical memory descriptor for non-embedded +* SLI_CONFIG commands for BMBX dumping purposes +*/ +struct efc_dma *bmbx_non_emb_pmd; + +struct efc_dma vpd_data; + u32 vpd_length; +}; +#endif /* !_SLI4_H */ Signature · 1 line
2.16.4
Thanks,
Daniel
Re: [PATCH v3 03/31] elx: libefc_sli: Data structures and defines for mbox commands
In reply to James SmartQuoted 25 lines · James Smart
This patch continues the
libefc_sliSLI-4 library population.This patch adds definitions for SLI-4 mailbox commands and responses.
Signed-off-by Ram Vegesna <[email protected]>Signed-off-by James Smart <[email protected]>---
v3:
Changed anonymous enums to named.
Split gaint enums into multiple enums.
Single Enum to #define
Added Link Speed defines to accommodate upto 128G SLI defines to spell out_MASKvalue directly. Changed multiple defines to named Enums for consistency.--- drivers/scsi/elx/libefc_sli/sli4.h | 1677 ++++++++++++++++++++++++++++++++++++ 1 file changed, 1677 insertions(+)drivers/scsi/elx/libefc_sli/sli4.h +0
-0
drivers/scsi/elx/libefc_sli/sli4.h enum sli4_els_cmd_type { · line 2013
Quoted 4 lines
drivers/scsi/elx/libefc_sli/sli4.h +1
-0@@ -2010,4 +2010,1681 @@ enum sli4_els_cmd_type { SLI4_ELS_REQUEST64_CMD_FABRIC = 0x0d, }; +#define SLI_PAGE_SIZE (1 << 12)/* 4096 */
SZ_4k?
Quoted 143 lines
drivers/scsi/elx/libefc_sli/sli4.h +143
-0+#define SLI_SUB_PAGE_MASK (SLI_PAGE_SIZE - 1) +#define SLI_ROUND_PAGE (b) (((b) + SLI_SUB_PAGE_MASK) & ~SLI_SUB_PAGE_MASK) + +#define SLI4_BMBX_TIMEOUT_MSEC 30000 +#define SLI4_FW_READY_TIMEOUT_MSEC 30000 + +#define SLI4_BMBX_DELAY_US 1000/* 1 ms */ +#define SLI4_INIT_PORT_DELAY_US 10000/* 10 ms */ + +static inline u32 +sli_page_count (size_t bytes,u32 page_size) +{ +if (!page_size) +return 0 ; + +return (bytes + (page_size -1 )) >>__ffs (page_size); +} + +/************************************************************************* +* SLI-4 mailbox command formats and definitions +*/ + +struct sli4_mbox_command_header { +u8 resvd0; +u8 command; +__le16 status;/* Port writes to indicate success/fail */ +}; + +enum sli4_mbx_cmd_value { +MBX_CMD_CONFIG_LINK =0x07 , +MBX_CMD_DUMP =0x17 , +MBX_CMD_DOWN_LINK =0x06 , +MBX_CMD_INIT_LINK =0x05 , +MBX_CMD_INIT_VFI =0xa3 , +MBX_CMD_INIT_VPI =0xa4 , +MBX_CMD_POST_XRI =0xa7 , +MBX_CMD_RELEASE_XRI =0xac , +MBX_CMD_READ_CONFIG =0x0b , +MBX_CMD_READ_STATUS =0x0e , +MBX_CMD_READ_NVPARMS =0x02 , +MBX_CMD_READ_REV =0x11 , +MBX_CMD_READ_LNK_STAT =0x12 , +MBX_CMD_READ_SPARM64 =0x8d , +MBX_CMD_READ_TOPOLOGY =0x95 , +MBX_CMD_REG_FCFI =0xa0 , +MBX_CMD_REG_FCFI_MRQ =0xaf , +MBX_CMD_REG_RPI =0x93 , +MBX_CMD_REG_RX_RQ =0xa6 , +MBX_CMD_REG_VFI =0x9f , +MBX_CMD_REG_VPI =0x96 , +MBX_CMD_RQST_FEATURES =0x9d , +MBX_CMD_SLI_CONFIG =0x9b , +MBX_CMD_UNREG_FCFI =0xa2 , +MBX_CMD_UNREG_RPI =0x14 , +MBX_CMD_UNREG_VFI =0xa1 , +MBX_CMD_UNREG_VPI =0x97 , +MBX_CMD_WRITE_NVPARMS =0x03 , +MBX_CMD_CFG_AUTO_XFER_RDY =0xAD , +}; + +enum sli4_mbx_status { +MBX_STATUS_SUCCESS =0x0000 , +MBX_STATUS_FAILURE =0x0001 , +MBX_STATUS_RPI_NOT_REG =0x1400 , +}; + +/* CONFIG_LINK */ +enum sli4_cmd_config_link_flags { +SLI4_CFG_LINK_BBSCN =0xf00 , +SLI4_CFG_LINK_CSCN =0x1000 , +}; + +struct sli4_cmd_config_link { +struct sli4_mbox_command_header hdr; +u8 maxbbc; +u8 rsvd5; +u8 rsvd6; +u8 rsvd7; +u8 alpa; +__le16 n_port_id; +u8 rsvd11; +__le32 rsvd12; +__le32 e_d_tov; +__le32 lp_tov; +__le32 r_a_tov; +__le32 r_t_tov; +__le32 al_tov; +__le32 rsvd36; +__le32 bbscn_dword; +}; + +#define SLI4_DUMP4_TYPE 0xf + +#define SLI4_WKI_TAG_SAT_TEM 0x1040 + +struct sli4_cmd_dump4 { +struct sli4_mbox_command_header hdr; +__le32 type_dword; +__le16 wki_selection; +__le16 rsvd10; +__le32 rsvd12; +__le32 returned_byte_cnt; +__le32 resp_data[59 ]; +}; + +/* INIT_LINK - initialize the link for a FC port */ +enum sli4_init_link_flags { +SLI4_INIT_LINK_F_LOOPBACK = (1 <<0 ), + +SLI4_INIT_LINK_F_P2P_ONLY = (1 <<1 ), +SLI4_INIT_LINK_F_FCAL_ONLY = (2 <<1 ), +SLI4_INIT_LINK_F_FCAL_FAIL_OVER = (0 <<1 ), +SLI4_INIT_LINK_F_P2P_FAIL_OVER = (1 <<1 ), + +SLI4_INIT_LINK_F_UNFAIR = (1 <<6 ), +SLI4_INIT_LINK_F_NO_LIRP = (1 <<7 ), +SLI4_INIT_LINK_F_LOOP_VALID_CHK = (1 <<8 ), +SLI4_INIT_LINK_F_NO_LISA = (1 <<9 ), +SLI4_INIT_LINK_F_FAIL_OVER = (1 <<10 ), +SLI4_INIT_LINK_F_FIXED_SPEED = (1 <<11 ), +SLI4_INIT_LINK_F_PICK_HI_ALPA = (1 <<15 ), + +}; + +enum sli4_fc_link_speed { +FC_LINK_SPEED_1G =1 , +FC_LINK_SPEED_2G , +FC_LINK_SPEED_AUTO_1_2 , +FC_LINK_SPEED_4G , +FC_LINK_SPEED_AUTO_4_1 , +FC_LINK_SPEED_AUTO_4_2 , +FC_LINK_SPEED_AUTO_4_2_1 , +FC_LINK_SPEED_8G , +FC_LINK_SPEED_AUTO_8_1 , +FC_LINK_SPEED_AUTO_8_2 , +FC_LINK_SPEED_AUTO_8_2_1 , +FC_LINK_SPEED_AUTO_8_4 , +FC_LINK_SPEED_AUTO_8_4_1 , +FC_LINK_SPEED_AUTO_8_4_2 , +FC_LINK_SPEED_10G , +FC_LINK_SPEED_16G , +FC_LINK_SPEED_AUTO_16_8_4 , +FC_LINK_SPEED_AUTO_16_8 ,
drivers/scsi/elx/libefc_sli/sli4.h enum sli4_els_cmd_type { · line 2166
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h +10
-0+FC_LINK_SPEED_32G , +FC_LINK_SPEED_AUTO_32_16_8 , +FC_LINK_SPEED_AUTO_32_16 , +FC_LINK_SPEED_64G , +FC_LINK_SPEED_AUTO_64_32_16 , +FC_LINK_SPEED_AUTO_64_32 , +FC_LINK_SPEED_128G , +FC_LINK_SPEED_AUTO_128_64_32 , + FC_LINK_SPEED_AUTO_128_64, +};
Please don't use the generic 'FC_LINK_SPEED_' prefix here; chances are that it might clash with a generic definition eg from libfc. SLI4_LINK_SPEED_?
Quoted 670 lines
drivers/scsi/elx/libefc_sli/sli4.h +670
-0+ +struct sli4_cmd_init_link { +struct sli4_mbox_command_header hdr; +__le32 sel_reset_al_pa_dword; +__le32 flags0; +__le32 link_speed_sel_code; +}; + +/* INIT_VFI - initialize the VFI resource */ +enum sli4_init_vfi_flags { +SLI4_INIT_VFI_FLAG_VP =0x1000 , +SLI4_INIT_VFI_FLAG_VF =0x2000 , +SLI4_INIT_VFI_FLAG_VT =0x4000 , +SLI4_INIT_VFI_FLAG_VR =0x8000 , + +SLI4_INIT_VFI_VFID =0x1fff , +SLI4_INIT_VFI_PRI =0xe000 , + +SLI4_INIT_VFI_HOP_COUNT =0xff000000 , +}; + +struct sli4_cmd_init_vfi { +struct sli4_mbox_command_header hdr; +__le16 vfi; +__le16 flags0_word; +__le16 fcfi; +__le16 vpi; +__le32 vf_id_pri_dword; +__le32 hop_cnt_dword; +}; + +/* INIT_VPI - initialize the VPI resource */ +struct sli4_cmd_init_vpi { +struct sli4_mbox_command_header hdr; +__le16 vpi; +__le16 vfi; +}; + +/* POST_XRI - post XRI resources to the SLI Port */ +enum sli4_post_xri_flags { +SLI4_POST_XRI_COUNT =0xfff , +SLI4_POST_XRI_FLAG_ENX =0x1000 , +SLI4_POST_XRI_FLAG_DL =0x2000 , +SLI4_POST_XRI_FLAG_DI =0x4000 , +SLI4_POST_XRI_FLAG_VAL =0x8000 , +}; + +struct sli4_cmd_post_xri { +struct sli4_mbox_command_header hdr; +__le16 xri_base; +__le16 xri_count_flags; +}; + +/* RELEASE_XRI - Release XRI resources from the SLI Port */ +enum sli4_release_xri_flags { +SLI4_RELEASE_XRI_REL_XRI_CNT =0x1f , +SLI4_RELEASE_XRI_COUNT =0x1f , +}; + +struct sli4_cmd_release_xri { +struct sli4_mbox_command_header hdr; +__le16 rel_xri_count_word; +__le16 xri_count_word; + +struct { +__le16 xri_tag0; +__le16 xri_tag1; + } xri_tbl[62 ]; +}; + +/* READ_CONFIG - read SLI port configuration parameters */ +struct sli4_cmd_read_config { +struct sli4_mbox_command_header hdr; +}; + +enum sli4_read_cfg_resp_flags { +SLI4_READ_CFG_RESP_RESOURCE_EXT =0x80000000 ,/* DW1 */ +SLI4_READ_CFG_RESP_TOPOLOGY =0xff000000 ,/* DW2 */ +}; + +enum sli4_read_cfg_topo { +SLI4_READ_CFG_TOPO_FC =0x1 ,/* FC topology unknown */ +SLI4_READ_CFG_TOPO_FC_DA =0x2 ,/* FC Direct Attach */ +SLI4_READ_CFG_TOPO_FC_AL =0x3 ,/* FC-AL topology */ +}; + +struct sli4_rsp_read_config { +struct sli4_mbox_command_header hdr; +__le32 ext_dword; +__le32 topology_dword; +__le32 resvd8; +__le16 e_d_tov; +__le16 resvd14; +__le32 resvd16; +__le16 r_a_tov; +__le16 resvd22; +__le32 resvd24; +__le32 resvd28; +__le16 lmt; +__le16 resvd34; +__le32 resvd36; +__le32 resvd40; +__le16 xri_base; +__le16 xri_count; +__le16 rpi_base; +__le16 rpi_count; +__le16 vpi_base; +__le16 vpi_count; +__le16 vfi_base; +__le16 vfi_count; +__le16 resvd60; +__le16 fcfi_count; +__le16 rq_count; +__le16 eq_count; +__le16 wq_count; +__le16 cq_count; +__le32 pad[45 ]; +}; + +/* READ_NVPARMS - read SLI port configuration parameters */ +enum sli4_read_nvparms_flags { +SLI4_READ_NVPARAMS_HARD_ALPA =0xff , +SLI4_READ_NVPARAMS_PREFERRED_D_ID =0xffffff00 , +}; + +struct sli4_cmd_read_nvparms { +struct sli4_mbox_command_header hdr; +__le32 resvd0; +__le32 resvd4; +__le32 resvd8; +__le32 resvd12; +u8 wwpn[8 ]; +u8 wwnn[8 ]; +__le32 hard_alpa_d_id; +}; + +/* WRITE_NVPARMS - write SLI port configuration parameters */ +struct sli4_cmd_write_nvparms { +struct sli4_mbox_command_header hdr; +__le32 resvd0; +__le32 resvd4; +__le32 resvd8; +__le32 resvd12; +u8 wwpn[8 ]; +u8 wwnn[8 ]; +__le32 hard_alpa_d_id; +}; + +/* READ_REV - read the Port revision levels */ +enum { +SLI4_READ_REV_FLAG_SLI_LEVEL =0xf , +SLI4_READ_REV_FLAG_FCOEM =0x10 , +SLI4_READ_REV_FLAG_CEEV =0x60 , +SLI4_READ_REV_FLAG_VPD =0x2000 , + +SLI4_READ_REV_AVAILABLE_LENGTH =0xffffff , +}; + +struct sli4_cmd_read_rev { +struct sli4_mbox_command_header hdr; +__le16 resvd0; +__le16 flags0_word; +__le32 first_hw_rev; +__le32 second_hw_rev; +__le32 resvd12; +__le32 third_hw_rev; +u8 fc_ph_low; +u8 fc_ph_high; +u8 feature_level_low; +u8 feature_level_high; +__le32 resvd24; +__le32 first_fw_id; +u8 first_fw_name[16 ]; +__le32 second_fw_id; +u8 second_fw_name[16 ]; +__le32 rsvd18[30 ]; +__le32 available_length_dword; +struct sli4_dmaaddr hostbuf; +__le32 returned_vpd_length; +__le32 actual_vpd_length; +}; + +/* READ_SPARM64 - read the Port service parameters */ +#define SLI4_READ_SPARM64_WWPN_OFFSET (4 * sizeof(u32)) +#define SLI4_READ_SPARM64_WWNN_OFFSET (6 * sizeof(u32)) + +struct sli4_cmd_read_sparm64 { +struct sli4_mbox_command_header hdr; +__le32 resvd0; +__le32 resvd4; +struct sli4_bde bde_64; +__le16 vpi; +__le16 resvd22; +__le16 port_name_start; +__le16 port_name_len; +__le16 node_name_start; +__le16 node_name_len; +}; + +/* READ_TOPOLOGY - read the link event information */ +enum sli4_read_topo_e { +SLI4_READTOPO_ATTEN_TYPE =0xff , +SLI4_READTOPO_FLAG_IL =0x100 , +SLI4_READTOPO_FLAG_PB_RECVD =0x200 , + +SLI4_READTOPO_LINKSTATE_RECV =0x3 , +SLI4_READTOPO_LINKSTATE_TRANS =0xc , +SLI4_READTOPO_LINKSTATE_MACHINE =0xf0 , +SLI4_READTOPO_LINKSTATE_SPEED =0xff00 , +SLI4_READTOPO_LINKSTATE_TF =0x40000000 , +SLI4_READTOPO_LINKSTATE_LU =0x80000000 , + +SLI4_READTOPO_SCN_BBSCN =0xf , +SLI4_READTOPO_SCN_CBBSCN =0xf0 , + +SLI4_READTOPO_R_T_TOV =0x1ff , +SLI4_READTOPO_AL_TOV =0xf000 , + +SLI4_READTOPO_PB_FLAG =0x80 , + +SLI4_READTOPO_INIT_N_PORTID =0xffffff , +}; + +#define SLI4_MIN_LOOP_MAP_BYTES 128 + +struct sli4_cmd_read_topology { +struct sli4_mbox_command_header hdr; +__le32 event_tag; +__le32 dw2_attentype; +u8 topology; +u8 lip_type; +u8 lip_al_ps; +u8 al_pa_granted; +struct sli4_bde bde_loop_map; +__le32 linkdown_state; +__le32 currlink_state; +u8 max_bbc; +u8 init_bbc; +u8 scn_flags; +u8 rsvd39; +__le16 dw10w0_al_rt_tov; +__le16 lp_tov; +u8 acquired_al_pa; +u8 pb_flags; +__le16 specified_al_pa; +__le32 dw12_init_n_port_id; +}; + +enum sli4_read_topo_link { +SLI4_READ_TOPOLOGY_LINK_UP =0x1 , +SLI4_READ_TOPOLOGY_LINK_DOWN , +SLI4_READ_TOPOLOGY_LINK_NO_ALPA , +}; + +enum sli4_read_topo { +SLI4_READ_TOPOLOGY_UNKNOWN =0x0 , +SLI4_READ_TOPOLOGY_NPORT , +SLI4_READ_TOPOLOGY_FC_AL , +}; + +enum sli4_read_topo_speed { +SLI4_READ_TOPOLOGY_SPEED_NONE =0x00 , +SLI4_READ_TOPOLOGY_SPEED_1G =0x04 , +SLI4_READ_TOPOLOGY_SPEED_2G =0x08 , +SLI4_READ_TOPOLOGY_SPEED_4G =0x10 , +SLI4_READ_TOPOLOGY_SPEED_8G =0x20 , +SLI4_READ_TOPOLOGY_SPEED_10G =0x40 , +SLI4_READ_TOPOLOGY_SPEED_16G =0x80 , +SLI4_READ_TOPOLOGY_SPEED_32G =0x90 , +}; + +/* REG_FCFI - activate a FC Forwarder */ +struct sli4_cmd_reg_fcfi_rq_cfg { +u8 r_ctl_mask; +u8 r_ctl_match; +u8 type_mask; +u8 type_match; +}; + +enum sli4_regfcfi_tag { +SLI4_REGFCFI_VLAN_TAG =0xfff , +SLI4_REGFCFI_VLANTAG_VALID =0x1000 , +}; + +#define SLI4_CMD_REG_FCFI_NUM_RQ_CFG 4 +struct sli4_cmd_reg_fcfi { +struct sli4_mbox_command_header hdr; +__le16 fcf_index; +__le16 fcfi; +__le16 rqid1; +__le16 rqid0; +__le16 rqid3; +__le16 rqid2; +struct sli4_cmd_reg_fcfi_rq_cfg + rq_cfg[SLI4_CMD_REG_FCFI_NUM_RQ_CFG ]; +__le32 dw8_vlan; +}; + +#define SLI4_CMD_REG_FCFI_MRQ_NUM_RQ_CFG 4 +#define SLI4_CMD_REG_FCFI_MRQ_MAX_NUM_RQ 32 +#define SLI4_CMD_REG_FCFI_SET_FCFI_MODE 0 +#define SLI4_CMD_REG_FCFI_SET_MRQ_MODE 1 + +enum sli4_reg_fcfi_mrq { +SLI4_REGFCFI_MRQ_VLAN_TAG =0xfff , +SLI4_REGFCFI_MRQ_VLANTAG_VALID =0x1000 , +SLI4_REGFCFI_MRQ_MODE =0x2000 , + +SLI4_REGFCFI_MRQ_MASK_NUM_PAIRS =0xff , +SLI4_REGFCFI_MRQ_FILTER_BITMASK =0xf00 , +SLI4_REGFCFI_MRQ_RQ_SEL_POLICY =0xf000 , +}; + +struct sli4_cmd_reg_fcfi_mrq { +struct sli4_mbox_command_header hdr; +__le16 fcf_index; +__le16 fcfi; +__le16 rqid1; +__le16 rqid0; +__le16 rqid3; +__le16 rqid2; +struct sli4_cmd_reg_fcfi_rq_cfg + rq_cfg[SLI4_CMD_REG_FCFI_MRQ_NUM_RQ_CFG ]; +__le32 dw8_vlan; +__le32 dw9_mrqflags; +}; + +struct sli4_cmd_rq_cfg { +__le16 rq_id; +u8 r_ctl_mask; +u8 r_ctl_match; +u8 type_mask; +u8 type_match; +}; + +/* REG_RPI - register a Remote Port Indicator */ +enum sli4_reg_rpi { +SLI4_REGRPI_REMOTE_N_PORTID =0xffffff ,/* DW2 */ +SLI4_REGRPI_UPD =0x1000000 , +SLI4_REGRPI_ETOW =0x8000000 , +SLI4_REGRPI_TERP =0x20000000 , +SLI4_REGRPI_CI =0x80000000 , +}; + +struct sli4_cmd_reg_rpi { +struct sli4_mbox_command_header hdr; +__le16 rpi; +__le16 rsvd2; +__le32 dw2_rportid_flags; +struct sli4_bde bde_64; +__le16 vpi; +__le16 rsvd26; +}; + +#define SLI4_REG_RPI_BUF_LEN 0x70 + +/* REG_VFI - register a Virtual Fabric Indicator */ +enum sli_reg_vfi { +SLI4_REGVFI_VP =0x1000 ,/* DW1 */ +SLI4_REGVFI_UPD =0x2000 , + +SLI4_REGVFI_LOCAL_N_PORTID =0xffffff ,/* DW10 */ +}; + +struct sli4_cmd_reg_vfi { +struct sli4_mbox_command_header hdr; +__le16 vfi; +__le16 dw0w1_flags; +__le16 fcfi; +__le16 vpi; +u8 wwpn[8 ]; +struct sli4_bde sparm; +__le32 e_d_tov; +__le32 r_a_tov; +__le32 dw10_lportid_flags; +}; + +/* REG_VPI - register a Virtual Port Indicator */ +enum sli4_reg_vpi { +SLI4_REGVPI_LOCAL_N_PORTID =0xffffff , +SLI4_REGVPI_UPD =0x1000000 , +}; + +struct sli4_cmd_reg_vpi { +struct sli4_mbox_command_header hdr; +__le32 rsvd0; +__le32 dw2_lportid_flags; +u8 wwpn[8 ]; +__le32 rsvd12; +__le16 vpi; +__le16 vfi; +}; + +/* REQUEST_FEATURES - request / query SLI features */ +enum sli4_req_features_flags { +SLI4_REQFEAT_QRY =0x1 ,/* Dw1 */ + +SLI4_REQFEAT_IAAB = (1 <<0 ),/* DW2 & DW3 */ +SLI4_REQFEAT_NPIV = (1 <<1 ), +SLI4_REQFEAT_DIF = (1 <<2 ), +SLI4_REQFEAT_VF = (1 <<3 ), +SLI4_REQFEAT_FCPI = (1 <<4 ), +SLI4_REQFEAT_FCPT = (1 <<5 ), +SLI4_REQFEAT_FCPC = (1 <<6 ), +SLI4_REQFEAT_RSVD = (1 <<7 ), +SLI4_REQFEAT_RQD = (1 <<8 ), +SLI4_REQFEAT_IAAR = (1 <<9 ), +SLI4_REQFEAT_HLM = (1 <<10 ), +SLI4_REQFEAT_PERFH = (1 <<11 ), +SLI4_REQFEAT_RXSEQ = (1 <<12 ), +SLI4_REQFEAT_RXRI = (1 <<13 ), +SLI4_REQFEAT_DCL2 = (1 <<14 ), +SLI4_REQFEAT_RSCO = (1 <<15 ), +SLI4_REQFEAT_MRQP = (1 <<16 ), +}; + +struct sli4_cmd_request_features { +struct sli4_mbox_command_header hdr; +__le32 dw1_qry; +__le32 cmd; +__le32 resp; +}; + +/* +* SLI_CONFIG - submit a configuration command to Port +* +* Command is either embedded as part of the payload (embed) or located +* in a separate memory buffer (mem) +*/ +enum sli4_sli_config { +SLI4_SLICONF_EMB =0x1 ,/* DW1 */ +SLI4_SLICONF_PMDCMD_SHIFT =3 , +SLI4_SLICONF_PMDCMD_MASK =0xF8 , +SLI4_SLICONF_PMDCMD_VAL_1 =8 , +SLI4_SLICONF_PMDCNT =0xF8 , + +SLI4_SLICONFIG_PMD_LEN =0x00ffffff , +}; + +struct sli4_cmd_sli_config { +struct sli4_mbox_command_header hdr; +__le32 dw1_flags; +__le32 payload_len; +__le32 rsvd12[3 ]; +union { +u8 embed[58 *sizeof (u32)]; +struct sli4_bufptr mem; + } payload; +}; + +/* READ_STATUS - read tx/rx status of a particular port */ +#define SLI4_READSTATUS_CLEAR_COUNTERS 0x1 + +struct sli4_cmd_read_status { +struct sli4_mbox_command_header hdr; +__le32 dw1_flags; +__le32 rsvd4; +__le32 trans_kbyte_cnt; +__le32 recv_kbyte_cnt; +__le32 trans_frame_cnt; +__le32 recv_frame_cnt; +__le32 trans_seq_cnt; +__le32 recv_seq_cnt; +__le32 tot_exchanges_orig; +__le32 tot_exchanges_resp; +__le32 recv_p_bsy_cnt; +__le32 recv_f_bsy_cnt; +__le32 no_rq_buf_dropped_frames_cnt; +__le32 empty_rq_timeout_cnt; +__le32 no_xri_dropped_frames_cnt; +__le32 empty_xri_pool_cnt; +}; + +/* READ_LNK_STAT - read link status of a particular port */ +enum sli4_read_link_stats_flags { +SLI4_READ_LNKSTAT_REC = (1 <<0 ), +SLI4_READ_LNKSTAT_GEC = (1 <<1 ), +SLI4_READ_LNKSTAT_W02OF = (1 <<2 ), +SLI4_READ_LNKSTAT_W03OF = (1 <<3 ), +SLI4_READ_LNKSTAT_W04OF = (1 <<4 ), +SLI4_READ_LNKSTAT_W05OF = (1 <<5 ), +SLI4_READ_LNKSTAT_W06OF = (1 <<6 ), +SLI4_READ_LNKSTAT_W07OF = (1 <<7 ), +SLI4_READ_LNKSTAT_W08OF = (1 <<8 ), +SLI4_READ_LNKSTAT_W09OF = (1 <<9 ), +SLI4_READ_LNKSTAT_W10OF = (1 <<10 ), +SLI4_READ_LNKSTAT_W11OF = (1 <<11 ), +SLI4_READ_LNKSTAT_W12OF = (1 <<12 ), +SLI4_READ_LNKSTAT_W13OF = (1 <<13 ), +SLI4_READ_LNKSTAT_W14OF = (1 <<14 ), +SLI4_READ_LNKSTAT_W15OF = (1 <<15 ), +SLI4_READ_LNKSTAT_W16OF = (1 <<16 ), +SLI4_READ_LNKSTAT_W17OF = (1 <<17 ), +SLI4_READ_LNKSTAT_W18OF = (1 <<18 ), +SLI4_READ_LNKSTAT_W19OF = (1 <<19 ), +SLI4_READ_LNKSTAT_W20OF = (1 <<20 ), +SLI4_READ_LNKSTAT_W21OF = (1 <<21 ), +SLI4_READ_LNKSTAT_CLRC = (1 <<30 ), +SLI4_READ_LNKSTAT_CLOF = (1 <<31 ), +}; + +struct sli4_cmd_read_link_stats { +struct sli4_mbox_command_header hdr; +__le32 dw1_flags; +__le32 linkfail_errcnt; +__le32 losssync_errcnt; +__le32 losssignal_errcnt; +__le32 primseq_errcnt; +__le32 inval_txword_errcnt; +__le32 crc_errcnt; +__le32 primseq_eventtimeout_cnt; +__le32 elastic_bufoverrun_errcnt; +__le32 arbit_fc_al_timeout_cnt; +__le32 adv_rx_buftor_to_buf_credit; +__le32 curr_rx_buf_to_buf_credit; +__le32 adv_tx_buf_to_buf_credit; +__le32 curr_tx_buf_to_buf_credit; +__le32 rx_eofa_cnt; +__le32 rx_eofdti_cnt; +__le32 rx_eofni_cnt; +__le32 rx_soff_cnt; +__le32 rx_dropped_no_aer_cnt; +__le32 rx_dropped_no_avail_rpi_rescnt; +__le32 rx_dropped_no_avail_xri_rescnt; +}; + +/* Format a WQE with WQ_ID Association performance hint */ +static inline void +sli_set_wq_id_association (void *entry,u16 q_id) +{ +u32 *wqe = entry; + +/* +* Set Word 10, bit 0 to zero +* Set Word 10, bits 15:1 to the WQ ID +*/ + wqe[10 ] &= ~0xffff ; + wqe[10 ] |= q_id <<1 ; +} + +/* UNREG_FCFI - unregister a FCFI */ +struct sli4_cmd_unreg_fcfi { +struct sli4_mbox_command_header hdr; +__le32 rsvd0; +__le16 fcfi; +__le16 rsvd6; +}; + +/* UNREG_RPI - unregister one or more RPI */ +enum sli4_unreg_rpi { +UNREG_RPI_DP =0x2000 , +UNREG_RPI_II_SHIFT =14 , +UNREG_RPI_II_MASK =0xC000 , +UNREG_RPI_II_RPI =0x0000 , +UNREG_RPI_II_VPI =0x4000 , +UNREG_RPI_II_VFI =0x8000 , +UNREG_RPI_II_FCFI =0xC000 , + +UNREG_RPI_DEST_N_PORTID_MASK =0x00ffffff , +}; + +struct sli4_cmd_unreg_rpi { +struct sli4_mbox_command_header hdr; +__le16 index; +__le16 dw1w1_flags; +__le32 dw2_dest_n_portid; +}; + +/* UNREG_VFI - unregister one or more VFI */ +enum sli4_unreg_vfi { +UNREG_VFI_II_SHIFT =14 , +UNREG_VFI_II_MASK =0xC000 , +UNREG_VFI_II_VFI =0x0000 , +UNREG_VFI_II_FCFI =0xC000 , +}; + +struct sli4_cmd_unreg_vfi { +struct sli4_mbox_command_header hdr; +__le32 rsvd0; +__le16 index; +__le16 dw2_flags; +}; + +enum sli4_unreg_type { +SLI4_UNREG_TYPE_PORT , +SLI4_UNREG_TYPE_DOMAIN , +SLI4_UNREG_TYPE_FCF , +SLI4_UNREG_TYPE_ALL +}; + +/* UNREG_VPI - unregister one or more VPI */ +enum sli4_unreg_vpi { +UNREG_VPI_II_SHIFT =14 , +UNREG_VPI_II_MASK =0xC000 , +UNREG_VPI_II_VPI =0x0000 , +UNREG_VPI_II_VFI =0x8000 , +UNREG_VPI_II_FCFI =0xC000 , +}; + +struct sli4_cmd_unreg_vpi { +struct sli4_mbox_command_header hdr; +__le32 rsvd0; +__le16 index; +__le16 dw2w0_flags; +}; + +/* AUTO_XFER_RDY - Configure the auto-generate XFER-RDY feature */ +struct sli4_cmd_config_auto_xfer_rdy { +struct sli4_mbox_command_header hdr; +__le32 rsvd0; +__le32 max_burst_len; +}; + +#define SLI4_CONFIG_AUTO_XFERRDY_BLKSIZE 0xffff + +struct sli4_cmd_config_auto_xfer_rdy_hp { +struct sli4_mbox_command_header hdr; +__le32 rsvd0; +__le32 max_burst_len; +__le32 dw3_esoc_flags; +__le16 block_size; +__le16 rsvd14; +}; + +/************************************************************************* +* SLI-4 common configuration command formats and definitions +*/ + +/* +* Subsystem values. +*/ +enum sli4_subsystem { +SLI4_SUBSYSTEM_COMMON =0x01 , +SLI4_SUBSYSTEM_LOWLEVEL =0x0B , +SLI4_SUBSYSTEM_FC =0x0C , +SLI4_SUBSYSTEM_DMTF =0x11 , +}; + +#define SLI4_OPC_LOWLEVEL_SET_WATCHDOG 0X36 + +/* +* Common opcode (OPC) values. +*/ +enum sli4_cmn_opcode { +CMN_FUNCTION_RESET =0x3d , +CMN_CREATE_CQ =0x0c , +CMN_CREATE_CQ_SET =0x1d , +CMN_DESTROY_CQ =0x36 , +CMN_MODIFY_EQ_DELAY =0x29 , +CMN_CREATE_EQ =0x0d , +CMN_DESTROY_EQ =0x37 , +CMN_CREATE_MQ_EXT =0x5a , +CMN_DESTROY_MQ =0x35 , +CMN_GET_CNTL_ATTRIBUTES =0x20 , +CMN_NOP =0x21 , +CMN_GET_RSC_EXTENT_INFO =0x9a , +CMN_GET_SLI4_PARAMS =0xb5 , +CMN_QUERY_FW_CONFIG =0x3a , +CMN_GET_PORT_NAME =0x4d , + +CMN_WRITE_FLASHROM =0x07 , +/* TRANSCEIVER Data */ +CMN_READ_TRANS_DATA =0x49 , +CMN_GET_CNTL_ADDL_ATTRS =0x79 , +CMN_GET_FUNCTION_CFG =0xa0 , +CMN_GET_PROFILE_CFG =0xa4 , +CMN_SET_PROFILE_CFG =0xa5 , +CMN_GET_PROFILE_LIST =0xa6 , +CMN_GET_ACTIVE_PROFILE =0xa7 , +CMN_SET_ACTIVE_PROFILE =0xa8 ,
drivers/scsi/elx/libefc_sli/sli4.h enum sli4_els_cmd_type { · line 2846
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h +10
-0+CMN_READ_OBJECT =0xab , +CMN_WRITE_OBJECT =0xac , +CMN_DELETE_OBJECT =0xae , +CMN_READ_OBJECT_LIST =0xad , +CMN_SET_DUMP_LOCATION =0xb8 , +CMN_SET_FEATURES =0xbf , +CMN_GET_RECFG_LINK_INFO =0xc9 , + CMN_SET_RECNG_LINK_ID = 0xca, +}; +
Same here; please prefix with SLI4_
Quoted 225 lines
drivers/scsi/elx/libefc_sli/sli4.h +225
-0+/* DMTF opcode (OPC) values */ +#define DMTF_EXEC_CLP_CMD 0x01 + +/* +* COMMON_FUNCTION_RESET +* +* Resets the Port, returning it to a power-on state. This configuration +* command does not have a payload and should set/expect the lengths to +* be zero. +*/ +struct sli4_rqst_cmn_function_reset { +struct sli4_rqst_hdr hdr; +}; + +struct sli4_rsp_cmn_function_reset { +struct sli4_rsp_hdr hdr; +}; + + +/* +* COMMON_GET_CNTL_ATTRIBUTES +* +* Query for information about the SLI Port +*/ +enum sli4_cntrl_attr_flags { +SLI4_CNTL_ATTR_PORTNUM =0x3f , +SLI4_CNTL_ATTR_PORTTYPE =0xc0 , +}; + +struct sli4_rsp_cmn_get_cntl_attributes { +struct sli4_rsp_hdr hdr; +u8 version_str[32 ]; +u8 manufacturer_name[32 ]; +__le32 supported_modes; +u8 eprom_version_lo; +u8 eprom_version_hi; +__le16 rsvd17; +__le32 mbx_ds_version; +__le32 ep_fw_ds_version; +u8 ncsi_version_str[12 ]; +__le32 def_extended_timeout; +u8 model_number[32 ]; +u8 description[64 ]; +u8 serial_number[32 ]; +u8 ip_version_str[32 ]; +u8 fw_version_str[32 ]; +u8 bios_version_str[32 ]; +u8 redboot_version_str[32 ]; +u8 driver_version_str[32 ]; +u8 fw_on_flash_version_str[32 ]; +__le32 functionalities_supported; +__le16 max_cdb_length; +u8 asic_revision; +u8 generational_guid0; +__le32 generational_guid1_12[3 ]; +__le16 generational_guid13_14; +u8 generational_guid15; +u8 hba_port_count; +__le16 default_link_down_timeout; +u8 iscsi_version_min_max; +u8 multifunctional_device; +u8 cache_valid; +u8 hba_status; +u8 max_domains_supported; +u8 port_num_type_flags; +__le32 firmware_post_status; +__le32 hba_mtu; +u8 iscsi_features; +u8 rsvd121[3 ]; +__le16 pci_vendor_id; +__le16 pci_device_id; +__le16 pci_sub_vendor_id; +__le16 pci_sub_system_id; +u8 pci_bus_number; +u8 pci_device_number; +u8 pci_function_number; +u8 interface_type; +__le64 unique_identifier; +u8 number_of_netfilters; +u8 rsvd122[3 ]; +}; + +/* +* COMMON_GET_CNTL_ATTRIBUTES +* +* This command queries the controller information from the Flash ROM. +*/ +struct sli4_rqst_cmn_get_cntl_addl_attributes { +struct sli4_rqst_hdr hdr; +}; + +struct sli4_rsp_cmn_get_cntl_addl_attributes { +struct sli4_rsp_hdr hdr; +__le16 ipl_file_number; +u8 ipl_file_version; +u8 rsvd4; +u8 on_die_temperature; +u8 rsvd5[3 ]; +__le32 driver_advanced_features_supported; +__le32 rsvd7[4 ]; +char universal_bios_version[32 ]; +char x86_bios_version[32 ]; +char efi_bios_version[32 ]; +char fcode_version[32 ]; +char uefi_bios_version[32 ]; +char uefi_nic_version[32 ]; +char uefi_fcode_version[32 ]; +char uefi_iscsi_version[32 ]; +char iscsi_x86_bios_version[32 ]; +char pxe_x86_bios_version[32 ]; +u8 default_wwpn[8 ]; +u8 ext_phy_version[32 ]; +u8 fc_universal_bios_version[32 ]; +u8 fc_x86_bios_version[32 ]; +u8 fc_efi_bios_version[32 ]; +u8 fc_fcode_version[32 ]; +u8 ext_phy_crc_label[8 ]; +u8 ipl_file_name[16 ]; +u8 rsvd139[72 ]; +}; + +/* +* COMMON_NOP +* +* This command does not do anything; it only returns +* the payload in the completion. +*/ +struct sli4_rqst_cmn_nop { +struct sli4_rqst_hdr hdr; +__le32 context[2 ]; +}; + +struct sli4_rsp_cmn_nop { +struct sli4_rsp_hdr hdr; +__le32 context[2 ]; +}; + +struct sli4_rqst_cmn_get_resource_extent_info { +struct sli4_rqst_hdr hdr; +__le16 resource_type; +__le16 rsvd16; +}; + +enum sli4_rsc_type { +SLI4_RSC_TYPE_VFI =0x20 , +SLI4_RSC_TYPE_VPI =0x21 , +SLI4_RSC_TYPE_RPI =0x22 , +SLI4_RSC_TYPE_XRI =0x23 , +}; + +struct sli4_rsp_cmn_get_resource_extent_info { +struct sli4_rsp_hdr hdr; +__le16 resource_extent_count; +__le16 resource_extent_size; +}; + +#define SLI4_128BYTE_WQE_SUPPORT 0x02 + +#define GET_Q_CNT_METHOD (m) \ + (((m) & RSP_GET_PARAM_Q_CNT_MTHD_MASK) >> RSP_GET_PARAM_Q_CNT_MTHD_SHFT) +#define GET_Q_CREATE_VERSION (v) \ + (((v) & RSP_GET_PARAM_QV_MASK) >> RSP_GET_PARAM_QV_SHIFT) + +enum sli4_rsp_get_params_e { +/*GENERIC*/ +RSP_GET_PARAM_Q_CNT_MTHD_SHFT =24 , +RSP_GET_PARAM_Q_CNT_MTHD_MASK = (0xF <<24 ), +RSP_GET_PARAM_QV_SHIFT =14 , +RSP_GET_PARAM_QV_MASK = (3 <<14 ), + +/* DW4 */ +RSP_GET_PARAM_PROTO_TYPE_MASK =0xFF , +/* DW5 */ +RSP_GET_PARAM_FT = (1 <<0 ), +RSP_GET_PARAM_SLI_REV_MASK = (0xF <<4 ), +RSP_GET_PARAM_SLI_FAM_MASK = (0xF <<8 ), +RSP_GET_PARAM_IF_TYPE_MASK = (0xF <<12 ), +RSP_GET_PARAM_SLI_HINT1_MASK = (0xFF <<16 ), +RSP_GET_PARAM_SLI_HINT2_MASK = (0x1F <<24 ), +/* DW6 */ +RSP_GET_PARAM_EQ_PAGE_CNT_MASK = (0xF <<0 ), +RSP_GET_PARAM_EQE_SZS_MASK = (0xF <<8 ), +RSP_GET_PARAM_EQ_PAGE_SZS_MASK = (0xFF <<16 ), +/* DW8 */ +RSP_GET_PARAM_CQ_PAGE_CNT_MASK = (0xF <<0 ), +RSP_GET_PARAM_CQE_SZS_MASK = (0xF <<8 ), +RSP_GET_PARAM_CQ_PAGE_SZS_MASK = (0xFF <<16 ), +/* DW10 */ +RSP_GET_PARAM_MQ_PAGE_CNT_MASK = (0xF <<0 ), +RSP_GET_PARAM_MQ_PAGE_SZS_MASK = (0xFF <<16 ), +/* DW12 */ +RSP_GET_PARAM_WQ_PAGE_CNT_MASK = (0xF <<0 ), +RSP_GET_PARAM_WQE_SZS_MASK = (0xF <<8 ), +RSP_GET_PARAM_WQ_PAGE_SZS_MASK = (0xFF <<16 ), +/* DW14 */ +RSP_GET_PARAM_RQ_PAGE_CNT_MASK = (0xF <<0 ), +RSP_GET_PARAM_RQE_SZS_MASK = (0xF <<8 ), +RSP_GET_PARAM_RQ_PAGE_SZS_MASK = (0xFF <<16 ), +/* DW15W1*/ +RSP_GET_PARAM_RQ_DB_WINDOW_MASK =0xF000 , +/* DW16 */ +RSP_GET_PARAM_FC = (1 <<0 ), +RSP_GET_PARAM_EXT = (1 <<1 ), +RSP_GET_PARAM_HDRR = (1 <<2 ), +RSP_GET_PARAM_SGLR = (1 <<3 ), +RSP_GET_PARAM_FBRR = (1 <<4 ), +RSP_GET_PARAM_AREG = (1 <<5 ), +RSP_GET_PARAM_TGT = (1 <<6 ), +RSP_GET_PARAM_TERP = (1 <<7 ), +RSP_GET_PARAM_ASSI = (1 <<8 ), +RSP_GET_PARAM_WCHN = (1 <<9 ), +RSP_GET_PARAM_TCCA = (1 <<10 ), +RSP_GET_PARAM_TRTY = (1 <<11 ), +RSP_GET_PARAM_TRIR = (1 <<12 ), +RSP_GET_PARAM_PHOFF = (1 <<13 ), +RSP_GET_PARAM_PHON = (1 <<14 ), +RSP_GET_PARAM_PHWQ = (1 <<15 ), +RSP_GET_PARAM_BOUND_4GA = (1 <<16 ), +RSP_GET_PARAM_RXC = (1 <<17 ), +RSP_GET_PARAM_HLM = (1 <<18 ), +RSP_GET_PARAM_IPR = (1 <<19 ), +RSP_GET_PARAM_RXRI = (1 <<20 ), +RSP_GET_PARAM_SGLC = (1 <<21 ), +RSP_GET_PARAM_TIMM = (1 <<22 ), +RSP_GET_PARAM_TSMM = (1 <<23 ),
drivers/scsi/elx/libefc_sli/sli4.h enum sli4_els_cmd_type { · line 3081
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h +10
-0+RSP_GET_PARAM_OAS = (1 <<25 ), +RSP_GET_PARAM_LC = (1 <<26 ), +RSP_GET_PARAM_AGXF = (1 <<27 ), +RSP_GET_PARAM_LOOPBACK_MASK = (0xF <<28 ), +/* DW18 */ +RSP_GET_PARAM_SGL_PAGE_CNT_MASK = (0xF <<0 ), +RSP_GET_PARAM_SGL_PAGE_SZS_MASK = (0xFF <<8 ), + RSP_GET_PARAM_SGL_PP_ALIGN_MASK = (0xFF << 16), +}; +
Same here.
Quoted 91 lines
drivers/scsi/elx/libefc_sli/sli4.h +91
-0+struct sli4_rqst_cmn_get_sli4_params { +struct sli4_rqst_hdr hdr; +}; + +struct sli4_rsp_cmn_get_sli4_params { +struct sli4_rsp_hdr hdr; +__le32 dw4_protocol_type; +__le32 dw5_sli; +__le32 dw6_eq_page_cnt; +__le16 eqe_count_mask; +__le16 rsvd26; +__le32 dw8_cq_page_cnt; +__le16 cqe_count_mask; +__le16 rsvd34; +__le32 dw10_mq_page_cnt; +__le16 mqe_count_mask; +__le16 rsvd42; +__le32 dw12_wq_page_cnt; +__le16 wqe_count_mask; +__le16 rsvd50; +__le32 dw14_rq_page_cnt; +__le16 rqe_count_mask; +__le16 dw15w1_rq_db_window; +__le32 dw16_loopback_scope; +__le32 sge_supported_length; +__le32 dw18_sgl_page_cnt; +__le16 min_rq_buffer_size; +__le16 rsvd75; +__le32 max_rq_buffer_size; +__le16 physical_xri_max; +__le16 physical_rpi_max; +__le16 physical_vpi_max; +__le16 physical_vfi_max; +__le32 rsvd88; +__le16 frag_num_field_offset; +__le16 frag_num_field_size; +__le16 sgl_index_field_offset; +__le16 sgl_index_field_size; +__le32 chain_sge_initial_value_lo; +__le32 chain_sge_initial_value_hi; +}; + +/* +* COMMON_QUERY_FW_CONFIG +* +* This command retrieves firmware configuration parameters and adapter +* resources available to the driver. +*/ +struct sli4_rqst_cmn_query_fw_config { +struct sli4_rqst_hdr hdr; +}; + +struct sli4_rsp_cmn_query_fw_config { +struct sli4_rsp_hdr hdr; +__le32 config_number; +__le32 asic_rev; +__le32 physical_port; +__le32 function_mode; +__le32 ulp0_mode; +__le32 ulp0_nic_wqid_base; +__le32 ulp0_nic_wq_total;/* DW10 */ +__le32 ulp0_toe_wqid_base; +__le32 ulp0_toe_wq_total; +__le32 ulp0_toe_rqid_base; +__le32 ulp0_toe_rq_total; +__le32 ulp0_toe_defrqid_base; +__le32 ulp0_toe_defrq_total; +__le32 ulp0_lro_rqid_base; +__le32 ulp0_lro_rq_total; +__le32 ulp0_iscsi_icd_base; +__le32 ulp0_iscsi_icd_total;/* DW20 */ +__le32 ulp1_mode; +__le32 ulp1_nic_wqid_base; +__le32 ulp1_nic_wq_total; +__le32 ulp1_toe_wqid_base; +__le32 ulp1_toe_wq_total; +__le32 ulp1_toe_rqid_base; +__le32 ulp1_toe_rq_total; +__le32 ulp1_toe_defrqid_base; +__le32 ulp1_toe_defrq_total; +__le32 ulp1_lro_rqid_base;/* DW30 */ +__le32 ulp1_lro_rq_total; +__le32 ulp1_iscsi_icd_base; +__le32 ulp1_iscsi_icd_total; +__le32 function_capabilities; +__le32 ulp0_cq_base; +__le32 ulp0_cq_total; +__le32 ulp0_eq_base; +__le32 ulp0_eq_total; +__le32 ulp0_iscsi_chain_icd_base; +__le32 ulp0_iscsi_chain_icd_total;/* DW40 */
drivers/scsi/elx/libefc_sli/sli4.h enum sli4_els_cmd_type { · line 3182
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h +10
-0+__le32 ulp1_iscsi_chain_icd_base; +__le32 ulp1_iscsi_chain_icd_total; +}; + +/*Port Types*/ +enum sli4_port_types { +PORT_TYPE_ETH =0 , +PORT_TYPE_FC =1 , +}; +
And here.
Quoted 386 lines
drivers/scsi/elx/libefc_sli/sli4.h +386
-0+struct sli4_rqst_cmn_get_port_name { +struct sli4_rqst_hdr hdr; +u8 port_type; +u8 rsvd4[3 ]; +}; + +struct sli4_rsp_cmn_get_port_name { +struct sli4_rsp_hdr hdr; +char port_name[4 ]; +}; + +struct sli4_rqst_cmn_write_flashrom { +struct sli4_rqst_hdr hdr; +__le32 flash_rom_access_opcode; +__le32 flash_rom_access_operation_type; +__le32 data_buffer_size; +__le32 offset; +u8 data_buffer[4 ]; +}; + +/* +* COMMON_READ_TRANSCEIVER_DATA +* +* This command reads SFF transceiver data(Format is defined +* by the SFF-8472 specification). +*/ +struct sli4_rqst_cmn_read_transceiver_data { +struct sli4_rqst_hdr hdr; +__le32 page_number; +__le32 port; +}; + +struct sli4_rsp_cmn_read_transceiver_data { +struct sli4_rsp_hdr hdr; +__le32 page_number; +__le32 port; +u8 page_data[128 ]; +u8 page_data_2[128 ]; +}; + +#define SLI4_REQ_DESIRE_READLEN 0xFFFFFF + +struct sli4_rqst_cmn_read_object { +struct sli4_rqst_hdr hdr; +__le32 desired_read_length_dword; +__le32 read_offset; +u8 object_name[104 ]; +__le32 host_buffer_descriptor_count; +struct sli4_bde host_buffer_descriptor[0 ]; +}; + +#define RSP_COM_READ_OBJ_EOF 0x80000000 + +struct sli4_rsp_cmn_read_object { +struct sli4_rsp_hdr hdr; +__le32 actual_read_length; +__le32 eof_dword; +}; + +enum sli4_rqst_write_object_flags { +SLI4_RQ_DES_WRITE_LEN =0xFFFFFF , +SLI4_RQ_DES_WRITE_LEN_NOC =0x40000000 , +SLI4_RQ_DES_WRITE_LEN_EOF =0x80000000 , +}; + +struct sli4_rqst_cmn_write_object { +struct sli4_rqst_hdr hdr; +__le32 desired_write_len_dword; +__le32 write_offset; +u8 object_name[104 ]; +__le32 host_buffer_descriptor_count; +struct sli4_bde host_buffer_descriptor[0 ]; +}; + +#define RSP_CHANGE_STATUS 0xFF + +struct sli4_rsp_cmn_write_object { +struct sli4_rsp_hdr hdr; +__le32 actual_write_length; +__le32 change_status_dword; +}; + +struct sli4_rqst_cmn_delete_object { +struct sli4_rqst_hdr hdr; +__le32 rsvd4; +__le32 rsvd5; +u8 object_name[104 ]; +}; + +#define SLI4_RQ_OBJ_LIST_READ_LEN 0xFFFFFF + +struct sli4_rqst_cmn_read_object_list { +struct sli4_rqst_hdr hdr; +__le32 desired_read_length_dword; +__le32 read_offset; +u8 object_name[104 ]; +__le32 host_buffer_descriptor_count; +struct sli4_bde host_buffer_descriptor[0 ]; +}; + +enum sli4_rqst_set_dump_flags { +SLI4_CMN_SET_DUMP_BUFFER_LEN =0xFFFFFF , +SLI4_CMN_SET_DUMP_FDB =0x20000000 , +SLI4_CMN_SET_DUMP_BLP =0x40000000 , +SLI4_CMN_SET_DUMP_QRY =0x80000000 , +}; + +struct sli4_rqst_cmn_set_dump_location { +struct sli4_rqst_hdr hdr; +__le32 buffer_length_dword; +__le32 buf_addr_low; +__le32 buf_addr_high; +}; + +struct sli4_rsp_cmn_set_dump_location { +struct sli4_rsp_hdr hdr; +__le32 buffer_length_dword; +}; + +enum sli4_dump_level { +SLI4_DUMP_LEVEL_NONE , +SLI4_CHIP_LEVEL_DUMP , +SLI4_FUNC_DESC_DUMP , +}; + +enum sli4_dump_state { +SLI4_DUMP_STATE_NONE , +SLI4_CHIP_DUMP_STATE_VALID , +SLI4_FUNC_DUMP_STATE_VALID , +}; + +enum sli4_dump_status { +SLI4_DUMP_READY_STATUS_NOT_READY , +SLI4_DUMP_READY_STATUS_DD_PRESENT , +SLI4_DUMP_READY_STATUS_FDB_PRESENT , +SLI4_DUMP_READY_STATUS_SKIP_DUMP , +SLI4_DUMP_READY_STATUS_FAILED =-1 , +}; + +enum sli4_set_features { +SLI4_SET_FEATURES_DIF_SEED =0x01 , +SLI4_SET_FEATURES_XRI_TIMER =0x03 , +SLI4_SET_FEATURES_MAX_PCIE_SPEED =0x04 , +SLI4_SET_FEATURES_FCTL_CHECK =0x05 , +SLI4_SET_FEATURES_FEC =0x06 , +SLI4_SET_FEATURES_PCIE_RECV_DETECT =0x07 , +SLI4_SET_FEATURES_DIF_MEMORY_MODE =0x08 , +SLI4_SET_FEATURES_DISABLE_SLI_PORT_PAUSE_STATE =0x09 , +SLI4_SET_FEATURES_ENABLE_PCIE_OPTIONS =0x0A , +SLI4_SET_FEAT_CFG_AUTO_XFER_RDY_T10PI =0x0C , +SLI4_SET_FEATURES_ENABLE_MULTI_RECEIVE_QUEUE =0x0D , +SLI4_SET_FEATURES_SET_FTD_XFER_HINT =0x0F , +SLI4_SET_FEATURES_SLI_PORT_HEALTH_CHECK =0x11 , +}; + +struct sli4_rqst_cmn_set_features { +struct sli4_rqst_hdr hdr; +__le32 feature; +__le32 param_len; +__le32 params[8 ]; +}; + +struct sli4_rqst_cmn_set_features_dif_seed { +__le16 seed; +__le16 rsvd16; +}; + +enum sli4_rqst_set_mrq_features { +SLI4_RQ_MULTIRQ_ISR =0x1 , +SLI4_RQ_MULTIRQ_AUTOGEN_XFER_RDY =0x2 , + +SLI4_RQ_MULTIRQ_NUM_RQS =0xFF , +SLI4_RQ_MULTIRQ_RQ_SELECT =0xF00 , +}; + +struct sli4_rqst_cmn_set_features_multirq { +__le32 auto_gen_xfer_dword; +__le32 num_rqs_dword; +}; + +enum sli4_rqst_health_check_flags { +SLI4_RQ_HEALTH_CHECK_ENABLE =0x1 , +SLI4_RQ_HEALTH_CHECK_QUERY =0x2 , +}; + +struct sli4_rqst_cmn_set_features_health_check { +__le32 health_check_dword; +}; + +struct sli4_rqst_cmn_set_features_set_fdt_xfer_hint { +__le32 fdt_xfer_hint; +}; + +struct sli4_rqst_dmtf_exec_clp_cmd { +struct sli4_rqst_hdr hdr; +__le32 cmd_buf_length; +__le32 resp_buf_length; +__le32 cmd_buf_addr_low; +__le32 cmd_buf_addr_high; +__le32 resp_buf_addr_low; +__le32 resp_buf_addr_high; +}; + +struct sli4_rsp_dmtf_exec_clp_cmd { +struct sli4_rsp_hdr hdr; +__le32 rsvd4; +__le32 resp_length; +__le32 rsvd6; +__le32 rsvd7; +__le32 rsvd8; +__le32 rsvd9; +__le32 clp_status; +__le32 clp_detailed_status; +}; + +#define SLI4_PROTOCOL_FC 0x10 +#define SLI4_PROTOCOL_DEFAULT 0xff + +struct sli4_rspource_descriptor_v1 { +u8 descriptor_type; +u8 descriptor_length; +__le16 rsvd16; +__le32 type_specific[0 ]; +}; + +enum sli4_pcie_desc_flags { +SLI4_PCIE_DESC_IMM =0x4000 , +SLI4_PCIE_DESC_NOSV =0x8000 , + +SLI4_PCIE_DESC_PF_NO =0x3FF0000 , + +SLI4_PCIE_DESC_MISSN_ROLE =0xFF , +SLI4_PCIE_DESC_PCHG =0x8000000 , +SLI4_PCIE_DESC_SCHG =0x10000000 , +SLI4_PCIE_DESC_XCHG =0x20000000 , +SLI4_PCIE_DESC_XROM =0xC0000000 +}; + +struct sli4_pcie_resource_descriptor_v1 { +u8 descriptor_type; +u8 descriptor_length; +__le16 imm_nosv_dword; +__le32 pf_number_dword; +__le32 rsvd3; +u8 sriov_state; +u8 pf_state; +u8 pf_type; +u8 rsvd4; +__le16 number_of_vfs; +__le16 rsvd5; +__le32 mission_roles_dword; +__le32 rsvd7[16 ]; +}; + +struct sli4_rqst_cmn_get_function_config { +struct sli4_rqst_hdr hdr; +}; + +struct sli4_rsp_cmn_get_function_config { +struct sli4_rsp_hdr hdr; +__le32 desc_count; +__le32 desc[54 ]; +}; + +/* Link Config Descriptor for link config functions */ +struct sli4_link_config_descriptor { +u8 link_config_id; +u8 rsvd1[3 ]; +__le32 config_description[8 ]; +}; + +#define MAX_LINK_DES 10 + +struct sli4_rqst_cmn_get_reconfig_link_info { +struct sli4_rqst_hdr hdr; +}; + +struct sli4_rsp_cmn_get_reconfig_link_info { +struct sli4_rsp_hdr hdr; +u8 active_link_config_id; +u8 rsvd17; +u8 next_link_config_id; +u8 rsvd19; +__le32 link_configuration_descriptor_count; +struct sli4_link_config_descriptor + desc[MAX_LINK_DES ]; +}; + +enum sli4_set_reconfig_link_flags { +SLI4_SET_RECONFIG_LINKID_NEXT =0xff , +SLI4_SET_RECONFIG_LINKID_FD = (1 <<31 ), +}; + +struct sli4_rqst_cmn_set_reconfig_link_id { +struct sli4_rqst_hdr hdr; +__le32 dw4_flags; +}; + +struct sli4_rsp_cmn_set_reconfig_link_id { +struct sli4_rsp_hdr hdr; +}; + +struct sli4_rqst_lowlevel_set_watchdog { +struct sli4_rqst_hdr hdr; +__le16 watchdog_timeout; +__le16 rsvd18; +}; + +struct sli4_rsp_lowlevel_set_watchdog { +struct sli4_rsp_hdr hdr; +__le32 rsvd; +}; + +/* FC opcode (OPC) values */ +enum sli4_fc_opcodes { +SLI4_OPC_WQ_CREATE =0x1 , +SLI4_OPC_WQ_DESTROY =0x2 , +SLI4_OPC_POST_SGL_PAGES =0x3 , +SLI4_OPC_RQ_CREATE =0x5 , +SLI4_OPC_RQ_DESTROY =0x6 , +SLI4_OPC_READ_FCF_TABLE =0x8 , +SLI4_OPC_POST_HDR_TEMPLATES =0xb , +SLI4_OPC_REDISCOVER_FCF =0x10 , +}; + +/* Use the default CQ associated with the WQ */ +#define SLI4_CQ_DEFAULT 0xffff + +/* +* POST_SGL_PAGES +* +* Register the scatter gather list (SGL) memory and +* associate it with an XRI. +*/ +struct sli4_rqst_post_sgl_pages { +struct sli4_rqst_hdr hdr; +__le16 xri_start; +__le16 xri_count; +struct { +__le32 page0_low; +__le32 page0_high; +__le32 page1_low; +__le32 page1_high; + } page_set[10 ]; +}; + +struct sli4_rsp_post_sgl_pages { +struct sli4_rsp_hdr hdr; +}; + +struct sli4_rqst_post_hdr_templates { +struct sli4_rqst_hdr hdr; +__le16 rpi_offset; +__le16 page_count; +struct sli4_dmaaddr page_descriptor[0 ]; +}; + +#define SLI4_HDR_TEMPLATE_SIZE 64 + +enum sli4_io_flags { +/* The XRI associated with this IO is already active */ +SLI4_IO_CONTINUATION = (1 <<0 ), +/* Automatically generate a good RSP frame */ +SLI4_IO_AUTO_GOOD_RESPONSE = (1 <<1 ), +SLI4_IO_NO_ABORT = (1 <<2 ), +/* Set the DNRX bit because no auto xref rdy buffer is posted */ +SLI4_IO_DNRX = (1 <<3 ), +}; + +enum sli4_callback { +SLI4_CB_LINK , +SLI4_CB_MAX , +}; + +enum sli4_link_status { +SLI_LINK_STATUS_UP , +SLI_LINK_STATUS_DOWN , +SLI_LINK_STATUS_NO_ALPA , +SLI_LINK_STATUS_MAX , +}; + +enum sli4_link_topology { +SLI_LINK_TOPO_NPORT =1 , +SLI_LINK_TOPO_LOOP , +SLI_LINK_TOPO_LOOPBACK_INTERNAL , +SLI_LINK_TOPO_LOOPBACK_EXTERNAL ,
drivers/scsi/elx/libefc_sli/sli4.h enum sli4_els_cmd_type { · line 3578
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h +10
-0+SLI_LINK_TOPO_NONE , + SLI_LINK_TOPO_MAX, +}; + +enum sli4_link_medium { +SLI_LINK_MEDIUM_ETHERNET , +SLI_LINK_MEDIUM_FC , +SLI_LINK_MEDIUM_MAX , +}; +
Why 'SLI_LINK_' and not 'SLI4_LINK_' like everywhere else?
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h +10
-0+/*Driver specific structures*/ + +struct sli4_link_event { +enum sli4_link_status status; +enum sli4_link_topology topology; +enum sli4_link_medium medium; +u32 speed; +u8 *loop_map; +u32 fc_id; +};
drivers/scsi/elx/libefc_sli/sli4.h enum sli4_els_cmd_type { · line 3598
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h +10
-0+ +enum sli4_resource { +SLI_RSRC_VFI , +SLI_RSRC_VPI , +SLI_RSRC_RPI , +SLI_RSRC_XRI , +SLI_RSRC_FCFI , +SLI_RSRC_MAX , +}; +
Hmm?
Quoted 83 lines
drivers/scsi/elx/libefc_sli/sli4.h +82
-0+struct sli4_extent { +u32 number; +u32 size; +u32 n_alloc; +u32 *base; +unsigned long *use_map; +u32 map_size; +}; + +struct sli4_queue_info { +u16 max_qcount[SLI_QTYPE_MAX ]; +u32 max_qentries[SLI_QTYPE_MAX ]; +u16 count_mask[SLI_QTYPE_MAX ]; +u16 count_method[SLI_QTYPE_MAX ]; +u32 qpage_count[SLI_QTYPE_MAX ]; +}; + +#define SLI_PCI_MAX_REGS 6 +struct sli4 { +void *os; +struct pci_dev *pcidev; +void __iomem *reg[SLI_PCI_MAX_REGS ]; + +u32 sli_rev; +u32 sli_family; +u32 if_type; + +u16 asic_type; +u16 asic_rev; + +u16 e_d_tov; +u16 r_a_tov; +struct sli4_queue_info qinfo; +u16 link_module_type; +u8 rq_batch; +u16 rq_min_buf_size; +u32 rq_max_buf_size; +u8 topology; +u8 wwpn[8 ]; +u8 wwnn[8 ]; +u32 fw_rev[2 ]; +u8 fw_name[2 ][16 ]; +char ipl_name[16 ]; +u32 hw_rev[3 ]; +u8 port_number; +char port_name[2 ]; +char modeldesc[64 ]; +char bios_version_string[32 ]; +/* +* Tracks the port resources using extents metaphor. For +* devices that don't implement extents (i.e. +* has_extents == FALSE), the code models each resource as +* a single large extent. +*/ +struct sli4_extent extent[SLI_RSRC_MAX ]; +u32 features; +u32 has_extents:1 , + auto_reg:1 , + auto_xfer_rdy:1 , + hdr_template_req:1 , + perf_hint:1 , + perf_wq_id_association:1 , + cq_create_version:2 , + mq_create_version:2 , + high_login_mode:1 , + sgl_pre_registered:1 , + sgl_pre_registration_required:1 , + t10_dif_inline_capable:1 , + t10_dif_separate_capable:1 ; +u32 sge_supported_length; +u32 sgl_page_sizes; +u32 max_sgl_pages; +u32 wqe_size; + +/* +* Callback functions +*/ +int (*link)(void *ctx,void *event); +void *link_arg; + +struct efc_dma bmbx; +
drivers/scsi/elx/libefc_sli/sli4.h enum sli4_els_cmd_type { · line 3690
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.h +9
-0+/* Save pointer to physical memory descriptor for non-embedded +* SLI_CONFIG commands for BMBX dumping purposes +*/ +struct efc_dma *bmbx_non_emb_pmd; + +struct efc_dma vpd_data; + u32 vpd_length; +}; +#endif /* !_SLI4_H */
Cheers,
Hannes
Signature · 4 lines
Dr. Hannes Reinecke Teamlead Storage & Networking [email protected] +49 911 74053 688 SUSE Software Solutions GmbH, Maxfeldstr. 5, 90409 Nürnberg HRB 36809 (AG Nürnberg), Geschäftsführer: Felix Imendörffer
PATCH v3 4/31 elx: libefc_sli: queue create/destroy/parse routines
In reply to James SmartThis patch continues the libefc_sli SLI-4 library population.
This patch adds service routines to create mailbox commands and adds APIs to create/destroy/parse SLI-4 EQ, CQ, RQ and MQ queues.
---
v3:
Removed efc_assert define. Replaced with WARN_ON. Returned defined return values EFC_SUCCESS/FAIL
--- drivers/scsi/elx/include/efc_common.h | 18 + drivers/scsi/elx/libefc_sli/sli4.c | 1514 +++++++++++++++++++++++++++++++++ drivers/scsi/elx/libefc_sli/sli4.h | 9 + 3 files changed, 1541 insertions(+)
drivers/scsi/elx/include/efc_common.h +18 -0
@@ -22,4 +22,22 @@ struct efc_dma {struct pci_dev *pdev; }; +#define efc_log_crit(efc, fmt, args...) \ + dev_crit(&((efc)->pcidev)->dev, fmt, ##args) + +#define efc_log_err(efc, fmt, args...) \ + dev_err(&((efc)->pcidev)->dev, fmt, ##args) + +#define efc_log_warn(efc, fmt, args...) \ + dev_warn(&((efc)->pcidev)->dev, fmt, ##args) + +#define efc_log_info(efc, fmt, args...) \ + dev_info(&((efc)->pcidev)->dev, fmt, ##args) + +#define efc_log_test(efc, fmt, args...) \ + dev_dbg(&((efc)->pcidev)->dev, fmt, ##args) + +#define efc_log_debug(efc, fmt, args...) \ + dev_dbg(&((efc)->pcidev)->dev, fmt, ##args) +#endif /* __EFC_COMMON_H__ */
drivers/scsi/elx/libefc_sli/sli4.c +1514 -0
1,517 lines not on this page · raw message
drivers/scsi/elx/libefc_sli/sli4.h +9 -0
@@ -3687,4 +3687,13 @@ struct sli4 { u32 vpd_length; }; +static inline void +sli_cmd_fill_hdr (struct sli4_rqst_hdr *hdr,u8 opc,u8 sub,u32 ver,__le32 len) +{ + hdr->opcode = opc; + hdr->subsystem = sub; + hdr->dw3_version =cpu_to_le32 (ver); + hdr->request_length = len; +} +#endif /* !_SLI4_H */
Signature · 1 line
2.16.4
Re: [PATCH v3 04/31] elx: libefc_sli: queue create/destroy/parse routines
Hi,
Quoted 64 lines · James Smart
This patch continues the
libefc_sliSLI-4 library population.This patch adds service routines to create mailbox commands and adds APIs to create/destroy/parse SLI-4 EQ, CQ, RQ and MQ queues.
Signed-off-by Ram Vegesna <[email protected]>Signed-off-by James Smart <[email protected]>---
v3:
Removedefc_assertdefine. Replaced withWARN_ON. Returned defined return values EFC_SUCCESS/FAIL--- drivers/scsi/elx/include/efc_common.h | 18 + drivers/scsi/elx/libefc_sli/sli4.c | 1514 +++++++++++++++++++++++++++++++++ drivers/scsi/elx/libefc_sli/sli4.h | 9 + 3 files changed, 1541 insertions(+)drivers/scsi/elx/include/efc_common.h +18
-0@@ -22,4 +22,22 @@ struct efc_dma {struct pci_dev *pdev; }; +#define efc_log_crit(efc, fmt, args...) \ + dev_crit(&((efc)->pcidev)->dev, fmt, ##args) + +#define efc_log_err(efc, fmt, args...) \ + dev_err(&((efc)->pcidev)->dev, fmt, ##args) + +#define efc_log_warn(efc, fmt, args...) \ + dev_warn(&((efc)->pcidev)->dev, fmt, ##args) + +#define efc_log_info(efc, fmt, args...) \ + dev_info(&((efc)->pcidev)->dev, fmt, ##args) + +#define efc_log_test(efc, fmt, args...) \ + dev_dbg(&((efc)->pcidev)->dev, fmt, ##args) + +#define efc_log_debug(efc, fmt, args...) \ + dev_dbg(&((efc)->pcidev)->dev, fmt, ##args) +#endif /* __EFC_COMMON_H__ */ drivers/scsi/elx/libefc_sli/sli4.c +11
-0@@ -24,3 +24,1517 @@ static struct sli4_asic_entry_t sli4_asic_table[] = { { SLI4_ASIC_REV_A3, SLI4_ASIC_GEN_6}, { SLI4_ASIC_REV_A1, SLI4_ASIC_GEN_7}, }; + +/* Convert queue type enum (SLI_QTYPE_*) into a string */ +static char *SLI_QNAME [] = { +"Event Queue" , +"Completion Queue" , +"Mailbox Queue" , +"Work Queue" , +"Receive Queue" , +"Undefined" +}; +
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 47
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+/* +* Write a SLI_CONFIG command to the provided buffer. +* +* @sli4 SLI context pointer. +* @buf Destination buffer for the command. +* @size size of the destination buffer(buf). +* @length Length in bytes of attached command. +* @dma DMA buffer for non-embedded commands. +* +*/
Turn this into kerneldoc style.
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 53
Quoted 6 lines
drivers/scsi/elx/libefc_sli/sli4.c +6
-0+static void * +sli_config_cmd_init (struct sli4 *sli4,void *buf, +size_t size,u32 length, +struct efc_dma *dma) +{ +struct sli4_cmd_sli_config *config =NULL ;
Not needed, config gets buf assigned.
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 64
Quoted 11 lines
drivers/scsi/elx/libefc_sli/sli4.c +11
-0+u32 flags =0 ; + +if (length >sizeof (config->payload.embed) && !dma) { +efc_log_err (sli4,"Too big for an embedded cmd with len(%d)\n" , + length); +return NULL ; + } + + config = buf; + +memset (buf,0 , size);
Maybe do the memset first and then do the config = buf assignemnt.
Quoted 21 lines
drivers/scsi/elx/libefc_sli/sli4.c +21
-0+ + config->hdr.command =MBX_CMD_SLI_CONFIG ; +if (!dma) { + flags |=SLI4_SLICONF_EMB ; + config->dw1_flags =cpu_to_le32 (flags); + config->payload_len =cpu_to_le32 (length); + buf += offsetof(struct sli4_cmd_sli_config, payload.embed); +return buf; + } + + flags =SLI4_SLICONF_PMDCMD_VAL_1 ; + flags &= ~SLI4_SLICONF_EMB ; + config->dw1_flags =cpu_to_le32 (flags); + + config->payload.mem.addr.low =cpu_to_le32 (lower_32_bits (dma->phys)); + config->payload.mem.addr.high =cpu_to_le32 (upper_32_bits (dma->phys)); + config->payload.mem.length = +cpu_to_le32 (dma->size &SLI4_SLICONFIG_PMD_LEN ); + config->payload_len =cpu_to_le32 (dma->size); +/* save pointer to DMA for BMBX dumping purposes */ + sli4->bmbx_non_emb_pmd = dma;
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 95
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+return dma->virt; +} + +/* +* Write a COMMON_CREATE_CQ command. +* +* This creates a Version 2 message. +* +* Returns 0 on success, or non-zero otherwise. +*/
kerneldoc style
Quoted 23 lines
drivers/scsi/elx/libefc_sli/sli4.c +23
-0+static int +sli_cmd_common_create_cq (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *qmem, +u16 eq_id) +{ +struct sli4_rqst_cmn_create_cq_v2 *cqv2 =NULL ; +u32 p; +uintptr_t addr; +u32 page_bytes =0 ; +u32 num_pages =0 ; +size_t cmd_size =0 ; +u32 page_size =0 ; +u32 n_cqe =0 ; +u32 dw5_flags =0 ; +u16 dw6w1_arm =0 ; +__le32 len; + +/* First calculate number of pages and the mailbox cmd length */ + n_cqe = qmem->size /SLI4_CQE_BYTES ; +switch (n_cqe) { +case 256 : +case 512 : +case 1024 :
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 128
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+case 2048 : + page_size =1 ; +break ; +case 4096 : + page_size =2 ; +break ; +default : +return EFC_FAIL ; + } + page_bytes = page_size *SLI_PAGE_SIZE ;
page_size is confusing variable name, multiplying page_size with SLI_PAGE_SIZE gives bytes.
Quoted 57 lines
drivers/scsi/elx/libefc_sli/sli4.c +57
-0+ num_pages =sli_page_count (qmem->size, page_bytes); + + cmd_size =CFG_RQST_CMDSZ (cmn_create_cq_v2) +SZ_DMAADDR * num_pages; + + cqv2 =sli_config_cmd_init (sli4, buf, size, cmd_size,NULL ); +if (!cqv2) +return EFC_FAIL ; + + len =CFG_RQST_PYLD_LEN_VAR (cmn_create_cq_v2, +SZ_DMAADDR * num_pages); +sli_cmd_fill_hdr (&cqv2->hdr,CMN_CREATE_CQ ,SLI4_SUBSYSTEM_COMMON , +CMD_V2 , len); + cqv2->page_size = page_size; + +/* valid values for number of pages: 1, 2, 4, 8 (sec 4.4.3) */ + cqv2->num_pages =cpu_to_le16 (num_pages); +if (!num_pages || num_pages >SLI4_CMN_CREATE_CQ_V2_MAX_PAGES ) +return EFC_FAIL ; + +switch (num_pages) { +case 1 : + dw5_flags |=CQ_CNT_VAL (256 ); +break ; +case 2 : + dw5_flags |=CQ_CNT_VAL (512 ); +break ; +case 4 : + dw5_flags |=CQ_CNT_VAL (1024 ); +break ; +case 8 : + dw5_flags |=CQ_CNT_VAL (LARGE ); + cqv2->cqe_count =cpu_to_le16 (n_cqe); +break ; +default : +efc_log_err (sli4,"num_pages %d not valid\n" , num_pages); +return EFC_FAIL ; + } + +if (sli4->if_type ==SLI4_INTF_IF_TYPE_6 ) + dw5_flags |=CREATE_CQV2_AUTOVALID ; + + dw5_flags |=CREATE_CQV2_EVT ; + dw5_flags |=CREATE_CQV2_VALID ; + + cqv2->dw5_flags =cpu_to_le32 (dw5_flags); + cqv2->dw6w1_arm =cpu_to_le16 (dw6w1_arm); + cqv2->eq_id =cpu_to_le16 (eq_id); + +for (p =0 , addr = qmem->phys; p < num_pages; p++, addr += page_bytes) { + cqv2->page_phys_addr[p].low =cpu_to_le32 (lower_32_bits (addr)); + cqv2->page_phys_addr[p].high =cpu_to_le32 (upper_32_bits (addr)); + } + +return EFC_SUCCESS ; +} + +/* Write a COMMON_CREATE_EQ command */
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 195
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+static int +sli_cmd_common_create_eq (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *qmem) +{ +struct sli4_rqst_cmn_create_eq *eq; +u32 p; +uintptr_t addr; +u16 num_pages; +u32 dw5_flags =0 ; +u32 dw6_flags =0 , ver =CMD_V0 ;
Maybe initialize ver below when for SLI4_INTF_IF_TYPE_6 is tested. That would keep the setting of ver in one place.
Quoted 147 lines
drivers/scsi/elx/libefc_sli/sli4.c +147
-0+ + eq =sli_config_cmd_init (sli4, buf, size, +SLI_CONFIG_PYLD_LENGTH (cmn_create_eq),NULL ); +if (!eq) +return EFC_FAIL ; + +if (sli4->if_type ==SLI4_INTF_IF_TYPE_6 ) + ver =CMD_V2 ; + +sli_cmd_fill_hdr (&eq->hdr,CMN_CREATE_EQ ,SLI4_SUBSYSTEM_COMMON , + ver,CFG_RQST_PYLD_LEN (cmn_create_eq)); + +/* valid values for number of pages: 1, 2, 4 (sec 4.4.3) */ + num_pages = qmem->size /SLI_PAGE_SIZE ; + eq->num_pages =cpu_to_le16 (num_pages); + +switch (num_pages) { +case 1 : + dw5_flags |=SLI4_EQE_SIZE_4 ; + dw6_flags |=EQ_CNT_VAL (1024 ); +break ; +case 2 : + dw5_flags |=SLI4_EQE_SIZE_4 ; + dw6_flags |=EQ_CNT_VAL (2048 ); +break ; +case 4 : + dw5_flags |=SLI4_EQE_SIZE_4 ; + dw6_flags |=EQ_CNT_VAL (4096 ); +break ; +default : +efc_log_err (sli4,"num_pages %d not valid\n" , num_pages); +return EFC_FAIL ; + } + +if (sli4->if_type ==SLI4_INTF_IF_TYPE_6 ) + dw5_flags |=CREATE_EQ_AUTOVALID ; + + dw5_flags |=CREATE_EQ_VALID ; + dw6_flags &= (~CREATE_EQ_ARM ); + eq->dw5_flags =cpu_to_le32 (dw5_flags); + eq->dw6_flags =cpu_to_le32 (dw6_flags); + eq->dw7_delaymulti =cpu_to_le32 (CREATE_EQ_DELAYMULTI ); + +for (p =0 , addr = qmem->phys; p < num_pages; + p++, addr +=SLI_PAGE_SIZE ) { + eq->page_address[p].low =cpu_to_le32 (lower_32_bits (addr)); + eq->page_address[p].high =cpu_to_le32 (upper_32_bits (addr)); + } + +return EFC_SUCCESS ; +} + +static int +sli_cmd_common_create_mq_ext (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *qmem, +u16 cq_id) +{ +struct sli4_rqst_cmn_create_mq_ext *mq; +u32 p; +uintptr_t addr; +u32 num_pages; +u16 dw6w1_flags =0 ; + + mq =sli_config_cmd_init (sli4, buf, size, +SLI_CONFIG_PYLD_LENGTH (cmn_create_mq_ext), +NULL ); +if (!mq) +return EFC_FAIL ; + +sli_cmd_fill_hdr (&mq->hdr,CMN_CREATE_MQ_EXT ,SLI4_SUBSYSTEM_COMMON , +CMD_V0 ,CFG_RQST_PYLD_LEN (cmn_create_mq_ext)); + +/* valid values for number of pages: 1, 2, 4, 8 (sec 4.4.12) */ + num_pages = qmem->size /SLI_PAGE_SIZE ; + mq->num_pages =cpu_to_le16 (num_pages); +switch (num_pages) { +case 1 : + dw6w1_flags |=SLI4_MQE_SIZE_16 ; +break ; +case 2 : + dw6w1_flags |=SLI4_MQE_SIZE_32 ; +break ; +case 4 : + dw6w1_flags |=SLI4_MQE_SIZE_64 ; +break ; +case 8 : + dw6w1_flags |=SLI4_MQE_SIZE_128 ; +break ; +default : +efc_log_info (sli4,"num_pages %d not valid\n" , num_pages); +return EFC_FAIL ; + } + + mq->async_event_bitmap =cpu_to_le32 (SLI4_ASYNC_EVT_FC_ALL ); + +if (sli4->mq_create_version) { + mq->cq_id_v1 =cpu_to_le16 (cq_id); + mq->hdr.dw3_version =cpu_to_le32 (CMD_V1 ); + }else { + dw6w1_flags |= (cq_id <<CREATE_MQEXT_CQID_SHIFT ); + } + mq->dw7_val =cpu_to_le32 (CREATE_MQEXT_VAL ); + + mq->dw6w1_flags =cpu_to_le16 (dw6w1_flags); +for (p =0 , addr = qmem->phys; p < num_pages; + p++, addr +=SLI_PAGE_SIZE ) { + mq->page_phys_addr[p].low =cpu_to_le32 (lower_32_bits (addr)); + mq->page_phys_addr[p].high =cpu_to_le32 (upper_32_bits (addr)); + } + +return EFC_SUCCESS ; +} + +int +sli_cmd_wq_create (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *qmem,u16 cq_id) +{ +struct sli4_rqst_wq_create *wq; +u32 p; +uintptr_t addr; +u32 page_size =0 ; +u32 page_bytes =0 ; +u32 n_wqe =0 ; +u16 num_pages; + + wq =sli_config_cmd_init (sli4, buf, size, +SLI_CONFIG_PYLD_LENGTH (wq_create),NULL ); +if (!wq) +return EFC_FAIL ; + +sli_cmd_fill_hdr (&wq->hdr,SLI4_OPC_WQ_CREATE ,SLI4_SUBSYSTEM_FC , +CMD_V1 ,CFG_RQST_PYLD_LEN (wq_create)); + n_wqe = qmem->size / sli4->wqe_size; + +switch (qmem->size) { +case 4096 : +case 8192 : +case 16384 : +case 32768 : + page_size =1 ; +break ; +case 65536 : + page_size =2 ; +break ; +case 131072 : + page_size =4 ; +break ;
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 352
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+case 262144 : + page_size =8 ; +break ; +case 524288 : + page_size =10 ; +break ; +default : +return EFC_FAIL ; + } + page_bytes = page_size *SLI_PAGE_SIZE ;
same comment as above about the page_size variable name.
Quoted 20 lines
drivers/scsi/elx/libefc_sli/sli4.c +20
-0+ +/* valid values for number of pages(num_pages): 1-8 */ + num_pages =sli_page_count (qmem->size, page_bytes); + wq->num_pages =cpu_to_le16 (num_pages); +if (!num_pages || num_pages >SLI4_WQ_CREATE_MAX_PAGES ) +return EFC_FAIL ; + + wq->cq_id =cpu_to_le16 (cq_id); + + wq->page_size = page_size; + +if (sli4->wqe_size ==SLI4_WQE_EXT_BYTES ) + wq->wqe_size_byte |=SLI4_WQE_EXT_SIZE ; +else + wq->wqe_size_byte |=SLI4_WQE_SIZE ; + + wq->wqe_count =cpu_to_le16 (n_wqe); + +for (p =0 , addr = qmem->phys; p < num_pages; p++, addr += page_bytes) { + wq->page_phys_addr[p].low =cpu_to_le32 (lower_32_bits (addr));
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 382
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+ wq->page_phys_addr[p].high =cpu_to_le32 (upper_32_bits (addr)); + } + +return EFC_SUCCESS ; +} + +int +sli_cmd_rq_create (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *qmem, +u16 cq_id,u16 buffer_size)
I think sli_cmd_rq_create() should be called sli_cmd_rq_create_v0() to match sli_cmd_rq_create_{v1|v2}() and make it more explicit in the API which version of this function is.
Quoted 138 lines
drivers/scsi/elx/libefc_sli/sli4.c +138
-0+{ +struct sli4_rqst_rq_create *rq; +u32 p; +uintptr_t addr; +u16 num_pages; + + rq =sli_config_cmd_init (sli4, buf, size, +SLI_CONFIG_PYLD_LENGTH (rq_create),NULL ); +if (!rq) +return EFC_FAIL ; + +sli_cmd_fill_hdr (&rq->hdr,SLI4_OPC_RQ_CREATE ,SLI4_SUBSYSTEM_FC , +CMD_V0 ,CFG_RQST_PYLD_LEN (rq_create)); +/* valid values for number of pages: 1-8 (sec 4.5.6) */ + num_pages =sli_page_count (qmem->size,SLI_PAGE_SIZE ); + rq->num_pages =cpu_to_le16 (num_pages); +if (!num_pages || + num_pages >SLI4_RQ_CREATE_V0_MAX_PAGES ) { +efc_log_info (sli4,"num_pages %d not valid\n" , num_pages); +return EFC_FAIL ; + } + +/* +* RQE count is the log base 2 of the total number of entries +*/ + rq->rqe_count_byte |=31 -__builtin_clz (qmem->size /SLI4_RQE_SIZE ); + +if (buffer_size <SLI4_RQ_CREATE_V0_MIN_BUF_SIZE || + buffer_size >SLI4_RQ_CREATE_V0_MAX_BUF_SIZE ) { +efc_log_err (sli4,"buffer_size %d out of range (%d-%d)\n" , + buffer_size, +SLI4_RQ_CREATE_V0_MIN_BUF_SIZE , +SLI4_RQ_CREATE_V0_MAX_BUF_SIZE ); +return EFC_FAIL ; + } + rq->buffer_size =cpu_to_le16 (buffer_size); + + rq->cq_id =cpu_to_le16 (cq_id); + +for (p =0 , addr = qmem->phys; p < num_pages; + p++, addr +=SLI_PAGE_SIZE ) { + rq->page_phys_addr[p].low =cpu_to_le32 (lower_32_bits (addr)); + rq->page_phys_addr[p].high =cpu_to_le32 (upper_32_bits (addr)); + } + +return EFC_SUCCESS ; +} + +int +sli_cmd_rq_create_v1 (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *qmem,u16 cq_id, +u16 buffer_size) +{ +struct sli4_rqst_rq_create_v1 *rq; +u32 p; +uintptr_t addr; +u32 num_pages; + + rq =sli_config_cmd_init (sli4, buf, size, +SLI_CONFIG_PYLD_LENGTH (rq_create_v1),NULL ); +if (!rq) +return EFC_FAIL ; + +sli_cmd_fill_hdr (&rq->hdr,SLI4_OPC_RQ_CREATE ,SLI4_SUBSYSTEM_FC , +CMD_V1 ,CFG_RQST_PYLD_LEN (rq_create_v1)); +/* Disable "no buffer warnings" to avoid Lancer bug */ + rq->dim_dfd_dnb |=SLI4_RQ_CREATE_V1_DNB ; + +/* valid values for number of pages: 1-8 (sec 4.5.6) */ + num_pages =sli_page_count (qmem->size,SLI_PAGE_SIZE ); + rq->num_pages =cpu_to_le16 (num_pages); +if (!num_pages || + num_pages >SLI4_RQ_CREATE_V1_MAX_PAGES ) { +efc_log_info (sli4,"num_pages %d not valid, max %d\n" , + num_pages,SLI4_RQ_CREATE_V1_MAX_PAGES ); +return EFC_FAIL ; + } + +/* +* RQE count is the total number of entries (note not lg2(# entries)) +*/ + rq->rqe_count =cpu_to_le16 (qmem->size /SLI4_RQE_SIZE ); + + rq->rqe_size_byte |=SLI4_RQE_SIZE_8 ; + + rq->page_size =SLI4_RQ_PAGE_SIZE_4096 ; + +if (buffer_size < sli4->rq_min_buf_size || + buffer_size > sli4->rq_max_buf_size) { +efc_log_err (sli4,"buffer_size %d out of range (%d-%d)\n" , + buffer_size, + sli4->rq_min_buf_size, + sli4->rq_max_buf_size); +return EFC_FAIL ; + } + rq->buffer_size =cpu_to_le32 (buffer_size); + + rq->cq_id =cpu_to_le16 (cq_id); + +for (p =0 , addr = qmem->phys; + p < num_pages; + p++, addr +=SLI_PAGE_SIZE ) { + rq->page_phys_addr[p].low =cpu_to_le32 (lower_32_bits (addr)); + rq->page_phys_addr[p].high =cpu_to_le32 (upper_32_bits (addr)); + } + +return EFC_SUCCESS ; +} + +static int +sli_cmd_rq_create_v2 (struct sli4 *sli4,u32 num_rqs, +struct sli4_queue *qs[],u32 base_cq_id, +u32 header_buffer_size, +u32 payload_buffer_size,struct efc_dma *dma) +{ +struct sli4_rqst_rq_create_v2 *req =NULL ; +u32 i, p, offset =0 ; +u32 payload_size, page_count; +uintptr_t addr; +u32 num_pages; +__le32 req_len; + + page_count =sli_page_count (qs[0 ]->dma.size,SLI_PAGE_SIZE ) * num_rqs; + +/* Payload length must accommodate both request and response */ + payload_size =max (CFG_RQST_CMDSZ (rq_create_v2) + +SZ_DMAADDR * page_count, +sizeof (struct sli4_rsp_cmn_create_queue_set )); + + dma->size = payload_size; + dma->virt =dma_alloc_coherent (&sli4->pcidev->dev, dma->size, + &dma->phys,GFP_DMA ); +if (!dma->virt) +return EFC_FAIL ; + +memset (dma->virt,0 , payload_size); + + req = sli_config_cmd_init(sli4, sli4->bmbx.virt, SLI4_BMBX_SIZE,
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 530
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+ payload_size, dma); +if (!req) +return EFC_FAIL ; + + req_len =CFG_RQST_PYLD_LEN_VAR (rq_create_v2,SZ_DMAADDR * page_count); +sli_cmd_fill_hdr (&req->hdr,SLI4_OPC_RQ_CREATE ,SLI4_SUBSYSTEM_FC , +CMD_V2 , req_len); +/* Fill Payload fields */ + req->dim_dfd_dnb |=SLI4_RQCREATEV2_DNB ; + num_pages =sli_page_count (qs[0 ]->dma.size,SLI_PAGE_SIZE );
code alignment
Quoted 22 lines
drivers/scsi/elx/libefc_sli/sli4.c +22
-0+ req->num_pages =cpu_to_le16 (num_pages); + req->rqe_count =cpu_to_le16 (qs[0 ]->dma.size /SLI4_RQE_SIZE ); + req->rqe_size_byte |=SLI4_RQE_SIZE_8 ; + req->page_size =SLI4_RQ_PAGE_SIZE_4096 ; + req->rq_count = num_rqs; + req->base_cq_id =cpu_to_le16 (base_cq_id); + req->hdr_buffer_size =cpu_to_le16 (header_buffer_size); + req->payload_buffer_size =cpu_to_le16 (payload_buffer_size); + +for (i =0 ; i < num_rqs; i++) { +for (p =0 , addr = qs[i]->dma.phys; p < num_pages; + p++, addr +=SLI_PAGE_SIZE ) { + req->page_phys_addr[offset].low = +cpu_to_le32 (lower_32_bits (addr)); + req->page_phys_addr[offset].high = +cpu_to_le32 (upper_32_bits (addr)); + offset++; + } + } + +return EFC_SUCCESS ; +}
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 562
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+ +static void +__sli_queue_destroy (struct sli4 *sli4,struct sli4_queue *q) +{ +if (!q->dma.size) +return ; + +dma_free_coherent (&sli4->pcidev->dev, q->dma.size, + q->dma.virt, q->dma.phys); +memset (&q->dma,0 ,sizeof (struct efc_dma ));
Is this necessary to clear q->dma? Just asking if it's possible to avoid the additional work.
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 571
Quoted 9 lines
drivers/scsi/elx/libefc_sli/sli4.c +9
-0+} + +int +__sli_queue_init (struct sli4 *sli4,struct sli4_queue *q, +u32 qtype,size_t size,u32 n_entries, +u32 align) +{ +if (!q->dma.virt || size != q->size || + n_entries != q->length) {
I would put all on one line. The column limit should be reached.
And couldn't you test logical inverse and return early and avoid the idention? And also I add the queue type to the log message so it's not necessary to add the some log statement through the code base. Something like:
if (q->dma.virt && size == q->size && n_entries == q->length) {
efc_log_err(sli4, "%s %s failed\n", __func__, SLI_QNAME[qtype]);
return EFC_FAIL;
}Maybe add combine the error path here and the below together and use a goto/label.
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 582
Quoted 11 lines
drivers/scsi/elx/libefc_sli/sli4.c +11
-0+if (q->dma.size) +__sli_queue_destroy (sli4, q); + +memset (q,0 ,sizeof (struct sli4_queue )); + + q->dma.size = size * n_entries; + q->dma.virt =dma_alloc_coherent (&sli4->pcidev->dev, + q->dma.size, &q->dma.phys, +GFP_DMA ); +if (!q->dma.virt) { +memset (&q->dma,0 ,sizeof (struct efc_dma ));
So if __sli_queue_destroy() keeps clearing q->dma, than this one can go away, since if __sli_queue_init() fails __sli_queue_destroy() will be called.
Quoted 262 lines
drivers/scsi/elx/libefc_sli/sli4.c +262
-0+efc_log_err (sli4,"%s allocation failed\n" , +SLI_QNAME [qtype]); +return EFC_FAIL ; + } + +memset (q->dma.virt,0 , size * n_entries); + +spin_lock_init (&q->lock); + + q->type = qtype; + q->size = size; + q->length = n_entries; + +if (q->type ==SLI_QTYPE_EQ || q->type ==SLI_QTYPE_CQ ) { +/* For prism, phase will be flipped after +* a sweep through eq and cq +*/ + q->phase =1 ; + } + +/* Limit to hwf the queue size per interrupt */ + q->proc_limit = n_entries /2 ; + +switch (q->type) { +case SLI_QTYPE_EQ : + q->posted_limit = q->length /2 ; +break ; +default : + q->posted_limit =64 ; +break ; + } + }else { +efc_log_err (sli4,"%s failed\n" , __func__); +return EFC_FAIL ; + } + +return EFC_SUCCESS ; +} + +int +sli_fc_rq_alloc (struct sli4 *sli4,struct sli4_queue *q, +u32 n_entries,u32 buffer_size, +struct sli4_queue *cq,bool is_hdr) +{ +if (__sli_queue_init (sli4, q,SLI_QTYPE_RQ ,SLI4_RQE_SIZE , + n_entries,SLI_PAGE_SIZE )) +return EFC_FAIL ; + +if (!sli_cmd_rq_create_v1 (sli4, sli4->bmbx.virt,SLI4_BMBX_SIZE , + &q->dma, cq->id, buffer_size)) { +if (__sli_create_queue (sli4, q)) { +efc_log_info (sli4,"Create queue failed %d\n" , q->id); + goto error; + } +if (is_hdr && q->id &1 ) { +efc_log_info (sli4,"bad header RQ_ID %d\n" , q->id); + goto error; + }else if (!is_hdr && (q->id &1 ) ==0 ) { +efc_log_info (sli4,"bad data RQ_ID %d\n" , q->id); + goto error; + } + }else { + goto error; + } +if (is_hdr) + q->u.flag.dword |=SLI4_QUEUE_FLAG_HDR ; +else + q->u.flag.dword &= ~SLI4_QUEUE_FLAG_HDR ; +return EFC_SUCCESS ; +error: +__sli_queue_destroy (sli4, q); +return EFC_FAIL ; +} + +int +sli_fc_rq_set_alloc (struct sli4 *sli4,u32 num_rq_pairs, +struct sli4_queue *qs[],u32 base_cq_id, +u32 n_entries,u32 header_buffer_size, +u32 payload_buffer_size) +{ +u32 i; +struct efc_dma dma; +struct sli4_rsp_cmn_create_queue_set *rsp =NULL ; +void __iomem *db_regaddr =NULL ; +u32 num_rqs = num_rq_pairs *2 ; + +for (i =0 ; i < num_rqs; i++) { +if (__sli_queue_init (sli4, qs[i],SLI_QTYPE_RQ , +SLI4_RQE_SIZE , n_entries, +SLI_PAGE_SIZE )) { + goto error; + } + } + +if (sli_cmd_rq_create_v2 (sli4, num_rqs, qs, base_cq_id, + header_buffer_size, payload_buffer_size, &dma)) { + goto error; + } + +if (sli_bmbx_command (sli4)) { +efc_log_err (sli4,"bootstrap mailbox write failed RQSet\n" ); + goto error; + } + +if (sli4->if_type ==SLI4_INTF_IF_TYPE_6 ) + db_regaddr = sli4->reg[1 ] +SLI4_IF6_RQ_DB_REG ; +else + db_regaddr = sli4->reg[0 ] +SLI4_RQ_DB_REG ; + + rsp = dma.virt; +if (rsp->hdr.status) { +efc_log_err (sli4,"bad create RQSet status=%#x addl=%#x\n" , + rsp->hdr.status, rsp->hdr.additional_status); + goto error; + }else { +for (i =0 ; i < num_rqs; i++) { + qs[i]->id = i +le16_to_cpu (rsp->q_id); +if ((qs[i]->id &1 ) ==0 ) + qs[i]->u.flag.dword |=SLI4_QUEUE_FLAG_HDR ; +else + qs[i]->u.flag.dword &= ~SLI4_QUEUE_FLAG_HDR ; + + qs[i]->db_regaddr = db_regaddr; + } + } + +dma_free_coherent (&sli4->pcidev->dev, dma.size, dma.virt, dma.phys); + +return EFC_SUCCESS ; + +error: +for (i =0 ; i < num_rqs; i++) +__sli_queue_destroy (sli4, qs[i]); + +if (dma.virt) +dma_free_coherent (&sli4->pcidev->dev, dma.size, dma.virt, + dma.phys); + +return EFC_FAIL ; +} + +static int +sli_res_sli_config (struct sli4 *sli4,void *buf) +{ +struct sli4_cmd_sli_config *sli_config = buf; + +/* sanity check */ +if (!buf || sli_config->hdr.command != +MBX_CMD_SLI_CONFIG ) { +efc_log_err (sli4,"bad parameter buf=%p cmd=%#x\n" , buf, + buf ? sli_config->hdr.command :-1 ); +return EFC_FAIL ; + } + +if (le16_to_cpu (sli_config->hdr.status)) +return le16_to_cpu (sli_config->hdr.status); + +if (le32_to_cpu (sli_config->dw1_flags) &SLI4_SLICONF_EMB ) +return sli_config->payload.embed[4 ]; + +efc_log_info (sli4,"external buffers not supported\n" ); +return EFC_FAIL ; +} + +int +__sli_create_queue (struct sli4 *sli4,struct sli4_queue *q) +{ +struct sli4_rsp_cmn_create_queue *res_q =NULL ; + +if (sli_bmbx_command (sli4)) { +efc_log_crit (sli4,"bootstrap mailbox write fail %s\n" , +SLI_QNAME [q->type]); +return EFC_FAIL ; + } +if (sli_res_sli_config (sli4, sli4->bmbx.virt)) { +efc_log_err (sli4,"bad status create %s\n" , +SLI_QNAME [q->type]); +return EFC_FAIL ; + } + res_q = (void *)((u8 *)sli4->bmbx.virt + + offsetof(struct sli4_cmd_sli_config , payload)); + +if (res_q->hdr.status) { +efc_log_err (sli4,"bad create %s status=%#x addl=%#x\n" , +SLI_QNAME [q->type], res_q->hdr.status, + res_q->hdr.additional_status); +return EFC_FAIL ; + } + q->id =le16_to_cpu (res_q->q_id); +switch (q->type) { +case SLI_QTYPE_EQ : +if (sli4->if_type ==SLI4_INTF_IF_TYPE_6 ) + q->db_regaddr = sli4->reg[1 ] +SLI4_IF6_EQ_DB_REG ; +else + q->db_regaddr = sli4->reg[0 ] +SLI4_EQCQ_DB_REG ; +break ; +case SLI_QTYPE_CQ : +if (sli4->if_type ==SLI4_INTF_IF_TYPE_6 ) + q->db_regaddr = sli4->reg[1 ] +SLI4_IF6_CQ_DB_REG ; +else + q->db_regaddr = sli4->reg[0 ] +SLI4_EQCQ_DB_REG ; +break ; +case SLI_QTYPE_MQ : +if (sli4->if_type ==SLI4_INTF_IF_TYPE_6 ) + q->db_regaddr = sli4->reg[1 ] +SLI4_IF6_MQ_DB_REG ; +else + q->db_regaddr = sli4->reg[0 ] +SLI4_MQ_DB_REG ; +break ; +case SLI_QTYPE_RQ : +if (sli4->if_type ==SLI4_INTF_IF_TYPE_6 ) + q->db_regaddr = sli4->reg[1 ] +SLI4_IF6_RQ_DB_REG ; +else + q->db_regaddr = sli4->reg[0 ] +SLI4_RQ_DB_REG ; +break ; +case SLI_QTYPE_WQ : +if (sli4->if_type ==SLI4_INTF_IF_TYPE_6 ) + q->db_regaddr = sli4->reg[1 ] +SLI4_IF6_WQ_DB_REG ; +else + q->db_regaddr = sli4->reg[0 ] +SLI4_IO_WQ_DB_REG ; +break ; +default : +break ; + } + +return EFC_SUCCESS ; +} + +int +sli_get_queue_entry_size (struct sli4 *sli4,u32 qtype) +{ +u32 size =0 ; + +switch (qtype) { +case SLI_QTYPE_EQ : + size =sizeof (u32); +break ; +case SLI_QTYPE_CQ : + size =16 ; +break ; +case SLI_QTYPE_MQ : + size =256 ; +break ; +case SLI_QTYPE_WQ : + size = sli4->wqe_size; +break ; +case SLI_QTYPE_RQ : + size =SLI4_RQE_SIZE ; +break ; +default : +efc_log_info (sli4,"unknown queue type %d\n" , qtype); +return -1 ; + } +return size; +} + +int +sli_queue_alloc (struct sli4 *sli4,u32 qtype, +struct sli4_queue *q,u32 n_entries, +struct sli4_queue *assoc) +{ +int size; +u32 align =0 ;
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 854
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+ +/* get queue size */ + size =sli_get_queue_entry_size (sli4, qtype); +if (size <0 ) +return EFC_FAIL ; + align =SLI_PAGE_SIZE ; + +if (__sli_queue_init (sli4, q, qtype, size, n_entries, align)) { +efc_log_err (sli4,"%s allocation failed\n" , +SLI_QNAME [qtype]);
__sli_queue_init() already logs this information.
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 864
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+return EFC_FAIL ; + } + +switch (qtype) { +case SLI_QTYPE_EQ : +if (!sli_cmd_common_create_eq (sli4, sli4->bmbx.virt, +SLI4_BMBX_SIZE , &q->dma)) { +if (__sli_create_queue (sli4, q)) { +efc_log_err (sli4,"create %s failed\n" , +SLI_QNAME [qtype]);
__sli_create_queue logs this already.
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 871
Quoted 7 lines
drivers/scsi/elx/libefc_sli/sli4.c +7
-0+ goto error; + } + }else { +efc_log_err (sli4,"cannot create %s\n" , +SLI_QNAME [qtype]); + goto error; + }
So I think you could just do
if (sli_cmd_common_create_eq(...) || __sli_create_queue(...))) goto error;
or even do an early exit on success and avoid the 'goto error'
if (!sli_cmd_common_create_eq(...) && !__sli_create_queue(...)) return EFC_SUCCESS;
Quoted 6 lines
drivers/scsi/elx/libefc_sli/sli4.c +6
-0+ +break ; +case SLI_QTYPE_CQ : +if (!sli_cmd_common_create_cq (sli4, sli4->bmbx.virt, +SLI4_BMBX_SIZE , &q->dma, + assoc ? assoc->id :0 )) {
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 887
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+if (__sli_create_queue (sli4, q)) { +efc_log_err (sli4,"create %s failed\n" , +SLI_QNAME [qtype]); + goto error; + } + }else { +efc_log_err (sli4,"cannot create %s\n" , +SLI_QNAME [qtype]); + goto error; + }
Same as above
Quoted 6 lines
drivers/scsi/elx/libefc_sli/sli4.c +6
-0+break ; +case SLI_QTYPE_MQ : + assoc->u.flag.dword |=SLI4_QUEUE_FLAG_MQ ; +if (!sli_cmd_common_create_mq_ext (sli4, sli4->bmbx.virt, +SLI4_BMBX_SIZE , &q->dma, + assoc->id)) {
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 903
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+if (__sli_create_queue (sli4, q)) { +efc_log_err (sli4,"create %s failed\n" , +SLI_QNAME [qtype]); + goto error; + } + }else { +efc_log_err (sli4,"cannot create %s\n" , +SLI_QNAME [qtype]); + goto error; + }
and here
Quoted 97 lines
drivers/scsi/elx/libefc_sli/sli4.c +97
-0+ +break ; +case SLI_QTYPE_WQ : +if (!sli_cmd_wq_create (sli4, sli4->bmbx.virt, +SLI4_BMBX_SIZE , &q->dma, + assoc ? assoc->id :0 )) { +if (__sli_create_queue (sli4, q)) { +efc_log_err (sli4,"create %s failed\n" , +SLI_QNAME [qtype]); + goto error; + } + }else { +efc_log_err (sli4,"cannot create %s\n" , +SLI_QNAME [qtype]); + goto error; + } +break ; +default : +efc_log_info (sli4,"unknown queue type %d\n" , qtype); + goto error; + } + +return EFC_SUCCESS ; +error: +__sli_queue_destroy (sli4, q); +return EFC_FAIL ; +} + +static int sli_cmd_cq_set_create (struct sli4 *sli4, +struct sli4_queue *qs[],u32 num_cqs, +struct sli4_queue *eqs[], +struct efc_dma *dma) +{ +struct sli4_rqst_cmn_create_cq_set_v0 *req =NULL ; +uintptr_t addr; +u32 i, offset =0 , page_bytes =0 , payload_size; +u32 p =0 , page_size =0 , n_cqe =0 , num_pages_cq; +u32 dw5_flags =0 ; +u16 dw6w1_flags =0 ; +__le32 req_len; + + n_cqe = qs[0 ]->dma.size /SLI4_CQE_BYTES ; +switch (n_cqe) { +case 256 : +case 512 : +case 1024 : +case 2048 : + page_size =1 ; +break ; +case 4096 : + page_size =2 ; +break ; +default : +return EFC_FAIL ; + } + + page_bytes = page_size *SLI_PAGE_SIZE ; + num_pages_cq =sli_page_count (qs[0 ]->dma.size, page_bytes); + payload_size =max (CFG_RQST_CMDSZ (cmn_create_cq_set_v0) + + (SZ_DMAADDR * num_pages_cq * num_cqs), +sizeof (struct sli4_rsp_cmn_create_queue_set )); + + dma->size = payload_size; + dma->virt =dma_alloc_coherent (&sli4->pcidev->dev, dma->size, + &dma->phys,GFP_DMA ); +if (!dma->virt) +return EFC_FAIL ; + +memset (dma->virt,0 , payload_size); + + req =sli_config_cmd_init (sli4, sli4->bmbx.virt,SLI4_BMBX_SIZE , + payload_size, dma); +if (!req) +return EFC_FAIL ; + + req_len =CFG_RQST_PYLD_LEN_VAR (cmn_create_cq_set_v0, +SZ_DMAADDR * num_pages_cq * num_cqs); +sli_cmd_fill_hdr (&req->hdr,CMN_CREATE_CQ_SET ,SLI4_SUBSYSTEM_FC , +CMD_V0 , req_len); + req->page_size = page_size; + + req->num_pages =cpu_to_le16 (num_pages_cq); +switch (num_pages_cq) { +case 1 : + dw5_flags |=CQ_CNT_VAL (256 ); +break ; +case 2 : + dw5_flags |=CQ_CNT_VAL (512 ); +break ; +case 4 : + dw5_flags |=CQ_CNT_VAL (1024 ); +break ; +case 8 : + dw5_flags |=CQ_CNT_VAL (LARGE ); + dw6w1_flags |= (n_cqe &CREATE_CQSETV0_CQE_COUNT ); +break ; +default :
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1010
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+efc_log_info (sli4,"num_pages %d not valid\n" , num_pages_cq); +return EFC_FAIL ; + } + + dw5_flags |=CREATE_CQSETV0_EVT ; + dw5_flags |=CREATE_CQSETV0_VALID ; +if (sli4->if_type ==SLI4_INTF_IF_TYPE_6 ) + dw5_flags |=CREATE_CQSETV0_AUTOVALID ; + + dw6w1_flags &= (~CREATE_CQSETV0_ARM );
The brakets are not needed.
Quoted 20 lines
drivers/scsi/elx/libefc_sli/sli4.c +20
-0+ + req->dw5_flags =cpu_to_le32 (dw5_flags); + req->dw6w1_flags =cpu_to_le16 (dw6w1_flags); + + req->num_cq_req =cpu_to_le16 (num_cqs); + +/* Fill page addresses of all the CQs. */ +for (i =0 ; i < num_cqs; i++) { + req->eq_id[i] =cpu_to_le16 (eqs[i]->id); +for (p =0 , addr = qs[i]->dma.phys; p < num_pages_cq; + p++, addr += page_bytes) { + req->page_phys_addr[offset].low = +cpu_to_le32 (lower_32_bits (addr)); + req->page_phys_addr[offset].high = +cpu_to_le32 (upper_32_bits (addr)); + offset++; + } + } + +return EFC_SUCCESS ;
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1040
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+} + +int +sli_cq_alloc_set (struct sli4 *sli4,struct sli4_queue *qs[], +u32 num_cqs,u32 n_entries,struct sli4_queue *eqs[]) +{ +u32 i; +struct efc_dma dma; +struct sli4_rsp_cmn_create_queue_set *res =NULL ; +void __iomem *db_regaddr =NULL ;
res and db_regaddr do not to be pre-initialized here
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1047
Quoted 7 lines
drivers/scsi/elx/libefc_sli/sli4.c +7
-0+ +/* Align the queue DMA memory */ +for (i =0 ; i < num_cqs; i++) { +if (__sli_queue_init (sli4, qs[i],SLI_QTYPE_CQ , +SLI4_CQE_BYTES , + n_entries,SLI_PAGE_SIZE )) { +efc_log_err (sli4,"Queue init failed.\n" );
__sli_queue_init() already logs this information.
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1058
Quoted 11 lines
drivers/scsi/elx/libefc_sli/sli4.c +11
-0+ goto error; + } + } + +if (sli_cmd_cq_set_create (sli4, qs, num_cqs, eqs, &dma)) + goto error; + +if (sli_bmbx_command (sli4)) { +efc_log_crit (sli4,"bootstrap mailbox write fail CQSet\n" ); + goto error; + }
Since sli_bmbx_command already logs an error, is it this necessary?
Quoted 33 lines
drivers/scsi/elx/libefc_sli/sli4.c +33
-0+ +if (sli4->if_type ==SLI4_INTF_IF_TYPE_6 ) + db_regaddr = sli4->reg[1 ] +SLI4_IF6_CQ_DB_REG ; +else + db_regaddr = sli4->reg[0 ] +SLI4_EQCQ_DB_REG ; + + res = dma.virt; +if (res->hdr.status) { +efc_log_err (sli4,"bad create CQSet status=%#x addl=%#x\n" , + res->hdr.status, res->hdr.additional_status); + goto error; + }else { +/* Check if we got all requested CQs. */ +if (le16_to_cpu (res->num_q_allocated) != num_cqs) { +efc_log_crit (sli4,"Requested count CQs doesn't match.\n" ); + goto error; + } +/* Fill the resp cq ids. */ +for (i =0 ; i < num_cqs; i++) { + qs[i]->id =le16_to_cpu (res->q_id) + i; + qs[i]->db_regaddr = db_regaddr; + } + } + +dma_free_coherent (&sli4->pcidev->dev, dma.size, dma.virt, dma.phys); + +return EFC_SUCCESS ; + +error: +for (i =0 ; i < num_cqs; i++) +__sli_queue_destroy (sli4, qs[i]); + +if (dma.virt)
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1101
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+dma_free_coherent (&sli4->pcidev->dev, dma.size, dma.virt, + dma.phys); + +return EFC_FAIL ; +} + +static int +sli_cmd_common_destroy_q (struct sli4 *sli4,u8 opc,u8 subsystem,u16 q_id) +{ +struct sli4_rqst_cmn_destroy_q *req =NULL ;
Not necessary to pre-initilize req here.
Quoted 43 lines
drivers/scsi/elx/libefc_sli/sli4.c +43
-0+ +/* Payload length must accommodate both request and response */ + req =sli_config_cmd_init (sli4, sli4->bmbx.virt,SLI4_BMBX_SIZE , +SLI_CONFIG_PYLD_LENGTH (cmn_destroy_q),NULL ); +if (!req) +return EFC_FAIL ; + +sli_cmd_fill_hdr (&req->hdr, opc, subsystem, +CMD_V0 ,CFG_RQST_PYLD_LEN (cmn_destroy_q)); + +return EFC_SUCCESS ; +} + +int +sli_queue_free (struct sli4 *sli4,struct sli4_queue *q, +u32 destroy_queues,u32 free_memory) +{ +int rc =EFC_SUCCESS ; +u8 opcode, subsystem; +struct sli4_rsp_hdr *res; + +if (!q) { +efc_log_err (sli4,"bad parameter sli4=%p q=%p\n" , sli4, q); +return EFC_FAIL ; + } + +if (!destroy_queues) + goto free_mem; + +switch (q->type) { +case SLI_QTYPE_EQ : + opcode =CMN_DESTROY_EQ ; + subsystem =SLI4_SUBSYSTEM_COMMON ; +break ; +case SLI_QTYPE_CQ : + opcode =CMN_DESTROY_CQ ; + subsystem =SLI4_SUBSYSTEM_COMMON ; +break ; +case SLI_QTYPE_MQ : + opcode =CMN_DESTROY_MQ ; + subsystem =SLI4_SUBSYSTEM_COMMON ; +break ; +case SLI_QTYPE_WQ :
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1154
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+ opcode =SLI4_OPC_WQ_DESTROY ; + subsystem =SLI4_SUBSYSTEM_FC ; +break ; +case SLI_QTYPE_RQ : + opcode =SLI4_OPC_RQ_DESTROY ; + subsystem =SLI4_SUBSYSTEM_FC ; +break ; +default : +efc_log_info (sli4,"bad queue type %d\n" , q->type); +return EFC_FAIL ;
and why not 'goto free_mem'?
I think I would move the destroy queue code into a new function instead all in this function...
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1163
Quoted 9 lines
drivers/scsi/elx/libefc_sli/sli4.c +9
-0+ } + + rc =sli_cmd_common_destroy_q (sli4, opcode, subsystem, q->id); +if (!rc) + goto free_mem; + +if (sli_bmbx_command (sli4)) { +efc_log_crit (sli4,"bootstrap mailbox fail destroy %s\n" , +SLI_QNAME [q->type]);
...and if this is an seperate function it would be possible to use an early return and don't have to do this else if dance.
Quoted 16 lines
drivers/scsi/elx/libefc_sli/sli4.c +16
-0+ }else if (sli_res_sli_config (sli4, sli4->bmbx.virt)) { +efc_log_err (sli4,"bad status %s\n" ,SLI_QNAME [q->type]); + }else { + res = (void *)((u8 *)sli4->bmbx.virt + + offsetof(struct sli4_cmd_sli_config , payload)); + +if (res->status) { +efc_log_err (sli4,"destroy %s st=%#x addl=%#x\n" , +SLI_QNAME [q->type], res->status, + res->additional_status); + }else { + rc =EFC_SUCCESS ; + } + } + +free_mem:
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1189
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+if (free_memory) +__sli_queue_destroy (sli4, q); + +return rc; +} + +int +sli_queue_eq_arm (struct sli4 *sli4,struct sli4_queue *q,bool arm) +{ +u32 val =0 ;
No need to pre-initialize val;
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1197
Quoted 8 lines
drivers/scsi/elx/libefc_sli/sli4.c +8
-0+unsigned long flags =0 ; +u32 a = arm ?SLI4_EQCQ_ARM :SLI4_EQCQ_UNARM ; + +spin_lock_irqsave (&q->lock, flags); +if (sli4->if_type ==SLI4_INTF_IF_TYPE_6 ) + val =SLI4_IF6_EQ_DOORBELL (q->n_posted, q->id, a); +else + val =SLI4_EQ_DOORBELL (q->n_posted, q->id, a);
After seeing SLI4_*_DOORBELL in action I would prefer these are inline functions and q and arm are passed in. All the macro magic could happend inside there. This would avoid the "a = arm ?..." here.
Quoted 39 lines
drivers/scsi/elx/libefc_sli/sli4.c +39
-0+ +writel (val, q->db_regaddr); + q->n_posted =0 ; +spin_unlock_irqrestore (&q->lock, flags); + +return EFC_SUCCESS ; +} + +int +sli_queue_arm (struct sli4 *sli4,struct sli4_queue *q,bool arm) +{ +u32 val =0 ; +unsigned long flags =0 ; +u32 a = arm ?SLI4_EQCQ_ARM :SLI4_EQCQ_UNARM ; + +spin_lock_irqsave (&q->lock, flags); + +switch (q->type) { +case SLI_QTYPE_EQ : +if (sli4->if_type ==SLI4_INTF_IF_TYPE_6 ) + val =SLI4_IF6_EQ_DOORBELL (q->n_posted, q->id, a); +else + val =SLI4_EQ_DOORBELL (q->n_posted, q->id, a); + +writel (val, q->db_regaddr); + q->n_posted =0 ; +break ; +case SLI_QTYPE_CQ : +if (sli4->if_type ==SLI4_INTF_IF_TYPE_6 ) + val =SLI4_IF6_CQ_DOORBELL (q->n_posted, q->id, a); +else + val =SLI4_CQ_DOORBELL (q->n_posted, q->id, a); + +writel (val, q->db_regaddr); + q->n_posted =0 ; +break ; +default : +efc_log_info (sli4,"should only be used for EQ/CQ, not %s\n" , +SLI_QNAME [q->type]);
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1246
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+ } + +spin_unlock_irqrestore (&q->lock, flags); + +return EFC_SUCCESS ; +} + +int +sli_wq_write (struct sli4 *sli4,struct sli4_queue *q, +u8 *entry)
entry still fits on the line above.
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1250
Quoted 4 lines
drivers/scsi/elx/libefc_sli/sli4.c +4
-0+{ +u8 *qe = q->dma.virt; +u32 qindex; +u32 val =0 ;
code indention not consistent
Quoted 9 lines
drivers/scsi/elx/libefc_sli/sli4.c +9
-0+ + qindex = q->index; + qe += q->index * q->size; + +if (sli4->perf_wq_id_association) +sli_set_wq_id_association (entry, q->id); + +memcpy (qe, entry, q->size); + q->n_posted =1 ;
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1269
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+ +if (sli4->if_type ==SLI4_INTF_IF_TYPE_6 ) +/* non-dpp write for iftype = 6 */ + val =SLI4_WQ_DOORBELL (q->n_posted,0 , q->id); +else + val =SLI4_WQ_DOORBELL (q->n_posted, q->index, q->id); + +writel (val, q->db_regaddr); + q->index = (q->index + q->n_posted) & (q->length -1 ); + q->n_posted =0 ;
Why does this not need a lock protection as in sli_queue_arm()?
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1276
Quoted 7 lines
drivers/scsi/elx/libefc_sli/sli4.c +7
-0+ +return qindex; +} + +int +sli_mq_write (struct sli4 *sli4,struct sli4_queue *q, +u8 *entry)
entry also fits on the line above
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1288
Quoted 12 lines
drivers/scsi/elx/libefc_sli/sli4.c +12
-0+{ +u8 *qe = q->dma.virt; +u32 qindex; +u32 val =0 ; +unsigned long flags; + +spin_lock_irqsave (&q->lock, flags); + qindex = q->index; + qe += q->index * q->size; + +memcpy (qe, entry, q->size); + q->n_posted =1 ;
Shouldn't this be q->n_posted++ ? Or is it garanteed n_posted is 0?
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1301
Quoted 13 lines
drivers/scsi/elx/libefc_sli/sli4.c +13
-0+ + val =SLI4_MQ_DOORBELL (q->n_posted, q->id); +writel (val, q->db_regaddr); + q->index = (q->index + q->n_posted) & (q->length -1 ); + q->n_posted =0 ; +spin_unlock_irqrestore (&q->lock, flags); + +return qindex; +} + +int +sli_rq_write (struct sli4 *sli4,struct sli4_queue *q, +u8 *entry)
enrry fits on the line above
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1311
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+{ +u8 *qe = q->dma.virt; +u32 qindex, n_posted; +u32 val =0 ; + + qindex = q->index; + qe += q->index * q->size; + +memcpy (qe, entry, q->size); + q->n_posted =1 ;
Again why not q->n_posted++ ?
I am confused why no lock is used here and in the fuction above. A few words on the locking desing would be highly appreciated.
Quoted 27 lines
drivers/scsi/elx/libefc_sli/sli4.c +27
-0+ + n_posted = q->n_posted; + +/* +* In RQ-pair, an RQ either contains the FC header +* (i.e. is_hdr == TRUE) or the payload. +* +* Don't ring doorbell for payload RQ +*/ +if (!(q->u.flag.dword &SLI4_QUEUE_FLAG_HDR )) + goto skip; + +/* +* Some RQ cannot be incremented one entry at a time. +* Instead, the driver collects a number of entries +* and updates the RQ in batches. +*/ +if (q->u.flag.dword &SLI4_QUEUE_FLAG_RQBATCH ) { +if (((q->index + q->n_posted) % +SLI4_QUEUE_RQ_BATCH )) { + goto skip; + } + n_posted =SLI4_QUEUE_RQ_BATCH ; + } + + val =SLI4_RQ_DOORBELL (n_posted, q->id); +writel (val, q->db_regaddr);
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1348
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+skip: + q->index = (q->index + q->n_posted) & (q->length -1 ); + q->n_posted =0 ; + +return qindex; +} + +int +sli_eq_read (struct sli4 *sli4, +struct sli4_queue *q,u8 *entry)
this fits on one line
Quoted 31 lines
drivers/scsi/elx/libefc_sli/sli4.c +31
-0+{ +u8 *qe = q->dma.virt; +u32 *qindex =NULL ; +unsigned long flags =0 ; +u8 clear = false, valid = false; +u16 wflags =0 ; + + clear = (sli4->if_type ==SLI4_INTF_IF_TYPE_6 ) ? false : true; + + qindex = &q->index; + +spin_lock_irqsave (&q->lock, flags); + + qe += *qindex * q->size; + +/* Check if eqe is valid */ + wflags =le16_to_cpu (((struct sli4_eqe *)qe)->dw0w0_flags); + valid = ((wflags &SLI4_EQE_VALID ) == q->phase); +if (!valid) { +spin_unlock_irqrestore (&q->lock, flags); +return EFC_FAIL ; + } + +if (valid && clear) { + wflags &= ~SLI4_EQE_VALID ; + ((struct sli4_eqe *)qe)->dw0w0_flags = +cpu_to_le16 (wflags); + } + +memcpy (entry, qe, q->size); + *qindex = (*qindex +1 ) & (q->length -1 );
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1389
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+ q->n_posted++; +/* +* For prism, the phase value will be used +* to check the validity of eq/cq entries. +* The value toggles after a complete sweep +* through the queue. +*/ + +if (sli4->if_type ==SLI4_INTF_IF_TYPE_6 && *qindex ==0 ) + q->phase ^= (u16 )0x1 ;
q->phase = !q->phase;
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1398
Quoted 9 lines
drivers/scsi/elx/libefc_sli/sli4.c +9
-0+ +spin_unlock_irqrestore (&q->lock, flags); + +return EFC_SUCCESS ; +} + +int +sli_cq_read (struct sli4 *sli4, +struct sli4_queue *q,u8 *entry)
fits on the same line
Quoted 12 lines
drivers/scsi/elx/libefc_sli/sli4.c +12
-0+{ +u8 *qe = q->dma.virt; +u32 *qindex =NULL ; +unsigned long flags =0 ; +u8 clear = false; +u32 dwflags =0 ; +bool valid = false, valid_bit_set = false; + + clear = (sli4->if_type ==SLI4_INTF_IF_TYPE_6 ) ? false : true; + + qindex = &q->index; +
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1420
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+spin_lock_irqsave (&q->lock, flags); + + qe += *qindex * q->size; + +/* Check if cqe is valid */ + dwflags =le32_to_cpu (((struct sli4_mcqe *)qe)->dw3_flags); + valid_bit_set = (dwflags &SLI4_MCQE_VALID ) !=0 ; + + valid = (valid_bit_set == q->phase); +if (!valid) {
if (valid_bit_set == q->phase)
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1372
Quoted 5 lines
drivers/scsi/elx/libefc_sli/sli4.c +5
-0+spin_unlock_irqrestore (&q->lock, flags); +return EFC_FAIL ; + } + +if (valid && clear) {
valid is alway true
Quoted 7 lines
drivers/scsi/elx/libefc_sli/sli4.c +7
-0+ dwflags &= ~SLI4_MCQE_VALID ; + ((struct sli4_mcqe *)qe)->dw3_flags = +cpu_to_le32 (dwflags); + } + +memcpy (entry, qe, q->size); + *qindex = (*qindex +1 ) & (q->length -1 );
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1442
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+ q->n_posted++; +/* +* For prism, the phase value will be used +* to check the validity of eq/cq entries. +* The value toggles after a complete sweep +* through the queue. +*/ + +if (sli4->if_type ==SLI4_INTF_IF_TYPE_6 && *qindex ==0 ) + q->phase ^= (u16 )0x1 ;
q->phase = !q->phase;
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1451
Quoted 9 lines
drivers/scsi/elx/libefc_sli/sli4.c +9
-0+ +spin_unlock_irqrestore (&q->lock, flags); + +return EFC_SUCCESS ; +} + +int +sli_mq_read (struct sli4 *sli4, +struct sli4_queue *q,u8 *entry)
fits on one line
Quoted 65 lines
drivers/scsi/elx/libefc_sli/sli4.c +65
-0+{ +u8 *qe = q->dma.virt; +u32 *qindex =NULL ; +unsigned long flags =0 ; + + qindex = &q->u.r_idx; + +spin_lock_irqsave (&q->lock, flags); + + qe += *qindex * q->size; + +/* Check if mqe is valid */ +if (q->index == q->u.r_idx) { +spin_unlock_irqrestore (&q->lock, flags); +return EFC_FAIL ; + } + +memcpy (entry, qe, q->size); + *qindex = (*qindex +1 ) & (q->length -1 ); + +spin_unlock_irqrestore (&q->lock, flags); + +return EFC_SUCCESS ; +} + +int +sli_eq_parse (struct sli4 *sli4,u8 *buf,u16 *cq_id) +{ +struct sli4_eqe *eqe = (void *)buf; +int rc =EFC_SUCCESS ; +u16 flags =0 ; +u16 majorcode; +u16 minorcode; + +if (!buf || !cq_id) { +efc_log_err (sli4,"bad parameters sli4=%p buf=%p cq_id=%p\n" , + sli4, buf, cq_id); +return EFC_FAIL ; + } + + flags =le16_to_cpu (eqe->dw0w0_flags); + majorcode = (flags &SLI4_EQE_MJCODE ) >>1 ; + minorcode = (flags &SLI4_EQE_MNCODE ) >>4 ; +switch (majorcode) { +case SLI4_MAJOR_CODE_STANDARD : + *cq_id =le16_to_cpu (eqe->resource_id); +break ; +case SLI4_MAJOR_CODE_SENTINEL : +efc_log_info (sli4,"sentinel EQE\n" ); + rc =SLI4_EQE_STATUS_EQ_FULL ; +break ; +default : +efc_log_info (sli4,"Unsupported EQE: major %x minor %x\n" , + majorcode, minorcode); + rc =EFC_FAIL ; + } + +return rc; +} + +/* Parse a CQ entry to retrieve the event type and the associated queue */ +int +sli_cq_parse (struct sli4 *sli4,struct sli4_queue *cq,u8 *cqe, +enum sli4_qentry *etype,u16 *q_id) +{
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1526
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+int rc =EFC_SUCCESS ; + +if (!cq || !cqe || !etype) { +efc_log_err (sli4,"bad params sli4=%p cq=%p cqe=%p etype=%p q_id=%p\n" , + sli4, cq, cqe, etype, q_id); +return -EINVAL ; + } + +if (cq->u.flag.dword &SLI4_QUEUE_FLAG_MQ ) { +struct sli4_mcqe *mcqe = (void *)cqe;
whitespace damage
Quoted 19 lines
drivers/scsi/elx/libefc_sli/sli4.c +14
-0+ +if (le32_to_cpu (mcqe->dw3_flags) &SLI4_MCQE_AE ) { + *etype =SLI_QENTRY_ASYNC ; + }else { + *etype =SLI_QENTRY_MQ ; + rc =sli_cqe_mq (sli4, mcqe); + } + *q_id =-1 ; + }else { + rc =sli_fc_cqe_parse (sli4, cq, cqe, etype, q_id); + } + +return rc; +}drivers/scsi/elx/libefc_sli/sli4.h +0
-0
drivers/scsi/elx/libefc_sli/sli4.h struct sli4 { · line 3691
Quoted 5 lines
drivers/scsi/elx/libefc_sli/sli4.h +2
-0@@ -3687,4 +3687,13 @@ struct sli4 {u32 vpd_length; }; +static inline void +sli_cmd_fill_hdr (struct sli4_rqst_hdr *hdr,u8 opc,u8 sub,u32 ver,__le32 len)
line is too long
Quoted 12 lines
drivers/scsi/elx/libefc_sli/sli4.h +7
-0+{ + hdr->opcode = opc; + hdr->subsystem = sub; + hdr->dw3_version =cpu_to_le32 (ver); + hdr->request_length = len; +} +#endif /* !_SLI4_H */ Signature · 1 line
2.16.4
Thanks,
Daniel
Re: [PATCH v3 04/31] elx: libefc_sli: queue create/destroy/parse routines
On 4/15/2020 3:04 AM, Daniel Wagner wrote:
...
Quoted 4 lines
Quoted 4 lines
drivers/scsi/elx/libefc_sli/sli4.c +4
-0+static void +__sli_queue_destroy (struct sli4 *sli4,struct sli4_queue *q) +{ +if (!q->dma.size)
Quoted 8 lines
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 562
Quoted 5 lines
drivers/scsi/elx/libefc_sli/sli4.c +5
-0+return ; + +dma_free_coherent (&sli4->pcidev->dev, q->dma.size, + q->dma.virt, q->dma.phys); +memset (&q->dma,0 ,sizeof (struct efc_dma ));Is this necessary to clear
q->dma? Just asking if it's possible to avoid the additional work.
unfortunately, yes - at least q->dma.size must be cleared. It's used to detect validity (must be non-0).
...
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 582
Quoted 6 lines
drivers/scsi/elx/libefc_sli/sli4.c +6
-0+ q->dma.size = size * n_entries; + q->dma.virt =dma_alloc_coherent (&sli4->pcidev->dev, + q->dma.size, &q->dma.phys, +GFP_DMA ); +if (!q->dma.virt) { +memset (&q->dma,0 ,sizeof (struct efc_dma ));So if
__sli_queue_destroy()keeps clearingq->dma, than this one can go away, since if__sli_queue_init()fails__sli_queue_destroy()will be called.
Well, this is the same thing - with q->dma.size being set to 0 so the dma_free_coherent() is avoided in the destroy call.
...
Quoted 8 lines
Quoted 8 lines
drivers/scsi/elx/libefc_sli/sli4.c +8
-0+sli_mq_write(struct sli4 *sli4, struct sli4_queue *q, + u8 *entry) +{ + u8 *qe = q->dma.virt; +u32 qindex; +u32 val =0 ; +unsigned long flags; +
Quoted 8 lines
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1259
Quoted 6 lines
drivers/scsi/elx/libefc_sli/sli4.c +6
-0+spin_lock_irqsave (&q->lock, flags); + qindex = q->index; + qe += q->index * q->size; + +memcpy (qe, entry, q->size); + q->n_posted =1 ;Shouldn't this be q->n_posted++ ? Or is it garanteed
n_postedis 0?
yes - we post 1 at a time.
...
Quoted 6 lines
Quoted 6 lines
drivers/scsi/elx/libefc_sli/sli4.c +6
-0+sli_rq_write(struct sli4 *sli4, struct sli4_queue *q, + u8 *entry) +{ + u8 *qe = q->dma.virt; +u32 qindex, n_posted; +u32 val =0 ;
Quoted 8 lines
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1259
Quoted 6 lines
drivers/scsi/elx/libefc_sli/sli4.c +6
-0+ + qindex = q->index; + qe += q->index * q->size; + +memcpy (qe, entry, q->size); + q->n_posted =1 ;Again why not q->n_posted++ ?
Same thing.
Quoted 3 lines
I am confused why no lock is used here and in the fuction above. A few words on the locking desing would be highly appreciated.
Q lock is held while calling this function. There were comments in the caller. Will add one here.
Agree with the rest of the comments and will address.
-- james
Re: [PATCH v3 04/31] elx: libefc_sli: queue create/destroy/parse routines
Quoted 15 lines · James Smart
On 4/15/2020 3:04 AM, Daniel Wagner wrote:
...Quoted 4 lines
Quoted 4 lines
drivers/scsi/elx/libefc_sli/sli4.c +4
-0+static void +__sli_queue_destroy (struct sli4 *sli4,struct sli4_queue *q) +{ +if (!q->dma.size)Quoted 8 lines
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 562
Quoted 5 lines
drivers/scsi/elx/libefc_sli/sli4.c +5
-0+return ; + +dma_free_coherent (&sli4->pcidev->dev, q->dma.size, + q->dma.virt, q->dma.phys); +memset (&q->dma,0 ,sizeof (struct efc_dma ));Is this necessary to clear
q->dma? Just asking if it's possible to avoid the additional work.
Quoted 2 lines
unfortunately, yes - at least
q->dma.sizemust be cleared. It's used to detect validity (must be non-0).
I see.
Quoted 17 lines
Quoted 8 lines
Quoted 8 lines
drivers/scsi/elx/libefc_sli/sli4.c +8
-0+sli_mq_write(struct sli4 *sli4, struct sli4_queue *q, + u8 *entry) +{ + u8 *qe = q->dma.virt; +u32 qindex; +u32 val =0 ; +unsigned long flags; +Quoted 8 lines
drivers/scsi/elx/libefc_sli/sli4.c static struct sli4_asic_entry_t sli4_asic_table[] = { · line 1259
Quoted 6 lines
drivers/scsi/elx/libefc_sli/sli4.c +6
-0+spin_lock_irqsave (&q->lock, flags); + qindex = q->index; + qe += q->index * q->size; + +memcpy (qe, entry, q->size); + q->n_posted =1 ;Shouldn't this be q->n_posted++ ? Or is it garanteed
n_postedis 0?
Quoted 1 line
yes - we post 1 at a time.
Sorry to ask again, but I worried that sli_mq_write() is called while there is work pending. Maybe it could at least documented with something like WARN_ON_ONCE(n_posted != 0)
Re: [PATCH v3 04/31] elx: libefc_sli: queue create/destroy/parse routines
Quoted 7 lines · Daniel Wagner
Quoted 3 lines
Quoted 1 line
Shouldn't this be q->n_posted++ ? Or is it garanteed
n_postedis 0?yes - we post 1 at a time.
Sorry to ask again, but I worried that
sli_mq_write()is called while there is work pending. Maybe it could at least documented with something likeWARN_ON_ONCE(n_posted != 0)
Yes - I'm having us re-look at the q->n_posted field. n_posted is to be used as an accumulator for when consuming or posting multiple elements from/to a queue. As RQ and MQ are not doing multiples, it makes no sense to set the field to one. So the DB writes will just explicitly set the DB value and ignore the field. The only code then setting n_posted will be the code that actually uses it as an accumulator. This should address your concerns. We'll also look at whether the queue structure is actually defined well - meaning perhaps it should contain common definitions (used by all queues) and a union of per-queue-type structs - so it's very clear what things a queue-type accesses. Not sure what will look the cleanest in the end, but that's the thinking.
-- james
Re: [PATCH v3 04/31] elx: libefc_sli: queue create/destroy/parse routines
In reply to James SmartQuoted 12 lines · James Smart
This patch continues the
libefc_sliSLI-4 library population.This patch adds service routines to create mailbox commands and adds APIs to create/destroy/parse SLI-4 EQ, CQ, RQ and MQ queues.
Signed-off-by Ram Vegesna <[email protected]>Signed-off-by James Smart <[email protected]>---
v3:
Removedefc_assertdefine. Replaced withWARN_ON. Returned defined return values EFC_SUCCESS/FAIL
Quoted 6 lines
--- drivers/scsi/elx/include/efc_common.h | 18 + drivers/scsi/elx/libefc_sli/sli4.c | 1514 +++++++++++++++++++++++++++++++++ drivers/scsi/elx/libefc_sli/sli4.h | 9 + 3 files changed, 1541 insertions(+)
Cheers,
Hannes
Signature · 4 lines
Dr. Hannes Reinecke Teamlead Storage & Networking [email protected] +49 911 74053 688 SUSE Software Solutions GmbH, Maxfeldstr. 5, 90409 Nürnberg HRB 36809 (AG Nürnberg), Geschäftsführer: Felix Imendörffer
PATCH v3 5/31 elx: libefc_sli: Populate and post different WQEs
In reply to James SmartThis patch continues the libefc_sli SLI-4 library population.
This patch adds service routines to create different WQEs and adds APIs to issue iread, iwrite, treceive, tsend and other work queue entries.
---
v3:
Return defined return values EFC_SUCCESS/FAIL
Removed HLM argument for WQE calls.
Reduced args for sli_fcp_treceive64_wqe(),
sli_fcp_cont_treceive64_wqe(), sli_fcp_trsp64_wqe(). Defined new
structure sli_fcp_tgt_params.
Removed sli_fc_process_link_state function which was not used for FC.
---
drivers/scsi/elx/libefc_sli/sli4.c | 1565 ++++++++++++++++++++++++++++++++++++
1 file changed, 1565 insertions(+)drivers/scsi/elx/libefc_sli/sli4.c +1565 -0
@@ -1538,3 +1538,1568 @@ sli_cq_parse(struct sli4 *sli4, struct sli4_queue *cq, u8 *cqe,return rc; } + +/* Write an ABORT_WQE work queue entry */ +int +sli_abort_wqe (struct sli4 *sli4,void *buf,size_t size, +enum sli4_abort_type type,bool send_abts,u32 ids, +u32 mask,u16 tag,u16 cq_id) +{ +struct sli4_abort_wqe *abort = buf; + +memset (buf,0 , size); + +switch (type) { +case SLI_ABORT_XRI : + abort->criteria =SLI4_ABORT_CRITERIA_XRI_TAG ; +if (mask) { +efc_log_warn (sli4,"%#x aborting XRI %#x warning non-zero mask" , + mask, ids); + mask =0 ; + } +break ; +case SLI_ABORT_ABORT_ID : + abort->criteria =SLI4_ABORT_CRITERIA_ABORT_TAG ; +break ; +case SLI_ABORT_REQUEST_ID : + abort->criteria =SLI4_ABORT_CRITERIA_REQUEST_TAG ; +break ; +default : +efc_log_info (sli4,"unsupported type %#x\n" , type); +return EFC_FAIL ; + } + + abort->ia_ir_byte |= send_abts ?0 :1 ; + +/* Suppress ABTS retries */ + abort->ia_ir_byte |=SLI4_ABRT_WQE_IR ; + + abort->t_mask =cpu_to_le32 (mask); + abort->t_tag =cpu_to_le32 (ids); + abort->command =SLI4_WQE_ABORT ; + abort->request_tag =cpu_to_le16 (tag); + + abort->dw10w0_flags =cpu_to_le16 (SLI4_ABRT_WQE_QOSD ); + + abort->cq_id =cpu_to_le16 (cq_id); + abort->cmdtype_wqec_byte |=SLI4_CMD_ABORT_WQE ; + +return EFC_SUCCESS ; +} + +/* Write an ELS_REQUEST64_WQE work queue entry */ +int +sli_els_request64_wqe (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *sgl, +u8 req_type,u32 req_len,u32 max_rsp_len, +u8 timeout,u16 xri,u16 tag, +u16 cq_id,u16 rnodeindicator,u16 sportindicator, +bool rnodeattached,u32 rnode_fcid,u32 sport_fcid) +{ +struct sli4_els_request64_wqe *els = buf; +struct sli4_sge *sge = sgl->virt; +bool is_fabric = false; +struct sli4_bde *bptr; + +memset (buf,0 , size); + + bptr = &els->els_request_payload; +if (sli4->sgl_pre_registered) { + els->qosd_xbl_hlm_iod_dbde_wqes &= ~SLI4_REQ_WQE_XBL ; + + els->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_REQ_WQE_DBDE ; + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (req_len &SLI4_BDE_MASK_BUFFER_LEN )); + + bptr->u.data.low = sge[0 ].buffer_address_low; + bptr->u.data.high = sge[0 ].buffer_address_high; + }else { + els->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_REQ_WQE_XBL ; + + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BLP <<BDE_TYPE_SHIFT ) | + ((2 *sizeof (struct sli4_sge )) & +SLI4_BDE_MASK_BUFFER_LEN )); + bptr->u.blp.low =cpu_to_le32 (lower_32_bits (sgl->phys)); + bptr->u.blp.high =cpu_to_le32 (upper_32_bits (sgl->phys)); + } + + els->els_request_payload_length =cpu_to_le32 (req_len); + els->max_response_payload_length =cpu_to_le32 (max_rsp_len); + + els->xri_tag =cpu_to_le16 (xri); + els->timer = timeout; + els->class_byte |=SLI4_GENERIC_CLASS_CLASS_3 ; + + els->command =SLI4_WQE_ELS_REQUEST64 ; + + els->request_tag =cpu_to_le16 (tag); + + els->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_REQ_WQE_IOD ; + + els->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_REQ_WQE_QOSD ; + +/* figure out the ELS_ID value from the request buffer */ + +switch (req_type) { +case ELS_LOGO : + els->cmdtype_elsid_byte |= +SLI4_ELS_REQUEST64_LOGO <<SLI4_REQ_WQE_ELSID_SHFT ; +if (rnodeattached) { + els->ct_byte |= (SLI4_GENERIC_CONTEXT_RPI << +SLI4_REQ_WQE_CT_SHFT ); + els->context_tag =cpu_to_le16 (rnodeindicator); + }else { + els->ct_byte |= +SLI4_GENERIC_CONTEXT_VPI <<SLI4_REQ_WQE_CT_SHFT ; + els->context_tag = +cpu_to_le16 (sportindicator); + } +if (rnode_fcid ==FC_FID_FLOGI ) + is_fabric = true; +break ; +case ELS_FDISC : +if (rnode_fcid ==FC_FID_FLOGI ) + is_fabric = true; +if (sport_fcid ==0 ) { + els->cmdtype_elsid_byte |= +SLI4_ELS_REQUEST64_FDISC <<SLI4_REQ_WQE_ELSID_SHFT ; + is_fabric = true; + }else { + els->cmdtype_elsid_byte |= +SLI4_ELS_REQUEST64_OTHER <<SLI4_REQ_WQE_ELSID_SHFT ; + } + els->ct_byte |= (SLI4_GENERIC_CONTEXT_VPI << +SLI4_REQ_WQE_CT_SHFT ); + els->context_tag =cpu_to_le16 (sportindicator); + els->sid_sp_dword |=cpu_to_le32 (1 <<SLI4_REQ_WQE_SP_SHFT ); +break ; +case ELS_FLOGI : + els->ct_byte |= +SLI4_GENERIC_CONTEXT_VPI <<SLI4_REQ_WQE_CT_SHFT ; + els->context_tag =cpu_to_le16 (sportindicator); +/* +* Set SP here ... we haven't done a REG_VPI yet +* need to maybe not set this when we have +* completed VFI/VPI registrations ... +* +* Use the FC_ID of the SPORT if it has been allocated, +* otherwise use an S_ID of zero. +*/ + els->sid_sp_dword |=cpu_to_le32 (1 <<SLI4_REQ_WQE_SP_SHFT ); +if (sport_fcid !=U32_MAX ) + els->sid_sp_dword |=cpu_to_le32 (sport_fcid); +break ; +case ELS_PLOGI : + els->cmdtype_elsid_byte |= +SLI4_ELS_REQUEST64_PLOGI <<SLI4_REQ_WQE_ELSID_SHFT ; + els->ct_byte |= +SLI4_GENERIC_CONTEXT_VPI <<SLI4_REQ_WQE_CT_SHFT ; + els->context_tag =cpu_to_le16 (sportindicator); +break ; +case ELS_SCR : + els->cmdtype_elsid_byte |= +SLI4_ELS_REQUEST64_OTHER <<SLI4_REQ_WQE_ELSID_SHFT ; + els->ct_byte |= +SLI4_GENERIC_CONTEXT_VPI <<SLI4_REQ_WQE_CT_SHFT ; + els->context_tag =cpu_to_le16 (sportindicator); +break ; +default : + els->cmdtype_elsid_byte |= +SLI4_ELS_REQUEST64_OTHER <<SLI4_REQ_WQE_ELSID_SHFT ; +if (rnodeattached) { + els->ct_byte |= (SLI4_GENERIC_CONTEXT_RPI << +SLI4_REQ_WQE_CT_SHFT ); + els->context_tag =cpu_to_le16 (sportindicator); + }else { + els->ct_byte |= +SLI4_GENERIC_CONTEXT_VPI <<SLI4_REQ_WQE_CT_SHFT ; + els->context_tag = +cpu_to_le16 (sportindicator); + } +break ; + } + +if (is_fabric) + els->cmdtype_elsid_byte |=SLI4_ELS_REQUEST64_CMD_FABRIC ; +else + els->cmdtype_elsid_byte |=SLI4_ELS_REQUEST64_CMD_NON_FABRIC ; + + els->cq_id =cpu_to_le16 (cq_id); + +if (((els->ct_byte &SLI4_REQ_WQE_CT ) >>SLI4_REQ_WQE_CT_SHFT ) != +SLI4_GENERIC_CONTEXT_RPI ) + els->remote_id_dword =cpu_to_le32 (rnode_fcid); + +if (((els->ct_byte &SLI4_REQ_WQE_CT ) >>SLI4_REQ_WQE_CT_SHFT ) == +SLI4_GENERIC_CONTEXT_VPI ) + els->temporary_rpi =cpu_to_le16 (rnodeindicator); + +return EFC_SUCCESS ; +} + +/* Write an FCP_ICMND64_WQE work queue entry */ +int +sli_fcp_icmnd64_wqe (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *sgl,u16 xri,u16 tag, +u16 cq_id,u32 rpi,u32 rnode_fcid,u8 timeout) +{ +struct sli4_fcp_icmnd64_wqe *icmnd = buf; +struct sli4_sge *sge =NULL ; +struct sli4_bde *bptr; +u32 len; + +memset (buf,0 , size); + +if (!sgl || !sgl->virt) { +efc_log_err (sli4,"bad parameter sgl=%p virt=%p\n" , + sgl, sgl ? sgl->virt :NULL ); +return EFC_FAIL ; + } + sge = sgl->virt; + bptr = &icmnd->bde; +if (sli4->sgl_pre_registered) { + icmnd->qosd_xbl_hlm_iod_dbde_wqes &= ~SLI4_ICMD_WQE_XBL ; + + icmnd->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_ICMD_WQE_DBDE ; + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (le32_to_cpu (sge[0 ].buffer_length) & +SLI4_BDE_MASK_BUFFER_LEN )); + + bptr->u.data.low = sge[0 ].buffer_address_low; + bptr->u.data.high = sge[0 ].buffer_address_high; + }else { + icmnd->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_ICMD_WQE_XBL ; + + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BLP <<BDE_TYPE_SHIFT ) | + (sgl->size &SLI4_BDE_MASK_BUFFER_LEN )); + + bptr->u.blp.low =cpu_to_le32 (lower_32_bits (sgl->phys)); + bptr->u.blp.high =cpu_to_le32 (upper_32_bits (sgl->phys)); + } + + len =le32_to_cpu (sge[0 ].buffer_length) + +le32_to_cpu (sge[1 ].buffer_length); + icmnd->payload_offset_length =cpu_to_le16 (len); + icmnd->xri_tag =cpu_to_le16 (xri); + icmnd->context_tag =cpu_to_le16 (rpi); + icmnd->timer = timeout; + +/* WQE word 4 contains read transfer length */ + icmnd->class_pu_byte |=2 <<SLI4_ICMD_WQE_PU_SHFT ; + icmnd->class_pu_byte |=SLI4_GENERIC_CLASS_CLASS_3 ; + icmnd->command =SLI4_WQE_FCP_ICMND64 ; + icmnd->dif_ct_bs_byte |= +SLI4_GENERIC_CONTEXT_RPI <<SLI4_ICMD_WQE_CT_SHFT ; + + icmnd->abort_tag =cpu_to_le32 (xri); + + icmnd->request_tag =cpu_to_le16 (tag); + icmnd->len_loc1_byte |=SLI4_ICMD_WQE_LEN_LOC_BIT1 ; + icmnd->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_ICMD_WQE_LEN_LOC_BIT2 ; + icmnd->cmd_type_byte |=SLI4_CMD_FCP_ICMND64_WQE ; + icmnd->cq_id =cpu_to_le16 (cq_id); + +return EFC_SUCCESS ; +} + +/* Write an FCP_IREAD64_WQE work queue entry */ +int +sli_fcp_iread64_wqe (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *sgl,u32 first_data_sge, +u32 xfer_len,u16 xri,u16 tag, +u16 cq_id,u32 rpi,u32 rnode_fcid, +u8 dif,u8 bs,u8 timeout) +{ +struct sli4_fcp_iread64_wqe *iread = buf; +struct sli4_sge *sge =NULL ; +struct sli4_bde *bptr; +u32 sge_flags, len; + +memset (buf,0 , size); + +if (!sgl || !sgl->virt) { +efc_log_err (sli4,"bad parameter sgl=%p virt=%p\n" , + sgl, sgl ? sgl->virt :NULL ); +return EFC_FAIL ; + } + + sge = sgl->virt; + bptr = &iread->bde; +if (sli4->sgl_pre_registered) { + iread->qosd_xbl_hlm_iod_dbde_wqes &= ~SLI4_IR_WQE_XBL ; + + iread->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_IR_WQE_DBDE ; + + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (le32_to_cpu (sge[0 ].buffer_length) & +SLI4_BDE_MASK_BUFFER_LEN )); + + bptr->u.blp.low = sge[0 ].buffer_address_low; + bptr->u.blp.high = sge[0 ].buffer_address_high; + }else { + iread->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_IR_WQE_XBL ; + + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BLP <<BDE_TYPE_SHIFT ) | + (sgl->size &SLI4_BDE_MASK_BUFFER_LEN )); + + bptr->u.blp.low = +cpu_to_le32 (lower_32_bits (sgl->phys)); + bptr->u.blp.high = +cpu_to_le32 (upper_32_bits (sgl->phys)); + +/* +* fill out fcp_cmnd buffer len and change resp buffer to be of +* type "skip" (note: response will still be written to sge[1] +* if necessary) +*/ + len =le32_to_cpu (sge[0 ].buffer_length); + iread->fcp_cmd_buffer_length =cpu_to_le16 (len); + + sge_flags =le32_to_cpu (sge[1 ].dw2_flags); + sge_flags &= (~SLI4_SGE_TYPE_MASK ); + sge_flags |= (SLI4_SGE_TYPE_SKIP <<SLI4_SGE_TYPE_SHIFT ); + sge[1 ].dw2_flags =cpu_to_le32 (sge_flags); + } + + len =le32_to_cpu (sge[0 ].buffer_length) + +le32_to_cpu (sge[1 ].buffer_length); + iread->payload_offset_length =cpu_to_le16 (len); + iread->total_transfer_length =cpu_to_le32 (xfer_len); + + iread->xri_tag =cpu_to_le16 (xri); + iread->context_tag =cpu_to_le16 (rpi); + + iread->timer = timeout; + +/* WQE word 4 contains read transfer length */ + iread->class_pu_byte |=2 <<SLI4_IR_WQE_PU_SHFT ; + iread->class_pu_byte |=SLI4_GENERIC_CLASS_CLASS_3 ; + iread->command =SLI4_WQE_FCP_IREAD64 ; + iread->dif_ct_bs_byte |= +SLI4_GENERIC_CONTEXT_RPI <<SLI4_IR_WQE_CT_SHFT ; + iread->dif_ct_bs_byte |= dif; + iread->dif_ct_bs_byte |= bs <<SLI4_IR_WQE_BS_SHFT ; + + iread->abort_tag =cpu_to_le32 (xri); + + iread->request_tag =cpu_to_le16 (tag); + iread->len_loc1_byte |=SLI4_IR_WQE_LEN_LOC_BIT1 ; + iread->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_IR_WQE_LEN_LOC_BIT2 ; + iread->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_IR_WQE_IOD ; + iread->cmd_type_byte |=SLI4_CMD_FCP_IREAD64_WQE ; + iread->cq_id =cpu_to_le16 (cq_id); + +if (sli4->perf_hint) { + bptr = &iread->first_data_bde; + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (le32_to_cpu (sge[first_data_sge].buffer_length) & +SLI4_BDE_MASK_BUFFER_LEN )); + bptr->u.data.low = + sge[first_data_sge].buffer_address_low; + bptr->u.data.high = + sge[first_data_sge].buffer_address_high; + } + +return EFC_SUCCESS ; +} + +/* Write an FCP_IWRITE64_WQE work queue entry */ +int +sli_fcp_iwrite64_wqe (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *sgl, +u32 first_data_sge,u32 xfer_len, +u32 first_burst,u16 xri,u16 tag, +u16 cq_id,u32 rpi, +u32 rnode_fcid, +u8 dif,u8 bs,u8 timeout) +{ +struct sli4_fcp_iwrite64_wqe *iwrite = buf; +struct sli4_sge *sge =NULL ; +struct sli4_bde *bptr; +u32 sge_flags, min, len; + +memset (buf,0 , size); + +if (!sgl || !sgl->virt) { +efc_log_err (sli4,"bad parameter sgl=%p virt=%p\n" , + sgl, sgl ? sgl->virt :NULL ); +return EFC_FAIL ; + } + sge = sgl->virt; + bptr = &iwrite->bde; +if (sli4->sgl_pre_registered) { + iwrite->qosd_xbl_hlm_iod_dbde_wqes &= ~SLI4_IWR_WQE_XBL ; + + iwrite->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_IWR_WQE_DBDE ; + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (le32_to_cpu (sge[0 ].buffer_length) & +SLI4_BDE_MASK_BUFFER_LEN )); + bptr->u.data.low = sge[0 ].buffer_address_low; + bptr->u.data.high = sge[0 ].buffer_address_high; + }else { + iwrite->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_IWR_WQE_XBL ; + + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (sgl->size &SLI4_BDE_MASK_BUFFER_LEN )); + + bptr->u.blp.low = +cpu_to_le32 (lower_32_bits (sgl->phys)); + bptr->u.blp.high = +cpu_to_le32 (upper_32_bits (sgl->phys)); + +/* +* fill out fcp_cmnd buffer len and change resp buffer to be of +* type "skip" (note: response will still be written to sge[1] +* if necessary) +*/ + len =le32_to_cpu (sge[0 ].buffer_length); + iwrite->fcp_cmd_buffer_length =cpu_to_le16 (len); + sge_flags =le32_to_cpu (sge[1 ].dw2_flags); + sge_flags &= ~SLI4_SGE_TYPE_MASK ; + sge_flags |= (SLI4_SGE_TYPE_SKIP <<SLI4_SGE_TYPE_SHIFT ); + sge[1 ].dw2_flags =cpu_to_le32 (sge_flags); + } + + len =le32_to_cpu (sge[0 ].buffer_length) + +le32_to_cpu (sge[1 ].buffer_length); + iwrite->payload_offset_length =cpu_to_le16 (len); + iwrite->total_transfer_length =cpu_to_le16 (xfer_len); + min = (xfer_len < first_burst) ? xfer_len : first_burst; + iwrite->initial_transfer_length =cpu_to_le16 (min); + + iwrite->xri_tag =cpu_to_le16 (xri); + iwrite->context_tag =cpu_to_le16 (rpi); + + iwrite->timer = timeout; +/* WQE word 4 contains read transfer length */ + iwrite->class_pu_byte |=2 <<SLI4_IWR_WQE_PU_SHFT ; + iwrite->class_pu_byte |=SLI4_GENERIC_CLASS_CLASS_3 ; + iwrite->command =SLI4_WQE_FCP_IWRITE64 ; + iwrite->dif_ct_bs_byte |= +SLI4_GENERIC_CONTEXT_RPI <<SLI4_IWR_WQE_CT_SHFT ; + iwrite->dif_ct_bs_byte |= dif; + iwrite->dif_ct_bs_byte |= bs <<SLI4_IWR_WQE_BS_SHFT ; + + iwrite->abort_tag =cpu_to_le32 (xri); + + iwrite->request_tag =cpu_to_le16 (tag); + iwrite->len_loc1_byte |=SLI4_IWR_WQE_LEN_LOC_BIT1 ; + iwrite->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_IWR_WQE_LEN_LOC_BIT2 ; + iwrite->cmd_type_byte |=SLI4_CMD_FCP_IWRITE64_WQE ; + iwrite->cq_id =cpu_to_le16 (cq_id); + +if (sli4->perf_hint) { + bptr = &iwrite->first_data_bde; + + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (le32_to_cpu (sge[first_data_sge].buffer_length) & +SLI4_BDE_MASK_BUFFER_LEN )); + + bptr->u.data.low = + sge[first_data_sge].buffer_address_low; + bptr->u.data.high = + sge[first_data_sge].buffer_address_high; + } + +return EFC_SUCCESS ; +} + +/* Write an FCP_TRECEIVE64_WQE work queue entry */ +int +sli_fcp_treceive64_wqe (struct sli4 *sli,void *buf, +struct efc_dma *sgl, +u32 first_data_sge, +u32 xfer_len,u16 xri,u16 tag, +u16 cq_id,u32 rpi,u32 rnode_fcid,u8 dif,u8 bs, +struct sli_fcp_tgt_params *params) +{ +struct sli4_fcp_treceive64_wqe *trecv = buf; +struct sli4_fcp_128byte_wqe *trecv_128 = buf; +struct sli4_sge *sge =NULL ; +struct sli4_bde *bptr; + +memset (buf,0 , sli->wqe_size); + +if (!sgl || !sgl->virt) { +efc_log_err (sli,"bad parameter sgl=%p virt=%p\n" , + sgl, sgl ? sgl->virt :NULL ); +return EFC_FAIL ; + } + sge = sgl->virt; + bptr = &trecv->bde; +if (sli->sgl_pre_registered) { + trecv->qosd_xbl_hlm_iod_dbde_wqes &= ~SLI4_TRCV_WQE_XBL ; + + trecv->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_TRCV_WQE_DBDE ; + + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (le32_to_cpu (sge[0 ].buffer_length) + &SLI4_BDE_MASK_BUFFER_LEN )); + + bptr->u.data.low = sge[0 ].buffer_address_low; + bptr->u.data.high = sge[0 ].buffer_address_high; + + trecv->payload_offset_length = sge[0 ].buffer_length; + }else { + trecv->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_TRCV_WQE_XBL ; + +/* if data is a single physical address, use a BDE */ +if (!dif && xfer_len <=le32_to_cpu (sge[2 ].buffer_length)) { + trecv->qosd_xbl_hlm_iod_dbde_wqes |= +SLI4_TRCV_WQE_DBDE ; + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (le32_to_cpu (sge[2 ].buffer_length) + &SLI4_BDE_MASK_BUFFER_LEN )); + + bptr->u.data.low = + sge[2 ].buffer_address_low; + bptr->u.data.high = + sge[2 ].buffer_address_high; + }else { + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BLP <<BDE_TYPE_SHIFT ) | + (sgl->size &SLI4_BDE_MASK_BUFFER_LEN )); + bptr->u.blp.low = +cpu_to_le32 (lower_32_bits (sgl->phys)); + bptr->u.blp.high = +cpu_to_le32 (upper_32_bits (sgl->phys)); + } + } + + trecv->relative_offset =cpu_to_le32 (params->offset); + +if (params->flags &SLI4_IO_CONTINUATION ) + trecv->eat_xc_ccpe |=SLI4_TRCV_WQE_XC ; + + trecv->xri_tag =cpu_to_le16 (xri); + + trecv->context_tag =cpu_to_le16 (rpi); + +/* WQE uses relative offset */ + trecv->class_ar_pu_byte |=1 <<SLI4_TRCV_WQE_PU_SHFT ; + +if (params->flags &SLI4_IO_AUTO_GOOD_RESPONSE ) + trecv->class_ar_pu_byte |=SLI4_TRCV_WQE_AR ; + + trecv->command =SLI4_WQE_FCP_TRECEIVE64 ; + trecv->class_ar_pu_byte |=SLI4_GENERIC_CLASS_CLASS_3 ; + trecv->dif_ct_bs_byte |= +SLI4_GENERIC_CONTEXT_RPI <<SLI4_TRCV_WQE_CT_SHFT ; + trecv->dif_ct_bs_byte |= bs <<SLI4_TRCV_WQE_BS_SHFT ; + + trecv->remote_xid =cpu_to_le16 (params->ox_id); + + trecv->request_tag =cpu_to_le16 (tag); + + trecv->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_TRCV_WQE_IOD ; + + trecv->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_TRCV_WQE_LEN_LOC_BIT2 ; + + trecv->cmd_type_byte |=SLI4_CMD_FCP_TRECEIVE64_WQE ; + + trecv->cq_id =cpu_to_le16 (cq_id); + + trecv->fcp_data_receive_length =cpu_to_le32 (xfer_len); + +if (sli->perf_hint) { + bptr = &trecv->first_data_bde; + + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (le32_to_cpu (sge[first_data_sge].buffer_length) & +SLI4_BDE_MASK_BUFFER_LEN )); + bptr->u.data.low = + sge[first_data_sge].buffer_address_low; + bptr->u.data.high = + sge[first_data_sge].buffer_address_high; + } + +/* The upper 7 bits of csctl is the priority */ +if (params->cs_ctl &SLI4_MASK_CCP ) { + trecv->eat_xc_ccpe |=SLI4_TRCV_WQE_CCPE ; + trecv->ccp = (params->cs_ctl &SLI4_MASK_CCP ); + } + +if (params->app_id && sli->wqe_size ==SLI4_WQE_EXT_BYTES && + !(trecv->eat_xc_ccpe &SLI4_TRSP_WQE_EAT )) { + trecv->lloc1_appid |=SLI4_TRCV_WQE_APPID ; + trecv->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_TRCV_WQE_WQES ; + trecv_128->dw[31 ] = params->app_id; + } +return EFC_SUCCESS ; +} + +/* Write an FCP_CONT_TRECEIVE64_WQE work queue entry */ +int +sli_fcp_cont_treceive64_wqe (struct sli4 *sli,void *buf, +struct efc_dma *sgl,u32 first_data_sge, +u32 xfer_len,u16 xri,u16 sec_xri,u16 tag, +u16 cq_id,u32 rpi,u32 rnode_fcid,u8 dif,u8 bs, +struct sli_fcp_tgt_params *params) +{ +int rc; + + rc =sli_fcp_treceive64_wqe (sli, buf, sgl, first_data_sge, + xfer_len, xri, tag, cq_id, + rpi, rnode_fcid, dif, bs, params); +if (rc ==0 ) { +struct sli4_fcp_treceive64_wqe *trecv = buf; + + trecv->command =SLI4_WQE_FCP_CONT_TRECEIVE64 ; + trecv->dword5.sec_xri_tag =cpu_to_le16 (sec_xri); + } +return rc; +} + +/* Write an FCP_TRSP64_WQE work queue entry */ +int +sli_fcp_trsp64_wqe (struct sli4 *sli4,void *buf,struct efc_dma *sgl, +u32 rsp_len,u16 xri,u16 tag,u16 cq_id,u32 rpi, +u32 rnode_fcid,u8 port_owned, +struct sli_fcp_tgt_params *params) +{ +struct sli4_fcp_trsp64_wqe *trsp = buf; +struct sli4_fcp_128byte_wqe *trsp_128 = buf; +struct sli4_bde *bptr; + +memset (buf,0 , sli4->wqe_size); + +if (params->flags &SLI4_IO_AUTO_GOOD_RESPONSE ) { + trsp->class_ag_byte |=SLI4_TRSP_WQE_AG ; + }else { +struct sli4_sge *sge = sgl->virt; + +if (sli4->sgl_pre_registered || port_owned) + trsp->qosd_xbl_hlm_dbde_wqes |=SLI4_TRSP_WQE_DBDE ; +else + trsp->qosd_xbl_hlm_dbde_wqes |=SLI4_TRSP_WQE_XBL ; + bptr = &trsp->bde; + + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (le32_to_cpu (sge[0 ].buffer_length) & +SLI4_BDE_MASK_BUFFER_LEN )); + bptr->u.data.low = sge[0 ].buffer_address_low; + bptr->u.data.high = sge[0 ].buffer_address_high; + + trsp->fcp_response_length =cpu_to_le32 (rsp_len); + } + +if (params->flags &SLI4_IO_CONTINUATION ) + trsp->eat_xc_ccpe |=SLI4_TRSP_WQE_XC ; + + trsp->xri_tag =cpu_to_le16 (xri); + trsp->rpi =cpu_to_le16 (rpi); + + trsp->command =SLI4_WQE_FCP_TRSP64 ; + trsp->class_ag_byte |=SLI4_GENERIC_CLASS_CLASS_3 ; + + trsp->remote_xid =cpu_to_le16 (params->ox_id); + trsp->request_tag =cpu_to_le16 (tag); +if (params->flags &SLI4_IO_DNRX ) + trsp->ct_dnrx_byte |=SLI4_TRSP_WQE_DNRX ; +else + trsp->ct_dnrx_byte &= ~SLI4_TRSP_WQE_DNRX ; + + trsp->lloc1_appid |=0x1 ; + trsp->cq_id =cpu_to_le16 (cq_id); + trsp->cmd_type_byte =SLI4_CMD_FCP_TRSP64_WQE ; + +/* The upper 7 bits of csctl is the priority */ +if (params->cs_ctl &SLI4_MASK_CCP ) { + trsp->eat_xc_ccpe |=SLI4_TRSP_WQE_CCPE ; + trsp->ccp = (params->cs_ctl &SLI4_MASK_CCP ); + } + +if (params->app_id && sli4->wqe_size ==SLI4_WQE_EXT_BYTES && + !(trsp->eat_xc_ccpe &SLI4_TRSP_WQE_EAT )) { + trsp->lloc1_appid |=SLI4_TRSP_WQE_APPID ; + trsp->qosd_xbl_hlm_dbde_wqes |=SLI4_TRSP_WQE_WQES ; + trsp_128->dw[31 ] = params->app_id; + } +return EFC_SUCCESS ; +} + +/* Write an FCP_TSEND64_WQE work queue entry */ +int +sli_fcp_tsend64_wqe (struct sli4 *sli4,void *buf,struct efc_dma *sgl, +u32 first_data_sge,u32 xfer_len,u16 xri,u16 tag, +u16 cq_id,u32 rpi,u32 rnode_fcid,u8 dif,u8 bs, +struct sli_fcp_tgt_params *params) +{ +struct sli4_fcp_tsend64_wqe *tsend = buf; +struct sli4_fcp_128byte_wqe *tsend_128 = buf; +struct sli4_sge *sge =NULL ; +struct sli4_bde *bptr; + +memset (buf,0 , sli4->wqe_size); + +if (!sgl || !sgl->virt) { +efc_log_err (sli4,"bad parameter sgl=%p virt=%p\n" , + sgl, sgl ? sgl->virt :NULL ); +return EFC_FAIL ; + } + sge = sgl->virt; + + bptr = &tsend->bde; +if (sli4->sgl_pre_registered) { + tsend->ll_qd_xbl_hlm_iod_dbde &= ~SLI4_TSEND_WQE_XBL ; + + tsend->ll_qd_xbl_hlm_iod_dbde |=SLI4_TSEND_WQE_DBDE ; + + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (le32_to_cpu (sge[2 ].buffer_length) & +SLI4_BDE_MASK_BUFFER_LEN )); + +/* TSEND64_WQE specifies first two SGE are skipped (3rd is +* valid) +*/ + bptr->u.data.low = sge[2 ].buffer_address_low; + bptr->u.data.high = sge[2 ].buffer_address_high; + }else { + tsend->ll_qd_xbl_hlm_iod_dbde |=SLI4_TSEND_WQE_XBL ; + +/* if data is a single physical address, use a BDE */ +if (!dif && xfer_len <=le32_to_cpu (sge[2 ].buffer_length)) { + tsend->ll_qd_xbl_hlm_iod_dbde |=SLI4_TSEND_WQE_DBDE ; + + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (le32_to_cpu (sge[2 ].buffer_length) & +SLI4_BDE_MASK_BUFFER_LEN )); +/* +* TSEND64_WQE specifies first two SGE are skipped +* (i.e. 3rd is valid) +*/ + bptr->u.data.low = + sge[2 ].buffer_address_low; + bptr->u.data.high = + sge[2 ].buffer_address_high; + }else { + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BLP <<BDE_TYPE_SHIFT ) | + (sgl->size & +SLI4_BDE_MASK_BUFFER_LEN )); + bptr->u.blp.low = +cpu_to_le32 (lower_32_bits (sgl->phys)); + bptr->u.blp.high = +cpu_to_le32 (upper_32_bits (sgl->phys)); + } + } + + tsend->relative_offset =cpu_to_le32 (params->offset); + +if (params->flags &SLI4_IO_CONTINUATION ) + tsend->dw10byte2 |=SLI4_TSEND_XC ; + + tsend->xri_tag =cpu_to_le16 (xri); + + tsend->rpi =cpu_to_le16 (rpi); +/* WQE uses relative offset */ + tsend->class_pu_ar_byte |=1 <<SLI4_TSEND_WQE_PU_SHFT ; + +if (params->flags &SLI4_IO_AUTO_GOOD_RESPONSE ) + tsend->class_pu_ar_byte |=SLI4_TSEND_WQE_AR ; + + tsend->command =SLI4_WQE_FCP_TSEND64 ; + tsend->class_pu_ar_byte |=SLI4_GENERIC_CLASS_CLASS_3 ; + tsend->ct_byte |=SLI4_GENERIC_CONTEXT_RPI <<SLI4_TSEND_CT_SHFT ; + tsend->ct_byte |= dif; + tsend->ct_byte |= bs <<SLI4_TSEND_BS_SHFT ; + + tsend->remote_xid =cpu_to_le16 (params->ox_id); + + tsend->request_tag =cpu_to_le16 (tag); + + tsend->ll_qd_xbl_hlm_iod_dbde |=SLI4_TSEND_LEN_LOC_BIT2 ; + + tsend->cq_id =cpu_to_le16 (cq_id); + + tsend->cmd_type_byte |=SLI4_CMD_FCP_TSEND64_WQE ; + + tsend->fcp_data_transmit_length =cpu_to_le32 (xfer_len); + +if (sli4->perf_hint) { + bptr = &tsend->first_data_bde; + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (le32_to_cpu (sge[first_data_sge].buffer_length) & +SLI4_BDE_MASK_BUFFER_LEN )); + bptr->u.data.low = + sge[first_data_sge].buffer_address_low; + bptr->u.data.high = + sge[first_data_sge].buffer_address_high; + } + +/* The upper 7 bits of csctl is the priority */ +if (params->cs_ctl &SLI4_MASK_CCP ) { + tsend->dw10byte2 |=SLI4_TSEND_CCPE ; + tsend->ccp = (params->cs_ctl &SLI4_MASK_CCP ); + } + +if (params->app_id && sli4->wqe_size ==SLI4_WQE_EXT_BYTES && + !(tsend->dw10byte2 &SLI4_TSEND_EAT )) { + tsend->dw10byte0 |=SLI4_TSEND_APPID_VALID ; + tsend->ll_qd_xbl_hlm_iod_dbde |=SLI4_TSEND_WQES ; + tsend_128->dw[31 ] = params->app_id; + } +return EFC_SUCCESS ; +} + +/* Write a GEN_REQUEST64 work queue entry */ +int +sli_gen_request64_wqe (struct sli4 *sli4,void *buf,struct efc_dma *sgl, +u32 req_len,u32 max_rsp_len,u16 xri,u16 tag, +u16 cq_id,u32 rnode_fcid,u16 rnodeindicator, +struct sli_ct_params *params) +{ +struct sli4_gen_request64_wqe *gen = buf; +struct sli4_sge *sge =NULL ; +struct sli4_bde *bptr; + +memset (buf,0 , sli4->wqe_size); + +if (!sgl || !sgl->virt) { +efc_log_err (sli4,"bad parameter sgl=%p virt=%p\n" , + sgl, sgl ? sgl->virt :NULL ); +return EFC_FAIL ; + } + sge = sgl->virt; + bptr = &gen->bde; + +if (sli4->sgl_pre_registered) { + gen->dw10flags1 &= ~SLI4_GEN_REQ64_WQE_XBL ; + + gen->dw10flags1 |=SLI4_GEN_REQ64_WQE_DBDE ; + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (req_len &SLI4_BDE_MASK_BUFFER_LEN )); + + bptr->u.data.low = sge[0 ].buffer_address_low; + bptr->u.data.high = sge[0 ].buffer_address_high; + }else { + gen->dw10flags1 |=SLI4_GEN_REQ64_WQE_XBL ; + + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BLP <<BDE_TYPE_SHIFT ) | + ((2 *sizeof (struct sli4_sge )) & +SLI4_BDE_MASK_BUFFER_LEN )); + + bptr->u.blp.low = +cpu_to_le32 (lower_32_bits (sgl->phys)); + bptr->u.blp.high = +cpu_to_le32 (upper_32_bits (sgl->phys)); + } + + gen->request_payload_length =cpu_to_le32 (req_len); + gen->max_response_payload_length =cpu_to_le32 (max_rsp_len); + + gen->df_ctl = params->df_ctl; + gen->type = params->type; + gen->r_ctl = params->r_ctl; + + gen->xri_tag =cpu_to_le16 (xri); + + gen->ct_byte =SLI4_GENERIC_CONTEXT_RPI <<SLI4_GEN_REQ64_CT_SHFT ; + gen->context_tag =cpu_to_le16 (rnodeindicator); + + gen->class_byte =SLI4_GENERIC_CLASS_CLASS_3 ; + + gen->command =SLI4_WQE_GEN_REQUEST64 ; + + gen->timer = params->timeout; + + gen->request_tag =cpu_to_le16 (tag); + + gen->dw10flags1 |=SLI4_GEN_REQ64_WQE_IOD ; + + gen->dw10flags0 |=SLI4_GEN_REQ64_WQE_QOSD ; + + gen->cmd_type_byte =SLI4_CMD_GEN_REQUEST64_WQE ; + + gen->cq_id =cpu_to_le16 (cq_id); + +return EFC_SUCCESS ; +} + +/* Write a SEND_FRAME work queue entry */ +int +sli_send_frame_wqe (struct sli4 *sli4,void *buf,size_t size, +u8 sof,u8 eof,u32 *hdr, +struct efc_dma *payload,u32 req_len, +u8 timeout,u16 xri,u16 req_tag) +{ +struct sli4_send_frame_wqe *sf = buf; + +memset (buf,0 , size); + + sf->dw10flags1 |=SLI4_SF_WQE_DBDE ; + sf->bde.bde_type_buflen =cpu_to_le32 (req_len & +SLI4_BDE_MASK_BUFFER_LEN ); + sf->bde.u.data.low = +cpu_to_le32 (lower_32_bits (payload->phys)); + sf->bde.u.data.high = +cpu_to_le32 (upper_32_bits (payload->phys)); + +/* Copy FC header */ + sf->fc_header_0_1[0 ] =cpu_to_le32 (hdr[0 ]); + sf->fc_header_0_1[1 ] =cpu_to_le32 (hdr[1 ]); + sf->fc_header_2_5[0 ] =cpu_to_le32 (hdr[2 ]); + sf->fc_header_2_5[1 ] =cpu_to_le32 (hdr[3 ]); + sf->fc_header_2_5[2 ] =cpu_to_le32 (hdr[4 ]); + sf->fc_header_2_5[3 ] =cpu_to_le32 (hdr[5 ]); + + sf->frame_length =cpu_to_le32 (req_len); + + sf->xri_tag =cpu_to_le16 (xri); + sf->dw7flags0 &= ~SLI4_SF_PU ; + sf->context_tag =0 ; + + sf->ct_byte &= ~SLI4_SF_CT ; + sf->command =SLI4_WQE_SEND_FRAME ; + sf->dw7flags0 |=SLI4_GENERIC_CLASS_CLASS_3 ; + sf->timer = timeout; + + sf->request_tag =cpu_to_le16 (req_tag); + sf->eof = eof; + sf->sof = sof; + + sf->dw10flags1 &= ~SLI4_SF_QOSD ; + sf->dw10flags0 |=SLI4_SF_LEN_LOC_BIT1 ; + sf->dw10flags2 &= ~SLI4_SF_XC ; + + sf->dw10flags1 |=SLI4_SF_XBL ; + + sf->cmd_type_byte |=SLI4_CMD_SEND_FRAME_WQE ; + sf->cq_id =cpu_to_le16 (0xffff ); + +return EFC_SUCCESS ; +} + +/* Write an XMIT_BLS_RSP64_WQE work queue entry */ +int +sli_xmit_bls_rsp64_wqe (struct sli4 *sli4,void *buf,size_t size, +struct sli_bls_payload *payload,u16 xri, +u16 tag,u16 cq_id, +bool rnodeattached,u16 rnodeindicator, +u16 sportindicator,u32 rnode_fcid, +u32 sport_fcid,u32 s_id) +{ +struct sli4_xmit_bls_rsp_wqe *bls = buf; +u32 dw_ridflags =0 ; + +/* +* Callers can either specify RPI or S_ID, but not both +*/ +if (rnodeattached && s_id !=U32_MAX ) { +efc_log_info (sli4,"S_ID specified for attached remote node %d\n" , + rnodeindicator); +return EFC_FAIL ; + } + +memset (buf,0 , size); + +if (payload->type ==SLI4_SLI_BLS_ACC ) { + bls->payload_word0 = +cpu_to_le32 ((payload->u.acc.seq_id_last <<16 ) | + (payload->u.acc.seq_id_validity <<24 )); + bls->high_seq_cnt = payload->u.acc.high_seq_cnt; + bls->low_seq_cnt = payload->u.acc.low_seq_cnt; + }else if (payload->type ==SLI4_SLI_BLS_RJT ) { + bls->payload_word0 = +cpu_to_le32 (*((u32 *)&payload->u.rjt)); + dw_ridflags |=SLI4_BLS_RSP_WQE_AR ; + }else { +efc_log_info (sli4,"bad BLS type %#x\n" , payload->type); +return EFC_FAIL ; + } + + bls->ox_id = payload->ox_id; + bls->rx_id = payload->rx_id; + +if (rnodeattached) { + bls->dw8flags0 |= +SLI4_GENERIC_CONTEXT_RPI <<SLI4_BLS_RSP_WQE_CT_SHFT ; + bls->context_tag =cpu_to_le16 (rnodeindicator); + }else { + bls->dw8flags0 |= +SLI4_GENERIC_CONTEXT_VPI <<SLI4_BLS_RSP_WQE_CT_SHFT ; + bls->context_tag =cpu_to_le16 (sportindicator); + +if (s_id !=U32_MAX ) + bls->local_n_port_id_dword |= +cpu_to_le32 (s_id &0x00ffffff ); +else + bls->local_n_port_id_dword |= +cpu_to_le32 (sport_fcid &0x00ffffff ); + + dw_ridflags = (dw_ridflags & ~SLI4_BLS_RSP_RID ) | + (rnode_fcid &SLI4_BLS_RSP_RID ); + + bls->temporary_rpi =cpu_to_le16 (rnodeindicator); + } + + bls->xri_tag =cpu_to_le16 (xri); + + bls->dw8flags1 |=SLI4_GENERIC_CLASS_CLASS_3 ; + + bls->command =SLI4_WQE_XMIT_BLS_RSP ; + + bls->request_tag =cpu_to_le16 (tag); + + bls->dw11flags1 |=SLI4_BLS_RSP_WQE_QOSD ; + + bls->remote_id_dword =cpu_to_le32 (dw_ridflags); + bls->cq_id =cpu_to_le16 (cq_id); + + bls->dw12flags0 |=SLI4_CMD_XMIT_BLS_RSP64_WQE ; + +return EFC_SUCCESS ; +} + +/* Write a XMIT_ELS_RSP64_WQE work queue entry */ +int +sli_xmit_els_rsp64_wqe (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *rsp,u32 rsp_len, +u16 xri,u16 tag,u16 cq_id, +u16 ox_id,u16 rnodeindicator, +u16 sportindicator, +bool rnodeattached,u32 rnode_fcid, +u32 flags,u32 s_id) +{ +struct sli4_xmit_els_rsp64_wqe *els = buf; + +memset (buf,0 , size); + +if (sli4->sgl_pre_registered) + els->flags2 |=SLI4_ELS_DBDE ; +else + els->flags2 |=SLI4_ELS_XBL ; + + els->els_response_payload.bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (rsp_len &SLI4_BDE_MASK_BUFFER_LEN )); + els->els_response_payload.u.data.low = +cpu_to_le32 (lower_32_bits (rsp->phys)); + els->els_response_payload.u.data.high = +cpu_to_le32 (upper_32_bits (rsp->phys)); + + els->els_response_payload_length =cpu_to_le32 (rsp_len); + + els->xri_tag =cpu_to_le16 (xri); + + els->class_byte |=SLI4_GENERIC_CLASS_CLASS_3 ; + + els->command =SLI4_WQE_ELS_RSP64 ; + + els->request_tag =cpu_to_le16 (tag); + + els->ox_id =cpu_to_le16 (ox_id); + + els->flags2 |= (SLI4_ELS_IOD &SLI4_ELS_REQUEST64_DIR_WRITE ); + + els->flags2 |=SLI4_ELS_QOSD ; + +if (flags &SLI4_IO_CONTINUATION ) + els->flags3 |=SLI4_ELS_XC ; + +if (rnodeattached) { + els->ct_byte |= +SLI4_GENERIC_CONTEXT_RPI <<SLI4_ELS_CT_OFFSET ; + els->context_tag =cpu_to_le16 (rnodeindicator); + }else { + els->ct_byte |= +SLI4_GENERIC_CONTEXT_VPI <<SLI4_ELS_CT_OFFSET ; + els->context_tag =cpu_to_le16 (sportindicator); + els->rid_dw =cpu_to_le32 (rnode_fcid &SLI4_ELS_RID ); + els->temporary_rpi =cpu_to_le16 (rnodeindicator); +if (s_id !=U32_MAX ) { + els->sid_dw |=cpu_to_le32 (SLI4_ELS_SP | + (s_id &SLI4_ELS_SID )); + } + } + + els->cmd_type_wqec =SLI4_ELS_REQUEST64_CMD_GEN ; + + els->cq_id =cpu_to_le16 (cq_id); + +return EFC_SUCCESS ; +} + +/* Write a XMIT_SEQUENCE64 work queue entry */ +int +sli_xmit_sequence64_wqe (struct sli4 *sli4,void *buf, +struct efc_dma *payload,u32 payload_len, +u16 xri,u16 tag,u32 rnode_fcid, +u16 rnodeindicator,struct sli_ct_params *params) +{ +struct sli4_xmit_sequence64_wqe *xmit = buf; + +memset (buf,0 , sli4->wqe_size); + +if (!payload || !payload->virt) { +efc_log_err (sli4,"bad parameter sgl=%p virt=%p\n" , + payload, payload ? payload->virt :NULL ); +return EFC_FAIL ; + } + +if (sli4->sgl_pre_registered) + xmit->dw10w0 |=cpu_to_le16 (SLI4_SEQ_WQE_DBDE ); +else + xmit->dw10w0 |=cpu_to_le16 (SLI4_SEQ_WQE_XBL ); + + xmit->bde.bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (payload_len &SLI4_BDE_MASK_BUFFER_LEN )); + xmit->bde.u.data.low = +cpu_to_le32 (lower_32_bits (payload->phys)); + xmit->bde.u.data.high = +cpu_to_le32 (upper_32_bits (payload->phys)); + xmit->sequence_payload_len =cpu_to_le32 (payload_len); + + xmit->remote_n_port_id_dword |=cpu_to_le32 (rnode_fcid &0x00ffffff ); + + xmit->relative_offset =0 ; + +/* sequence initiative - this matches what is seen from +* FC switches in response to FCGS commands +*/ + xmit->dw5flags0 &= (~SLI4_SEQ_WQE_SI ); + xmit->dw5flags0 &= (~SLI4_SEQ_WQE_FT );/* force transmit */ + xmit->dw5flags0 &= (~SLI4_SEQ_WQE_XO );/* exchange responder */ + xmit->dw5flags0 |=SLI4_SEQ_WQE_LS ;/* last in seqence */ + xmit->df_ctl = params->df_ctl; + xmit->type = params->type; + xmit->r_ctl = params->r_ctl; + + xmit->xri_tag =cpu_to_le16 (xri); + xmit->context_tag =cpu_to_le16 (rnodeindicator); + + xmit->dw7flags0 &= (~SLI4_SEQ_WQE_DIF ); + xmit->dw7flags0 |= +SLI4_GENERIC_CONTEXT_RPI <<SLI4_SEQ_WQE_CT_SHIFT ; + xmit->dw7flags0 &= (~SLI4_SEQ_WQE_BS ); + + xmit->command =SLI4_WQE_XMIT_SEQUENCE64 ; + xmit->dw7flags1 |=SLI4_GENERIC_CLASS_CLASS_3 ; + xmit->dw7flags1 &= (~SLI4_SEQ_WQE_PU ); + xmit->timer = params->timeout; + + xmit->abort_tag =0 ; + xmit->request_tag =cpu_to_le16 (tag); + xmit->remote_xid =cpu_to_le16 (params->ox_id); + + xmit->dw10w0 |= +cpu_to_le16 (SLI4_ELS_REQUEST64_DIR_READ <<SLI4_SEQ_WQE_IOD_SHIFT ); + + xmit->cmd_type_wqec_byte |=SLI4_CMD_XMIT_SEQUENCE64_WQE ; + + xmit->dw10w0 |=cpu_to_le16 (2 <<SLI4_SEQ_WQE_LEN_LOC_SHIFT ); + + xmit->cq_id =cpu_to_le16 (0xFFFF ); + +return EFC_SUCCESS ; +} + +/* Write a REQUEUE_XRI_WQE work queue entry */ +int +sli_requeue_xri_wqe (struct sli4 *sli4,void *buf,size_t size, +u16 xri,u16 tag,u16 cq_id) +{ +struct sli4_requeue_xri_wqe *requeue = buf; + +memset (buf,0 , size); + + requeue->command =SLI4_WQE_REQUEUE_XRI ; + requeue->xri_tag =cpu_to_le16 (xri); + requeue->request_tag =cpu_to_le16 (tag); + requeue->flags2 |=cpu_to_le16 (SLI4_REQU_XRI_WQE_XC ); + requeue->flags1 |=cpu_to_le16 (SLI4_REQU_XRI_WQE_QOSD ); + requeue->cq_id =cpu_to_le16 (cq_id); + requeue->cmd_type_wqec_byte =SLI4_CMD_REQUEUE_XRI_WQE ; +return EFC_SUCCESS ; +} + +/* Process an asynchronous Link Attention event entry */ +int +sli_fc_process_link_attention (struct sli4 *sli4,void *acqe) +{ +struct sli4_link_attention *link_attn = acqe; +struct sli4_link_event event = {0 }; + +efc_log_info (sli4,"link=%d attn_type=%#x top=%#x speed=%#x pfault=%#x\n" , + link_attn->link_number, link_attn->attn_type, + link_attn->topology, link_attn->port_speed, + link_attn->port_fault); +efc_log_info (sli4,"shared_lnk_status=%#x logl_lnk_speed=%#x evttag=%#x\n" , + link_attn->shared_link_status, +le16_to_cpu (link_attn->logical_link_speed), +le32_to_cpu (link_attn->event_tag)); + +if (!sli4->link) +return EFC_FAIL ; + + event.medium =SLI_LINK_MEDIUM_FC ; + +switch (link_attn->attn_type) { +case LINK_ATTN_TYPE_LINK_UP : + event.status =SLI_LINK_STATUS_UP ; +break ; +case LINK_ATTN_TYPE_LINK_DOWN : + event.status =SLI_LINK_STATUS_DOWN ; +break ; +case LINK_ATTN_TYPE_NO_HARD_ALPA : +efc_log_info (sli4,"attn_type: no hard alpa\n" ); + event.status =SLI_LINK_STATUS_NO_ALPA ; +break ; +default : +efc_log_info (sli4,"attn_type: unknown\n" ); +break ; + } + +switch (link_attn->event_type) { +case FC_EVENT_LINK_ATTENTION : +break ; +case FC_EVENT_SHARED_LINK_ATTENTION : +efc_log_info (sli4,"event_type: FC shared link event\n" ); +break ; +default : +efc_log_info (sli4,"event_type: unknown\n" ); +break ; + } + +switch (link_attn->topology) { +case LINK_ATTN_P2P : + event.topology =SLI_LINK_TOPO_NPORT ; +break ; +case LINK_ATTN_FC_AL : + event.topology =SLI_LINK_TOPO_LOOP ; +break ; +case LINK_ATTN_INTERNAL_LOOPBACK : +efc_log_info (sli4,"topology Internal loopback\n" ); + event.topology =SLI_LINK_TOPO_LOOPBACK_INTERNAL ; +break ; +case LINK_ATTN_SERDES_LOOPBACK : +efc_log_info (sli4,"topology serdes loopback\n" ); + event.topology =SLI_LINK_TOPO_LOOPBACK_EXTERNAL ; +break ; +default : +efc_log_info (sli4,"topology: unknown\n" ); +break ; + } + + event.speed = link_attn->port_speed *1000 ; + + sli4->link (sli4->link_arg, (void *)&event); + +return EFC_SUCCESS ; +} + +/* Parse an FC work queue CQ entry */ +int +sli_fc_cqe_parse (struct sli4 *sli4,struct sli4_queue *cq, +u8 *cqe,enum sli4_qentry *etype,u16 *r_id) +{ +u8 code = cqe[SLI4_CQE_CODE_OFFSET ]; +int rc; + +switch (code) { +case SLI4_CQE_CODE_WORK_REQUEST_COMPLETION : + { +struct sli4_fc_wcqe *wcqe = (void *)cqe; + + *etype =SLI_QENTRY_WQ ; + *r_id =le16_to_cpu (wcqe->request_tag); + rc = wcqe->status; + +/* Flag errors except for FCP_RSP_FAILURE */ +if (rc && rc !=SLI4_FC_WCQE_STATUS_FCP_RSP_FAILURE ) { +efc_log_info (sli4,"WCQE: status=%#x hw_status=%#x tag=%#x\n" , + wcqe->status, wcqe->hw_status, +le16_to_cpu (wcqe->request_tag)); +efc_log_info (sli4,"w1=%#x w2=%#x xb=%d\n" , +le32_to_cpu (wcqe->wqe_specific_1), +le32_to_cpu (wcqe->wqe_specific_2), + (wcqe->flags &SLI4_WCQE_XB )); +efc_log_info (sli4," %08X %08X %08X %08X\n" , + ((u32 *)cqe)[0 ], + ((u32 *)cqe)[1 ], + ((u32 *)cqe)[2 ], + ((u32 *)cqe)[3 ]); + } + +break ; + } +case SLI4_CQE_CODE_RQ_ASYNC : + { +struct sli4_fc_async_rcqe *rcqe = (void *)cqe; + + *etype =SLI_QENTRY_RQ ; + *r_id =le16_to_cpu (rcqe->fcfi_rq_id_word) &SLI4_RACQE_RQ_ID ; + rc = rcqe->status; +break ; + } +case SLI4_CQE_CODE_RQ_ASYNC_V1 : + { +struct sli4_fc_async_rcqe_v1 *rcqe = (void *)cqe; + + *etype =SLI_QENTRY_RQ ; + *r_id =le16_to_cpu (rcqe->rq_id); + rc = rcqe->status; +break ; + } +case SLI4_CQE_CODE_OPTIMIZED_WRITE_CMD : + { +struct sli4_fc_optimized_write_cmd_cqe *optcqe = (void *)cqe; + + *etype =SLI_QENTRY_OPT_WRITE_CMD ; + *r_id =le16_to_cpu (optcqe->rq_id); + rc = optcqe->status; +break ; + } +case SLI4_CQE_CODE_OPTIMIZED_WRITE_DATA : + { +struct sli4_fc_optimized_write_data_cqe *dcqe = (void *)cqe; + + *etype =SLI_QENTRY_OPT_WRITE_DATA ; + *r_id =le16_to_cpu (dcqe->xri); + rc = dcqe->status; + +/* Flag errors */ +if (rc !=SLI4_FC_WCQE_STATUS_SUCCESS ) { +efc_log_info (sli4,"Optimized DATA CQE: status=%#x\n" , + dcqe->status); +efc_log_info (sli4,"hstat=%#x xri=%#x dpl=%#x w3=%#x xb=%d\n" , + dcqe->hw_status,le16_to_cpu (dcqe->xri), +le32_to_cpu (dcqe->total_data_placed), + ((u32 *)cqe)[3 ], + (dcqe->flags &SLI4_OCQE_XB )); + } +break ; + } +case SLI4_CQE_CODE_RQ_COALESCING : + { +struct sli4_fc_coalescing_rcqe *rcqe = (void *)cqe; + + *etype =SLI_QENTRY_RQ ; + *r_id =le16_to_cpu (rcqe->rq_id); + rc = rcqe->status; +break ; + } +case SLI4_CQE_CODE_XRI_ABORTED : + { +struct sli4_fc_xri_aborted_cqe *xa = (void *)cqe; + + *etype =SLI_QENTRY_XABT ; + *r_id =le16_to_cpu (xa->xri); + rc =EFC_SUCCESS ; +break ; + } +case SLI4_CQE_CODE_RELEASE_WQE : { +struct sli4_fc_wqec *wqec = (void *)cqe; + + *etype =SLI_QENTRY_WQ_RELEASE ; + *r_id =le16_to_cpu (wqec->wq_id); + rc =EFC_SUCCESS ; +break ; + } +default : +efc_log_info (sli4,"CQE completion code %d not handled\n" , + code); + *etype =SLI_QENTRY_MAX ; + *r_id =U16_MAX ; + rc = -EINVAL ; + } + +return rc; +} + +u32 +sli_fc_response_length (struct sli4 *sli4,u8 *cqe) +{ +struct sli4_fc_wcqe *wcqe = (void *)cqe; + +return le32_to_cpu (wcqe->wqe_specific_1); +} + +u32 +sli_fc_io_length (struct sli4 *sli4,u8 *cqe) +{ +struct sli4_fc_wcqe *wcqe = (void *)cqe; + +return le32_to_cpu (wcqe->wqe_specific_1); +} + +int +sli_fc_els_did (struct sli4 *sli4,u8 *cqe,u32 *d_id) +{ +struct sli4_fc_wcqe *wcqe = (void *)cqe; + + *d_id =0 ; + +if (wcqe->status) +return EFC_FAIL ; + *d_id =le32_to_cpu (wcqe->wqe_specific_2) &0x00ffffff ; +return EFC_SUCCESS ; +} + +u32 +sli_fc_ext_status (struct sli4 *sli4,u8 *cqe) +{ +struct sli4_fc_wcqe *wcqe = (void *)cqe; +u32 mask; + +switch (wcqe->status) { +case SLI4_FC_WCQE_STATUS_FCP_RSP_FAILURE : + mask =U32_MAX ; +break ; +case SLI4_FC_WCQE_STATUS_LOCAL_REJECT : +case SLI4_FC_WCQE_STATUS_CMD_REJECT : + mask =0xff ; +break ; +case SLI4_FC_WCQE_STATUS_NPORT_RJT : +case SLI4_FC_WCQE_STATUS_FABRIC_RJT : +case SLI4_FC_WCQE_STATUS_NPORT_BSY : +case SLI4_FC_WCQE_STATUS_FABRIC_BSY : +case SLI4_FC_WCQE_STATUS_LS_RJT : + mask =U32_MAX ; +break ; +case SLI4_FC_WCQE_STATUS_DI_ERROR : + mask =U32_MAX ; +break ; +default : + mask =0 ; + } + +return le32_to_cpu (wcqe->wqe_specific_2) & mask; +} + +/* Retrieve the RQ index from the completion */ +int +sli_fc_rqe_rqid_and_index (struct sli4 *sli4,u8 *cqe, +u16 *rq_id,u32 *index) +{ +struct sli4_fc_async_rcqe *rcqe = (void *)cqe; +struct sli4_fc_async_rcqe_v1 *rcqe_v1 = (void *)cqe; +int rc =EFC_FAIL ; +u8 code =0 ; +u16 rq_element_index; + + *rq_id =0 ; + *index =U32_MAX ; + + code = cqe[SLI4_CQE_CODE_OFFSET ]; + +if (code ==SLI4_CQE_CODE_RQ_ASYNC ) { + *rq_id =le16_to_cpu (rcqe->fcfi_rq_id_word) &SLI4_RACQE_RQ_ID ; + rq_element_index = +le16_to_cpu (rcqe->rq_elmt_indx_word) &SLI4_RACQE_RQ_EL_INDX ; + *index = rq_element_index; +if (rcqe->status ==SLI4_FC_ASYNC_RQ_SUCCESS ) { + rc =EFC_SUCCESS ; + }else { + rc = rcqe->status; +efc_log_info (sli4,"status=%02x (%s) rq_id=%d\n" , + rcqe->status, +sli_fc_get_status_string (rcqe->status), +le16_to_cpu (rcqe->fcfi_rq_id_word) & +SLI4_RACQE_RQ_ID ); + +efc_log_info (sli4,"pdpl=%x sof=%02x eof=%02x hdpl=%x\n" , +le16_to_cpu (rcqe->data_placement_length), + rcqe->sof_byte, rcqe->eof_byte, + rcqe->hdpl_byte &SLI4_RACQE_HDPL ); + } + }else if (code ==SLI4_CQE_CODE_RQ_ASYNC_V1 ) { + *rq_id =le16_to_cpu (rcqe_v1->rq_id); + rq_element_index = + (le16_to_cpu (rcqe_v1->rq_elmt_indx_word) & +SLI4_RACQE_RQ_EL_INDX ); + *index = rq_element_index; +if (rcqe_v1->status ==SLI4_FC_ASYNC_RQ_SUCCESS ) { + rc =EFC_SUCCESS ; + }else { + rc = rcqe_v1->status; +efc_log_info (sli4,"status=%02x (%s) rq_id=%d, index=%x\n" , + rcqe_v1->status, +sli_fc_get_status_string (rcqe_v1->status), +le16_to_cpu (rcqe_v1->rq_id), rq_element_index); + +efc_log_info (sli4,"pdpl=%x sof=%02x eof=%02x hdpl=%x\n" , +le16_to_cpu (rcqe_v1->data_placement_length), + rcqe_v1->sof_byte, rcqe_v1->eof_byte, + rcqe_v1->hdpl_byte &SLI4_RACQE_HDPL ); + } + }else if (code ==SLI4_CQE_CODE_OPTIMIZED_WRITE_CMD ) { +struct sli4_fc_optimized_write_cmd_cqe *optcqe = (void *)cqe; + + *rq_id =le16_to_cpu (optcqe->rq_id); + *index =le16_to_cpu (optcqe->w1) &SLI4_OCQE_RQ_EL_INDX ; +if (optcqe->status ==SLI4_FC_ASYNC_RQ_SUCCESS ) { + rc =EFC_SUCCESS ; + }else { + rc = optcqe->status; +efc_log_info (sli4,"stat=%02x (%s) rqid=%d, idx=%x pdpl=%x\n" , + optcqe->status, +sli_fc_get_status_string (optcqe->status), +le16_to_cpu (optcqe->rq_id), *index, +le16_to_cpu (optcqe->data_placement_length)); + +efc_log_info (sli4,"hdpl=%x oox=%d agxr=%d xri=0x%x rpi=%x\n" , + (optcqe->hdpl_vld &SLI4_OCQE_HDPL ), + (optcqe->flags1 &SLI4_OCQE_OOX ), + (optcqe->flags1 &SLI4_OCQE_AGXR ), optcqe->xri, +le16_to_cpu (optcqe->rpi)); + } + }else if (code ==SLI4_CQE_CODE_RQ_COALESCING ) { +struct sli4_fc_coalescing_rcqe *rcqe = (void *)cqe; +u16 rq_element_index = + (le16_to_cpu (rcqe->rq_elmt_indx_word) & +SLI4_RCQE_RQ_EL_INDX ); + + *rq_id =le16_to_cpu (rcqe->rq_id); +if (rcqe->status ==SLI4_FC_COALESCE_RQ_SUCCESS ) { + *index = rq_element_index; + rc =EFC_SUCCESS ; + }else { + *index =U32_MAX ; + rc = rcqe->status; + +efc_log_info (sli4,"stat=%02x (%s) rq_id=%d, idx=%x\n" , + rcqe->status, +sli_fc_get_status_string (rcqe->status), +le16_to_cpu (rcqe->rq_id), rq_element_index); +efc_log_info (sli4,"rq_id=%#x sdpl=%x\n" , +le16_to_cpu (rcqe->rq_id), +le16_to_cpu (rcqe->sequence_reporting_placement_length)); + } + }else { + *index =U32_MAX ; + + rc = rcqe->status; + +efc_log_info (sli4,"status=%02x rq_id=%d, index=%x pdpl=%x\n" , + rcqe->status, +le16_to_cpu (rcqe->fcfi_rq_id_word) &SLI4_RACQE_RQ_ID , + (le16_to_cpu (rcqe->rq_elmt_indx_word) &SLI4_RACQE_RQ_EL_INDX ), +le16_to_cpu (rcqe->data_placement_length)); +efc_log_info (sli4,"sof=%02x eof=%02x hdpl=%x\n" , + rcqe->sof_byte, rcqe->eof_byte, + rcqe->hdpl_byte &SLI4_RACQE_HDPL ); + } + +return rc; +}
Signature · 1 line
2.16.4
Re: [PATCH v3 05/31] elx: libefc_sli: Populate and post different WQEs
Quoted 27 lines · James Smart
This patch continues the
libefc_sliSLI-4 library population.This patch adds service routines to create different WQEs and adds APIs to issue iread, iwrite, treceive, tsend and other work queue entries.
Signed-off-by Ram Vegesna <[email protected]>Signed-off-by James Smart <[email protected]>---
v3:
Return defined return values EFC_SUCCESS/FAIL
Removed HLM argument for WQE calls.
Reduced args forsli_fcp_treceive64_wqe(),sli_fcp_cont_treceive64_wqe(), sli_fcp_trsp64_wqe(). Defined new structure sli_fcp_tgt_params. Removed sli_fc_process_link_state function which was not used for FC. --- drivers/scsi/elx/libefc_sli/sli4.c | 1565 ++++++++++++++++++++++++++++++++++++ 1 file changed, 1565 insertions(+)drivers/scsi/elx/libefc_sli/sli4.c +0
-0@@ -1538,3 +1538,1568 @@ sli_cq_parse(struct sli4 *sli4, struct sli4_queue *cq, u8 *cqe,
drivers/scsi/elx/libefc_sli/sli4.c sli_cq_parse(struct sli4 *sli4, struct sli4_queue *cq, u8 *cqe, · line 1548
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +8
-0return rc; } + +/* Write an ABORT_WQE work queue entry */ +int +sli_abort_wqe (struct sli4 *sli4,void *buf,size_t size, +enum sli4_abort_type type,bool send_abts,u32 ids, +u32 mask,u16 tag,u16 cq_id) +{ +struct sli4_abort_wqe *abort = buf;
Why not just a space instead of a tab?
drivers/scsi/elx/libefc_sli/sli4.c sli_cq_parse(struct sli4 *sli4, struct sli4_queue *cq, u8 *cqe, · line 1550
Quoted 2 lines
drivers/scsi/elx/libefc_sli/sli4.c +2
-0+ +memset (buf,0 , size);
Is 'size' expected to be equal to the size of 'struct sli4_abort_wqe'? Or could it be bigger? In case 'size' can be bigger than 'abort', do you need to clear the complete buffer, or would it be enough to clear only the size of 'abort'?
Quoted 39 lines
drivers/scsi/elx/libefc_sli/sli4.c +39
-0+ +switch (type) { +case SLI_ABORT_XRI : + abort->criteria =SLI4_ABORT_CRITERIA_XRI_TAG ; +if (mask) { +efc_log_warn (sli4,"%#x aborting XRI %#x warning non-zero mask" , + mask, ids); + mask =0 ; + } +break ; +case SLI_ABORT_ABORT_ID : + abort->criteria =SLI4_ABORT_CRITERIA_ABORT_TAG ; +break ; +case SLI_ABORT_REQUEST_ID : + abort->criteria =SLI4_ABORT_CRITERIA_REQUEST_TAG ; +break ; +default : +efc_log_info (sli4,"unsupported type %#x\n" , type); +return EFC_FAIL ; + } + + abort->ia_ir_byte |= send_abts ?0 :1 ; + +/* Suppress ABTS retries */ + abort->ia_ir_byte |=SLI4_ABRT_WQE_IR ; + + abort->t_mask =cpu_to_le32 (mask); + abort->t_tag =cpu_to_le32 (ids); + abort->command =SLI4_WQE_ABORT ; + abort->request_tag =cpu_to_le16 (tag); + + abort->dw10w0_flags =cpu_to_le16 (SLI4_ABRT_WQE_QOSD ); + + abort->cq_id =cpu_to_le16 (cq_id); + abort->cmdtype_wqec_byte |=SLI4_CMD_ABORT_WQE ; + +return EFC_SUCCESS ; +} +
drivers/scsi/elx/libefc_sli/sli4.c sli_cq_parse(struct sli4 *sli4, struct sli4_queue *cq, u8 *cqe, · line 1599
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+/* Write an ELS_REQUEST64_WQE work queue entry */ +int +sli_els_request64_wqe (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *sgl, +u8 req_type,u32 req_len,u32 max_rsp_len, +u8 timeout,u16 xri,u16 tag, +u16 cq_id,u16 rnodeindicator,u16 sportindicator, +bool rnodeattached,u32 rnode_fcid,u32 sport_fcid) +{ +struct sli4_els_request64_wqe *els = buf;
And here as well, a tab and the following decleration use a space.
drivers/scsi/elx/libefc_sli/sli4.c sli_cq_parse(struct sli4 *sli4, struct sli4_queue *cq, u8 *cqe, · line 1604
Quoted 5 lines
drivers/scsi/elx/libefc_sli/sli4.c +5
-0+struct sli4_sge *sge = sgl->virt; +bool is_fabric = false; +struct sli4_bde *bptr; + +memset (buf,0 , size);
The same question as above about the size.
Quoted 37 lines
drivers/scsi/elx/libefc_sli/sli4.c +37
-0+ + bptr = &els->els_request_payload; +if (sli4->sgl_pre_registered) { + els->qosd_xbl_hlm_iod_dbde_wqes &= ~SLI4_REQ_WQE_XBL ; + + els->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_REQ_WQE_DBDE ; + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (req_len &SLI4_BDE_MASK_BUFFER_LEN )); + + bptr->u.data.low = sge[0 ].buffer_address_low; + bptr->u.data.high = sge[0 ].buffer_address_high; + }else { + els->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_REQ_WQE_XBL ; + + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BLP <<BDE_TYPE_SHIFT ) | + ((2 *sizeof (struct sli4_sge )) & +SLI4_BDE_MASK_BUFFER_LEN )); + bptr->u.blp.low =cpu_to_le32 (lower_32_bits (sgl->phys)); + bptr->u.blp.high =cpu_to_le32 (upper_32_bits (sgl->phys)); + } + + els->els_request_payload_length =cpu_to_le32 (req_len); + els->max_response_payload_length =cpu_to_le32 (max_rsp_len); + + els->xri_tag =cpu_to_le16 (xri); + els->timer = timeout; + els->class_byte |=SLI4_GENERIC_CLASS_CLASS_3 ; + + els->command =SLI4_WQE_ELS_REQUEST64 ; + + els->request_tag =cpu_to_le16 (tag); + + els->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_REQ_WQE_IOD ; + + els->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_REQ_WQE_QOSD ;
drivers/scsi/elx/libefc_sli/sli4.c sli_cq_parse(struct sli4 *sli4, struct sli4_queue *cq, u8 *cqe, · line 1651
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+ +/* figure out the ELS_ID value from the request buffer */ + +switch (req_type) { +case ELS_LOGO : + els->cmdtype_elsid_byte |= +SLI4_ELS_REQUEST64_LOGO <<SLI4_REQ_WQE_ELSID_SHFT ; +if (rnodeattached) { + els->ct_byte |= (SLI4_GENERIC_CONTEXT_RPI << +SLI4_REQ_WQE_CT_SHFT );
The brackets are not needed.
Quoted 13 lines
drivers/scsi/elx/libefc_sli/sli4.c +13
-0+ els->context_tag =cpu_to_le16 (rnodeindicator); + }else { + els->ct_byte |= +SLI4_GENERIC_CONTEXT_VPI <<SLI4_REQ_WQE_CT_SHFT ; + els->context_tag = +cpu_to_le16 (sportindicator); + } +if (rnode_fcid ==FC_FID_FLOGI ) + is_fabric = true; +break ; +case ELS_FDISC : +if (rnode_fcid ==FC_FID_FLOGI ) + is_fabric = true;
drivers/scsi/elx/libefc_sli/sli4.c sli_cq_parse(struct sli4 *sli4, struct sli4_queue *cq, u8 *cqe, · line 1674
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+if (sport_fcid ==0 ) { + els->cmdtype_elsid_byte |= +SLI4_ELS_REQUEST64_FDISC <<SLI4_REQ_WQE_ELSID_SHFT ; + is_fabric = true; + }else { + els->cmdtype_elsid_byte |= +SLI4_ELS_REQUEST64_OTHER <<SLI4_REQ_WQE_ELSID_SHFT ; + } + els->ct_byte |= (SLI4_GENERIC_CONTEXT_VPI << +SLI4_REQ_WQE_CT_SHFT );
Brakets are not needed
Quoted 473 lines
drivers/scsi/elx/libefc_sli/sli4.c +473
-0+ els->context_tag =cpu_to_le16 (sportindicator); + els->sid_sp_dword |=cpu_to_le32 (1 <<SLI4_REQ_WQE_SP_SHFT ); +break ; +case ELS_FLOGI : + els->ct_byte |= +SLI4_GENERIC_CONTEXT_VPI <<SLI4_REQ_WQE_CT_SHFT ; + els->context_tag =cpu_to_le16 (sportindicator); +/* +* Set SP here ... we haven't done a REG_VPI yet +* need to maybe not set this when we have +* completed VFI/VPI registrations ... +* +* Use the FC_ID of the SPORT if it has been allocated, +* otherwise use an S_ID of zero. +*/ + els->sid_sp_dword |=cpu_to_le32 (1 <<SLI4_REQ_WQE_SP_SHFT ); +if (sport_fcid !=U32_MAX ) + els->sid_sp_dword |=cpu_to_le32 (sport_fcid); +break ; +case ELS_PLOGI : + els->cmdtype_elsid_byte |= +SLI4_ELS_REQUEST64_PLOGI <<SLI4_REQ_WQE_ELSID_SHFT ; + els->ct_byte |= +SLI4_GENERIC_CONTEXT_VPI <<SLI4_REQ_WQE_CT_SHFT ; + els->context_tag =cpu_to_le16 (sportindicator); +break ; +case ELS_SCR : + els->cmdtype_elsid_byte |= +SLI4_ELS_REQUEST64_OTHER <<SLI4_REQ_WQE_ELSID_SHFT ; + els->ct_byte |= +SLI4_GENERIC_CONTEXT_VPI <<SLI4_REQ_WQE_CT_SHFT ; + els->context_tag =cpu_to_le16 (sportindicator); +break ; +default : + els->cmdtype_elsid_byte |= +SLI4_ELS_REQUEST64_OTHER <<SLI4_REQ_WQE_ELSID_SHFT ; +if (rnodeattached) { + els->ct_byte |= (SLI4_GENERIC_CONTEXT_RPI << +SLI4_REQ_WQE_CT_SHFT ); + els->context_tag =cpu_to_le16 (sportindicator); + }else { + els->ct_byte |= +SLI4_GENERIC_CONTEXT_VPI <<SLI4_REQ_WQE_CT_SHFT ; + els->context_tag = +cpu_to_le16 (sportindicator); + } +break ; + } + +if (is_fabric) + els->cmdtype_elsid_byte |=SLI4_ELS_REQUEST64_CMD_FABRIC ; +else + els->cmdtype_elsid_byte |=SLI4_ELS_REQUEST64_CMD_NON_FABRIC ; + + els->cq_id =cpu_to_le16 (cq_id); + +if (((els->ct_byte &SLI4_REQ_WQE_CT ) >>SLI4_REQ_WQE_CT_SHFT ) != +SLI4_GENERIC_CONTEXT_RPI ) + els->remote_id_dword =cpu_to_le32 (rnode_fcid); + +if (((els->ct_byte &SLI4_REQ_WQE_CT ) >>SLI4_REQ_WQE_CT_SHFT ) == +SLI4_GENERIC_CONTEXT_VPI ) + els->temporary_rpi =cpu_to_le16 (rnodeindicator); + +return EFC_SUCCESS ; +} + +/* Write an FCP_ICMND64_WQE work queue entry */ +int +sli_fcp_icmnd64_wqe (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *sgl,u16 xri,u16 tag, +u16 cq_id,u32 rpi,u32 rnode_fcid,u8 timeout) +{ +struct sli4_fcp_icmnd64_wqe *icmnd = buf; +struct sli4_sge *sge =NULL ; +struct sli4_bde *bptr; +u32 len; + +memset (buf,0 , size); + +if (!sgl || !sgl->virt) { +efc_log_err (sli4,"bad parameter sgl=%p virt=%p\n" , + sgl, sgl ? sgl->virt :NULL ); +return EFC_FAIL ; + } + sge = sgl->virt; + bptr = &icmnd->bde; +if (sli4->sgl_pre_registered) { + icmnd->qosd_xbl_hlm_iod_dbde_wqes &= ~SLI4_ICMD_WQE_XBL ; + + icmnd->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_ICMD_WQE_DBDE ; + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (le32_to_cpu (sge[0 ].buffer_length) & +SLI4_BDE_MASK_BUFFER_LEN )); + + bptr->u.data.low = sge[0 ].buffer_address_low; + bptr->u.data.high = sge[0 ].buffer_address_high; + }else { + icmnd->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_ICMD_WQE_XBL ; + + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BLP <<BDE_TYPE_SHIFT ) | + (sgl->size &SLI4_BDE_MASK_BUFFER_LEN )); + + bptr->u.blp.low =cpu_to_le32 (lower_32_bits (sgl->phys)); + bptr->u.blp.high =cpu_to_le32 (upper_32_bits (sgl->phys)); + } + + len =le32_to_cpu (sge[0 ].buffer_length) + +le32_to_cpu (sge[1 ].buffer_length); + icmnd->payload_offset_length =cpu_to_le16 (len); + icmnd->xri_tag =cpu_to_le16 (xri); + icmnd->context_tag =cpu_to_le16 (rpi); + icmnd->timer = timeout; + +/* WQE word 4 contains read transfer length */ + icmnd->class_pu_byte |=2 <<SLI4_ICMD_WQE_PU_SHFT ; + icmnd->class_pu_byte |=SLI4_GENERIC_CLASS_CLASS_3 ; + icmnd->command =SLI4_WQE_FCP_ICMND64 ; + icmnd->dif_ct_bs_byte |= +SLI4_GENERIC_CONTEXT_RPI <<SLI4_ICMD_WQE_CT_SHFT ; + + icmnd->abort_tag =cpu_to_le32 (xri); + + icmnd->request_tag =cpu_to_le16 (tag); + icmnd->len_loc1_byte |=SLI4_ICMD_WQE_LEN_LOC_BIT1 ; + icmnd->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_ICMD_WQE_LEN_LOC_BIT2 ; + icmnd->cmd_type_byte |=SLI4_CMD_FCP_ICMND64_WQE ; + icmnd->cq_id =cpu_to_le16 (cq_id); + +return EFC_SUCCESS ; +} + +/* Write an FCP_IREAD64_WQE work queue entry */ +int +sli_fcp_iread64_wqe (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *sgl,u32 first_data_sge, +u32 xfer_len,u16 xri,u16 tag, +u16 cq_id,u32 rpi,u32 rnode_fcid, +u8 dif,u8 bs,u8 timeout) +{ +struct sli4_fcp_iread64_wqe *iread = buf; +struct sli4_sge *sge =NULL ; +struct sli4_bde *bptr; +u32 sge_flags, len; + +memset (buf,0 , size); + +if (!sgl || !sgl->virt) { +efc_log_err (sli4,"bad parameter sgl=%p virt=%p\n" , + sgl, sgl ? sgl->virt :NULL ); +return EFC_FAIL ; + } + + sge = sgl->virt; + bptr = &iread->bde; +if (sli4->sgl_pre_registered) { + iread->qosd_xbl_hlm_iod_dbde_wqes &= ~SLI4_IR_WQE_XBL ; + + iread->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_IR_WQE_DBDE ; + + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (le32_to_cpu (sge[0 ].buffer_length) & +SLI4_BDE_MASK_BUFFER_LEN )); + + bptr->u.blp.low = sge[0 ].buffer_address_low; + bptr->u.blp.high = sge[0 ].buffer_address_high; + }else { + iread->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_IR_WQE_XBL ; + + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BLP <<BDE_TYPE_SHIFT ) | + (sgl->size &SLI4_BDE_MASK_BUFFER_LEN )); + + bptr->u.blp.low = +cpu_to_le32 (lower_32_bits (sgl->phys)); + bptr->u.blp.high = +cpu_to_le32 (upper_32_bits (sgl->phys)); + +/* +* fill out fcp_cmnd buffer len and change resp buffer to be of +* type "skip" (note: response will still be written to sge[1] +* if necessary) +*/ + len =le32_to_cpu (sge[0 ].buffer_length); + iread->fcp_cmd_buffer_length =cpu_to_le16 (len); + + sge_flags =le32_to_cpu (sge[1 ].dw2_flags); + sge_flags &= (~SLI4_SGE_TYPE_MASK ); + sge_flags |= (SLI4_SGE_TYPE_SKIP <<SLI4_SGE_TYPE_SHIFT ); + sge[1 ].dw2_flags =cpu_to_le32 (sge_flags); + } + + len =le32_to_cpu (sge[0 ].buffer_length) + +le32_to_cpu (sge[1 ].buffer_length); + iread->payload_offset_length =cpu_to_le16 (len); + iread->total_transfer_length =cpu_to_le32 (xfer_len); + + iread->xri_tag =cpu_to_le16 (xri); + iread->context_tag =cpu_to_le16 (rpi); + + iread->timer = timeout; + +/* WQE word 4 contains read transfer length */ + iread->class_pu_byte |=2 <<SLI4_IR_WQE_PU_SHFT ; + iread->class_pu_byte |=SLI4_GENERIC_CLASS_CLASS_3 ; + iread->command =SLI4_WQE_FCP_IREAD64 ; + iread->dif_ct_bs_byte |= +SLI4_GENERIC_CONTEXT_RPI <<SLI4_IR_WQE_CT_SHFT ; + iread->dif_ct_bs_byte |= dif; + iread->dif_ct_bs_byte |= bs <<SLI4_IR_WQE_BS_SHFT ; + + iread->abort_tag =cpu_to_le32 (xri); + + iread->request_tag =cpu_to_le16 (tag); + iread->len_loc1_byte |=SLI4_IR_WQE_LEN_LOC_BIT1 ; + iread->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_IR_WQE_LEN_LOC_BIT2 ; + iread->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_IR_WQE_IOD ; + iread->cmd_type_byte |=SLI4_CMD_FCP_IREAD64_WQE ; + iread->cq_id =cpu_to_le16 (cq_id); + +if (sli4->perf_hint) { + bptr = &iread->first_data_bde; + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (le32_to_cpu (sge[first_data_sge].buffer_length) & +SLI4_BDE_MASK_BUFFER_LEN )); + bptr->u.data.low = + sge[first_data_sge].buffer_address_low; + bptr->u.data.high = + sge[first_data_sge].buffer_address_high; + } + +return EFC_SUCCESS ; +} + +/* Write an FCP_IWRITE64_WQE work queue entry */ +int +sli_fcp_iwrite64_wqe (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *sgl, +u32 first_data_sge,u32 xfer_len, +u32 first_burst,u16 xri,u16 tag, +u16 cq_id,u32 rpi, +u32 rnode_fcid, +u8 dif,u8 bs,u8 timeout) +{ +struct sli4_fcp_iwrite64_wqe *iwrite = buf; +struct sli4_sge *sge =NULL ; +struct sli4_bde *bptr; +u32 sge_flags, min, len; + +memset (buf,0 , size); + +if (!sgl || !sgl->virt) { +efc_log_err (sli4,"bad parameter sgl=%p virt=%p\n" , + sgl, sgl ? sgl->virt :NULL ); +return EFC_FAIL ; + } + sge = sgl->virt; + bptr = &iwrite->bde; +if (sli4->sgl_pre_registered) { + iwrite->qosd_xbl_hlm_iod_dbde_wqes &= ~SLI4_IWR_WQE_XBL ; + + iwrite->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_IWR_WQE_DBDE ; + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (le32_to_cpu (sge[0 ].buffer_length) & +SLI4_BDE_MASK_BUFFER_LEN )); + bptr->u.data.low = sge[0 ].buffer_address_low; + bptr->u.data.high = sge[0 ].buffer_address_high; + }else { + iwrite->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_IWR_WQE_XBL ; + + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (sgl->size &SLI4_BDE_MASK_BUFFER_LEN )); + + bptr->u.blp.low = +cpu_to_le32 (lower_32_bits (sgl->phys)); + bptr->u.blp.high = +cpu_to_le32 (upper_32_bits (sgl->phys)); + +/* +* fill out fcp_cmnd buffer len and change resp buffer to be of +* type "skip" (note: response will still be written to sge[1] +* if necessary) +*/ + len =le32_to_cpu (sge[0 ].buffer_length); + iwrite->fcp_cmd_buffer_length =cpu_to_le16 (len); + sge_flags =le32_to_cpu (sge[1 ].dw2_flags); + sge_flags &= ~SLI4_SGE_TYPE_MASK ; + sge_flags |= (SLI4_SGE_TYPE_SKIP <<SLI4_SGE_TYPE_SHIFT ); + sge[1 ].dw2_flags =cpu_to_le32 (sge_flags); + } + + len =le32_to_cpu (sge[0 ].buffer_length) + +le32_to_cpu (sge[1 ].buffer_length); + iwrite->payload_offset_length =cpu_to_le16 (len); + iwrite->total_transfer_length =cpu_to_le16 (xfer_len); + min = (xfer_len < first_burst) ? xfer_len : first_burst; + iwrite->initial_transfer_length =cpu_to_le16 (min); + + iwrite->xri_tag =cpu_to_le16 (xri); + iwrite->context_tag =cpu_to_le16 (rpi); + + iwrite->timer = timeout; +/* WQE word 4 contains read transfer length */ + iwrite->class_pu_byte |=2 <<SLI4_IWR_WQE_PU_SHFT ; + iwrite->class_pu_byte |=SLI4_GENERIC_CLASS_CLASS_3 ; + iwrite->command =SLI4_WQE_FCP_IWRITE64 ; + iwrite->dif_ct_bs_byte |= +SLI4_GENERIC_CONTEXT_RPI <<SLI4_IWR_WQE_CT_SHFT ; + iwrite->dif_ct_bs_byte |= dif; + iwrite->dif_ct_bs_byte |= bs <<SLI4_IWR_WQE_BS_SHFT ; + + iwrite->abort_tag =cpu_to_le32 (xri); + + iwrite->request_tag =cpu_to_le16 (tag); + iwrite->len_loc1_byte |=SLI4_IWR_WQE_LEN_LOC_BIT1 ; + iwrite->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_IWR_WQE_LEN_LOC_BIT2 ; + iwrite->cmd_type_byte |=SLI4_CMD_FCP_IWRITE64_WQE ; + iwrite->cq_id =cpu_to_le16 (cq_id); + +if (sli4->perf_hint) { + bptr = &iwrite->first_data_bde; + + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (le32_to_cpu (sge[first_data_sge].buffer_length) & +SLI4_BDE_MASK_BUFFER_LEN )); + + bptr->u.data.low = + sge[first_data_sge].buffer_address_low; + bptr->u.data.high = + sge[first_data_sge].buffer_address_high; + } + +return EFC_SUCCESS ; +} + +/* Write an FCP_TRECEIVE64_WQE work queue entry */ +int +sli_fcp_treceive64_wqe (struct sli4 *sli,void *buf, +struct efc_dma *sgl, +u32 first_data_sge, +u32 xfer_len,u16 xri,u16 tag, +u16 cq_id,u32 rpi,u32 rnode_fcid,u8 dif,u8 bs, +struct sli_fcp_tgt_params *params) +{ +struct sli4_fcp_treceive64_wqe *trecv = buf; +struct sli4_fcp_128byte_wqe *trecv_128 = buf; +struct sli4_sge *sge =NULL ; +struct sli4_bde *bptr; + +memset (buf,0 , sli->wqe_size); + +if (!sgl || !sgl->virt) { +efc_log_err (sli,"bad parameter sgl=%p virt=%p\n" , + sgl, sgl ? sgl->virt :NULL ); +return EFC_FAIL ; + } + sge = sgl->virt; + bptr = &trecv->bde; +if (sli->sgl_pre_registered) { + trecv->qosd_xbl_hlm_iod_dbde_wqes &= ~SLI4_TRCV_WQE_XBL ; + + trecv->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_TRCV_WQE_DBDE ; + + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (le32_to_cpu (sge[0 ].buffer_length) + &SLI4_BDE_MASK_BUFFER_LEN )); + + bptr->u.data.low = sge[0 ].buffer_address_low; + bptr->u.data.high = sge[0 ].buffer_address_high; + + trecv->payload_offset_length = sge[0 ].buffer_length; + }else { + trecv->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_TRCV_WQE_XBL ; + +/* if data is a single physical address, use a BDE */ +if (!dif && xfer_len <=le32_to_cpu (sge[2 ].buffer_length)) { + trecv->qosd_xbl_hlm_iod_dbde_wqes |= +SLI4_TRCV_WQE_DBDE ; + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (le32_to_cpu (sge[2 ].buffer_length) + &SLI4_BDE_MASK_BUFFER_LEN )); + + bptr->u.data.low = + sge[2 ].buffer_address_low; + bptr->u.data.high = + sge[2 ].buffer_address_high; + }else { + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BLP <<BDE_TYPE_SHIFT ) | + (sgl->size &SLI4_BDE_MASK_BUFFER_LEN )); + bptr->u.blp.low = +cpu_to_le32 (lower_32_bits (sgl->phys)); + bptr->u.blp.high = +cpu_to_le32 (upper_32_bits (sgl->phys)); + } + } + + trecv->relative_offset =cpu_to_le32 (params->offset); + +if (params->flags &SLI4_IO_CONTINUATION ) + trecv->eat_xc_ccpe |=SLI4_TRCV_WQE_XC ; + + trecv->xri_tag =cpu_to_le16 (xri); + + trecv->context_tag =cpu_to_le16 (rpi); + +/* WQE uses relative offset */ + trecv->class_ar_pu_byte |=1 <<SLI4_TRCV_WQE_PU_SHFT ; + +if (params->flags &SLI4_IO_AUTO_GOOD_RESPONSE ) + trecv->class_ar_pu_byte |=SLI4_TRCV_WQE_AR ; + + trecv->command =SLI4_WQE_FCP_TRECEIVE64 ; + trecv->class_ar_pu_byte |=SLI4_GENERIC_CLASS_CLASS_3 ; + trecv->dif_ct_bs_byte |= +SLI4_GENERIC_CONTEXT_RPI <<SLI4_TRCV_WQE_CT_SHFT ; + trecv->dif_ct_bs_byte |= bs <<SLI4_TRCV_WQE_BS_SHFT ; + + trecv->remote_xid =cpu_to_le16 (params->ox_id); + + trecv->request_tag =cpu_to_le16 (tag); + + trecv->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_TRCV_WQE_IOD ; + + trecv->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_TRCV_WQE_LEN_LOC_BIT2 ; + + trecv->cmd_type_byte |=SLI4_CMD_FCP_TRECEIVE64_WQE ; + + trecv->cq_id =cpu_to_le16 (cq_id); + + trecv->fcp_data_receive_length =cpu_to_le32 (xfer_len); + +if (sli->perf_hint) { + bptr = &trecv->first_data_bde; + + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (le32_to_cpu (sge[first_data_sge].buffer_length) & +SLI4_BDE_MASK_BUFFER_LEN )); + bptr->u.data.low = + sge[first_data_sge].buffer_address_low; + bptr->u.data.high = + sge[first_data_sge].buffer_address_high; + } + +/* The upper 7 bits of csctl is the priority */ +if (params->cs_ctl &SLI4_MASK_CCP ) { + trecv->eat_xc_ccpe |=SLI4_TRCV_WQE_CCPE ; + trecv->ccp = (params->cs_ctl &SLI4_MASK_CCP ); + } + +if (params->app_id && sli->wqe_size ==SLI4_WQE_EXT_BYTES && + !(trecv->eat_xc_ccpe &SLI4_TRSP_WQE_EAT )) { + trecv->lloc1_appid |=SLI4_TRCV_WQE_APPID ; + trecv->qosd_xbl_hlm_iod_dbde_wqes |=SLI4_TRCV_WQE_WQES ; + trecv_128->dw[31 ] = params->app_id; + } +return EFC_SUCCESS ; +} + +/* Write an FCP_CONT_TRECEIVE64_WQE work queue entry */ +int +sli_fcp_cont_treceive64_wqe(struct sli4 *sli, void *buf, + struct efc_dma *sgl, u32 first_data_sge,
drivers/scsi/elx/libefc_sli/sli4.c sli_cq_parse(struct sli4 *sli4, struct sli4_queue *cq, u8 *cqe, · line 2157
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+ u32 xfer_len, u16 xri, u16 sec_xri, u16 tag, + u16 cq_id, u32 rpi, u32 rnode_fcid, u8 dif, u8 bs, + struct sli_fcp_tgt_params *params) +{ + int rc; + + rc =sli_fcp_treceive64_wqe (sli, buf, sgl, first_data_sge, + xfer_len, xri, tag, cq_id, + rpi, rnode_fcid, dif, bs, params); +if (rc ==0 ) {
if (rc == EFC_SUCCESS)
Quoted 445 lines
drivers/scsi/elx/libefc_sli/sli4.c +445
-0+struct sli4_fcp_treceive64_wqe *trecv = buf; + + trecv->command =SLI4_WQE_FCP_CONT_TRECEIVE64 ; + trecv->dword5.sec_xri_tag =cpu_to_le16 (sec_xri); + } +return rc; +} + +/* Write an FCP_TRSP64_WQE work queue entry */ +int +sli_fcp_trsp64_wqe (struct sli4 *sli4,void *buf,struct efc_dma *sgl, +u32 rsp_len,u16 xri,u16 tag,u16 cq_id,u32 rpi, +u32 rnode_fcid,u8 port_owned, +struct sli_fcp_tgt_params *params) +{ +struct sli4_fcp_trsp64_wqe *trsp = buf; +struct sli4_fcp_128byte_wqe *trsp_128 = buf; +struct sli4_bde *bptr; + +memset (buf,0 , sli4->wqe_size); + +if (params->flags &SLI4_IO_AUTO_GOOD_RESPONSE ) { + trsp->class_ag_byte |=SLI4_TRSP_WQE_AG ; + }else { +struct sli4_sge *sge = sgl->virt; + +if (sli4->sgl_pre_registered || port_owned) + trsp->qosd_xbl_hlm_dbde_wqes |=SLI4_TRSP_WQE_DBDE ; +else + trsp->qosd_xbl_hlm_dbde_wqes |=SLI4_TRSP_WQE_XBL ; + bptr = &trsp->bde; + + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (le32_to_cpu (sge[0 ].buffer_length) & +SLI4_BDE_MASK_BUFFER_LEN )); + bptr->u.data.low = sge[0 ].buffer_address_low; + bptr->u.data.high = sge[0 ].buffer_address_high; + + trsp->fcp_response_length =cpu_to_le32 (rsp_len); + } + +if (params->flags &SLI4_IO_CONTINUATION ) + trsp->eat_xc_ccpe |=SLI4_TRSP_WQE_XC ; + + trsp->xri_tag =cpu_to_le16 (xri); + trsp->rpi =cpu_to_le16 (rpi); + + trsp->command =SLI4_WQE_FCP_TRSP64 ; + trsp->class_ag_byte |=SLI4_GENERIC_CLASS_CLASS_3 ; + + trsp->remote_xid =cpu_to_le16 (params->ox_id); + trsp->request_tag =cpu_to_le16 (tag); +if (params->flags &SLI4_IO_DNRX ) + trsp->ct_dnrx_byte |=SLI4_TRSP_WQE_DNRX ; +else + trsp->ct_dnrx_byte &= ~SLI4_TRSP_WQE_DNRX ; + + trsp->lloc1_appid |=0x1 ; + trsp->cq_id =cpu_to_le16 (cq_id); + trsp->cmd_type_byte =SLI4_CMD_FCP_TRSP64_WQE ; + +/* The upper 7 bits of csctl is the priority */ +if (params->cs_ctl &SLI4_MASK_CCP ) { + trsp->eat_xc_ccpe |=SLI4_TRSP_WQE_CCPE ; + trsp->ccp = (params->cs_ctl &SLI4_MASK_CCP ); + } + +if (params->app_id && sli4->wqe_size ==SLI4_WQE_EXT_BYTES && + !(trsp->eat_xc_ccpe &SLI4_TRSP_WQE_EAT )) { + trsp->lloc1_appid |=SLI4_TRSP_WQE_APPID ; + trsp->qosd_xbl_hlm_dbde_wqes |=SLI4_TRSP_WQE_WQES ; + trsp_128->dw[31 ] = params->app_id; + } +return EFC_SUCCESS ; +} + +/* Write an FCP_TSEND64_WQE work queue entry */ +int +sli_fcp_tsend64_wqe (struct sli4 *sli4,void *buf,struct efc_dma *sgl, +u32 first_data_sge,u32 xfer_len,u16 xri,u16 tag, +u16 cq_id,u32 rpi,u32 rnode_fcid,u8 dif,u8 bs, +struct sli_fcp_tgt_params *params) +{ +struct sli4_fcp_tsend64_wqe *tsend = buf; +struct sli4_fcp_128byte_wqe *tsend_128 = buf; +struct sli4_sge *sge =NULL ; +struct sli4_bde *bptr; + +memset (buf,0 , sli4->wqe_size); + +if (!sgl || !sgl->virt) { +efc_log_err (sli4,"bad parameter sgl=%p virt=%p\n" , + sgl, sgl ? sgl->virt :NULL ); +return EFC_FAIL ; + } + sge = sgl->virt; + + bptr = &tsend->bde; +if (sli4->sgl_pre_registered) { + tsend->ll_qd_xbl_hlm_iod_dbde &= ~SLI4_TSEND_WQE_XBL ; + + tsend->ll_qd_xbl_hlm_iod_dbde |=SLI4_TSEND_WQE_DBDE ; + + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (le32_to_cpu (sge[2 ].buffer_length) & +SLI4_BDE_MASK_BUFFER_LEN )); + +/* TSEND64_WQE specifies first two SGE are skipped (3rd is +* valid) +*/ + bptr->u.data.low = sge[2 ].buffer_address_low; + bptr->u.data.high = sge[2 ].buffer_address_high; + }else { + tsend->ll_qd_xbl_hlm_iod_dbde |=SLI4_TSEND_WQE_XBL ; + +/* if data is a single physical address, use a BDE */ +if (!dif && xfer_len <=le32_to_cpu (sge[2 ].buffer_length)) { + tsend->ll_qd_xbl_hlm_iod_dbde |=SLI4_TSEND_WQE_DBDE ; + + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (le32_to_cpu (sge[2 ].buffer_length) & +SLI4_BDE_MASK_BUFFER_LEN )); +/* +* TSEND64_WQE specifies first two SGE are skipped +* (i.e. 3rd is valid) +*/ + bptr->u.data.low = + sge[2 ].buffer_address_low; + bptr->u.data.high = + sge[2 ].buffer_address_high; + }else { + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BLP <<BDE_TYPE_SHIFT ) | + (sgl->size & +SLI4_BDE_MASK_BUFFER_LEN )); + bptr->u.blp.low = +cpu_to_le32 (lower_32_bits (sgl->phys)); + bptr->u.blp.high = +cpu_to_le32 (upper_32_bits (sgl->phys)); + } + } + + tsend->relative_offset =cpu_to_le32 (params->offset); + +if (params->flags &SLI4_IO_CONTINUATION ) + tsend->dw10byte2 |=SLI4_TSEND_XC ; + + tsend->xri_tag =cpu_to_le16 (xri); + + tsend->rpi =cpu_to_le16 (rpi); +/* WQE uses relative offset */ + tsend->class_pu_ar_byte |=1 <<SLI4_TSEND_WQE_PU_SHFT ; + +if (params->flags &SLI4_IO_AUTO_GOOD_RESPONSE ) + tsend->class_pu_ar_byte |=SLI4_TSEND_WQE_AR ; + + tsend->command =SLI4_WQE_FCP_TSEND64 ; + tsend->class_pu_ar_byte |=SLI4_GENERIC_CLASS_CLASS_3 ; + tsend->ct_byte |=SLI4_GENERIC_CONTEXT_RPI <<SLI4_TSEND_CT_SHFT ; + tsend->ct_byte |= dif; + tsend->ct_byte |= bs <<SLI4_TSEND_BS_SHFT ; + + tsend->remote_xid =cpu_to_le16 (params->ox_id); + + tsend->request_tag =cpu_to_le16 (tag); + + tsend->ll_qd_xbl_hlm_iod_dbde |=SLI4_TSEND_LEN_LOC_BIT2 ; + + tsend->cq_id =cpu_to_le16 (cq_id); + + tsend->cmd_type_byte |=SLI4_CMD_FCP_TSEND64_WQE ; + + tsend->fcp_data_transmit_length =cpu_to_le32 (xfer_len); + +if (sli4->perf_hint) { + bptr = &tsend->first_data_bde; + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (le32_to_cpu (sge[first_data_sge].buffer_length) & +SLI4_BDE_MASK_BUFFER_LEN )); + bptr->u.data.low = + sge[first_data_sge].buffer_address_low; + bptr->u.data.high = + sge[first_data_sge].buffer_address_high; + } + +/* The upper 7 bits of csctl is the priority */ +if (params->cs_ctl &SLI4_MASK_CCP ) { + tsend->dw10byte2 |=SLI4_TSEND_CCPE ; + tsend->ccp = (params->cs_ctl &SLI4_MASK_CCP ); + } + +if (params->app_id && sli4->wqe_size ==SLI4_WQE_EXT_BYTES && + !(tsend->dw10byte2 &SLI4_TSEND_EAT )) { + tsend->dw10byte0 |=SLI4_TSEND_APPID_VALID ; + tsend->ll_qd_xbl_hlm_iod_dbde |=SLI4_TSEND_WQES ; + tsend_128->dw[31 ] = params->app_id; + } +return EFC_SUCCESS ; +} + +/* Write a GEN_REQUEST64 work queue entry */ +int +sli_gen_request64_wqe (struct sli4 *sli4,void *buf,struct efc_dma *sgl, +u32 req_len,u32 max_rsp_len,u16 xri,u16 tag, +u16 cq_id,u32 rnode_fcid,u16 rnodeindicator, +struct sli_ct_params *params) +{ +struct sli4_gen_request64_wqe *gen = buf; +struct sli4_sge *sge =NULL ; +struct sli4_bde *bptr; + +memset (buf,0 , sli4->wqe_size); + +if (!sgl || !sgl->virt) { +efc_log_err (sli4,"bad parameter sgl=%p virt=%p\n" , + sgl, sgl ? sgl->virt :NULL ); +return EFC_FAIL ; + } + sge = sgl->virt; + bptr = &gen->bde; + +if (sli4->sgl_pre_registered) { + gen->dw10flags1 &= ~SLI4_GEN_REQ64_WQE_XBL ; + + gen->dw10flags1 |=SLI4_GEN_REQ64_WQE_DBDE ; + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (req_len &SLI4_BDE_MASK_BUFFER_LEN )); + + bptr->u.data.low = sge[0 ].buffer_address_low; + bptr->u.data.high = sge[0 ].buffer_address_high; + }else { + gen->dw10flags1 |=SLI4_GEN_REQ64_WQE_XBL ; + + bptr->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BLP <<BDE_TYPE_SHIFT ) | + ((2 *sizeof (struct sli4_sge )) & +SLI4_BDE_MASK_BUFFER_LEN )); + + bptr->u.blp.low = +cpu_to_le32 (lower_32_bits (sgl->phys)); + bptr->u.blp.high = +cpu_to_le32 (upper_32_bits (sgl->phys)); + } + + gen->request_payload_length =cpu_to_le32 (req_len); + gen->max_response_payload_length =cpu_to_le32 (max_rsp_len); + + gen->df_ctl = params->df_ctl; + gen->type = params->type; + gen->r_ctl = params->r_ctl; + + gen->xri_tag =cpu_to_le16 (xri); + + gen->ct_byte =SLI4_GENERIC_CONTEXT_RPI <<SLI4_GEN_REQ64_CT_SHFT ; + gen->context_tag =cpu_to_le16 (rnodeindicator); + + gen->class_byte =SLI4_GENERIC_CLASS_CLASS_3 ; + + gen->command =SLI4_WQE_GEN_REQUEST64 ; + + gen->timer = params->timeout; + + gen->request_tag =cpu_to_le16 (tag); + + gen->dw10flags1 |=SLI4_GEN_REQ64_WQE_IOD ; + + gen->dw10flags0 |=SLI4_GEN_REQ64_WQE_QOSD ; + + gen->cmd_type_byte =SLI4_CMD_GEN_REQUEST64_WQE ; + + gen->cq_id =cpu_to_le16 (cq_id); + +return EFC_SUCCESS ; +} + +/* Write a SEND_FRAME work queue entry */ +int +sli_send_frame_wqe (struct sli4 *sli4,void *buf,size_t size, +u8 sof,u8 eof,u32 *hdr, +struct efc_dma *payload,u32 req_len, +u8 timeout,u16 xri,u16 req_tag) +{ +struct sli4_send_frame_wqe *sf = buf; + +memset (buf,0 , size); + + sf->dw10flags1 |=SLI4_SF_WQE_DBDE ; + sf->bde.bde_type_buflen =cpu_to_le32 (req_len & +SLI4_BDE_MASK_BUFFER_LEN ); + sf->bde.u.data.low = +cpu_to_le32 (lower_32_bits (payload->phys)); + sf->bde.u.data.high = +cpu_to_le32 (upper_32_bits (payload->phys)); + +/* Copy FC header */ + sf->fc_header_0_1[0 ] =cpu_to_le32 (hdr[0 ]); + sf->fc_header_0_1[1 ] =cpu_to_le32 (hdr[1 ]); + sf->fc_header_2_5[0 ] =cpu_to_le32 (hdr[2 ]); + sf->fc_header_2_5[1 ] =cpu_to_le32 (hdr[3 ]); + sf->fc_header_2_5[2 ] =cpu_to_le32 (hdr[4 ]); + sf->fc_header_2_5[3 ] =cpu_to_le32 (hdr[5 ]); + + sf->frame_length =cpu_to_le32 (req_len); + + sf->xri_tag =cpu_to_le16 (xri); + sf->dw7flags0 &= ~SLI4_SF_PU ; + sf->context_tag =0 ; + + sf->ct_byte &= ~SLI4_SF_CT ; + sf->command =SLI4_WQE_SEND_FRAME ; + sf->dw7flags0 |=SLI4_GENERIC_CLASS_CLASS_3 ; + sf->timer = timeout; + + sf->request_tag =cpu_to_le16 (req_tag); + sf->eof = eof; + sf->sof = sof; + + sf->dw10flags1 &= ~SLI4_SF_QOSD ; + sf->dw10flags0 |=SLI4_SF_LEN_LOC_BIT1 ; + sf->dw10flags2 &= ~SLI4_SF_XC ; + + sf->dw10flags1 |=SLI4_SF_XBL ; + + sf->cmd_type_byte |=SLI4_CMD_SEND_FRAME_WQE ; + sf->cq_id =cpu_to_le16 (0xffff ); + +return EFC_SUCCESS ; +} + +/* Write an XMIT_BLS_RSP64_WQE work queue entry */ +int +sli_xmit_bls_rsp64_wqe (struct sli4 *sli4,void *buf,size_t size, +struct sli_bls_payload *payload,u16 xri, +u16 tag,u16 cq_id, +bool rnodeattached,u16 rnodeindicator, +u16 sportindicator,u32 rnode_fcid, +u32 sport_fcid,u32 s_id) +{ +struct sli4_xmit_bls_rsp_wqe *bls = buf; +u32 dw_ridflags =0 ; + +/* +* Callers can either specify RPI or S_ID, but not both +*/ +if (rnodeattached && s_id !=U32_MAX ) { +efc_log_info (sli4,"S_ID specified for attached remote node %d\n" , + rnodeindicator); +return EFC_FAIL ; + } + +memset (buf,0 , size); + +if (payload->type ==SLI4_SLI_BLS_ACC ) { + bls->payload_word0 = +cpu_to_le32 ((payload->u.acc.seq_id_last <<16 ) | + (payload->u.acc.seq_id_validity <<24 )); + bls->high_seq_cnt = payload->u.acc.high_seq_cnt; + bls->low_seq_cnt = payload->u.acc.low_seq_cnt; + }else if (payload->type ==SLI4_SLI_BLS_RJT ) { + bls->payload_word0 = +cpu_to_le32 (*((u32 *)&payload->u.rjt)); + dw_ridflags |=SLI4_BLS_RSP_WQE_AR ; + }else { +efc_log_info (sli4,"bad BLS type %#x\n" , payload->type); +return EFC_FAIL ; + } + + bls->ox_id = payload->ox_id; + bls->rx_id = payload->rx_id; + +if (rnodeattached) { + bls->dw8flags0 |= +SLI4_GENERIC_CONTEXT_RPI <<SLI4_BLS_RSP_WQE_CT_SHFT ; + bls->context_tag =cpu_to_le16 (rnodeindicator); + }else { + bls->dw8flags0 |= +SLI4_GENERIC_CONTEXT_VPI <<SLI4_BLS_RSP_WQE_CT_SHFT ; + bls->context_tag =cpu_to_le16 (sportindicator); + +if (s_id !=U32_MAX ) + bls->local_n_port_id_dword |= +cpu_to_le32 (s_id &0x00ffffff ); +else + bls->local_n_port_id_dword |= +cpu_to_le32 (sport_fcid &0x00ffffff ); + + dw_ridflags = (dw_ridflags & ~SLI4_BLS_RSP_RID ) | + (rnode_fcid &SLI4_BLS_RSP_RID ); + + bls->temporary_rpi =cpu_to_le16 (rnodeindicator); + } + + bls->xri_tag =cpu_to_le16 (xri); + + bls->dw8flags1 |=SLI4_GENERIC_CLASS_CLASS_3 ; + + bls->command =SLI4_WQE_XMIT_BLS_RSP ; + + bls->request_tag =cpu_to_le16 (tag); + + bls->dw11flags1 |=SLI4_BLS_RSP_WQE_QOSD ; + + bls->remote_id_dword =cpu_to_le32 (dw_ridflags); + bls->cq_id =cpu_to_le16 (cq_id); + + bls->dw12flags0 |=SLI4_CMD_XMIT_BLS_RSP64_WQE ; + +return EFC_SUCCESS ; +} + +/* Write a XMIT_ELS_RSP64_WQE work queue entry */ +int +sli_xmit_els_rsp64_wqe (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *rsp,u32 rsp_len, +u16 xri,u16 tag,u16 cq_id, +u16 ox_id,u16 rnodeindicator, +u16 sportindicator, +bool rnodeattached,u32 rnode_fcid, +u32 flags,u32 s_id) +{ +struct sli4_xmit_els_rsp64_wqe *els = buf; + +memset (buf,0 , size); + +if (sli4->sgl_pre_registered) + els->flags2 |=SLI4_ELS_DBDE ; +else + els->flags2 |=SLI4_ELS_XBL ; + + els->els_response_payload.bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (rsp_len &SLI4_BDE_MASK_BUFFER_LEN )); + els->els_response_payload.u.data.low = +cpu_to_le32 (lower_32_bits (rsp->phys)); + els->els_response_payload.u.data.high = +cpu_to_le32 (upper_32_bits (rsp->phys)); + + els->els_response_payload_length =cpu_to_le32 (rsp_len); + + els->xri_tag =cpu_to_le16 (xri);
drivers/scsi/elx/libefc_sli/sli4.c sli_cq_parse(struct sli4 *sli4, struct sli4_queue *cq, u8 *cqe, · line 2612
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+ + els->class_byte |=SLI4_GENERIC_CLASS_CLASS_3 ; + + els->command =SLI4_WQE_ELS_RSP64 ; + + els->request_tag =cpu_to_le16 (tag); + + els->ox_id =cpu_to_le16 (ox_id); + + els->flags2 |= (SLI4_ELS_IOD &SLI4_ELS_REQUEST64_DIR_WRITE );
Brakets not needed.
Quoted 497 lines
drivers/scsi/elx/libefc_sli/sli4.c +493
-0+ + els->flags2 |=SLI4_ELS_QOSD ; + +if (flags &SLI4_IO_CONTINUATION ) + els->flags3 |=SLI4_ELS_XC ; + +if (rnodeattached) { + els->ct_byte |= +SLI4_GENERIC_CONTEXT_RPI <<SLI4_ELS_CT_OFFSET ; + els->context_tag =cpu_to_le16 (rnodeindicator); + }else { + els->ct_byte |= +SLI4_GENERIC_CONTEXT_VPI <<SLI4_ELS_CT_OFFSET ; + els->context_tag =cpu_to_le16 (sportindicator); + els->rid_dw =cpu_to_le32 (rnode_fcid &SLI4_ELS_RID ); + els->temporary_rpi =cpu_to_le16 (rnodeindicator); +if (s_id !=U32_MAX ) { + els->sid_dw |=cpu_to_le32 (SLI4_ELS_SP | + (s_id &SLI4_ELS_SID )); + } + } + + els->cmd_type_wqec =SLI4_ELS_REQUEST64_CMD_GEN ; + + els->cq_id =cpu_to_le16 (cq_id); + +return EFC_SUCCESS ; +} + +/* Write a XMIT_SEQUENCE64 work queue entry */ +int +sli_xmit_sequence64_wqe (struct sli4 *sli4,void *buf, +struct efc_dma *payload,u32 payload_len, +u16 xri,u16 tag,u32 rnode_fcid, +u16 rnodeindicator,struct sli_ct_params *params) +{ +struct sli4_xmit_sequence64_wqe *xmit = buf; + +memset (buf,0 , sli4->wqe_size); + +if (!payload || !payload->virt) { +efc_log_err (sli4,"bad parameter sgl=%p virt=%p\n" , + payload, payload ? payload->virt :NULL ); +return EFC_FAIL ; + } + +if (sli4->sgl_pre_registered) + xmit->dw10w0 |=cpu_to_le16 (SLI4_SEQ_WQE_DBDE ); +else + xmit->dw10w0 |=cpu_to_le16 (SLI4_SEQ_WQE_XBL ); + + xmit->bde.bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (payload_len &SLI4_BDE_MASK_BUFFER_LEN )); + xmit->bde.u.data.low = +cpu_to_le32 (lower_32_bits (payload->phys)); + xmit->bde.u.data.high = +cpu_to_le32 (upper_32_bits (payload->phys)); + xmit->sequence_payload_len =cpu_to_le32 (payload_len); + + xmit->remote_n_port_id_dword |=cpu_to_le32 (rnode_fcid &0x00ffffff ); + + xmit->relative_offset =0 ; + +/* sequence initiative - this matches what is seen from +* FC switches in response to FCGS commands +*/ + xmit->dw5flags0 &= (~SLI4_SEQ_WQE_SI ); + xmit->dw5flags0 &= (~SLI4_SEQ_WQE_FT );/* force transmit */ + xmit->dw5flags0 &= (~SLI4_SEQ_WQE_XO );/* exchange responder */ + xmit->dw5flags0 |=SLI4_SEQ_WQE_LS ;/* last in seqence */ + xmit->df_ctl = params->df_ctl; + xmit->type = params->type; + xmit->r_ctl = params->r_ctl; + + xmit->xri_tag =cpu_to_le16 (xri); + xmit->context_tag =cpu_to_le16 (rnodeindicator); + + xmit->dw7flags0 &= (~SLI4_SEQ_WQE_DIF ); + xmit->dw7flags0 |= +SLI4_GENERIC_CONTEXT_RPI <<SLI4_SEQ_WQE_CT_SHIFT ; + xmit->dw7flags0 &= (~SLI4_SEQ_WQE_BS ); + + xmit->command =SLI4_WQE_XMIT_SEQUENCE64 ; + xmit->dw7flags1 |=SLI4_GENERIC_CLASS_CLASS_3 ; + xmit->dw7flags1 &= (~SLI4_SEQ_WQE_PU ); + xmit->timer = params->timeout; + + xmit->abort_tag =0 ; + xmit->request_tag =cpu_to_le16 (tag); + xmit->remote_xid =cpu_to_le16 (params->ox_id); + + xmit->dw10w0 |= +cpu_to_le16 (SLI4_ELS_REQUEST64_DIR_READ <<SLI4_SEQ_WQE_IOD_SHIFT ); + + xmit->cmd_type_wqec_byte |=SLI4_CMD_XMIT_SEQUENCE64_WQE ; + + xmit->dw10w0 |=cpu_to_le16 (2 <<SLI4_SEQ_WQE_LEN_LOC_SHIFT ); + + xmit->cq_id =cpu_to_le16 (0xFFFF ); + +return EFC_SUCCESS ; +} + +/* Write a REQUEUE_XRI_WQE work queue entry */ +int +sli_requeue_xri_wqe (struct sli4 *sli4,void *buf,size_t size, +u16 xri,u16 tag,u16 cq_id) +{ +struct sli4_requeue_xri_wqe *requeue = buf; + +memset (buf,0 , size); + + requeue->command =SLI4_WQE_REQUEUE_XRI ; + requeue->xri_tag =cpu_to_le16 (xri); + requeue->request_tag =cpu_to_le16 (tag); + requeue->flags2 |=cpu_to_le16 (SLI4_REQU_XRI_WQE_XC ); + requeue->flags1 |=cpu_to_le16 (SLI4_REQU_XRI_WQE_QOSD ); + requeue->cq_id =cpu_to_le16 (cq_id); + requeue->cmd_type_wqec_byte =SLI4_CMD_REQUEUE_XRI_WQE ; +return EFC_SUCCESS ; +} + +/* Process an asynchronous Link Attention event entry */ +int +sli_fc_process_link_attention (struct sli4 *sli4,void *acqe) +{ +struct sli4_link_attention *link_attn = acqe; +struct sli4_link_event event = {0 }; + +efc_log_info (sli4,"link=%d attn_type=%#x top=%#x speed=%#x pfault=%#x\n" , + link_attn->link_number, link_attn->attn_type, + link_attn->topology, link_attn->port_speed, + link_attn->port_fault); +efc_log_info (sli4,"shared_lnk_status=%#x logl_lnk_speed=%#x evttag=%#x\n" , + link_attn->shared_link_status, +le16_to_cpu (link_attn->logical_link_speed), +le32_to_cpu (link_attn->event_tag)); + +if (!sli4->link) +return EFC_FAIL ; + + event.medium =SLI_LINK_MEDIUM_FC ; + +switch (link_attn->attn_type) { +case LINK_ATTN_TYPE_LINK_UP : + event.status =SLI_LINK_STATUS_UP ; +break ; +case LINK_ATTN_TYPE_LINK_DOWN : + event.status =SLI_LINK_STATUS_DOWN ; +break ; +case LINK_ATTN_TYPE_NO_HARD_ALPA : +efc_log_info (sli4,"attn_type: no hard alpa\n" ); + event.status =SLI_LINK_STATUS_NO_ALPA ; +break ; +default : +efc_log_info (sli4,"attn_type: unknown\n" ); +break ; + } + +switch (link_attn->event_type) { +case FC_EVENT_LINK_ATTENTION : +break ; +case FC_EVENT_SHARED_LINK_ATTENTION : +efc_log_info (sli4,"event_type: FC shared link event\n" ); +break ; +default : +efc_log_info (sli4,"event_type: unknown\n" ); +break ; + } + +switch (link_attn->topology) { +case LINK_ATTN_P2P : + event.topology =SLI_LINK_TOPO_NPORT ; +break ; +case LINK_ATTN_FC_AL : + event.topology =SLI_LINK_TOPO_LOOP ; +break ; +case LINK_ATTN_INTERNAL_LOOPBACK : +efc_log_info (sli4,"topology Internal loopback\n" ); + event.topology =SLI_LINK_TOPO_LOOPBACK_INTERNAL ; +break ; +case LINK_ATTN_SERDES_LOOPBACK : +efc_log_info (sli4,"topology serdes loopback\n" ); + event.topology =SLI_LINK_TOPO_LOOPBACK_EXTERNAL ; +break ; +default : +efc_log_info (sli4,"topology: unknown\n" ); +break ; + } + + event.speed = link_attn->port_speed *1000 ; + + sli4->link (sli4->link_arg, (void *)&event); + +return EFC_SUCCESS ; +} + +/* Parse an FC work queue CQ entry */ +int +sli_fc_cqe_parse (struct sli4 *sli4,struct sli4_queue *cq, +u8 *cqe,enum sli4_qentry *etype,u16 *r_id) +{ +u8 code = cqe[SLI4_CQE_CODE_OFFSET ]; +int rc; + +switch (code) { +case SLI4_CQE_CODE_WORK_REQUEST_COMPLETION : + { +struct sli4_fc_wcqe *wcqe = (void *)cqe; + + *etype =SLI_QENTRY_WQ ; + *r_id =le16_to_cpu (wcqe->request_tag); + rc = wcqe->status; + +/* Flag errors except for FCP_RSP_FAILURE */ +if (rc && rc !=SLI4_FC_WCQE_STATUS_FCP_RSP_FAILURE ) { +efc_log_info (sli4,"WCQE: status=%#x hw_status=%#x tag=%#x\n" , + wcqe->status, wcqe->hw_status, +le16_to_cpu (wcqe->request_tag)); +efc_log_info (sli4,"w1=%#x w2=%#x xb=%d\n" , +le32_to_cpu (wcqe->wqe_specific_1), +le32_to_cpu (wcqe->wqe_specific_2), + (wcqe->flags &SLI4_WCQE_XB )); +efc_log_info (sli4," %08X %08X %08X %08X\n" , + ((u32 *)cqe)[0 ], + ((u32 *)cqe)[1 ], + ((u32 *)cqe)[2 ], + ((u32 *)cqe)[3 ]); + } + +break ; + } +case SLI4_CQE_CODE_RQ_ASYNC : + { +struct sli4_fc_async_rcqe *rcqe = (void *)cqe; + + *etype =SLI_QENTRY_RQ ; + *r_id =le16_to_cpu (rcqe->fcfi_rq_id_word) &SLI4_RACQE_RQ_ID ; + rc = rcqe->status; +break ; + } +case SLI4_CQE_CODE_RQ_ASYNC_V1 : + { +struct sli4_fc_async_rcqe_v1 *rcqe = (void *)cqe; + + *etype =SLI_QENTRY_RQ ; + *r_id =le16_to_cpu (rcqe->rq_id); + rc = rcqe->status; +break ; + } +case SLI4_CQE_CODE_OPTIMIZED_WRITE_CMD : + { +struct sli4_fc_optimized_write_cmd_cqe *optcqe = (void *)cqe; + + *etype =SLI_QENTRY_OPT_WRITE_CMD ; + *r_id =le16_to_cpu (optcqe->rq_id); + rc = optcqe->status; +break ; + } +case SLI4_CQE_CODE_OPTIMIZED_WRITE_DATA : + { +struct sli4_fc_optimized_write_data_cqe *dcqe = (void *)cqe; + + *etype =SLI_QENTRY_OPT_WRITE_DATA ; + *r_id =le16_to_cpu (dcqe->xri); + rc = dcqe->status; + +/* Flag errors */ +if (rc !=SLI4_FC_WCQE_STATUS_SUCCESS ) { +efc_log_info (sli4,"Optimized DATA CQE: status=%#x\n" , + dcqe->status); +efc_log_info (sli4,"hstat=%#x xri=%#x dpl=%#x w3=%#x xb=%d\n" , + dcqe->hw_status,le16_to_cpu (dcqe->xri), +le32_to_cpu (dcqe->total_data_placed), + ((u32 *)cqe)[3 ], + (dcqe->flags &SLI4_OCQE_XB )); + } +break ; + } +case SLI4_CQE_CODE_RQ_COALESCING : + { +struct sli4_fc_coalescing_rcqe *rcqe = (void *)cqe; + + *etype =SLI_QENTRY_RQ ; + *r_id =le16_to_cpu (rcqe->rq_id); + rc = rcqe->status; +break ; + } +case SLI4_CQE_CODE_XRI_ABORTED : + { +struct sli4_fc_xri_aborted_cqe *xa = (void *)cqe; + + *etype =SLI_QENTRY_XABT ; + *r_id =le16_to_cpu (xa->xri); + rc =EFC_SUCCESS ; +break ; + } +case SLI4_CQE_CODE_RELEASE_WQE : { +struct sli4_fc_wqec *wqec = (void *)cqe; + + *etype =SLI_QENTRY_WQ_RELEASE ; + *r_id =le16_to_cpu (wqec->wq_id); + rc =EFC_SUCCESS ; +break ; + } +default : +efc_log_info (sli4,"CQE completion code %d not handled\n" , + code); + *etype =SLI_QENTRY_MAX ; + *r_id =U16_MAX ; + rc = -EINVAL ; + } + +return rc; +} + +u32 +sli_fc_response_length (struct sli4 *sli4,u8 *cqe) +{ +struct sli4_fc_wcqe *wcqe = (void *)cqe; + +return le32_to_cpu (wcqe->wqe_specific_1); +} + +u32 +sli_fc_io_length (struct sli4 *sli4,u8 *cqe) +{ +struct sli4_fc_wcqe *wcqe = (void *)cqe; + +return le32_to_cpu (wcqe->wqe_specific_1); +} + +int +sli_fc_els_did (struct sli4 *sli4,u8 *cqe,u32 *d_id) +{ +struct sli4_fc_wcqe *wcqe = (void *)cqe; + + *d_id =0 ; + +if (wcqe->status) +return EFC_FAIL ; + *d_id =le32_to_cpu (wcqe->wqe_specific_2) &0x00ffffff ; +return EFC_SUCCESS ; +} + +u32 +sli_fc_ext_status (struct sli4 *sli4,u8 *cqe) +{ +struct sli4_fc_wcqe *wcqe = (void *)cqe; +u32 mask; + +switch (wcqe->status) { +case SLI4_FC_WCQE_STATUS_FCP_RSP_FAILURE : + mask =U32_MAX ; +break ; +case SLI4_FC_WCQE_STATUS_LOCAL_REJECT : +case SLI4_FC_WCQE_STATUS_CMD_REJECT : + mask =0xff ; +break ; +case SLI4_FC_WCQE_STATUS_NPORT_RJT : +case SLI4_FC_WCQE_STATUS_FABRIC_RJT : +case SLI4_FC_WCQE_STATUS_NPORT_BSY : +case SLI4_FC_WCQE_STATUS_FABRIC_BSY : +case SLI4_FC_WCQE_STATUS_LS_RJT : + mask =U32_MAX ; +break ; +case SLI4_FC_WCQE_STATUS_DI_ERROR : + mask =U32_MAX ; +break ; +default : + mask =0 ; + } + +return le32_to_cpu (wcqe->wqe_specific_2) & mask; +} + +/* Retrieve the RQ index from the completion */ +int +sli_fc_rqe_rqid_and_index (struct sli4 *sli4,u8 *cqe, +u16 *rq_id,u32 *index) +{ +struct sli4_fc_async_rcqe *rcqe = (void *)cqe; +struct sli4_fc_async_rcqe_v1 *rcqe_v1 = (void *)cqe; +int rc =EFC_FAIL ; +u8 code =0 ; +u16 rq_element_index; + + *rq_id =0 ; + *index =U32_MAX ; + + code = cqe[SLI4_CQE_CODE_OFFSET ]; + +if (code ==SLI4_CQE_CODE_RQ_ASYNC ) { + *rq_id =le16_to_cpu (rcqe->fcfi_rq_id_word) &SLI4_RACQE_RQ_ID ; + rq_element_index = +le16_to_cpu (rcqe->rq_elmt_indx_word) &SLI4_RACQE_RQ_EL_INDX ; + *index = rq_element_index; +if (rcqe->status ==SLI4_FC_ASYNC_RQ_SUCCESS ) { + rc =EFC_SUCCESS ; + }else { + rc = rcqe->status; +efc_log_info (sli4,"status=%02x (%s) rq_id=%d\n" , + rcqe->status, +sli_fc_get_status_string (rcqe->status), +le16_to_cpu (rcqe->fcfi_rq_id_word) & +SLI4_RACQE_RQ_ID ); + +efc_log_info (sli4,"pdpl=%x sof=%02x eof=%02x hdpl=%x\n" , +le16_to_cpu (rcqe->data_placement_length), + rcqe->sof_byte, rcqe->eof_byte, + rcqe->hdpl_byte &SLI4_RACQE_HDPL ); + } + }else if (code ==SLI4_CQE_CODE_RQ_ASYNC_V1 ) { + *rq_id =le16_to_cpu (rcqe_v1->rq_id); + rq_element_index = + (le16_to_cpu (rcqe_v1->rq_elmt_indx_word) & +SLI4_RACQE_RQ_EL_INDX ); + *index = rq_element_index; +if (rcqe_v1->status ==SLI4_FC_ASYNC_RQ_SUCCESS ) { + rc =EFC_SUCCESS ; + }else { + rc = rcqe_v1->status; +efc_log_info (sli4,"status=%02x (%s) rq_id=%d, index=%x\n" , + rcqe_v1->status, +sli_fc_get_status_string (rcqe_v1->status), +le16_to_cpu (rcqe_v1->rq_id), rq_element_index); + +efc_log_info (sli4,"pdpl=%x sof=%02x eof=%02x hdpl=%x\n" , +le16_to_cpu (rcqe_v1->data_placement_length), + rcqe_v1->sof_byte, rcqe_v1->eof_byte, + rcqe_v1->hdpl_byte &SLI4_RACQE_HDPL ); + } + }else if (code ==SLI4_CQE_CODE_OPTIMIZED_WRITE_CMD ) { +struct sli4_fc_optimized_write_cmd_cqe *optcqe = (void *)cqe; + + *rq_id =le16_to_cpu (optcqe->rq_id); + *index =le16_to_cpu (optcqe->w1) &SLI4_OCQE_RQ_EL_INDX ; +if (optcqe->status ==SLI4_FC_ASYNC_RQ_SUCCESS ) { + rc =EFC_SUCCESS ; + }else { + rc = optcqe->status; +efc_log_info (sli4,"stat=%02x (%s) rqid=%d, idx=%x pdpl=%x\n" , + optcqe->status, +sli_fc_get_status_string (optcqe->status), +le16_to_cpu (optcqe->rq_id), *index, +le16_to_cpu (optcqe->data_placement_length)); + +efc_log_info (sli4,"hdpl=%x oox=%d agxr=%d xri=0x%x rpi=%x\n" , + (optcqe->hdpl_vld &SLI4_OCQE_HDPL ), + (optcqe->flags1 &SLI4_OCQE_OOX ), + (optcqe->flags1 &SLI4_OCQE_AGXR ), optcqe->xri, +le16_to_cpu (optcqe->rpi)); + } + }else if (code ==SLI4_CQE_CODE_RQ_COALESCING ) { +struct sli4_fc_coalescing_rcqe *rcqe = (void *)cqe; +u16 rq_element_index = + (le16_to_cpu (rcqe->rq_elmt_indx_word) & +SLI4_RCQE_RQ_EL_INDX ); + + *rq_id =le16_to_cpu (rcqe->rq_id); +if (rcqe->status ==SLI4_FC_COALESCE_RQ_SUCCESS ) { + *index = rq_element_index; + rc =EFC_SUCCESS ; + }else { + *index =U32_MAX ; + rc = rcqe->status; + +efc_log_info (sli4,"stat=%02x (%s) rq_id=%d, idx=%x\n" , + rcqe->status, +sli_fc_get_status_string (rcqe->status), +le16_to_cpu (rcqe->rq_id), rq_element_index); +efc_log_info (sli4,"rq_id=%#x sdpl=%x\n" , +le16_to_cpu (rcqe->rq_id), +le16_to_cpu (rcqe->sequence_reporting_placement_length)); + } + }else { + *index =U32_MAX ; + + rc = rcqe->status; + +efc_log_info (sli4,"status=%02x rq_id=%d, index=%x pdpl=%x\n" , + rcqe->status, +le16_to_cpu (rcqe->fcfi_rq_id_word) &SLI4_RACQE_RQ_ID , + (le16_to_cpu (rcqe->rq_elmt_indx_word) &SLI4_RACQE_RQ_EL_INDX ), +le16_to_cpu (rcqe->data_placement_length)); +efc_log_info (sli4,"sof=%02x eof=%02x hdpl=%x\n" , + rcqe->sof_byte, rcqe->eof_byte, + rcqe->hdpl_byte &SLI4_RACQE_HDPL ); + } + +return rc; +}Signature · 1 line
2.16.4
Thanks,
Daniel
Re: [PATCH v3 05/31] elx: libefc_sli: Populate and post different WQEs
On 4/15/2020 7:34 AM, Daniel Wagner wrote:
...
Quoted 6 lines
Quoted 6 lines
drivers/scsi/elx/libefc_sli/sli4.c +6
-0+/* Write an ABORT_WQE work queue entry */ +int +sli_abort_wqe (struct sli4 *sli4,void *buf,size_t size, +enum sli4_abort_type type,bool send_abts,u32 ids, +u32 mask,u16 tag,u16 cq_id) +{
Quoted 8 lines
drivers/scsi/elx/libefc_sli/sli4.c sli_cq_parse(struct sli4 *sli4, struct sli4_queue *cq, u8 *cqe, · line 1550
Quoted 3 lines
drivers/scsi/elx/libefc_sli/sli4.c +3
-0+struct sli4_abort_wqe *abort = buf; + +memset (buf,0 , size);Is 'size' expected to be equal to the size of 'struct
sli4_abort_wqe'? Or could it be bigger? In case 'size' can be bigger than 'abort', do you need to clear the complete buffer, or would it be enough to clear only the size of 'abort'?
'buf' represents the abort WQE. Size will be the WQE size. Yeah, this is unclear. Will fix up the coding to make the actions explicit and clear.
Agree with other comments and will address them.
-- james
PATCH v3 6/31 elx: libefc_sli: bmbx routines and SLI config commands
In reply to James SmartThis patch continues the libefc_sli SLI-4 library population.
This patch adds routines to create mailbox commands used during adapter initialization and adds APIs to issue mailbox commands to the adapter through the bootstrap mailbox register.
---
v3:
Return defined return values EFC_SUCCESS/FAIL
Added 64G link speed support.
Defined return values for sli_cqe_mq.
--- drivers/scsi/elx/libefc_sli/sli4.c | 1216 ++++++++++++++++++++++++++++++++++++ 1 file changed, 1216 insertions(+)
drivers/scsi/elx/libefc_sli/sli4.c +1216 -0
@@ -3103,3 +3103,1219 @@ sli_fc_rqe_rqid_and_index(struct sli4 *sli4, u8 *cqe,return rc; } + +/* Wait for the bootstrap mailbox to report "ready" */ +static int +sli_bmbx_wait (struct sli4 *sli4,u32 msec) +{ +u32 val =0 ; + +do { +mdelay (1 );/* 1 ms */ + val =readl (sli4->reg[0 ] +SLI4_BMBX_REG ); + msec--; + }while (msec && !(val &SLI4_BMBX_RDY )); + + val = (!(val &SLI4_BMBX_RDY )); +return val; +} + +/* Write bootstrap mailbox */ +static int +sli_bmbx_write (struct sli4 *sli4) +{ +u32 val =0 ; + +/* write buffer location to bootstrap mailbox register */ + val =SLI4_BMBX_WRITE_HI (sli4->bmbx.phys); +writel (val, (sli4->reg[0 ] +SLI4_BMBX_REG )); + +if (sli_bmbx_wait (sli4,SLI4_BMBX_DELAY_US )) { +efc_log_crit (sli4,"BMBX WRITE_HI failed\n" ); +return EFC_FAIL ; + } + val =SLI4_BMBX_WRITE_LO (sli4->bmbx.phys); +writel (val, (sli4->reg[0 ] +SLI4_BMBX_REG )); + +/* wait for SLI Port to set ready bit */ +return sli_bmbx_wait (sli4,SLI4_BMBX_TIMEOUT_MSEC ); +} + +/* Submit a command to the bootstrap mailbox and check the status */ +int +sli_bmbx_command (struct sli4 *sli4) +{ +void *cqe = (u8 *)sli4->bmbx.virt +SLI4_BMBX_SIZE ; + +if (sli_fw_error_status (sli4) >0 ) { +efc_log_crit (sli4,"Chip is in an error state -Mailbox command rejected" ); +efc_log_crit (sli4," status=%#x error1=%#x error2=%#x\n" , +sli_reg_read_status (sli4), +sli_reg_read_err1 (sli4), +sli_reg_read_err2 (sli4)); +return EFC_FAIL ; + } + +if (sli_bmbx_write (sli4)) { +efc_log_crit (sli4,"bootstrap mailbox write fail phys=%p reg=%#x\n" , + (void *)sli4->bmbx.phys, +readl (sli4->reg[0 ] +SLI4_BMBX_REG )); +return EFC_FAIL ; + } + +/* check completion queue entry status */ +if (le32_to_cpu (((struct sli4_mcqe *)cqe)->dw3_flags) & +SLI4_MCQE_VALID ) { +return sli_cqe_mq (sli4, cqe); + } +efc_log_crit (sli4,"invalid or wrong type\n" ); +return EFC_FAIL ; +} + +/* Write a CONFIG_LINK command to the provided buffer */ +int +sli_cmd_config_link (struct sli4 *sli4,void *buf,size_t size) +{ +struct sli4_cmd_config_link *config_link = buf; + +memset (buf,0 , size); + + config_link->hdr.command =MBX_CMD_CONFIG_LINK ; + +/* Port interprets zero in a field as "use default value" */ + +return EFC_SUCCESS ; +} + +/* Write a DOWN_LINK command to the provided buffer */ +int +sli_cmd_down_link (struct sli4 *sli4,void *buf,size_t size) +{ +struct sli4_mbox_command_header *hdr = buf; + +memset (buf,0 , size); + + hdr->command =MBX_CMD_DOWN_LINK ; + +/* Port interprets zero in a field as "use default value" */ + +return EFC_SUCCESS ; +} + +/* Write a DUMP Type 4 command to the provided buffer */ +int +sli_cmd_dump_type4 (struct sli4 *sli4,void *buf, +size_t size,u16 wki) +{ +struct sli4_cmd_dump4 *cmd = buf; + +memset (buf,0 , size); + + cmd->hdr.command =MBX_CMD_DUMP ; + cmd->type_dword =cpu_to_le32 (0x4 ); + cmd->wki_selection =cpu_to_le16 (wki); +return EFC_SUCCESS ; +} + +/* Write a COMMON_READ_TRANSCEIVER_DATA command */ +int +sli_cmd_common_read_transceiver_data (struct sli4 *sli4,void *buf, +size_t size,u32 page_num, +struct efc_dma *dma) +{ +struct sli4_rqst_cmn_read_transceiver_data *req =NULL ; +u32 psize; + +if (!dma) + psize =SLI_CONFIG_PYLD_LENGTH (cmn_read_transceiver_data); +else + psize = dma->size; + + req =sli_config_cmd_init (sli4, buf, size, + psize, dma); +if (!req) +return EFC_FAIL ; + +sli_cmd_fill_hdr (&req->hdr,CMN_READ_TRANS_DATA ,SLI4_SUBSYSTEM_COMMON , +CMD_V0 ,CFG_RQST_PYLD_LEN (cmn_read_transceiver_data)); + + req->page_number =cpu_to_le32 (page_num); + req->port =cpu_to_le32 (sli4->port_number); + +return EFC_SUCCESS ; +} + +/* Write a READ_LINK_STAT command to the provided buffer */ +int +sli_cmd_read_link_stats (struct sli4 *sli4,void *buf,size_t size, +u8 req_ext_counters, +u8 clear_overflow_flags, +u8 clear_all_counters) +{ +struct sli4_cmd_read_link_stats *cmd = buf; +u32 flags; + +memset (buf,0 , size); + + cmd->hdr.command =MBX_CMD_READ_LNK_STAT ; + + flags =0 ; +if (req_ext_counters) + flags |=SLI4_READ_LNKSTAT_REC ; +if (clear_all_counters) + flags |=SLI4_READ_LNKSTAT_CLRC ; +if (clear_overflow_flags) + flags |=SLI4_READ_LNKSTAT_CLOF ; + + cmd->dw1_flags =cpu_to_le32 (flags); +return EFC_SUCCESS ; +} + +/* Write a READ_STATUS command to the provided buffer */ +int +sli_cmd_read_status (struct sli4 *sli4,void *buf,size_t size, +u8 clear_counters) +{ +struct sli4_cmd_read_status *cmd = buf; +u32 flags =0 ; + +memset (buf,0 , size); + + cmd->hdr.command =MBX_CMD_READ_STATUS ; +if (clear_counters) + flags |=SLI4_READSTATUS_CLEAR_COUNTERS ; +else + flags &= ~SLI4_READSTATUS_CLEAR_COUNTERS ; + + cmd->dw1_flags =cpu_to_le32 (flags); +return EFC_SUCCESS ; +} + +/* Write an INIT_LINK command to the provided buffer */ +int +sli_cmd_init_link (struct sli4 *sli4,void *buf,size_t size, +u32 speed,u8 reset_alpa) +{ +struct sli4_cmd_init_link *init_link = buf; +u32 flags =0 ; + +memset (buf,0 , size); + + init_link->hdr.command =MBX_CMD_INIT_LINK ; + + init_link->sel_reset_al_pa_dword = +cpu_to_le32 (reset_alpa); + flags &= ~SLI4_INIT_LINK_F_LOOPBACK ; + + init_link->link_speed_sel_code =cpu_to_le32 (speed); +switch (speed) { +case FC_LINK_SPEED_1G : +case FC_LINK_SPEED_2G : +case FC_LINK_SPEED_4G : +case FC_LINK_SPEED_8G : +case FC_LINK_SPEED_16G : +case FC_LINK_SPEED_32G : +case FC_LINK_SPEED_64G : + flags |=SLI4_INIT_LINK_F_FIXED_SPEED ; +break ; +case FC_LINK_SPEED_10G : +efc_log_info (sli4,"unsupported FC speed %d\n" , speed); + init_link->flags0 =cpu_to_le32 (flags); +return EFC_FAIL ; + } + +switch (sli4->topology) { +case SLI4_READ_CFG_TOPO_FC : +/* Attempt P2P but failover to FC-AL */ + flags |=SLI4_INIT_LINK_F_FAIL_OVER ; + flags |=SLI4_INIT_LINK_F_P2P_FAIL_OVER ; +break ; +case SLI4_READ_CFG_TOPO_FC_AL : + flags |=SLI4_INIT_LINK_F_FCAL_ONLY ; +if (speed ==FC_LINK_SPEED_16G || speed ==FC_LINK_SPEED_32G ) { +efc_log_info (sli4,"unsupported FC-AL speed %d\n" , + speed); + init_link->flags0 =cpu_to_le32 (flags); +return EFC_FAIL ; + } +break ; +case SLI4_READ_CFG_TOPO_FC_DA : + flags |=SLI4_INIT_LINK_F_P2P_ONLY ; +break ; +default : + +efc_log_info (sli4,"unsupported topology %#x\n" , + sli4->topology); + + init_link->flags0 =cpu_to_le32 (flags); +return EFC_FAIL ; + } + + flags &= (~SLI4_INIT_LINK_F_UNFAIR ); + flags &= (~SLI4_INIT_LINK_F_NO_LIRP ); + flags &= (~SLI4_INIT_LINK_F_LOOP_VALID_CHK ); + flags &= (~SLI4_INIT_LINK_F_NO_LISA ); + flags &= (~SLI4_INIT_LINK_F_PICK_HI_ALPA ); + init_link->flags0 =cpu_to_le32 (flags); + +return EFC_SUCCESS ; +} + +/* Write an INIT_VFI command to the provided buffer */ +int +sli_cmd_init_vfi (struct sli4 *sli4,void *buf,size_t size, +u16 vfi,u16 fcfi,u16 vpi) +{ +struct sli4_cmd_init_vfi *init_vfi = buf; +u16 flags =0 ; + +memset (buf,0 , size); + + init_vfi->hdr.command =MBX_CMD_INIT_VFI ; + + init_vfi->vfi =cpu_to_le16 (vfi); + init_vfi->fcfi =cpu_to_le16 (fcfi); + +/* +* If the VPI is valid, initialize it at the same time as +* the VFI +*/ +if (vpi !=U16_MAX ) { + flags |=SLI4_INIT_VFI_FLAG_VP ; + init_vfi->flags0_word =cpu_to_le16 (flags); + init_vfi->vpi =cpu_to_le16 (vpi); + } + +return EFC_SUCCESS ; +} + +/* Write an INIT_VPI command to the provided buffer */ +int +sli_cmd_init_vpi (struct sli4 *sli4,void *buf,size_t size, +u16 vpi,u16 vfi) +{ +struct sli4_cmd_init_vpi *init_vpi = buf; + +memset (buf,0 , size); + + init_vpi->hdr.command =MBX_CMD_INIT_VPI ; + init_vpi->vpi =cpu_to_le16 (vpi); + init_vpi->vfi =cpu_to_le16 (vfi); + +return EFC_SUCCESS ; +} + +int +sli_cmd_post_xri (struct sli4 *sli4,void *buf,size_t size, +u16 xri_base,u16 xri_count) +{ +struct sli4_cmd_post_xri *post_xri = buf; +u16 xri_count_flags =0 ; + +memset (buf,0 , size); + + post_xri->hdr.command =MBX_CMD_POST_XRI ; + post_xri->xri_base =cpu_to_le16 (xri_base); + xri_count_flags = (xri_count &SLI4_POST_XRI_COUNT ); + xri_count_flags |=SLI4_POST_XRI_FLAG_ENX ; + xri_count_flags |=SLI4_POST_XRI_FLAG_VAL ; + post_xri->xri_count_flags =cpu_to_le16 (xri_count_flags); + +return EFC_SUCCESS ; +} + +int +sli_cmd_release_xri (struct sli4 *sli4,void *buf,size_t size, +u8 num_xri) +{ +struct sli4_cmd_release_xri *release_xri = buf; + +memset (buf,0 , size); + + release_xri->hdr.command =MBX_CMD_RELEASE_XRI ; + release_xri->xri_count_word =cpu_to_le16 (num_xri & +SLI4_RELEASE_XRI_COUNT ); + +return EFC_SUCCESS ; +} + +static int +sli_cmd_read_config (struct sli4 *sli4,void *buf,size_t size) +{ +struct sli4_cmd_read_config *read_config = buf; + +memset (buf,0 , size); + + read_config->hdr.command =MBX_CMD_READ_CONFIG ; + +return EFC_SUCCESS ; +} + +int +sli_cmd_read_nvparms (struct sli4 *sli4,void *buf,size_t size) +{ +struct sli4_cmd_read_nvparms *read_nvparms = buf; + +memset (buf,0 , size); + + read_nvparms->hdr.command =MBX_CMD_READ_NVPARMS ; + +return EFC_SUCCESS ; +} + +int +sli_cmd_write_nvparms (struct sli4 *sli4,void *buf,size_t size, +u8 *wwpn,u8 *wwnn,u8 hard_alpa, +u32 preferred_d_id) +{ +struct sli4_cmd_write_nvparms *write_nvparms = buf; + +memset (buf,0 , size); + + write_nvparms->hdr.command =MBX_CMD_WRITE_NVPARMS ; +memcpy (write_nvparms->wwpn, wwpn,8 ); +memcpy (write_nvparms->wwnn, wwnn,8 ); + + write_nvparms->hard_alpa_d_id = +cpu_to_le32 ((preferred_d_id <<8 ) | hard_alpa); +return EFC_SUCCESS ; +} + +static int +sli_cmd_read_rev (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *vpd) +{ +struct sli4_cmd_read_rev *read_rev = buf; + +memset (buf,0 , size); + + read_rev->hdr.command =MBX_CMD_READ_REV ; + +if (vpd && vpd->size) { + read_rev->flags0_word |=cpu_to_le16 (SLI4_READ_REV_FLAG_VPD ); + + read_rev->available_length_dword = +cpu_to_le32 (vpd->size & +SLI4_READ_REV_AVAILABLE_LENGTH ); + + read_rev->hostbuf.low = +cpu_to_le32 (lower_32_bits (vpd->phys)); + read_rev->hostbuf.high = +cpu_to_le32 (upper_32_bits (vpd->phys)); + } + +return EFC_SUCCESS ; +} + +int +sli_cmd_read_sparm64 (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *dma, +u16 vpi) +{ +struct sli4_cmd_read_sparm64 *read_sparm64 = buf; + +memset (buf,0 , size); + +if (vpi ==U16_MAX ) { +efc_log_err (sli4,"special VPI not supported!!!\n" ); +return EFC_FAIL ; + } + +if (!dma || !dma->phys) { +efc_log_err (sli4,"bad DMA buffer\n" ); +return EFC_FAIL ; + } + + read_sparm64->hdr.command =MBX_CMD_READ_SPARM64 ; + + read_sparm64->bde_64.bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (dma->size &SLI4_BDE_MASK_BUFFER_LEN )); + read_sparm64->bde_64.u.data.low = +cpu_to_le32 (lower_32_bits (dma->phys)); + read_sparm64->bde_64.u.data.high = +cpu_to_le32 (upper_32_bits (dma->phys)); + + read_sparm64->vpi =cpu_to_le16 (vpi); + +return EFC_SUCCESS ; +} + +int +sli_cmd_read_topology (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *dma) +{ +struct sli4_cmd_read_topology *read_topo = buf; + +memset (buf,0 , size); + + read_topo->hdr.command =MBX_CMD_READ_TOPOLOGY ; + +if (dma && dma->size) { +if (dma->size <SLI4_MIN_LOOP_MAP_BYTES ) { +efc_log_err (sli4,"loop map buffer too small %zx\n" , + dma->size); +return EFC_FAIL ; + } + +memset (dma->virt,0 , dma->size); + + read_topo->bde_loop_map.bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (dma->size &SLI4_BDE_MASK_BUFFER_LEN )); + read_topo->bde_loop_map.u.data.low = +cpu_to_le32 (lower_32_bits (dma->phys)); + read_topo->bde_loop_map.u.data.high = +cpu_to_le32 (upper_32_bits (dma->phys)); + } + +return EFC_SUCCESS ; +} + +int +sli_cmd_reg_fcfi (struct sli4 *sli4,void *buf,size_t size, +u16 index, +struct sli4_cmd_rq_cfg rq_cfg[SLI4_CMD_REG_FCFI_NUM_RQ_CFG ]) +{ +struct sli4_cmd_reg_fcfi *reg_fcfi = buf; +u32 i; + +memset (buf,0 , size); + + reg_fcfi->hdr.command =MBX_CMD_REG_FCFI ; + + reg_fcfi->fcf_index =cpu_to_le16 (index); + +for (i =0 ; i <SLI4_CMD_REG_FCFI_NUM_RQ_CFG ; i++) { +switch (i) { +case 0 : + reg_fcfi->rqid0 = rq_cfg[0 ].rq_id; +break ; +case 1 : + reg_fcfi->rqid1 = rq_cfg[1 ].rq_id; +break ; +case 2 : + reg_fcfi->rqid2 = rq_cfg[2 ].rq_id; +break ; +case 3 : + reg_fcfi->rqid3 = rq_cfg[3 ].rq_id; +break ; + } + reg_fcfi->rq_cfg[i].r_ctl_mask = rq_cfg[i].r_ctl_mask; + reg_fcfi->rq_cfg[i].r_ctl_match = rq_cfg[i].r_ctl_match; + reg_fcfi->rq_cfg[i].type_mask = rq_cfg[i].type_mask; + reg_fcfi->rq_cfg[i].type_match = rq_cfg[i].type_match; + } + +return EFC_SUCCESS ; +} + +int +sli_cmd_reg_fcfi_mrq (struct sli4 *sli4,void *buf,size_t size, +u8 mode,u16 fcf_index, +u8 rq_selection_policy,u8 mrq_bit_mask, +u16 num_mrqs, +struct sli4_cmd_rq_cfg rq_cfg[SLI4_CMD_REG_FCFI_NUM_RQ_CFG ]) +{ +struct sli4_cmd_reg_fcfi_mrq *reg_fcfi_mrq = buf; +u32 i; +u32 mrq_flags =0 ; + +memset (buf,0 , size); + + reg_fcfi_mrq->hdr.command =MBX_CMD_REG_FCFI_MRQ ; +if (mode ==SLI4_CMD_REG_FCFI_SET_FCFI_MODE ) { + reg_fcfi_mrq->fcf_index =cpu_to_le16 (fcf_index); + goto done; + } + +for (i =0 ; i <SLI4_CMD_REG_FCFI_NUM_RQ_CFG ; i++) { + reg_fcfi_mrq->rq_cfg[i].r_ctl_mask = rq_cfg[i].r_ctl_mask; + reg_fcfi_mrq->rq_cfg[i].r_ctl_match = rq_cfg[i].r_ctl_match; + reg_fcfi_mrq->rq_cfg[i].type_mask = rq_cfg[i].type_mask; + reg_fcfi_mrq->rq_cfg[i].type_match = rq_cfg[i].type_match; + +switch (i) { +case 3 : + reg_fcfi_mrq->rqid3 = rq_cfg[i].rq_id; +break ; +case 2 : + reg_fcfi_mrq->rqid2 = rq_cfg[i].rq_id; +break ; +case 1 : + reg_fcfi_mrq->rqid1 = rq_cfg[i].rq_id; +break ; +case 0 : + reg_fcfi_mrq->rqid0 = rq_cfg[i].rq_id; +break ; + } + } + + mrq_flags = num_mrqs &SLI4_REGFCFI_MRQ_MASK_NUM_PAIRS ; + mrq_flags |= (mrq_bit_mask <<8 ); + mrq_flags |= (rq_selection_policy <<12 ); + reg_fcfi_mrq->dw9_mrqflags =cpu_to_le32 (mrq_flags); +done: +return EFC_SUCCESS ; +} + +int +sli_cmd_reg_rpi (struct sli4 *sli4,void *buf,size_t size, +u32 nport_id,u16 rpi,u16 vpi, +struct efc_dma *dma,u8 update, +u8 enable_t10_pi) +{ +struct sli4_cmd_reg_rpi *reg_rpi = buf; +u32 rportid_flags =0 ; + +memset (buf,0 , size); + + reg_rpi->hdr.command =MBX_CMD_REG_RPI ; + + reg_rpi->rpi =cpu_to_le16 (rpi); + + rportid_flags = nport_id &SLI4_REGRPI_REMOTE_N_PORTID ; + +if (update) + rportid_flags |=SLI4_REGRPI_UPD ; +else + rportid_flags &= ~SLI4_REGRPI_UPD ; + +if (enable_t10_pi) + rportid_flags |=SLI4_REGRPI_ETOW ; +else + rportid_flags &= ~SLI4_REGRPI_ETOW ; + + reg_rpi->dw2_rportid_flags =cpu_to_le32 (rportid_flags); + + reg_rpi->bde_64.bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (SLI4_REG_RPI_BUF_LEN &SLI4_BDE_MASK_BUFFER_LEN )); + reg_rpi->bde_64.u.data.low = +cpu_to_le32 (lower_32_bits (dma->phys)); + reg_rpi->bde_64.u.data.high = +cpu_to_le32 (upper_32_bits (dma->phys)); + + reg_rpi->vpi =cpu_to_le16 (vpi); + +return EFC_SUCCESS ; +} + +int +sli_cmd_reg_vfi (struct sli4 *sli4,void *buf,size_t size, +u16 vfi,u16 fcfi,struct efc_dma dma, +u16 vpi,__be64 sli_wwpn,u32 fc_id) +{ +struct sli4_cmd_reg_vfi *reg_vfi = buf; + +memset (buf,0 , size); + + reg_vfi->hdr.command =MBX_CMD_REG_VFI ; + + reg_vfi->vfi =cpu_to_le16 (vfi); + + reg_vfi->fcfi =cpu_to_le16 (fcfi); + + reg_vfi->sparm.bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (SLI4_REG_RPI_BUF_LEN &SLI4_BDE_MASK_BUFFER_LEN )); + reg_vfi->sparm.u.data.low = +cpu_to_le32 (lower_32_bits (dma.phys)); + reg_vfi->sparm.u.data.high = +cpu_to_le32 (upper_32_bits (dma.phys)); + + reg_vfi->e_d_tov =cpu_to_le32 (sli4->e_d_tov); + reg_vfi->r_a_tov =cpu_to_le32 (sli4->r_a_tov); + + reg_vfi->dw0w1_flags |=cpu_to_le16 (SLI4_REGVFI_VP ); + reg_vfi->vpi =cpu_to_le16 (vpi); +memcpy (reg_vfi->wwpn, &sli_wwpn,sizeof (reg_vfi->wwpn)); + reg_vfi->dw10_lportid_flags =cpu_to_le32 (fc_id); + +return EFC_SUCCESS ; +} + +int +sli_cmd_reg_vpi (struct sli4 *sli4,void *buf,size_t size, +u32 fc_id,__be64 sli_wwpn,u16 vpi,u16 vfi, +bool update) +{ +struct sli4_cmd_reg_vpi *reg_vpi = buf; +u32 flags =0 ; + +memset (buf,0 , size); + + reg_vpi->hdr.command =MBX_CMD_REG_VPI ; + + flags = (fc_id &SLI4_REGVPI_LOCAL_N_PORTID ); +if (update) + flags |=SLI4_REGVPI_UPD ; +else + flags &= ~SLI4_REGVPI_UPD ; + + reg_vpi->dw2_lportid_flags =cpu_to_le32 (flags); +memcpy (reg_vpi->wwpn, &sli_wwpn,sizeof (reg_vpi->wwpn)); + reg_vpi->vpi =cpu_to_le16 (vpi); + reg_vpi->vfi =cpu_to_le16 (vfi); + +return EFC_SUCCESS ; +} + +static int +sli_cmd_request_features (struct sli4 *sli4,void *buf,size_t size, +u32 features_mask,bool query) +{ +struct sli4_cmd_request_features *req_features = buf; + +memset (buf,0 , size); + + req_features->hdr.command =MBX_CMD_RQST_FEATURES ; + +if (query) + req_features->dw1_qry =cpu_to_le32 (SLI4_REQFEAT_QRY ); + + req_features->cmd =cpu_to_le32 (features_mask); + +return EFC_SUCCESS ; +} + +int +sli_cmd_unreg_fcfi (struct sli4 *sli4,void *buf,size_t size, +u16 indicator) +{ +struct sli4_cmd_unreg_fcfi *unreg_fcfi = buf; + +memset (buf,0 , size); + + unreg_fcfi->hdr.command =MBX_CMD_UNREG_FCFI ; + + unreg_fcfi->fcfi =cpu_to_le16 (indicator); + +return EFC_SUCCESS ; +} + +int +sli_cmd_unreg_rpi (struct sli4 *sli4,void *buf,size_t size, +u16 indicator, +enum sli4_resource which,u32 fc_id) +{ +struct sli4_cmd_unreg_rpi *unreg_rpi = buf; +u32 flags =0 ; + +memset (buf,0 , size); + + unreg_rpi->hdr.command =MBX_CMD_UNREG_RPI ; + +switch (which) { +case SLI_RSRC_RPI : + flags |=UNREG_RPI_II_RPI ; +if (fc_id ==U32_MAX ) +break ; + + flags |=UNREG_RPI_DP ; + unreg_rpi->dw2_dest_n_portid = +cpu_to_le32 (fc_id &UNREG_RPI_DEST_N_PORTID_MASK ); +break ; +case SLI_RSRC_VPI : + flags |=UNREG_RPI_II_VPI ; +break ; +case SLI_RSRC_VFI : + flags |=UNREG_RPI_II_VFI ; +break ; +case SLI_RSRC_FCFI : + flags |=UNREG_RPI_II_FCFI ; +break ; +default : +efc_log_info (sli4,"unknown type %#x\n" , which); +return EFC_FAIL ; + } + + unreg_rpi->dw1w1_flags =cpu_to_le16 (flags); + unreg_rpi->index =cpu_to_le16 (indicator); + +return EFC_SUCCESS ; +} + +int +sli_cmd_unreg_vfi (struct sli4 *sli4,void *buf,size_t size, +u16 index,u32 which) +{ +struct sli4_cmd_unreg_vfi *unreg_vfi = buf; + +memset (buf,0 , size); + + unreg_vfi->hdr.command =MBX_CMD_UNREG_VFI ; +switch (which) { +case SLI4_UNREG_TYPE_DOMAIN : + unreg_vfi->index =cpu_to_le16 (index); +break ; +case SLI4_UNREG_TYPE_FCF : + unreg_vfi->index =cpu_to_le16 (index); +break ; +case SLI4_UNREG_TYPE_ALL : + unreg_vfi->index =cpu_to_le16 (U32_MAX ); +break ; +default : +return EFC_FAIL ; + } + +if (which !=SLI4_UNREG_TYPE_DOMAIN ) + unreg_vfi->dw2_flags = +cpu_to_le16 (UNREG_VFI_II_FCFI ); + +return EFC_SUCCESS ; +} + +int +sli_cmd_unreg_vpi (struct sli4 *sli4,void *buf,size_t size, +u16 indicator,u32 which) +{ +struct sli4_cmd_unreg_vpi *unreg_vpi = buf; +u32 flags =0 ; + +memset (buf,0 , size); + + unreg_vpi->hdr.command =MBX_CMD_UNREG_VPI ; + unreg_vpi->index =cpu_to_le16 (indicator); +switch (which) { +case SLI4_UNREG_TYPE_PORT : + flags |=UNREG_VPI_II_VPI ; +break ; +case SLI4_UNREG_TYPE_DOMAIN : + flags |=UNREG_VPI_II_VFI ; +break ; +case SLI4_UNREG_TYPE_FCF : + flags |=UNREG_VPI_II_FCFI ; +break ; +case SLI4_UNREG_TYPE_ALL : +/* override indicator */ + unreg_vpi->index =cpu_to_le16 (U32_MAX ); + flags |=UNREG_VPI_II_FCFI ; +break ; +default : +return EFC_FAIL ; + } + + unreg_vpi->dw2w0_flags =cpu_to_le16 (flags); +return EFC_SUCCESS ; +} + +static int +sli_cmd_common_modify_eq_delay (struct sli4 *sli4,void *buf,size_t size, +struct sli4_queue *q,int num_q,u32 shift, +u32 delay_mult) +{ +struct sli4_rqst_cmn_modify_eq_delay *req =NULL ; +int i; + + req =sli_config_cmd_init (sli4, buf, size, +SLI_CONFIG_PYLD_LENGTH (cmn_modify_eq_delay), +NULL ); +if (!req) +return EFC_FAIL ; + +sli_cmd_fill_hdr (&req->hdr,CMN_MODIFY_EQ_DELAY ,SLI4_SUBSYSTEM_COMMON , +CMD_V0 ,CFG_RQST_PYLD_LEN (cmn_modify_eq_delay)); + req->num_eq =cpu_to_le32 (num_q); + +for (i =0 ; i < num_q; i++) { + req->eq_delay_record[i].eq_id =cpu_to_le32 (q[i].id); + req->eq_delay_record[i].phase =cpu_to_le32 (shift); + req->eq_delay_record[i].delay_multiplier = +cpu_to_le32 (delay_mult); + } + +return EFC_SUCCESS ; +} + +void +sli4_cmd_lowlevel_set_watchdog (struct sli4 *sli4,void *buf, +size_t size,u16 timeout) +{ +struct sli4_rqst_lowlevel_set_watchdog *req =NULL ; + + req =sli_config_cmd_init (sli4, buf, size, +SLI_CONFIG_PYLD_LENGTH (lowlevel_set_watchdog), +NULL ); +if (!req) +return ; + +sli_cmd_fill_hdr (&req->hdr,SLI4_OPC_LOWLEVEL_SET_WATCHDOG , +SLI4_SUBSYSTEM_LOWLEVEL ,CMD_V0 , +CFG_RQST_PYLD_LEN (lowlevel_set_watchdog)); + req->watchdog_timeout =cpu_to_le16 (timeout); +} + +static int +sli_cmd_common_get_cntl_attributes (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *dma) +{ +struct sli4_rqst_hdr *hdr =NULL ; + + hdr =sli_config_cmd_init (sli4, buf, size,CFG_RQST_CMDSZ (hdr), dma); +if (!hdr) +return EFC_FAIL ; + + hdr->opcode =CMN_GET_CNTL_ATTRIBUTES ; + hdr->subsystem =SLI4_SUBSYSTEM_COMMON ; + hdr->request_length =cpu_to_le32 (dma->size); + +return EFC_SUCCESS ; +} + +static int +sli_cmd_common_get_cntl_addl_attributes (struct sli4 *sli4,void *buf, +size_t size,struct efc_dma *dma) +{ +struct sli4_rqst_hdr *hdr =NULL ; + + hdr =sli_config_cmd_init (sli4, buf, size,CFG_RQST_CMDSZ (hdr), dma); +if (!hdr) +return EFC_FAIL ; + + hdr->opcode =CMN_GET_CNTL_ADDL_ATTRS ; + hdr->subsystem =SLI4_SUBSYSTEM_COMMON ; + hdr->request_length =cpu_to_le32 (dma->size); + +return EFC_SUCCESS ; +} + +int +sli_cmd_common_nop (struct sli4 *sli4,void *buf, +size_t size,uint64_t context) +{ +struct sli4_rqst_cmn_nop *nop =NULL ; + + nop =sli_config_cmd_init (sli4, buf, size, +SLI_CONFIG_PYLD_LENGTH (cmn_nop),NULL ); +if (!nop) +return EFC_FAIL ; + +sli_cmd_fill_hdr (&nop->hdr,CMN_NOP ,SLI4_SUBSYSTEM_COMMON , +CMD_V0 ,CFG_RQST_PYLD_LEN (cmn_nop)); + +memcpy (&nop->context, &context,sizeof (context)); + +return EFC_SUCCESS ; +} + +int +sli_cmd_common_get_resource_extent_info (struct sli4 *sli4,void *buf, +size_t size,u16 rtype) +{ +struct sli4_rqst_cmn_get_resource_extent_info *extent =NULL ; + + extent =sli_config_cmd_init (sli4, buf, size, +CFG_RQST_CMDSZ (cmn_get_resource_extent_info), +NULL ); +if (extent) +return EFC_FAIL ; + +sli_cmd_fill_hdr (&extent->hdr,CMN_GET_RSC_EXTENT_INFO , +SLI4_SUBSYSTEM_COMMON ,CMD_V0 , +CFG_RQST_PYLD_LEN (cmn_get_resource_extent_info)); + + extent->resource_type =cpu_to_le16 (rtype); + +return EFC_SUCCESS ; +} + +int +sli_cmd_common_get_sli4_parameters (struct sli4 *sli4,void *buf, +size_t size) +{ +struct sli4_rqst_hdr *hdr =NULL ; + + hdr =sli_config_cmd_init (sli4, buf, size, +SLI_CONFIG_PYLD_LENGTH (cmn_get_sli4_params), +NULL ); +if (!hdr) +return EFC_FAIL ; + + hdr->opcode =CMN_GET_SLI4_PARAMS ; + hdr->subsystem =SLI4_SUBSYSTEM_COMMON ; + hdr->request_length =CFG_RQST_PYLD_LEN (cmn_get_sli4_params); + +return EFC_SUCCESS ; +} + +static int +sli_cmd_common_get_port_name (struct sli4 *sli4,void *buf,size_t size) +{ +struct sli4_rqst_cmn_get_port_name *pname; + + pname =sli_config_cmd_init (sli4, buf, size, +SLI_CONFIG_PYLD_LENGTH (cmn_get_port_name), +NULL ); +if (!pname) +return EFC_FAIL ; + +sli_cmd_fill_hdr (&pname->hdr,CMN_GET_PORT_NAME ,SLI4_SUBSYSTEM_COMMON , +CMD_V1 ,CFG_RQST_PYLD_LEN (cmn_get_port_name)); + +/* Set the port type value (ethernet=0, FC=1) for V1 commands */ + pname->port_type =PORT_TYPE_FC ; + +return EFC_SUCCESS ; +} + +int +sli_cmd_common_write_object (struct sli4 *sli4,void *buf,size_t size, +u16 noc, +u16 eof,u32 desired_write_length, +u32 offset,char *object_name, +struct efc_dma *dma) +{ +struct sli4_rqst_cmn_write_object *wr_obj =NULL ; +struct sli4_bde *bde; +u32 dwflags =0 ; + + wr_obj =sli_config_cmd_init (sli4, buf, size, +CFG_RQST_CMDSZ (cmn_write_object) + +sizeof (*bde),NULL ); +if (!wr_obj) +return EFC_FAIL ; + +sli_cmd_fill_hdr (&wr_obj->hdr,CMN_WRITE_OBJECT ,SLI4_SUBSYSTEM_COMMON , +CMD_V0 , +CFG_RQST_PYLD_LEN_VAR (cmn_write_object,sizeof (*bde))); + +if (noc) + dwflags |=SLI4_RQ_DES_WRITE_LEN_NOC ; +if (eof) + dwflags |=SLI4_RQ_DES_WRITE_LEN_EOF ; + dwflags |= (desired_write_length &SLI4_RQ_DES_WRITE_LEN ); + + wr_obj->desired_write_len_dword =cpu_to_le32 (dwflags); + + wr_obj->write_offset =cpu_to_le32 (offset); +strncpy (wr_obj->object_name, object_name, +sizeof (wr_obj->object_name)); + wr_obj->host_buffer_descriptor_count =cpu_to_le32 (1 ); + + bde = (struct sli4_bde *)wr_obj->host_buffer_descriptor; + +/* Setup to transfer xfer_size bytes to device */ + bde->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (desired_write_length &SLI4_BDE_MASK_BUFFER_LEN )); + bde->u.data.low =cpu_to_le32 (lower_32_bits (dma->phys)); + bde->u.data.high =cpu_to_le32 (upper_32_bits (dma->phys)); + +return EFC_SUCCESS ; +} + +int +sli_cmd_common_delete_object (struct sli4 *sli4,void *buf,size_t size, +char *object_name) +{ +struct sli4_rqst_cmn_delete_object *req =NULL ; + + req =sli_config_cmd_init (sli4, buf, size, +CFG_RQST_CMDSZ (cmn_delete_object),NULL ); +if (!req) +return EFC_FAIL ; + +sli_cmd_fill_hdr (&req->hdr,CMN_DELETE_OBJECT ,SLI4_SUBSYSTEM_COMMON , +CMD_V0 ,CFG_RQST_PYLD_LEN (cmn_delete_object)); + +strncpy (req->object_name, object_name,sizeof (req->object_name)); +return EFC_SUCCESS ; +} + +int +sli_cmd_common_read_object (struct sli4 *sli4,void *buf,size_t size, +u32 desired_read_length,u32 offset, +char *object_name,struct efc_dma *dma) +{ +struct sli4_rqst_cmn_read_object *rd_obj =NULL ; +struct sli4_bde *bde; + + rd_obj =sli_config_cmd_init (sli4, buf, size, +CFG_RQST_CMDSZ (cmn_read_object) + +sizeof (*bde),NULL ); +if (!rd_obj) +return EFC_FAIL ; + +sli_cmd_fill_hdr (&rd_obj->hdr,CMN_READ_OBJECT ,SLI4_SUBSYSTEM_COMMON , +CMD_V0 , +CFG_RQST_PYLD_LEN_VAR (cmn_read_object,sizeof (*bde))); + rd_obj->desired_read_length_dword = +cpu_to_le32 (desired_read_length &SLI4_REQ_DESIRE_READLEN ); + + rd_obj->read_offset =cpu_to_le32 (offset); +strncpy (rd_obj->object_name, object_name, +sizeof (rd_obj->object_name)); + rd_obj->host_buffer_descriptor_count =cpu_to_le32 (1 ); + + bde = (struct sli4_bde *)rd_obj->host_buffer_descriptor; + +/* Setup to transfer xfer_size bytes to device */ + bde->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (desired_read_length &SLI4_BDE_MASK_BUFFER_LEN )); +if (dma) { + bde->u.data.low =cpu_to_le32 (lower_32_bits (dma->phys)); + bde->u.data.high =cpu_to_le32 (upper_32_bits (dma->phys)); + }else { + bde->u.data.low =0 ; + bde->u.data.high =0 ; + } + +return EFC_SUCCESS ; +} + +int +sli_cmd_dmtf_exec_clp_cmd (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *cmd, +struct efc_dma *resp) +{ +struct sli4_rqst_dmtf_exec_clp_cmd *clp_cmd =NULL ; + + clp_cmd =sli_config_cmd_init (sli4, buf, size, +CFG_RQST_CMDSZ (dmtf_exec_clp_cmd),NULL ); +if (!clp_cmd) +return EFC_FAIL ; + +sli_cmd_fill_hdr (&clp_cmd->hdr,DMTF_EXEC_CLP_CMD ,SLI4_SUBSYSTEM_DMTF , +CMD_V0 ,CFG_RQST_PYLD_LEN (dmtf_exec_clp_cmd)); + + clp_cmd->cmd_buf_length =cpu_to_le32 (cmd->size); + clp_cmd->cmd_buf_addr_low =cpu_to_le32 (lower_32_bits (cmd->phys)); + clp_cmd->cmd_buf_addr_high =cpu_to_le32 (upper_32_bits (cmd->phys)); + clp_cmd->resp_buf_length =cpu_to_le32 (resp->size); + clp_cmd->resp_buf_addr_low =cpu_to_le32 (lower_32_bits (resp->phys)); + clp_cmd->resp_buf_addr_high =cpu_to_le32 (upper_32_bits (resp->phys)); + +return EFC_SUCCESS ; +} + +int +sli_cmd_common_set_dump_location (struct sli4 *sli4,void *buf, +size_t size,bool query, +bool is_buffer_list, +struct efc_dma *buffer,u8 fdb) +{ +struct sli4_rqst_cmn_set_dump_location *set_dump_loc =NULL ; +u32 buffer_length_flag =0 ; + + set_dump_loc =sli_config_cmd_init (sli4, buf, size, +CFG_RQST_CMDSZ (cmn_set_dump_location), +NULL ); +if (!set_dump_loc) +return EFC_FAIL ; + +sli_cmd_fill_hdr (&set_dump_loc->hdr,CMN_SET_DUMP_LOCATION , +SLI4_SUBSYSTEM_COMMON ,CMD_V0 , +CFG_RQST_PYLD_LEN (cmn_set_dump_location)); + +if (is_buffer_list) + buffer_length_flag |=SLI4_CMN_SET_DUMP_BLP ; + +if (query) + buffer_length_flag |=SLI4_CMN_SET_DUMP_QRY ; + +if (fdb) + buffer_length_flag |=SLI4_CMN_SET_DUMP_FDB ; + +if (buffer) { + set_dump_loc->buf_addr_low = +cpu_to_le32 (lower_32_bits (buffer->phys)); + set_dump_loc->buf_addr_high = +cpu_to_le32 (upper_32_bits (buffer->phys)); + + buffer_length_flag |= (buffer->len & +SLI4_CMN_SET_DUMP_BUFFER_LEN ); + }else { + set_dump_loc->buf_addr_low =0 ; + set_dump_loc->buf_addr_high =0 ; + set_dump_loc->buffer_length_dword =0 ; + } + set_dump_loc->buffer_length_dword =cpu_to_le32 (buffer_length_flag); +return EFC_SUCCESS ; +} + +int +sli_cmd_common_set_features (struct sli4 *sli4,void *buf,size_t size, +u32 feature, +u32 param_len, +void *parameter) +{ +struct sli4_rqst_cmn_set_features *cmd =NULL ; + + cmd =sli_config_cmd_init (sli4, buf, size, +CFG_RQST_CMDSZ (cmn_set_features),NULL ); +if (!cmd) +return EFC_FAIL ; + +sli_cmd_fill_hdr (&cmd->hdr,CMN_SET_FEATURES ,SLI4_SUBSYSTEM_COMMON , +CMD_V0 ,CFG_RQST_PYLD_LEN (cmn_set_features)); + + cmd->feature =cpu_to_le32 (feature); + cmd->param_len =cpu_to_le32 (param_len); +memcpy (cmd->params, parameter, param_len); + +return EFC_SUCCESS ; +} + +int +sli_cqe_mq (struct sli4 *sli4,void *buf) +{ +struct sli4_mcqe *mcqe = buf; +u32 dwflags =le32_to_cpu (mcqe->dw3_flags); +/* +* Firmware can split mbx completions into two MCQEs: first with only +* the "consumed" bit set and a second with the "complete" bit set. +* Thus, ignore MCQE unless "complete" is set. +*/ +if (!(dwflags &SLI4_MCQE_COMPLETED )) +return SLI4_MCQE_STATUS_NOT_COMPLETED ; + +if (le16_to_cpu (mcqe->completion_status)) { +efc_log_info (sli4,"status(st=%#x ext=%#x con=%d cmp=%d ae=%d val=%d)\n" , +le16_to_cpu (mcqe->completion_status), +le16_to_cpu (mcqe->extended_status), + (dwflags &SLI4_MCQE_CONSUMED ), + (dwflags &SLI4_MCQE_COMPLETED ), + (dwflags &SLI4_MCQE_AE ), + (dwflags &SLI4_MCQE_VALID )); + } + +return le16_to_cpu (mcqe->completion_status); +} + +int +sli_cqe_async (struct sli4 *sli4,void *buf) +{ +struct sli4_acqe *acqe = buf; +int rc =EFC_FAIL ; + +if (!buf) { +efc_log_err (sli4,"bad parameter sli4=%p buf=%p\n" , sli4, buf); +return EFC_FAIL ; + } + +switch (acqe->event_code) { +case SLI4_ACQE_EVENT_CODE_LINK_STATE : +efc_log_info (sli4,"Unsupported by FC link, evt code:%#x\n" , + acqe->event_code); +break ; +case SLI4_ACQE_EVENT_CODE_GRP_5 : +efc_log_info (sli4,"ACQE GRP5\n" ); +break ; +case SLI4_ACQE_EVENT_CODE_SLI_PORT_EVENT : +efc_log_info (sli4,"ACQE SLI Port, type=0x%x, data1,2=0x%08x,0x%08x\n" , + acqe->event_type, +le32_to_cpu (acqe->event_data[0 ]), +le32_to_cpu (acqe->event_data[1 ])); +break ; +case SLI4_ACQE_EVENT_CODE_FC_LINK_EVENT : + rc =sli_fc_process_link_attention (sli4, buf); +break ; +default : +efc_log_info (sli4,"ACQE unknown=%#x\n" , + acqe->event_code); + } + +return rc; +}
Signature · 1 line
2.16.4
Re: [PATCH v3 06/31] elx: libefc_sli: bmbx routines and SLI config commands
Quoted 25 lines · James Smart
This patch continues the
libefc_sliSLI-4 library population.This patch adds routines to create mailbox commands used during adapter initialization and adds APIs to issue mailbox commands to the adapter through the bootstrap mailbox register.
Signed-off-by Ram Vegesna <[email protected]>Signed-off-by James Smart <[email protected]>---
v3:
Return defined return values EFC_SUCCESS/FAIL
Added 64G link speed support.
Defined return values forsli_cqe_mq.--- drivers/scsi/elx/libefc_sli/sli4.c | 1216 ++++++++++++++++++++++++++++++++++++ 1 file changed, 1216 insertions(+)drivers/scsi/elx/libefc_sli/sli4.c +0
-0@@ -3103,3 +3103,1219 @@ sli_fc_rqe_rqid_and_index(struct sli4 *sli4, u8 *cqe,return rc;
drivers/scsi/elx/libefc_sli/sli4.c sli_fc_rqe_rqid_and_index(struct sli4 *sli4, u8 *cqe, · line 3114
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +9
-0} + +/* Wait for the bootstrap mailbox to report "ready" */ +static int +sli_bmbx_wait (struct sli4 *sli4,u32 msec) +{ +u32 val =0 ; + + do { + mdelay(1); /* 1 ms */
Will sli_bmbx_wait() be executed in atomic context? If not, something like this here is recommended:
end = jiffies + msecs_to_jiffies(msec);
do {
val = readl(sli4->reg[0] + SLI4_BMBX_REG);
if (val & SLI4_BMBX_RDY)
return EFC_SUCCESS;
usleep_range(1000, 2000);
} while (time_before(jiffies, end));
return EFC_FAIL;drivers/scsi/elx/libefc_sli/sli4.c sli_fc_rqe_rqid_and_index(struct sli4 *sli4, u8 *cqe, · line 3127
Quoted 13 lines
drivers/scsi/elx/libefc_sli/sli4.c +13
-0+ val =readl (sli4->reg[0 ] +SLI4_BMBX_REG ); + msec--; + }while (msec && !(val &SLI4_BMBX_RDY )); + + val = (!(val &SLI4_BMBX_RDY )); +return val; +} + +/* Write bootstrap mailbox */ +static int +sli_bmbx_write (struct sli4 *sli4) +{ +u32 val =0 ;
No need to pre-initialize val.
drivers/scsi/elx/libefc_sli/sli4.c sli_fc_rqe_rqid_and_index(struct sli4 *sli4, u8 *cqe, · line 3131
Quoted 4 lines
drivers/scsi/elx/libefc_sli/sli4.c +4
-0+ +/* write buffer location to bootstrap mailbox register */ + val =SLI4_BMBX_WRITE_HI (sli4->bmbx.phys); +writel (val, (sli4->reg[0 ] +SLI4_BMBX_REG ));
Is the access to the register serialized by a lock?
Quoted 217 lines
drivers/scsi/elx/libefc_sli/sli4.c +217
-0+ +if (sli_bmbx_wait (sli4,SLI4_BMBX_DELAY_US )) { +efc_log_crit (sli4,"BMBX WRITE_HI failed\n" ); +return EFC_FAIL ; + } + val =SLI4_BMBX_WRITE_LO (sli4->bmbx.phys); +writel (val, (sli4->reg[0 ] +SLI4_BMBX_REG )); + +/* wait for SLI Port to set ready bit */ +return sli_bmbx_wait (sli4,SLI4_BMBX_TIMEOUT_MSEC ); +} + +/* Submit a command to the bootstrap mailbox and check the status */ +int +sli_bmbx_command (struct sli4 *sli4) +{ +void *cqe = (u8 *)sli4->bmbx.virt +SLI4_BMBX_SIZE ; + +if (sli_fw_error_status (sli4) >0 ) { +efc_log_crit (sli4,"Chip is in an error state -Mailbox command rejected" ); +efc_log_crit (sli4," status=%#x error1=%#x error2=%#x\n" , +sli_reg_read_status (sli4), +sli_reg_read_err1 (sli4), +sli_reg_read_err2 (sli4)); +return EFC_FAIL ; + } + +if (sli_bmbx_write (sli4)) { +efc_log_crit (sli4,"bootstrap mailbox write fail phys=%p reg=%#x\n" , + (void *)sli4->bmbx.phys, +readl (sli4->reg[0 ] +SLI4_BMBX_REG )); +return EFC_FAIL ; + } + +/* check completion queue entry status */ +if (le32_to_cpu (((struct sli4_mcqe *)cqe)->dw3_flags) & +SLI4_MCQE_VALID ) { +return sli_cqe_mq (sli4, cqe); + } +efc_log_crit (sli4,"invalid or wrong type\n" ); +return EFC_FAIL ; +} + +/* Write a CONFIG_LINK command to the provided buffer */ +int +sli_cmd_config_link (struct sli4 *sli4,void *buf,size_t size) +{ +struct sli4_cmd_config_link *config_link = buf; + +memset (buf,0 , size); + + config_link->hdr.command =MBX_CMD_CONFIG_LINK ; + +/* Port interprets zero in a field as "use default value" */ + +return EFC_SUCCESS ; +} + +/* Write a DOWN_LINK command to the provided buffer */ +int +sli_cmd_down_link (struct sli4 *sli4,void *buf,size_t size) +{ +struct sli4_mbox_command_header *hdr = buf; + +memset (buf,0 , size); + + hdr->command =MBX_CMD_DOWN_LINK ; + +/* Port interprets zero in a field as "use default value" */ + +return EFC_SUCCESS ; +} + +/* Write a DUMP Type 4 command to the provided buffer */ +int +sli_cmd_dump_type4 (struct sli4 *sli4,void *buf, +size_t size,u16 wki) +{ +struct sli4_cmd_dump4 *cmd = buf; + +memset (buf,0 , size); + + cmd->hdr.command =MBX_CMD_DUMP ; + cmd->type_dword =cpu_to_le32 (0x4 ); + cmd->wki_selection =cpu_to_le16 (wki); +return EFC_SUCCESS ; +} + +/* Write a COMMON_READ_TRANSCEIVER_DATA command */ +int +sli_cmd_common_read_transceiver_data (struct sli4 *sli4,void *buf, +size_t size,u32 page_num, +struct efc_dma *dma) +{ +struct sli4_rqst_cmn_read_transceiver_data *req =NULL ; +u32 psize; + +if (!dma) + psize =SLI_CONFIG_PYLD_LENGTH (cmn_read_transceiver_data); +else + psize = dma->size; + + req =sli_config_cmd_init (sli4, buf, size, + psize, dma); +if (!req) +return EFC_FAIL ; + +sli_cmd_fill_hdr (&req->hdr,CMN_READ_TRANS_DATA ,SLI4_SUBSYSTEM_COMMON , +CMD_V0 ,CFG_RQST_PYLD_LEN (cmn_read_transceiver_data)); + + req->page_number =cpu_to_le32 (page_num); + req->port =cpu_to_le32 (sli4->port_number); + +return EFC_SUCCESS ; +} + +/* Write a READ_LINK_STAT command to the provided buffer */ +int +sli_cmd_read_link_stats (struct sli4 *sli4,void *buf,size_t size, +u8 req_ext_counters, +u8 clear_overflow_flags, +u8 clear_all_counters) +{ +struct sli4_cmd_read_link_stats *cmd = buf; +u32 flags; + +memset (buf,0 , size); + + cmd->hdr.command =MBX_CMD_READ_LNK_STAT ; + + flags =0 ; +if (req_ext_counters) + flags |=SLI4_READ_LNKSTAT_REC ; +if (clear_all_counters) + flags |=SLI4_READ_LNKSTAT_CLRC ; +if (clear_overflow_flags) + flags |=SLI4_READ_LNKSTAT_CLOF ; + + cmd->dw1_flags =cpu_to_le32 (flags); +return EFC_SUCCESS ; +} + +/* Write a READ_STATUS command to the provided buffer */ +int +sli_cmd_read_status (struct sli4 *sli4,void *buf,size_t size, +u8 clear_counters) +{ +struct sli4_cmd_read_status *cmd = buf; +u32 flags =0 ; + +memset (buf,0 , size); + + cmd->hdr.command =MBX_CMD_READ_STATUS ; +if (clear_counters) + flags |=SLI4_READSTATUS_CLEAR_COUNTERS ; +else + flags &= ~SLI4_READSTATUS_CLEAR_COUNTERS ; + + cmd->dw1_flags =cpu_to_le32 (flags); +return EFC_SUCCESS ; +} + +/* Write an INIT_LINK command to the provided buffer */ +int +sli_cmd_init_link (struct sli4 *sli4,void *buf,size_t size, +u32 speed,u8 reset_alpa) +{ +struct sli4_cmd_init_link *init_link = buf; +u32 flags =0 ; + +memset (buf,0 , size); + + init_link->hdr.command =MBX_CMD_INIT_LINK ; + + init_link->sel_reset_al_pa_dword = +cpu_to_le32 (reset_alpa); + flags &= ~SLI4_INIT_LINK_F_LOOPBACK ; + + init_link->link_speed_sel_code =cpu_to_le32 (speed); +switch (speed) { +case FC_LINK_SPEED_1G : +case FC_LINK_SPEED_2G : +case FC_LINK_SPEED_4G : +case FC_LINK_SPEED_8G : +case FC_LINK_SPEED_16G : +case FC_LINK_SPEED_32G : +case FC_LINK_SPEED_64G : + flags |=SLI4_INIT_LINK_F_FIXED_SPEED ; +break ; +case FC_LINK_SPEED_10G : +efc_log_info (sli4,"unsupported FC speed %d\n" , speed); + init_link->flags0 =cpu_to_le32 (flags); +return EFC_FAIL ; + } + +switch (sli4->topology) { +case SLI4_READ_CFG_TOPO_FC : +/* Attempt P2P but failover to FC-AL */ + flags |=SLI4_INIT_LINK_F_FAIL_OVER ; + flags |=SLI4_INIT_LINK_F_P2P_FAIL_OVER ; +break ; +case SLI4_READ_CFG_TOPO_FC_AL : + flags |=SLI4_INIT_LINK_F_FCAL_ONLY ; +if (speed ==FC_LINK_SPEED_16G || speed ==FC_LINK_SPEED_32G ) { +efc_log_info (sli4,"unsupported FC-AL speed %d\n" , + speed); + init_link->flags0 =cpu_to_le32 (flags); +return EFC_FAIL ; + } +break ; +case SLI4_READ_CFG_TOPO_FC_DA : + flags |=SLI4_INIT_LINK_F_P2P_ONLY ; +break ; +default : + +efc_log_info (sli4,"unsupported topology %#x\n" , + sli4->topology);
drivers/scsi/elx/libefc_sli/sli4.c sli_fc_rqe_rqid_and_index(struct sli4 *sli4, u8 *cqe, · line 3358
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+ + init_link->flags0 =cpu_to_le32 (flags); +return EFC_FAIL ; + } + + flags &= (~SLI4_INIT_LINK_F_UNFAIR ); + flags &= (~SLI4_INIT_LINK_F_NO_LIRP ); + flags &= (~SLI4_INIT_LINK_F_LOOP_VALID_CHK ); + flags &= (~SLI4_INIT_LINK_F_NO_LISA ); + flags &= (~SLI4_INIT_LINK_F_PICK_HI_ALPA );
The brackets are not needed.
Quoted 51 lines
drivers/scsi/elx/libefc_sli/sli4.c +51
-0+ init_link->flags0 =cpu_to_le32 (flags); + +return EFC_SUCCESS ; +} + +/* Write an INIT_VFI command to the provided buffer */ +int +sli_cmd_init_vfi (struct sli4 *sli4,void *buf,size_t size, +u16 vfi,u16 fcfi,u16 vpi) +{ +struct sli4_cmd_init_vfi *init_vfi = buf; +u16 flags =0 ; + +memset (buf,0 , size); + + init_vfi->hdr.command =MBX_CMD_INIT_VFI ; + + init_vfi->vfi =cpu_to_le16 (vfi); + init_vfi->fcfi =cpu_to_le16 (fcfi); + +/* +* If the VPI is valid, initialize it at the same time as +* the VFI +*/ +if (vpi !=U16_MAX ) { + flags |=SLI4_INIT_VFI_FLAG_VP ; + init_vfi->flags0_word =cpu_to_le16 (flags); + init_vfi->vpi =cpu_to_le16 (vpi); + } + +return EFC_SUCCESS ; +} + +/* Write an INIT_VPI command to the provided buffer */ +int +sli_cmd_init_vpi (struct sli4 *sli4,void *buf,size_t size, +u16 vpi,u16 vfi) +{ +struct sli4_cmd_init_vpi *init_vpi = buf; + +memset (buf,0 , size); + + init_vpi->hdr.command =MBX_CMD_INIT_VPI ; + init_vpi->vpi =cpu_to_le16 (vpi); + init_vpi->vfi =cpu_to_le16 (vfi); + +return EFC_SUCCESS ; +} + +int +sli_cmd_post_xri(struct sli4 *sli4, void *buf, size_t size,
drivers/scsi/elx/libefc_sli/sli4.c sli_fc_rqe_rqid_and_index(struct sli4 *sli4, u8 *cqe, · line 3419
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+ u16 xri_base, u16 xri_count) +{ +struct sli4_cmd_post_xri *post_xri = buf; +u16 xri_count_flags =0 ; + +memset (buf,0 , size); + + post_xri->hdr.command =MBX_CMD_POST_XRI ; + post_xri->xri_base =cpu_to_le16 (xri_base); + xri_count_flags = (xri_count &SLI4_POST_XRI_COUNT );
The brackets are not needed.
Quoted 4 lines
drivers/scsi/elx/libefc_sli/sli4.c +4
-0+ xri_count_flags |=SLI4_POST_XRI_FLAG_ENX ; + xri_count_flags |=SLI4_POST_XRI_FLAG_VAL ; + post_xri->xri_count_flags =cpu_to_le16 (xri_count_flags); +
drivers/scsi/elx/libefc_sli/sli4.c sli_fc_rqe_rqid_and_index(struct sli4 *sli4, u8 *cqe, · line 3433
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+return EFC_SUCCESS ; +} + +int +sli_cmd_release_xri (struct sli4 *sli4,void *buf,size_t size, +u8 num_xri) +{ +struct sli4_cmd_release_xri *release_xri = buf; + +memset (buf,0 , size);
Just as reminder, I think this memset() pattern should only operator on cmd size and not over the whole buffer if the firmware can handle it.
Quoted 116 lines
drivers/scsi/elx/libefc_sli/sli4.c +116
-0+ + release_xri->hdr.command =MBX_CMD_RELEASE_XRI ; + release_xri->xri_count_word =cpu_to_le16 (num_xri & +SLI4_RELEASE_XRI_COUNT ); + +return EFC_SUCCESS ; +} + +static int +sli_cmd_read_config (struct sli4 *sli4,void *buf,size_t size) +{ +struct sli4_cmd_read_config *read_config = buf; + +memset (buf,0 , size); + + read_config->hdr.command =MBX_CMD_READ_CONFIG ; + +return EFC_SUCCESS ; +} + +int +sli_cmd_read_nvparms (struct sli4 *sli4,void *buf,size_t size) +{ +struct sli4_cmd_read_nvparms *read_nvparms = buf; + +memset (buf,0 , size); + + read_nvparms->hdr.command =MBX_CMD_READ_NVPARMS ; + +return EFC_SUCCESS ; +} + +int +sli_cmd_write_nvparms (struct sli4 *sli4,void *buf,size_t size, +u8 *wwpn,u8 *wwnn,u8 hard_alpa, +u32 preferred_d_id) +{ +struct sli4_cmd_write_nvparms *write_nvparms = buf; + +memset (buf,0 , size); + + write_nvparms->hdr.command =MBX_CMD_WRITE_NVPARMS ; +memcpy (write_nvparms->wwpn, wwpn,8 ); +memcpy (write_nvparms->wwnn, wwnn,8 ); + + write_nvparms->hard_alpa_d_id = +cpu_to_le32 ((preferred_d_id <<8 ) | hard_alpa); +return EFC_SUCCESS ; +} + +static int +sli_cmd_read_rev (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *vpd) +{ +struct sli4_cmd_read_rev *read_rev = buf; + +memset (buf,0 , size); + + read_rev->hdr.command =MBX_CMD_READ_REV ; + +if (vpd && vpd->size) { + read_rev->flags0_word |=cpu_to_le16 (SLI4_READ_REV_FLAG_VPD ); + + read_rev->available_length_dword = +cpu_to_le32 (vpd->size & +SLI4_READ_REV_AVAILABLE_LENGTH ); + + read_rev->hostbuf.low = +cpu_to_le32 (lower_32_bits (vpd->phys)); + read_rev->hostbuf.high = +cpu_to_le32 (upper_32_bits (vpd->phys)); + } + +return EFC_SUCCESS ; +} + +int +sli_cmd_read_sparm64 (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *dma, +u16 vpi) +{ +struct sli4_cmd_read_sparm64 *read_sparm64 = buf; + +memset (buf,0 , size); + +if (vpi ==U16_MAX ) { +efc_log_err (sli4,"special VPI not supported!!!\n" ); +return EFC_FAIL ; + } + +if (!dma || !dma->phys) { +efc_log_err (sli4,"bad DMA buffer\n" ); +return EFC_FAIL ; + } + + read_sparm64->hdr.command =MBX_CMD_READ_SPARM64 ; + + read_sparm64->bde_64.bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (dma->size &SLI4_BDE_MASK_BUFFER_LEN )); + read_sparm64->bde_64.u.data.low = +cpu_to_le32 (lower_32_bits (dma->phys)); + read_sparm64->bde_64.u.data.high = +cpu_to_le32 (upper_32_bits (dma->phys)); + + read_sparm64->vpi =cpu_to_le16 (vpi); + +return EFC_SUCCESS ; +} + +int +sli_cmd_read_topology (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *dma) +{ +struct sli4_cmd_read_topology *read_topo = buf; +
drivers/scsi/elx/libefc_sli/sli4.c sli_fc_rqe_rqid_and_index(struct sli4 *sli4, u8 *cqe, · line 3559
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+memset (buf,0 , size); + + read_topo->hdr.command =MBX_CMD_READ_TOPOLOGY ; + +if (dma && dma->size) { +if (dma->size <SLI4_MIN_LOOP_MAP_BYTES ) { +efc_log_err (sli4,"loop map buffer too small %zx\n" , + dma->size); +return EFC_FAIL ; + }
Shouldn't this fail also when dma or dma->size is invalid?
if (!dma || !(dma->size && dma->size < SLI4_MIN_LOOP_MAP_BYTES)) return EFC_FAIL;
And why is this test not before memset()?
Quoted 579 lines
drivers/scsi/elx/libefc_sli/sli4.c +579
-0+ +memset (dma->virt,0 , dma->size); + + read_topo->bde_loop_map.bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (dma->size &SLI4_BDE_MASK_BUFFER_LEN )); + read_topo->bde_loop_map.u.data.low = +cpu_to_le32 (lower_32_bits (dma->phys)); + read_topo->bde_loop_map.u.data.high = +cpu_to_le32 (upper_32_bits (dma->phys)); + } + +return EFC_SUCCESS ; +} + +int +sli_cmd_reg_fcfi (struct sli4 *sli4,void *buf,size_t size, +u16 index, +struct sli4_cmd_rq_cfg rq_cfg[SLI4_CMD_REG_FCFI_NUM_RQ_CFG ]) +{ +struct sli4_cmd_reg_fcfi *reg_fcfi = buf; +u32 i; + +memset (buf,0 , size); + + reg_fcfi->hdr.command =MBX_CMD_REG_FCFI ; + + reg_fcfi->fcf_index =cpu_to_le16 (index); + +for (i =0 ; i <SLI4_CMD_REG_FCFI_NUM_RQ_CFG ; i++) { +switch (i) { +case 0 : + reg_fcfi->rqid0 = rq_cfg[0 ].rq_id; +break ; +case 1 : + reg_fcfi->rqid1 = rq_cfg[1 ].rq_id; +break ; +case 2 : + reg_fcfi->rqid2 = rq_cfg[2 ].rq_id; +break ; +case 3 : + reg_fcfi->rqid3 = rq_cfg[3 ].rq_id; +break ; + } + reg_fcfi->rq_cfg[i].r_ctl_mask = rq_cfg[i].r_ctl_mask; + reg_fcfi->rq_cfg[i].r_ctl_match = rq_cfg[i].r_ctl_match; + reg_fcfi->rq_cfg[i].type_mask = rq_cfg[i].type_mask; + reg_fcfi->rq_cfg[i].type_match = rq_cfg[i].type_match; + } + +return EFC_SUCCESS ; +} + +int +sli_cmd_reg_fcfi_mrq (struct sli4 *sli4,void *buf,size_t size, +u8 mode,u16 fcf_index, +u8 rq_selection_policy,u8 mrq_bit_mask, +u16 num_mrqs, +struct sli4_cmd_rq_cfg rq_cfg[SLI4_CMD_REG_FCFI_NUM_RQ_CFG ]) +{ +struct sli4_cmd_reg_fcfi_mrq *reg_fcfi_mrq = buf; +u32 i; +u32 mrq_flags =0 ; + +memset (buf,0 , size); + + reg_fcfi_mrq->hdr.command =MBX_CMD_REG_FCFI_MRQ ; +if (mode ==SLI4_CMD_REG_FCFI_SET_FCFI_MODE ) { + reg_fcfi_mrq->fcf_index =cpu_to_le16 (fcf_index); + goto done; + } + +for (i =0 ; i <SLI4_CMD_REG_FCFI_NUM_RQ_CFG ; i++) { + reg_fcfi_mrq->rq_cfg[i].r_ctl_mask = rq_cfg[i].r_ctl_mask; + reg_fcfi_mrq->rq_cfg[i].r_ctl_match = rq_cfg[i].r_ctl_match; + reg_fcfi_mrq->rq_cfg[i].type_mask = rq_cfg[i].type_mask; + reg_fcfi_mrq->rq_cfg[i].type_match = rq_cfg[i].type_match; + +switch (i) { +case 3 : + reg_fcfi_mrq->rqid3 = rq_cfg[i].rq_id; +break ; +case 2 : + reg_fcfi_mrq->rqid2 = rq_cfg[i].rq_id; +break ; +case 1 : + reg_fcfi_mrq->rqid1 = rq_cfg[i].rq_id; +break ; +case 0 : + reg_fcfi_mrq->rqid0 = rq_cfg[i].rq_id; +break ; + } + } + + mrq_flags = num_mrqs &SLI4_REGFCFI_MRQ_MASK_NUM_PAIRS ; + mrq_flags |= (mrq_bit_mask <<8 ); + mrq_flags |= (rq_selection_policy <<12 ); + reg_fcfi_mrq->dw9_mrqflags =cpu_to_le32 (mrq_flags); +done: +return EFC_SUCCESS ; +} + +int +sli_cmd_reg_rpi (struct sli4 *sli4,void *buf,size_t size, +u32 nport_id,u16 rpi,u16 vpi, +struct efc_dma *dma,u8 update, +u8 enable_t10_pi) +{ +struct sli4_cmd_reg_rpi *reg_rpi = buf; +u32 rportid_flags =0 ; + +memset (buf,0 , size); + + reg_rpi->hdr.command =MBX_CMD_REG_RPI ; + + reg_rpi->rpi =cpu_to_le16 (rpi); + + rportid_flags = nport_id &SLI4_REGRPI_REMOTE_N_PORTID ; + +if (update) + rportid_flags |=SLI4_REGRPI_UPD ; +else + rportid_flags &= ~SLI4_REGRPI_UPD ; + +if (enable_t10_pi) + rportid_flags |=SLI4_REGRPI_ETOW ; +else + rportid_flags &= ~SLI4_REGRPI_ETOW ; + + reg_rpi->dw2_rportid_flags =cpu_to_le32 (rportid_flags); + + reg_rpi->bde_64.bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (SLI4_REG_RPI_BUF_LEN &SLI4_BDE_MASK_BUFFER_LEN )); + reg_rpi->bde_64.u.data.low = +cpu_to_le32 (lower_32_bits (dma->phys)); + reg_rpi->bde_64.u.data.high = +cpu_to_le32 (upper_32_bits (dma->phys)); + + reg_rpi->vpi =cpu_to_le16 (vpi); + +return EFC_SUCCESS ; +} + +int +sli_cmd_reg_vfi (struct sli4 *sli4,void *buf,size_t size, +u16 vfi,u16 fcfi,struct efc_dma dma, +u16 vpi,__be64 sli_wwpn,u32 fc_id) +{ +struct sli4_cmd_reg_vfi *reg_vfi = buf; + +memset (buf,0 , size); + + reg_vfi->hdr.command =MBX_CMD_REG_VFI ; + + reg_vfi->vfi =cpu_to_le16 (vfi); + + reg_vfi->fcfi =cpu_to_le16 (fcfi); + + reg_vfi->sparm.bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (SLI4_REG_RPI_BUF_LEN &SLI4_BDE_MASK_BUFFER_LEN )); + reg_vfi->sparm.u.data.low = +cpu_to_le32 (lower_32_bits (dma.phys)); + reg_vfi->sparm.u.data.high = +cpu_to_le32 (upper_32_bits (dma.phys)); + + reg_vfi->e_d_tov =cpu_to_le32 (sli4->e_d_tov); + reg_vfi->r_a_tov =cpu_to_le32 (sli4->r_a_tov); + + reg_vfi->dw0w1_flags |=cpu_to_le16 (SLI4_REGVFI_VP ); + reg_vfi->vpi =cpu_to_le16 (vpi); +memcpy (reg_vfi->wwpn, &sli_wwpn,sizeof (reg_vfi->wwpn)); + reg_vfi->dw10_lportid_flags =cpu_to_le32 (fc_id); + +return EFC_SUCCESS ; +} + +int +sli_cmd_reg_vpi (struct sli4 *sli4,void *buf,size_t size, +u32 fc_id,__be64 sli_wwpn,u16 vpi,u16 vfi, +bool update) +{ +struct sli4_cmd_reg_vpi *reg_vpi = buf; +u32 flags =0 ; + +memset (buf,0 , size); + + reg_vpi->hdr.command =MBX_CMD_REG_VPI ; + + flags = (fc_id &SLI4_REGVPI_LOCAL_N_PORTID ); +if (update) + flags |=SLI4_REGVPI_UPD ; +else + flags &= ~SLI4_REGVPI_UPD ; + + reg_vpi->dw2_lportid_flags =cpu_to_le32 (flags); +memcpy (reg_vpi->wwpn, &sli_wwpn,sizeof (reg_vpi->wwpn)); + reg_vpi->vpi =cpu_to_le16 (vpi); + reg_vpi->vfi =cpu_to_le16 (vfi); + +return EFC_SUCCESS ; +} + +static int +sli_cmd_request_features (struct sli4 *sli4,void *buf,size_t size, +u32 features_mask,bool query) +{ +struct sli4_cmd_request_features *req_features = buf; + +memset (buf,0 , size); + + req_features->hdr.command =MBX_CMD_RQST_FEATURES ; + +if (query) + req_features->dw1_qry =cpu_to_le32 (SLI4_REQFEAT_QRY ); + + req_features->cmd =cpu_to_le32 (features_mask); + +return EFC_SUCCESS ; +} + +int +sli_cmd_unreg_fcfi (struct sli4 *sli4,void *buf,size_t size, +u16 indicator) +{ +struct sli4_cmd_unreg_fcfi *unreg_fcfi = buf; + +memset (buf,0 , size); + + unreg_fcfi->hdr.command =MBX_CMD_UNREG_FCFI ; + + unreg_fcfi->fcfi =cpu_to_le16 (indicator); + +return EFC_SUCCESS ; +} + +int +sli_cmd_unreg_rpi (struct sli4 *sli4,void *buf,size_t size, +u16 indicator, +enum sli4_resource which,u32 fc_id) +{ +struct sli4_cmd_unreg_rpi *unreg_rpi = buf; +u32 flags =0 ; + +memset (buf,0 , size); + + unreg_rpi->hdr.command =MBX_CMD_UNREG_RPI ; + +switch (which) { +case SLI_RSRC_RPI : + flags |=UNREG_RPI_II_RPI ; +if (fc_id ==U32_MAX ) +break ; + + flags |=UNREG_RPI_DP ; + unreg_rpi->dw2_dest_n_portid = +cpu_to_le32 (fc_id &UNREG_RPI_DEST_N_PORTID_MASK ); +break ; +case SLI_RSRC_VPI : + flags |=UNREG_RPI_II_VPI ; +break ; +case SLI_RSRC_VFI : + flags |=UNREG_RPI_II_VFI ; +break ; +case SLI_RSRC_FCFI : + flags |=UNREG_RPI_II_FCFI ; +break ; +default : +efc_log_info (sli4,"unknown type %#x\n" , which); +return EFC_FAIL ; + } + + unreg_rpi->dw1w1_flags =cpu_to_le16 (flags); + unreg_rpi->index =cpu_to_le16 (indicator); + +return EFC_SUCCESS ; +} + +int +sli_cmd_unreg_vfi (struct sli4 *sli4,void *buf,size_t size, +u16 index,u32 which) +{ +struct sli4_cmd_unreg_vfi *unreg_vfi = buf; + +memset (buf,0 , size); + + unreg_vfi->hdr.command =MBX_CMD_UNREG_VFI ; +switch (which) { +case SLI4_UNREG_TYPE_DOMAIN : + unreg_vfi->index =cpu_to_le16 (index); +break ; +case SLI4_UNREG_TYPE_FCF : + unreg_vfi->index =cpu_to_le16 (index); +break ; +case SLI4_UNREG_TYPE_ALL : + unreg_vfi->index =cpu_to_le16 (U32_MAX ); +break ; +default : +return EFC_FAIL ; + } + +if (which !=SLI4_UNREG_TYPE_DOMAIN ) + unreg_vfi->dw2_flags = +cpu_to_le16 (UNREG_VFI_II_FCFI ); + +return EFC_SUCCESS ; +} + +int +sli_cmd_unreg_vpi (struct sli4 *sli4,void *buf,size_t size, +u16 indicator,u32 which) +{ +struct sli4_cmd_unreg_vpi *unreg_vpi = buf; +u32 flags =0 ; + +memset (buf,0 , size); + + unreg_vpi->hdr.command =MBX_CMD_UNREG_VPI ; + unreg_vpi->index =cpu_to_le16 (indicator); +switch (which) { +case SLI4_UNREG_TYPE_PORT : + flags |=UNREG_VPI_II_VPI ; +break ; +case SLI4_UNREG_TYPE_DOMAIN : + flags |=UNREG_VPI_II_VFI ; +break ; +case SLI4_UNREG_TYPE_FCF : + flags |=UNREG_VPI_II_FCFI ; +break ; +case SLI4_UNREG_TYPE_ALL : +/* override indicator */ + unreg_vpi->index =cpu_to_le16 (U32_MAX ); + flags |=UNREG_VPI_II_FCFI ; +break ; +default : +return EFC_FAIL ; + } + + unreg_vpi->dw2w0_flags =cpu_to_le16 (flags); +return EFC_SUCCESS ; +} + +static int +sli_cmd_common_modify_eq_delay (struct sli4 *sli4,void *buf,size_t size, +struct sli4_queue *q,int num_q,u32 shift, +u32 delay_mult) +{ +struct sli4_rqst_cmn_modify_eq_delay *req =NULL ; +int i; + + req =sli_config_cmd_init (sli4, buf, size, +SLI_CONFIG_PYLD_LENGTH (cmn_modify_eq_delay), +NULL ); +if (!req) +return EFC_FAIL ; + +sli_cmd_fill_hdr (&req->hdr,CMN_MODIFY_EQ_DELAY ,SLI4_SUBSYSTEM_COMMON , +CMD_V0 ,CFG_RQST_PYLD_LEN (cmn_modify_eq_delay)); + req->num_eq =cpu_to_le32 (num_q); + +for (i =0 ; i < num_q; i++) { + req->eq_delay_record[i].eq_id =cpu_to_le32 (q[i].id); + req->eq_delay_record[i].phase =cpu_to_le32 (shift); + req->eq_delay_record[i].delay_multiplier = +cpu_to_le32 (delay_mult); + } + +return EFC_SUCCESS ; +} + +void +sli4_cmd_lowlevel_set_watchdog (struct sli4 *sli4,void *buf, +size_t size,u16 timeout) +{ +struct sli4_rqst_lowlevel_set_watchdog *req =NULL ; + + req =sli_config_cmd_init (sli4, buf, size, +SLI_CONFIG_PYLD_LENGTH (lowlevel_set_watchdog), +NULL ); +if (!req) +return ; + +sli_cmd_fill_hdr (&req->hdr,SLI4_OPC_LOWLEVEL_SET_WATCHDOG , +SLI4_SUBSYSTEM_LOWLEVEL ,CMD_V0 , +CFG_RQST_PYLD_LEN (lowlevel_set_watchdog)); + req->watchdog_timeout =cpu_to_le16 (timeout); +} + +static int +sli_cmd_common_get_cntl_attributes (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *dma) +{ +struct sli4_rqst_hdr *hdr =NULL ; + + hdr =sli_config_cmd_init (sli4, buf, size,CFG_RQST_CMDSZ (hdr), dma); +if (!hdr) +return EFC_FAIL ; + + hdr->opcode =CMN_GET_CNTL_ATTRIBUTES ; + hdr->subsystem =SLI4_SUBSYSTEM_COMMON ; + hdr->request_length =cpu_to_le32 (dma->size); + +return EFC_SUCCESS ; +} + +static int +sli_cmd_common_get_cntl_addl_attributes (struct sli4 *sli4,void *buf, +size_t size,struct efc_dma *dma) +{ +struct sli4_rqst_hdr *hdr =NULL ; + + hdr =sli_config_cmd_init (sli4, buf, size,CFG_RQST_CMDSZ (hdr), dma); +if (!hdr) +return EFC_FAIL ; + + hdr->opcode =CMN_GET_CNTL_ADDL_ATTRS ; + hdr->subsystem =SLI4_SUBSYSTEM_COMMON ; + hdr->request_length =cpu_to_le32 (dma->size); + +return EFC_SUCCESS ; +} + +int +sli_cmd_common_nop (struct sli4 *sli4,void *buf, +size_t size,uint64_t context) +{ +struct sli4_rqst_cmn_nop *nop =NULL ; + + nop =sli_config_cmd_init (sli4, buf, size, +SLI_CONFIG_PYLD_LENGTH (cmn_nop),NULL ); +if (!nop) +return EFC_FAIL ; + +sli_cmd_fill_hdr (&nop->hdr,CMN_NOP ,SLI4_SUBSYSTEM_COMMON , +CMD_V0 ,CFG_RQST_PYLD_LEN (cmn_nop)); + +memcpy (&nop->context, &context,sizeof (context)); + +return EFC_SUCCESS ; +} + +int +sli_cmd_common_get_resource_extent_info (struct sli4 *sli4,void *buf, +size_t size,u16 rtype) +{ +struct sli4_rqst_cmn_get_resource_extent_info *extent =NULL ; + + extent =sli_config_cmd_init (sli4, buf, size, +CFG_RQST_CMDSZ (cmn_get_resource_extent_info), +NULL ); +if (extent) +return EFC_FAIL ; + +sli_cmd_fill_hdr (&extent->hdr,CMN_GET_RSC_EXTENT_INFO , +SLI4_SUBSYSTEM_COMMON ,CMD_V0 , +CFG_RQST_PYLD_LEN (cmn_get_resource_extent_info)); + + extent->resource_type =cpu_to_le16 (rtype); + +return EFC_SUCCESS ; +} + +int +sli_cmd_common_get_sli4_parameters (struct sli4 *sli4,void *buf, +size_t size) +{ +struct sli4_rqst_hdr *hdr =NULL ; + + hdr =sli_config_cmd_init (sli4, buf, size, +SLI_CONFIG_PYLD_LENGTH (cmn_get_sli4_params), +NULL ); +if (!hdr) +return EFC_FAIL ; + + hdr->opcode =CMN_GET_SLI4_PARAMS ; + hdr->subsystem =SLI4_SUBSYSTEM_COMMON ; + hdr->request_length =CFG_RQST_PYLD_LEN (cmn_get_sli4_params); + +return EFC_SUCCESS ; +} + +static int +sli_cmd_common_get_port_name (struct sli4 *sli4,void *buf,size_t size) +{ +struct sli4_rqst_cmn_get_port_name *pname; + + pname =sli_config_cmd_init (sli4, buf, size, +SLI_CONFIG_PYLD_LENGTH (cmn_get_port_name), +NULL ); +if (!pname) +return EFC_FAIL ; + +sli_cmd_fill_hdr (&pname->hdr,CMN_GET_PORT_NAME ,SLI4_SUBSYSTEM_COMMON , +CMD_V1 ,CFG_RQST_PYLD_LEN (cmn_get_port_name)); + +/* Set the port type value (ethernet=0, FC=1) for V1 commands */ + pname->port_type =PORT_TYPE_FC ; + +return EFC_SUCCESS ; +} + +int +sli_cmd_common_write_object (struct sli4 *sli4,void *buf,size_t size, +u16 noc, +u16 eof,u32 desired_write_length, +u32 offset,char *object_name, +struct efc_dma *dma) +{ +struct sli4_rqst_cmn_write_object *wr_obj =NULL ; +struct sli4_bde *bde; +u32 dwflags =0 ; + + wr_obj =sli_config_cmd_init (sli4, buf, size, +CFG_RQST_CMDSZ (cmn_write_object) + +sizeof (*bde),NULL ); +if (!wr_obj) +return EFC_FAIL ; + +sli_cmd_fill_hdr (&wr_obj->hdr,CMN_WRITE_OBJECT ,SLI4_SUBSYSTEM_COMMON , +CMD_V0 , +CFG_RQST_PYLD_LEN_VAR (cmn_write_object,sizeof (*bde))); + +if (noc) + dwflags |=SLI4_RQ_DES_WRITE_LEN_NOC ; +if (eof) + dwflags |=SLI4_RQ_DES_WRITE_LEN_EOF ; + dwflags |= (desired_write_length &SLI4_RQ_DES_WRITE_LEN ); + + wr_obj->desired_write_len_dword =cpu_to_le32 (dwflags); + + wr_obj->write_offset =cpu_to_le32 (offset); +strncpy (wr_obj->object_name, object_name, +sizeof (wr_obj->object_name)); + wr_obj->host_buffer_descriptor_count =cpu_to_le32 (1 ); + + bde = (struct sli4_bde *)wr_obj->host_buffer_descriptor; + +/* Setup to transfer xfer_size bytes to device */ + bde->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (desired_write_length &SLI4_BDE_MASK_BUFFER_LEN )); + bde->u.data.low =cpu_to_le32 (lower_32_bits (dma->phys)); + bde->u.data.high =cpu_to_le32 (upper_32_bits (dma->phys)); + +return EFC_SUCCESS ; +} + +int +sli_cmd_common_delete_object (struct sli4 *sli4,void *buf,size_t size, +char *object_name) +{ +struct sli4_rqst_cmn_delete_object *req =NULL ; + + req =sli_config_cmd_init (sli4, buf, size, +CFG_RQST_CMDSZ (cmn_delete_object),NULL ); +if (!req) +return EFC_FAIL ; + +sli_cmd_fill_hdr (&req->hdr,CMN_DELETE_OBJECT ,SLI4_SUBSYSTEM_COMMON , +CMD_V0 ,CFG_RQST_PYLD_LEN (cmn_delete_object)); + +strncpy (req->object_name, object_name,sizeof (req->object_name)); +return EFC_SUCCESS ; +} + +int +sli_cmd_common_read_object (struct sli4 *sli4,void *buf,size_t size, +u32 desired_read_length,u32 offset, +char *object_name,struct efc_dma *dma) +{ +struct sli4_rqst_cmn_read_object *rd_obj =NULL ; +struct sli4_bde *bde; + + rd_obj =sli_config_cmd_init (sli4, buf, size, +CFG_RQST_CMDSZ (cmn_read_object) + +sizeof (*bde),NULL ); +if (!rd_obj) +return EFC_FAIL ;
drivers/scsi/elx/libefc_sli/sli4.c sli_fc_rqe_rqid_and_index(struct sli4 *sli4, u8 *cqe, · line 4148
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+ +sli_cmd_fill_hdr (&rd_obj->hdr,CMN_READ_OBJECT ,SLI4_SUBSYSTEM_COMMON , +CMD_V0 , +CFG_RQST_PYLD_LEN_VAR (cmn_read_object,sizeof (*bde))); + rd_obj->desired_read_length_dword = +cpu_to_le32 (desired_read_length &SLI4_REQ_DESIRE_READLEN ); + + rd_obj->read_offset =cpu_to_le32 (offset); +strncpy (rd_obj->object_name, object_name, +sizeof (rd_obj->object_name));
Does the string a NUL termination?
Quoted 30 lines
drivers/scsi/elx/libefc_sli/sli4.c +30
-0+ rd_obj->host_buffer_descriptor_count =cpu_to_le32 (1 ); + + bde = (struct sli4_bde *)rd_obj->host_buffer_descriptor; + +/* Setup to transfer xfer_size bytes to device */ + bde->bde_type_buflen = +cpu_to_le32 ((BDE_TYPE_BDE_64 <<BDE_TYPE_SHIFT ) | + (desired_read_length &SLI4_BDE_MASK_BUFFER_LEN )); +if (dma) { + bde->u.data.low =cpu_to_le32 (lower_32_bits (dma->phys)); + bde->u.data.high =cpu_to_le32 (upper_32_bits (dma->phys)); + }else { + bde->u.data.low =0 ; + bde->u.data.high =0 ; + } + +return EFC_SUCCESS ; +} + +int +sli_cmd_dmtf_exec_clp_cmd (struct sli4 *sli4,void *buf,size_t size, +struct efc_dma *cmd, +struct efc_dma *resp) +{ +struct sli4_rqst_dmtf_exec_clp_cmd *clp_cmd =NULL ; + + clp_cmd =sli_config_cmd_init (sli4, buf, size, +CFG_RQST_CMDSZ (dmtf_exec_clp_cmd),NULL ); +if (!clp_cmd) +return EFC_FAIL ;
drivers/scsi/elx/libefc_sli/sli4.c sli_fc_rqe_rqid_and_index(struct sli4 *sli4, u8 *cqe, · line 4188
Quoted 10 lines
drivers/scsi/elx/libefc_sli/sli4.c +10
-0+ +sli_cmd_fill_hdr (&clp_cmd->hdr,DMTF_EXEC_CLP_CMD ,SLI4_SUBSYSTEM_DMTF , +CMD_V0 ,CFG_RQST_PYLD_LEN (dmtf_exec_clp_cmd)); + + clp_cmd->cmd_buf_length =cpu_to_le32 (cmd->size); + clp_cmd->cmd_buf_addr_low =cpu_to_le32 (lower_32_bits (cmd->phys)); + clp_cmd->cmd_buf_addr_high =cpu_to_le32 (upper_32_bits (cmd->phys)); + clp_cmd->resp_buf_length =cpu_to_le32 (resp->size); + clp_cmd->resp_buf_addr_low =cpu_to_le32 (lower_32_bits (resp->phys)); + clp_cmd->resp_buf_addr_high =cpu_to_le32 (upper_32_bits (resp->phys));
whitespace damage
Quoted 136 lines
drivers/scsi/elx/libefc_sli/sli4.c +133
-0+ +return EFC_SUCCESS ; +} + +int +sli_cmd_common_set_dump_location (struct sli4 *sli4,void *buf, +size_t size,bool query, +bool is_buffer_list, +struct efc_dma *buffer,u8 fdb) +{ +struct sli4_rqst_cmn_set_dump_location *set_dump_loc =NULL ; +u32 buffer_length_flag =0 ; + + set_dump_loc =sli_config_cmd_init (sli4, buf, size, +CFG_RQST_CMDSZ (cmn_set_dump_location), +NULL ); +if (!set_dump_loc) +return EFC_FAIL ; + +sli_cmd_fill_hdr (&set_dump_loc->hdr,CMN_SET_DUMP_LOCATION , +SLI4_SUBSYSTEM_COMMON ,CMD_V0 , +CFG_RQST_PYLD_LEN (cmn_set_dump_location)); + +if (is_buffer_list) + buffer_length_flag |=SLI4_CMN_SET_DUMP_BLP ; + +if (query) + buffer_length_flag |=SLI4_CMN_SET_DUMP_QRY ; + +if (fdb) + buffer_length_flag |=SLI4_CMN_SET_DUMP_FDB ; + +if (buffer) { + set_dump_loc->buf_addr_low = +cpu_to_le32 (lower_32_bits (buffer->phys)); + set_dump_loc->buf_addr_high = +cpu_to_le32 (upper_32_bits (buffer->phys)); + + buffer_length_flag |= (buffer->len & +SLI4_CMN_SET_DUMP_BUFFER_LEN ); + }else { + set_dump_loc->buf_addr_low =0 ; + set_dump_loc->buf_addr_high =0 ; + set_dump_loc->buffer_length_dword =0 ; + } + set_dump_loc->buffer_length_dword =cpu_to_le32 (buffer_length_flag); +return EFC_SUCCESS ; +} + +int +sli_cmd_common_set_features (struct sli4 *sli4,void *buf,size_t size, +u32 feature, +u32 param_len, +void *parameter) +{ +struct sli4_rqst_cmn_set_features *cmd =NULL ; + + cmd =sli_config_cmd_init (sli4, buf, size, +CFG_RQST_CMDSZ (cmn_set_features),NULL ); +if (!cmd) +return EFC_FAIL ; + +sli_cmd_fill_hdr (&cmd->hdr,CMN_SET_FEATURES ,SLI4_SUBSYSTEM_COMMON , +CMD_V0 ,CFG_RQST_PYLD_LEN (cmn_set_features)); + + cmd->feature =cpu_to_le32 (feature); + cmd->param_len =cpu_to_le32 (param_len); +memcpy (cmd->params, parameter, param_len); + +return EFC_SUCCESS ; +} + +int +sli_cqe_mq (struct sli4 *sli4,void *buf) +{ +struct sli4_mcqe *mcqe = buf; +u32 dwflags =le32_to_cpu (mcqe->dw3_flags); +/* +* Firmware can split mbx completions into two MCQEs: first with only +* the "consumed" bit set and a second with the "complete" bit set. +* Thus, ignore MCQE unless "complete" is set. +*/ +if (!(dwflags &SLI4_MCQE_COMPLETED )) +return SLI4_MCQE_STATUS_NOT_COMPLETED ; + +if (le16_to_cpu (mcqe->completion_status)) { +efc_log_info (sli4,"status(st=%#x ext=%#x con=%d cmp=%d ae=%d val=%d)\n" , +le16_to_cpu (mcqe->completion_status), +le16_to_cpu (mcqe->extended_status), + (dwflags &SLI4_MCQE_CONSUMED ), + (dwflags &SLI4_MCQE_COMPLETED ), + (dwflags &SLI4_MCQE_AE ), + (dwflags &SLI4_MCQE_VALID )); + } + +return le16_to_cpu (mcqe->completion_status); +} + +int +sli_cqe_async (struct sli4 *sli4,void *buf) +{ +struct sli4_acqe *acqe = buf; +int rc =EFC_FAIL ; + +if (!buf) { +efc_log_err (sli4,"bad parameter sli4=%p buf=%p\n" , sli4, buf); +return EFC_FAIL ; + } + +switch (acqe->event_code) { +case SLI4_ACQE_EVENT_CODE_LINK_STATE : +efc_log_info (sli4,"Unsupported by FC link, evt code:%#x\n" , + acqe->event_code); +break ; +case SLI4_ACQE_EVENT_CODE_GRP_5 : +efc_log_info (sli4,"ACQE GRP5\n" ); +break ; +case SLI4_ACQE_EVENT_CODE_SLI_PORT_EVENT : +efc_log_info (sli4,"ACQE SLI Port, type=0x%x, data1,2=0x%08x,0x%08x\n" , + acqe->event_type, +le32_to_cpu (acqe->event_data[0 ]), +le32_to_cpu (acqe->event_data[1 ])); +break ; +case SLI4_ACQE_EVENT_CODE_FC_LINK_EVENT : + rc =sli_fc_process_link_attention (sli4, buf); +break ; +default : +efc_log_info (sli4,"ACQE unknown=%#x\n" , + acqe->event_code); + } + +return rc; +}Signature · 1 line
2.16.4
Thanks,
Daniel
Re: [PATCH v3 06/31] elx: libefc_sli: bmbx routines and SLI config commands
On 4/15/2020 9:10 AM, Daniel Wagner wrote:
...
Quoted 5 lines
drivers/scsi/elx/libefc_sli/sli4.c sli_fc_rqe_rqid_and_index(struct sli4 *sli4, u8 *cqe, · line 3131
Quoted 3 lines
drivers/scsi/elx/libefc_sli/sli4.c +3
-0+/* write buffer location to bootstrap mailbox register */ + val =SLI4_BMBX_WRITE_HI (sli4->bmbx.phys); +writel (val, (sli4->reg[0 ] +SLI4_BMBX_REG ));Is the access to the register serialized by a lock?
The BMBX is used only at adapter initialization start. The Initialization sequence serializes access.
Agree with rest of comments and will address.
-- james