mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-20 11:11:24 +00:00
Extended MSI-x vectors support for Invader and Fury(12Gb/s HBA).
This Driver will create multiple MSI-x vector depending upon what FW expose. As of now 12 Gbp/s MR controller (Invader and Fury) expose 96 msix vector. As of now 6 Gbp/s MR controller (Thunderbolt) expose 16 msix vector. Reviewed by: ambrisko MFC after: 2 weeks Sponsored by: AVAGO Technologies
This commit is contained in:
parent
90012054d6
commit
d18d1b472d
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=272739
@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/types.h>
|
||||
#include <sys/kthread.h>
|
||||
#include <sys/taskqueue.h>
|
||||
#include <sys/smp.h>
|
||||
|
||||
|
||||
/*
|
||||
@ -67,6 +68,8 @@ static d_ioctl_t mrsas_ioctl;
|
||||
|
||||
static struct mrsas_mgmt_info mrsas_mgmt_info;
|
||||
static struct mrsas_ident *mrsas_find_ident(device_t);
|
||||
static int mrsas_setup_msix(struct mrsas_softc *sc);
|
||||
static int mrsas_allocate_msix(struct mrsas_softc *sc);
|
||||
static void mrsas_shutdown_ctlr(struct mrsas_softc *sc, u_int32_t opcode);
|
||||
static void mrsas_flush_cache(struct mrsas_softc *sc);
|
||||
static void mrsas_reset_reply_desc(struct mrsas_softc *sc);
|
||||
@ -80,7 +83,7 @@ static int mrsas_setup_irq(struct mrsas_softc *sc);
|
||||
static int mrsas_alloc_mem(struct mrsas_softc *sc);
|
||||
static int mrsas_init_fw(struct mrsas_softc *sc);
|
||||
static int mrsas_setup_raidmap(struct mrsas_softc *sc);
|
||||
static int mrsas_complete_cmd(struct mrsas_softc *sc);
|
||||
static int mrsas_complete_cmd(struct mrsas_softc *sc, u_int32_t MSIxIndex);
|
||||
static int mrsas_clear_intr(struct mrsas_softc *sc);
|
||||
static int mrsas_get_ctrl_info(struct mrsas_softc *sc,
|
||||
struct mrsas_ctrl_info *ctrl_info);
|
||||
@ -151,7 +154,6 @@ static int mrsas_alloc_evt_log_info_cmd(struct mrsas_softc *sc);
|
||||
static void mrsas_free_evt_log_info_cmd(struct mrsas_softc *sc);
|
||||
SYSCTL_NODE(_hw, OID_AUTO, mrsas, CTLFLAG_RD, 0, "MRSAS Driver Parameters");
|
||||
|
||||
|
||||
/**
|
||||
* PCI device struct and table
|
||||
*
|
||||
@ -709,8 +711,63 @@ static int mrsas_start_aen(struct mrsas_softc *sc)
|
||||
|
||||
return mrsas_register_aen(sc, eli.newest_seq_num + 1,
|
||||
class_locale.word);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* mrsas_setup_msix: Allocate MSI-x vectors
|
||||
* @sc: Adapter soft state
|
||||
*/
|
||||
static int mrsas_setup_msix(struct mrsas_softc *sc)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < sc->msix_vectors; i++) {
|
||||
sc->irq_context[i].sc = sc;
|
||||
sc->irq_context[i].MSIxIndex = i;
|
||||
sc->irq_id[i] = i + 1;
|
||||
sc->mrsas_irq[i] = bus_alloc_resource_any
|
||||
(sc->mrsas_dev, SYS_RES_IRQ, &sc->irq_id[i]
|
||||
, RF_ACTIVE);
|
||||
if (sc->mrsas_irq[i] == NULL) {
|
||||
device_printf(sc->mrsas_dev, "Can't allocate MSI-x\n");
|
||||
goto irq_alloc_failed;
|
||||
}
|
||||
if (bus_setup_intr(sc->mrsas_dev,
|
||||
sc->mrsas_irq[i],
|
||||
INTR_MPSAFE|INTR_TYPE_CAM,
|
||||
NULL, mrsas_isr, &sc->irq_context[i],
|
||||
&sc->intr_handle[i])) {
|
||||
device_printf(sc->mrsas_dev,
|
||||
"Cannot set up MSI-x interrupt handler\n");
|
||||
goto irq_alloc_failed;
|
||||
}
|
||||
}
|
||||
return SUCCESS;
|
||||
|
||||
irq_alloc_failed:
|
||||
mrsas_teardown_intr(sc);
|
||||
return (FAIL);
|
||||
}
|
||||
|
||||
/**
|
||||
* mrsas_allocate_msix: Setup MSI-x vectors
|
||||
* @sc: Adapter soft state
|
||||
*/
|
||||
static int mrsas_allocate_msix(struct mrsas_softc *sc)
|
||||
{
|
||||
if (pci_alloc_msix(sc->mrsas_dev, &sc->msix_vectors) == 0) {
|
||||
device_printf(sc->mrsas_dev, "Using MSI-X with %d number"
|
||||
" of vectors\n", sc->msix_vectors);
|
||||
} else {
|
||||
device_printf(sc->mrsas_dev, "MSI-x setup failed\n");
|
||||
goto irq_alloc_failed;
|
||||
}
|
||||
return SUCCESS;
|
||||
|
||||
irq_alloc_failed:
|
||||
mrsas_teardown_intr(sc);
|
||||
return (FAIL);
|
||||
}
|
||||
/**
|
||||
* mrsas_attach: PCI entry point
|
||||
* input: device struct pointer
|
||||
@ -784,6 +841,8 @@ static int mrsas_attach(device_t dev)
|
||||
sc->adprecovery = MRSAS_HBA_OPERATIONAL;
|
||||
sc->UnevenSpanSupport = 0;
|
||||
|
||||
sc->msix_enable = 0;
|
||||
|
||||
/* Initialize Firmware */
|
||||
if (mrsas_init_fw(sc) != SUCCESS) {
|
||||
goto attach_fail_fw;
|
||||
@ -794,6 +853,7 @@ static int mrsas_attach(device_t dev)
|
||||
goto attach_fail_cam;
|
||||
}
|
||||
|
||||
|
||||
/* Register IRQs */
|
||||
if (mrsas_setup_irq(sc) != SUCCESS) {
|
||||
goto attach_fail_irq;
|
||||
@ -838,7 +898,9 @@ static int mrsas_attach(device_t dev)
|
||||
attach_fail_cam:
|
||||
mrsas_cam_detach(sc);
|
||||
attach_fail_fw:
|
||||
//attach_fail_raidmap:
|
||||
/* if MSIX vector is allocated and FW Init FAILED then release MSIX */
|
||||
if (sc->msix_enable == 1)
|
||||
pci_release_msi(sc->mrsas_dev);
|
||||
mrsas_free_mem(sc);
|
||||
mtx_destroy(&sc->sim_lock);
|
||||
mtx_destroy(&sc->aen_lock);
|
||||
@ -1081,11 +1143,28 @@ void mrsas_free_mem(struct mrsas_softc *sc)
|
||||
*/
|
||||
void mrsas_teardown_intr(struct mrsas_softc *sc)
|
||||
{
|
||||
if (sc->intr_handle)
|
||||
bus_teardown_intr(sc->mrsas_dev, sc->mrsas_irq, sc->intr_handle);
|
||||
if (sc->mrsas_irq != NULL)
|
||||
bus_release_resource(sc->mrsas_dev, SYS_RES_IRQ, sc->irq_id, sc->mrsas_irq);
|
||||
sc->intr_handle = NULL;
|
||||
int i;
|
||||
if (!sc->msix_enable) {
|
||||
if (sc->intr_handle[0])
|
||||
bus_teardown_intr(sc->mrsas_dev, sc->mrsas_irq[0], sc->intr_handle[0]);
|
||||
if (sc->mrsas_irq[0] != NULL)
|
||||
bus_release_resource(sc->mrsas_dev, SYS_RES_IRQ, sc->irq_id[0], sc->mrsas_irq[0]);
|
||||
sc->intr_handle[0] = NULL;
|
||||
} else {
|
||||
for (i = 0; i < sc->msix_vectors; i++) {
|
||||
if (sc->intr_handle[i])
|
||||
bus_teardown_intr(sc->mrsas_dev, sc->mrsas_irq[i],
|
||||
sc->intr_handle[i]);
|
||||
|
||||
if (sc->mrsas_irq[i] != NULL)
|
||||
bus_release_resource(sc->mrsas_dev, SYS_RES_IRQ,
|
||||
sc->irq_id[i], sc->mrsas_irq[i]);
|
||||
|
||||
sc->intr_handle[i] = NULL;
|
||||
}
|
||||
pci_release_msi(sc->mrsas_dev);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1195,19 +1274,29 @@ mrsas_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, d_thread_t *td)
|
||||
*/
|
||||
static int mrsas_setup_irq(struct mrsas_softc *sc)
|
||||
{
|
||||
sc->irq_id = 0;
|
||||
sc->mrsas_irq = bus_alloc_resource_any(sc->mrsas_dev, SYS_RES_IRQ,
|
||||
&sc->irq_id, RF_SHAREABLE | RF_ACTIVE);
|
||||
if (sc->mrsas_irq == NULL){
|
||||
device_printf(sc->mrsas_dev, "Cannot allocate interrupt\n");
|
||||
return (FAIL);
|
||||
}
|
||||
if (bus_setup_intr(sc->mrsas_dev, sc->mrsas_irq, INTR_MPSAFE|INTR_TYPE_CAM,
|
||||
NULL, mrsas_isr, sc, &sc->intr_handle)) {
|
||||
device_printf(sc->mrsas_dev, "Cannot set up interrupt\n");
|
||||
return (FAIL);
|
||||
}
|
||||
if (sc->msix_enable && (mrsas_setup_msix(sc) == SUCCESS))
|
||||
device_printf(sc->mrsas_dev, "MSI-x interrupts setup success\n");
|
||||
|
||||
else {
|
||||
device_printf(sc->mrsas_dev, "Fall back to legacy interrupt\n");
|
||||
sc->irq_context[0].sc = sc;
|
||||
sc->irq_context[0].MSIxIndex = 0;
|
||||
sc->irq_id[0] = 0;
|
||||
sc->mrsas_irq[0] = bus_alloc_resource_any(sc->mrsas_dev,
|
||||
SYS_RES_IRQ, &sc->irq_id[0], RF_SHAREABLE | RF_ACTIVE);
|
||||
if (sc->mrsas_irq[0] == NULL){
|
||||
device_printf(sc->mrsas_dev, "Cannot allocate legcay"
|
||||
"interrupt\n");
|
||||
return (FAIL);
|
||||
}
|
||||
if (bus_setup_intr(sc->mrsas_dev, sc->mrsas_irq[0],
|
||||
INTR_MPSAFE|INTR_TYPE_CAM, NULL, mrsas_isr,
|
||||
&sc->irq_context[0], &sc->intr_handle[0])) {
|
||||
device_printf(sc->mrsas_dev, "Cannot set up legacy"
|
||||
"interrupt\n");
|
||||
return (FAIL);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -1221,16 +1310,16 @@ static int mrsas_setup_irq(struct mrsas_softc *sc)
|
||||
*/
|
||||
void mrsas_isr(void *arg)
|
||||
{
|
||||
struct mrsas_softc *sc = (struct mrsas_softc *)arg;
|
||||
int status;
|
||||
struct mrsas_irq_context *irq_context = (struct mrsas_irq_context *)arg;
|
||||
struct mrsas_softc *sc = irq_context->sc;
|
||||
int status = 0;
|
||||
|
||||
/* Clear FW state change interrupt */
|
||||
status = mrsas_clear_intr(sc);
|
||||
if (!sc->msix_vectors) {
|
||||
status = mrsas_clear_intr(sc);
|
||||
if (!status)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Not our interrupt */
|
||||
if (!status)
|
||||
return;
|
||||
|
||||
/* If we are resetting, bail */
|
||||
if (test_bit(MRSAS_FUSION_IN_RESET, &sc->reset_flags)) {
|
||||
printf(" Entered into ISR when OCR is going active. \n");
|
||||
@ -1238,7 +1327,7 @@ void mrsas_isr(void *arg)
|
||||
return;
|
||||
}
|
||||
/* Process for reply request and clear response interrupt */
|
||||
if (mrsas_complete_cmd(sc) != SUCCESS)
|
||||
if (mrsas_complete_cmd(sc, irq_context->MSIxIndex) != SUCCESS)
|
||||
mrsas_clear_intr(sc);
|
||||
|
||||
return;
|
||||
@ -1255,7 +1344,7 @@ void mrsas_isr(void *arg)
|
||||
* the command type and perform the appropriate action. Before we
|
||||
* return, we clear the response interrupt.
|
||||
*/
|
||||
static int mrsas_complete_cmd(struct mrsas_softc *sc)
|
||||
static int mrsas_complete_cmd(struct mrsas_softc *sc, u_int32_t MSIxIndex)
|
||||
{
|
||||
Mpi2ReplyDescriptorsUnion_t *desc;
|
||||
MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR *reply_desc;
|
||||
@ -1276,7 +1365,9 @@ static int mrsas_complete_cmd(struct mrsas_softc *sc)
|
||||
return (DONE);
|
||||
|
||||
desc = sc->reply_desc_mem;
|
||||
desc += sc->last_reply_idx;
|
||||
//desc += sc->last_reply_idx[0];
|
||||
desc += ((MSIxIndex * sc->reply_alloc_sz)/sizeof(MPI2_REPLY_DESCRIPTORS_UNION))
|
||||
+ sc->last_reply_idx[MSIxIndex];
|
||||
|
||||
reply_desc = (MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR *)desc;
|
||||
|
||||
@ -1321,18 +1412,19 @@ static int mrsas_complete_cmd(struct mrsas_softc *sc)
|
||||
break;
|
||||
}
|
||||
|
||||
sc->last_reply_idx++;
|
||||
if (sc->last_reply_idx >= sc->reply_q_depth)
|
||||
sc->last_reply_idx = 0;
|
||||
sc->last_reply_idx[MSIxIndex]++;
|
||||
if (sc->last_reply_idx[MSIxIndex] >= sc->reply_q_depth)
|
||||
sc->last_reply_idx[MSIxIndex] = 0;
|
||||
|
||||
desc->Words = ~((uint64_t)0x00); /* set it back to all 0xFFFFFFFFs */
|
||||
num_completed++;
|
||||
threshold_reply_count++;
|
||||
|
||||
/* Get the next reply descriptor */
|
||||
if (!sc->last_reply_idx)
|
||||
if (!sc->last_reply_idx[MSIxIndex]){
|
||||
desc = sc->reply_desc_mem;
|
||||
else
|
||||
desc += ((MSIxIndex * sc->reply_alloc_sz)/sizeof(MPI2_REPLY_DESCRIPTORS_UNION));
|
||||
} else
|
||||
desc++;
|
||||
|
||||
reply_desc = (MPI2_SCSI_IO_SUCCESS_REPLY_DESCRIPTOR *)desc;
|
||||
@ -1349,18 +1441,40 @@ static int mrsas_complete_cmd(struct mrsas_softc *sc)
|
||||
* completed.
|
||||
*/
|
||||
if (threshold_reply_count >= THRESHOLD_REPLY_COUNT) {
|
||||
mrsas_write_reg(sc, offsetof(mrsas_reg_set, reply_post_host_index),
|
||||
sc->last_reply_idx);
|
||||
threshold_reply_count = 0;
|
||||
if (sc->msix_enable) {
|
||||
if ((sc->device_id == MRSAS_INVADER) ||
|
||||
(sc->device_id == MRSAS_FURY))
|
||||
mrsas_write_reg(sc, sc->msix_reg_offset[MSIxIndex/8],
|
||||
((MSIxIndex & 0x7) << 24) |
|
||||
sc->last_reply_idx[MSIxIndex]);
|
||||
else
|
||||
mrsas_write_reg(sc, sc->msix_reg_offset[0], (MSIxIndex << 24) |
|
||||
sc->last_reply_idx[MSIxIndex]);
|
||||
} else
|
||||
mrsas_write_reg(sc, offsetof(mrsas_reg_set,
|
||||
reply_post_host_index),sc->last_reply_idx[0]);
|
||||
|
||||
threshold_reply_count = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* No match, just return */
|
||||
if (num_completed == 0)
|
||||
return (DONE);
|
||||
|
||||
/* Clear response interrupt */
|
||||
mrsas_write_reg(sc, offsetof(mrsas_reg_set, reply_post_host_index),sc->last_reply_idx);
|
||||
if (sc->msix_enable) {
|
||||
if ((sc->device_id == MRSAS_INVADER) ||
|
||||
(sc->device_id == MRSAS_FURY)){
|
||||
mrsas_write_reg(sc, sc->msix_reg_offset[MSIxIndex/8],
|
||||
((MSIxIndex & 0x7) << 24) |
|
||||
sc->last_reply_idx[MSIxIndex]);
|
||||
} else
|
||||
mrsas_write_reg(sc, sc->msix_reg_offset[0], (MSIxIndex << 24) |
|
||||
sc->last_reply_idx[MSIxIndex]);
|
||||
} else
|
||||
mrsas_write_reg(sc, offsetof(mrsas_reg_set,
|
||||
reply_post_host_index),sc->last_reply_idx[0]);
|
||||
|
||||
return(0);
|
||||
}
|
||||
@ -1423,7 +1537,7 @@ void mrsas_map_mpt_cmd_status(struct mrsas_mpt_cmd *cmd, u_int8_t status, u_int8
|
||||
static int mrsas_alloc_mem(struct mrsas_softc *sc)
|
||||
{
|
||||
u_int32_t verbuf_size, io_req_size, reply_desc_size, sense_size,
|
||||
chain_frame_size, evt_detail_size;
|
||||
chain_frame_size, evt_detail_size, count;
|
||||
|
||||
/*
|
||||
* Allocate parent DMA tag
|
||||
@ -1537,10 +1651,11 @@ static int mrsas_alloc_mem(struct mrsas_softc *sc)
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
count = sc->msix_vectors > 0 ? sc->msix_vectors : 1;
|
||||
/*
|
||||
* Allocate Reply Descriptor Array
|
||||
*/
|
||||
reply_desc_size = sc->reply_alloc_sz;
|
||||
reply_desc_size = sc->reply_alloc_sz * count;
|
||||
if (bus_dma_tag_create( sc->mrsas_parent_tag, // parent
|
||||
16, 0, // algnmnt, boundary
|
||||
BUS_SPACE_MAXADDR_32BIT,// lowaddr
|
||||
@ -1796,13 +1911,15 @@ static int mrsas_setup_raidmap(struct mrsas_softc *sc)
|
||||
*/
|
||||
static int mrsas_init_fw(struct mrsas_softc *sc)
|
||||
{
|
||||
|
||||
int ret, loop, ocr = 0;
|
||||
u_int32_t max_sectors_1;
|
||||
u_int32_t max_sectors_2;
|
||||
u_int32_t tmp_sectors;
|
||||
struct mrsas_ctrl_info *ctrl_info;
|
||||
|
||||
int ret, ocr = 0;
|
||||
|
||||
u_int32_t scratch_pad_2;
|
||||
int msix_enable = 0;
|
||||
int fw_msix_count = 0;
|
||||
|
||||
/* Make sure Firmware is ready */
|
||||
ret = mrsas_transition_to_ready(sc, ocr);
|
||||
@ -1810,7 +1927,57 @@ static int mrsas_init_fw(struct mrsas_softc *sc)
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/* Get operational params, sge flags, send init cmd to ctlr */
|
||||
|
||||
/* MSI-x index 0- reply post host index register */
|
||||
sc->msix_reg_offset[0] = MPI2_REPLY_POST_HOST_INDEX_OFFSET;
|
||||
/* Check if MSI-X is supported while in ready state */
|
||||
msix_enable = (mrsas_read_reg(sc, offsetof(mrsas_reg_set, outbound_scratch_pad)) & 0x4000000) >> 0x1a;
|
||||
|
||||
if (msix_enable) {
|
||||
scratch_pad_2 = mrsas_read_reg(sc, offsetof(mrsas_reg_set,
|
||||
outbound_scratch_pad_2));
|
||||
|
||||
/* Check max MSI-X vectors */
|
||||
if (sc->device_id == MRSAS_TBOLT) {
|
||||
sc->msix_vectors = (scratch_pad_2
|
||||
& MR_MAX_REPLY_QUEUES_OFFSET) + 1;
|
||||
fw_msix_count = sc->msix_vectors;
|
||||
} else {
|
||||
/* Invader/Fury supports 96 MSI-X vectors */
|
||||
sc->msix_vectors = ((scratch_pad_2
|
||||
& MR_MAX_REPLY_QUEUES_EXT_OFFSET)
|
||||
>> MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT) + 1;
|
||||
fw_msix_count = sc->msix_vectors;
|
||||
|
||||
/* Save 1-15 reply post index address to local
|
||||
* memory
|
||||
* Index 0 is already saved from reg offset
|
||||
* MPI2_REPLY_POST_HOST_INDEX_OFFSET
|
||||
*/
|
||||
for (loop = 1; loop < MR_MAX_MSIX_REG_ARRAY;
|
||||
loop++) {
|
||||
sc->msix_reg_offset[loop] =
|
||||
MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET +
|
||||
(loop * 0x10);
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't bother allocating more MSI-X vectors than cpus */
|
||||
sc->msix_vectors = min(sc->msix_vectors,
|
||||
mp_ncpus);
|
||||
|
||||
/* Allocate MSI-x vectors */
|
||||
if (mrsas_allocate_msix(sc) == SUCCESS)
|
||||
sc->msix_enable = 1;
|
||||
else
|
||||
sc->msix_enable = 0;
|
||||
|
||||
device_printf(sc->mrsas_dev, "FW supports <%d> MSIX vector,"
|
||||
"Online CPU %d Current MSIX <%d>\n",
|
||||
fw_msix_count, mp_ncpus, sc->msix_vectors);
|
||||
}
|
||||
|
||||
/* Get operational params, sge flags, send init cmd to ctlr */
|
||||
if (mrsas_init_adapter(sc) != SUCCESS){
|
||||
device_printf(sc->mrsas_dev, "Adapter initialize Fail.\n");
|
||||
return(1);
|
||||
@ -1907,6 +2074,7 @@ int mrsas_init_adapter(struct mrsas_softc *sc)
|
||||
uint32_t status;
|
||||
u_int32_t max_cmd;
|
||||
int ret;
|
||||
int i = 0;
|
||||
|
||||
/* Read FW status register */
|
||||
status = mrsas_read_reg(sc, offsetof(mrsas_reg_set, outbound_scratch_pad));
|
||||
@ -1919,7 +2087,7 @@ int mrsas_init_adapter(struct mrsas_softc *sc)
|
||||
max_cmd = sc->max_fw_cmds;
|
||||
|
||||
/* Determine allocation size of command frames */
|
||||
sc->reply_q_depth = ((max_cmd *2 +1 +15)/16*16);
|
||||
sc->reply_q_depth = ((max_cmd +1 +15)/16*16);
|
||||
sc->request_alloc_sz = sizeof(MRSAS_REQUEST_DESCRIPTOR_UNION) * max_cmd;
|
||||
sc->reply_alloc_sz = sizeof(MPI2_REPLY_DESCRIPTORS_UNION) * (sc->reply_q_depth);
|
||||
sc->io_frames_alloc_sz = MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE + (MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE * (max_cmd + 1));
|
||||
@ -1936,7 +2104,9 @@ int mrsas_init_adapter(struct mrsas_softc *sc)
|
||||
sc->chain_offset_io_request = (MRSAS_MPI2_RAID_DEFAULT_IO_FRAME_SIZE -
|
||||
sizeof(MPI2_SGE_IO_UNION))/16;
|
||||
|
||||
sc->last_reply_idx = 0;
|
||||
int count = sc->msix_vectors > 0 ? sc->msix_vectors : 1;
|
||||
for (i = 0 ; i < count; i++)
|
||||
sc->last_reply_idx[i] = 0;
|
||||
|
||||
ret = mrsas_alloc_mem(sc);
|
||||
if (ret != SUCCESS)
|
||||
@ -1949,6 +2119,7 @@ int mrsas_init_adapter(struct mrsas_softc *sc)
|
||||
ret = mrsas_ioc_init(sc);
|
||||
if (ret != SUCCESS)
|
||||
return(ret);
|
||||
|
||||
|
||||
|
||||
return(0);
|
||||
@ -2042,12 +2213,21 @@ int mrsas_ioc_init(struct mrsas_softc *sc)
|
||||
IOCInitMsg->ReplyDescriptorPostQueueDepth = sc->reply_q_depth;
|
||||
IOCInitMsg->ReplyDescriptorPostQueueAddress = sc->reply_desc_phys_addr;
|
||||
IOCInitMsg->SystemRequestFrameBaseAddress = sc->io_request_phys_addr;
|
||||
IOCInitMsg->HostMSIxVectors = (sc->msix_vectors > 0 ? sc->msix_vectors : 0);
|
||||
|
||||
init_frame = (struct mrsas_init_frame *)sc->ioc_init_mem;
|
||||
init_frame->cmd = MFI_CMD_INIT;
|
||||
init_frame->cmd_status = 0xFF;
|
||||
init_frame->flags |= MFI_FRAME_DONT_POST_IN_REPLY_QUEUE;
|
||||
|
||||
/* driver support Extended MSIX */
|
||||
if ((sc->device_id == MRSAS_INVADER) ||
|
||||
(sc->device_id == MRSAS_FURY)) {
|
||||
init_frame->driver_operations.
|
||||
mfi_capabilities.support_additional_msix = 1;
|
||||
}
|
||||
|
||||
|
||||
if (sc->verbuf_mem) {
|
||||
snprintf((char *)sc->verbuf_mem, strlen(MRSAS_VERSION)+2,"%s\n",
|
||||
MRSAS_VERSION);
|
||||
@ -2113,7 +2293,7 @@ int mrsas_ioc_init(struct mrsas_softc *sc)
|
||||
int mrsas_alloc_mpt_cmds(struct mrsas_softc *sc)
|
||||
{
|
||||
int i, j;
|
||||
u_int32_t max_cmd;
|
||||
u_int32_t max_cmd, count;
|
||||
struct mrsas_mpt_cmd *cmd;
|
||||
pMpi2ReplyDescriptorsUnion_t reply_desc;
|
||||
u_int32_t offset, chain_offset, sense_offset;
|
||||
@ -2183,7 +2363,8 @@ int mrsas_alloc_mpt_cmds(struct mrsas_softc *sc)
|
||||
|
||||
/* Initialize reply descriptor array to 0xFFFFFFFF */
|
||||
reply_desc = sc->reply_desc_mem;
|
||||
for (i = 0; i < sc->reply_q_depth; i++, reply_desc++) {
|
||||
count = sc->msix_vectors > 0 ? sc->msix_vectors : 1;
|
||||
for (i = 0; i < sc->reply_q_depth * count ; i++, reply_desc++) {
|
||||
reply_desc->Words = MRSAS_ULONG_MAX;
|
||||
}
|
||||
return(0);
|
||||
@ -2400,11 +2581,14 @@ mrsas_ocr_thread(void *arg)
|
||||
*/
|
||||
void mrsas_reset_reply_desc(struct mrsas_softc *sc)
|
||||
{
|
||||
int i;
|
||||
int i, count;
|
||||
pMpi2ReplyDescriptorsUnion_t reply_desc;
|
||||
|
||||
sc->last_reply_idx = 0;
|
||||
reply_desc = sc->reply_desc_mem;
|
||||
count = sc->msix_vectors > 0 ? sc->msix_vectors : 1;
|
||||
for (i = 0 ; i < count ; i++)
|
||||
sc->last_reply_idx[i] = 0;
|
||||
|
||||
reply_desc = sc->reply_desc_mem;
|
||||
for (i = 0; i < sc->reply_q_depth; i++, reply_desc++) {
|
||||
reply_desc->Words = MRSAS_ULONG_MAX;
|
||||
}
|
||||
@ -2641,7 +2825,8 @@ void mrsas_kill_hba (struct mrsas_softc *sc)
|
||||
int mrsas_wait_for_outstanding(struct mrsas_softc *sc)
|
||||
{
|
||||
int i, outstanding, retval = 0;
|
||||
u_int32_t fw_state;
|
||||
u_int32_t fw_state, count, MSIxIndex;
|
||||
|
||||
|
||||
for (i = 0; i < MRSAS_RESET_WAIT_TIME; i++) {
|
||||
if (sc->remove_in_progress) {
|
||||
@ -2666,7 +2851,9 @@ int mrsas_wait_for_outstanding(struct mrsas_softc *sc)
|
||||
if (!(i % MRSAS_RESET_NOTICE_INTERVAL)) {
|
||||
mrsas_dprint(sc, MRSAS_OCR, "[%2d]waiting for %d "
|
||||
"commands to complete\n",i,outstanding);
|
||||
mrsas_complete_cmd(sc);
|
||||
count = sc->msix_vectors > 0 ? sc->msix_vectors : 1;
|
||||
for (MSIxIndex = 0 ; MSIxIndex < count; MSIxIndex++)
|
||||
mrsas_complete_cmd(sc, MSIxIndex);
|
||||
}
|
||||
DELAY(1000 * 1000);
|
||||
}
|
||||
|
@ -110,6 +110,7 @@ __FBSDID("$FreeBSD$");
|
||||
#define MRSAS_IO_TIMEOUT 180000 /* 180 second timeout */
|
||||
#define MRSAS_LDIO_QUEUE_DEPTH 70 /* 70 percent as default */
|
||||
#define THRESHOLD_REPLY_COUNT 50
|
||||
#define MAX_MSIX_COUNT 128
|
||||
|
||||
/*
|
||||
Boolean types
|
||||
@ -1959,6 +1960,16 @@ struct mrsas_ctrl_info {
|
||||
#define MRSAS_DEFAULT_CMD_TIMEOUT 90
|
||||
#define MRSAS_THROTTLE_QUEUE_DEPTH 16
|
||||
|
||||
/*
|
||||
* MSI-x regsiters offset defines
|
||||
*/
|
||||
#define MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET (0x0000030C)
|
||||
#define MPI2_REPLY_POST_HOST_INDEX_OFFSET (0x0000006C)
|
||||
#define MR_MAX_REPLY_QUEUES_OFFSET (0x0000001F)
|
||||
#define MR_MAX_REPLY_QUEUES_EXT_OFFSET (0x003FC000)
|
||||
#define MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT 14
|
||||
#define MR_MAX_MSIX_REG_ARRAY 16
|
||||
|
||||
/*
|
||||
* FW reports the maximum of number of commands that it can accept (maximum
|
||||
* commands that can be outstanding) at any time. The driver must report a
|
||||
@ -1968,7 +1979,7 @@ struct mrsas_ctrl_info {
|
||||
*/
|
||||
#define MRSAS_INT_CMDS 32
|
||||
#define MRSAS_SKINNY_INT_CMDS 5
|
||||
#define MRSAS_MAX_MSIX_QUEUES 16
|
||||
#define MRSAS_MAX_MSIX_QUEUES 128
|
||||
|
||||
/*
|
||||
* FW can accept both 32 and 64 bit SGLs. We want to allocate 32/64 bit
|
||||
@ -1993,6 +2004,17 @@ struct mrsas_ctrl_info {
|
||||
#define MFI_1068_FW_HANDSHAKE_OFFSET 0x64
|
||||
#define MFI_1068_FW_READY 0xDDDD0000
|
||||
|
||||
typedef union _MFI_CAPABILITIES {
|
||||
struct {
|
||||
u_int32_t support_fp_remote_lun:1;
|
||||
u_int32_t support_additional_msix:1;
|
||||
u_int32_t support_fastpath_wb:1;
|
||||
u_int32_t support_max_255lds:1;
|
||||
u_int32_t reserved:28;
|
||||
} mfi_capabilities;
|
||||
u_int32_t reg;
|
||||
} MFI_CAPABILITIES;
|
||||
|
||||
#pragma pack(1)
|
||||
struct mrsas_sge32 {
|
||||
u_int32_t phys_addr;
|
||||
@ -2035,18 +2057,6 @@ struct mrsas_header {
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
|
||||
typedef union _MFI_CAPABILITIES {
|
||||
struct {
|
||||
u_int32_t support_fp_remote_lun:1;
|
||||
u_int32_t support_additional_msix:1;
|
||||
u_int32_t support_fastpath_wb:1;
|
||||
u_int32_t support_max_255lds:1;
|
||||
u_int32_t reserved:28;
|
||||
} mfi_capabilities;
|
||||
u_int32_t reg;
|
||||
} MFI_CAPABILITIES;
|
||||
|
||||
#pragma pack(1)
|
||||
struct mrsas_init_frame {
|
||||
u_int8_t cmd; /*00h */
|
||||
@ -2162,8 +2172,7 @@ struct mrsas_abort_frame {
|
||||
u_int8_t cmd_status; /*02h */
|
||||
|
||||
u_int8_t reserved_1; /*03h */
|
||||
u_int32_t reserved_2; /*04h */
|
||||
|
||||
MFI_CAPABILITIES driver_operations; /*04h */
|
||||
u_int32_t context; /*08h */
|
||||
u_int32_t pad_0; /*0Ch */
|
||||
|
||||
@ -2419,6 +2428,11 @@ struct mrsas_evt_detail {
|
||||
|
||||
} __packed;
|
||||
|
||||
struct mrsas_irq_context {
|
||||
struct mrsas_softc *sc;
|
||||
uint32_t MSIxIndex;
|
||||
};
|
||||
|
||||
/* Controller management info added to support Linux Emulator */
|
||||
#define MAX_MGMT_ADAPTERS 1024
|
||||
|
||||
@ -2479,9 +2493,13 @@ struct mrsas_softc {
|
||||
struct mtx aen_lock; // aen lock
|
||||
uint32_t max_fw_cmds; // Max commands from FW
|
||||
uint32_t max_num_sge; // Max number of SGEs
|
||||
struct resource *mrsas_irq; // interrupt interface window
|
||||
void *intr_handle; // handle
|
||||
int irq_id; // intr resource id
|
||||
struct resource *mrsas_irq[MAX_MSIX_COUNT]; // interrupt interface window
|
||||
void *intr_handle[MAX_MSIX_COUNT]; // handle
|
||||
int irq_id[MAX_MSIX_COUNT]; // intr resource id
|
||||
struct mrsas_irq_context irq_context[MAX_MSIX_COUNT];
|
||||
int msix_vectors; // Max msix vectors
|
||||
int msix_enable; // MSI-x support
|
||||
uint32_t msix_reg_offset[16];
|
||||
struct mrsas_mpt_cmd **mpt_cmd_list;
|
||||
struct mrsas_mfi_cmd **mfi_cmd_list;
|
||||
TAILQ_HEAD(, mrsas_mpt_cmd) mrsas_mpt_cmd_list_head;
|
||||
@ -2492,7 +2510,7 @@ struct mrsas_softc {
|
||||
bus_addr_t io_request_frames_phys;
|
||||
u_int8_t *io_request_frames;
|
||||
bus_addr_t reply_frames_desc_phys;
|
||||
u_int16_t last_reply_idx;
|
||||
u_int16_t last_reply_idx[MAX_MSIX_COUNT];
|
||||
u_int32_t reply_q_depth;
|
||||
u_int32_t request_alloc_sz;
|
||||
u_int32_t reply_alloc_sz;
|
||||
|
@ -49,8 +49,14 @@ __FBSDID("$FreeBSD$");
|
||||
#include <cam/scsi/scsi_all.h>
|
||||
#include <cam/scsi/scsi_message.h>
|
||||
#include <sys/taskqueue.h>
|
||||
#include <sys/kernel.h>
|
||||
|
||||
|
||||
#include <sys/time.h> /* XXX for pcpu.h */
|
||||
#include <sys/pcpu.h> /* XXX for PCPU_GET */
|
||||
|
||||
#define smp_processor_id() PCPU_GET(cpuid)
|
||||
|
||||
/*
|
||||
* Function prototypes
|
||||
*/
|
||||
@ -794,7 +800,11 @@ int mrsas_setup_io(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
|
||||
fp_possible = io_info.fpOkForIo;
|
||||
}
|
||||
|
||||
if (fp_possible) {
|
||||
cmd->request_desc->SCSIIO.MSIxIndex =
|
||||
sc->msix_vectors ? smp_processor_id() % sc->msix_vectors : 0;
|
||||
|
||||
|
||||
if (fp_possible) {
|
||||
mrsas_set_pd_lba(io_request, csio->cdb_len, &io_info, ccb, map_ptr,
|
||||
start_lba_lo, ld_block_size);
|
||||
io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
|
||||
@ -881,6 +891,9 @@ int mrsas_build_dcdb(struct mrsas_softc *sc, struct mrsas_mpt_cmd *cmd,
|
||||
MRSAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
|
||||
cmd->request_desc->SCSIIO.DevHandle =
|
||||
map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
|
||||
cmd->request_desc->SCSIIO.MSIxIndex =
|
||||
sc->msix_vectors ? smp_processor_id() % sc->msix_vectors : 0;
|
||||
|
||||
}
|
||||
else {
|
||||
io_request->Function = MRSAS_MPI2_FUNCTION_LD_IO_REQUEST;
|
||||
|
Loading…
Reference in New Issue
Block a user