svn commit: r324764 - stable/10/sys/dev/qlxgbe
David C Somayajulu
davidcs at FreeBSD.org
Thu Oct 19 17:37:35 UTC 2017
Author: davidcs
Date: Thu Oct 19 17:37:33 2017
New Revision: 324764
URL: https://svnweb.freebsd.org/changeset/base/324764
Log:
MFC r324538
Added support driver state capture/retrieval
Modified:
stable/10/sys/dev/qlxgbe/ql_def.h
stable/10/sys/dev/qlxgbe/ql_glbl.h
stable/10/sys/dev/qlxgbe/ql_hw.h
stable/10/sys/dev/qlxgbe/ql_ioctl.c
stable/10/sys/dev/qlxgbe/ql_ioctl.h
stable/10/sys/dev/qlxgbe/ql_os.c
stable/10/sys/dev/qlxgbe/ql_ver.h
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/dev/qlxgbe/ql_def.h
==============================================================================
--- stable/10/sys/dev/qlxgbe/ql_def.h Thu Oct 19 17:35:37 2017 (r324763)
+++ stable/10/sys/dev/qlxgbe/ql_def.h Thu Oct 19 17:37:33 2017 (r324764)
@@ -201,7 +201,6 @@ struct qla_host {
qla_rx_buf_t *rxb_free;
uint32_t rxb_free_count;
- volatile uint32_t posting;
/* stats */
uint32_t err_m_getcl;
Modified: stable/10/sys/dev/qlxgbe/ql_glbl.h
==============================================================================
--- stable/10/sys/dev/qlxgbe/ql_glbl.h Thu Oct 19 17:35:37 2017 (r324763)
+++ stable/10/sys/dev/qlxgbe/ql_glbl.h Thu Oct 19 17:37:33 2017 (r324764)
@@ -112,4 +112,8 @@ extern unsigned int ql83xx_resetseq_len;
extern unsigned char ql83xx_minidump[];
extern unsigned int ql83xx_minidump_len;
+extern void ql_alloc_drvr_state_buffer(qla_host_t *ha);
+extern void ql_free_drvr_state_buffer(qla_host_t *ha);
+extern void ql_capture_drvr_state(qla_host_t *ha);
+
#endif /* #ifndef_QL_GLBL_H_ */
Modified: stable/10/sys/dev/qlxgbe/ql_hw.h
==============================================================================
--- stable/10/sys/dev/qlxgbe/ql_hw.h Thu Oct 19 17:35:37 2017 (r324763)
+++ stable/10/sys/dev/qlxgbe/ql_hw.h Thu Oct 19 17:37:33 2017 (r324764)
@@ -1703,6 +1703,9 @@ typedef struct _qla_hw {
uint32_t mdump_buffer_size;
void *mdump_template;
uint32_t mdump_template_size;
+
+ /* driver state related */
+ void *drvr_state;
} qla_hw_t;
#define QL_UPDATE_RDS_PRODUCER_INDEX(ha, prod_reg, val) \
Modified: stable/10/sys/dev/qlxgbe/ql_ioctl.c
==============================================================================
--- stable/10/sys/dev/qlxgbe/ql_ioctl.c Thu Oct 19 17:35:37 2017 (r324763)
+++ stable/10/sys/dev/qlxgbe/ql_ioctl.c Thu Oct 19 17:37:33 2017 (r324764)
@@ -39,7 +39,11 @@ __FBSDID("$FreeBSD$");
#include "ql_inline.h"
#include "ql_glbl.h"
#include "ql_ioctl.h"
+#include "ql_ver.h"
+#include "ql_dbg.h"
+static int ql_drvr_state(qla_host_t *ha, qla_driver_state_t *drvr_state);
+static uint32_t ql_drvr_state_size(qla_host_t *ha);
static int ql_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
struct thread *td);
@@ -279,6 +283,10 @@ ql_eioctl(struct cdev *dev, u_long cmd, caddr_t data,
rval = ENXIO;
break;
+ case QLA_RD_DRVR_STATE:
+ rval = ql_drvr_state(ha, (qla_driver_state_t *)data);
+ break;
+
case QLA_RD_PCI_IDS:
pci_ids = (qla_rd_pci_ids_t *)data;
pci_ids->ven_id = pci_get_vendor(pci_dev);
@@ -293,5 +301,225 @@ ql_eioctl(struct cdev *dev, u_long cmd, caddr_t data,
}
return rval;
+}
+
+
+static int
+ql_drvr_state(qla_host_t *ha, qla_driver_state_t *state)
+{
+ int rval = 0;
+ uint32_t drvr_state_size;
+ qla_drvr_state_hdr_t *hdr;
+
+ drvr_state_size = ql_drvr_state_size(ha);
+
+ if (state->buffer == NULL) {
+ state->size = drvr_state_size;
+ return (0);
+ }
+
+ if (state->size < drvr_state_size)
+ return (ENXIO);
+
+ if (ha->hw.drvr_state == NULL)
+ return (ENOMEM);
+
+ hdr = ha->hw.drvr_state;
+
+ if (!hdr->drvr_version_major)
+ ql_capture_drvr_state(ha);
+
+ rval = copyout(ha->hw.drvr_state, state->buffer, drvr_state_size);
+
+ bzero(ha->hw.drvr_state, drvr_state_size);
+
+ return (rval);
+}
+
+static uint32_t
+ql_drvr_state_size(qla_host_t *ha)
+{
+ uint32_t drvr_state_size;
+ uint32_t size;
+
+ size = sizeof (qla_drvr_state_hdr_t);
+ drvr_state_size = QL_ALIGN(size, 64);
+
+ size = ha->hw.num_tx_rings * (sizeof (qla_drvr_state_tx_t));
+ drvr_state_size += QL_ALIGN(size, 64);
+
+ size = ha->hw.num_rds_rings * (sizeof (qla_drvr_state_rx_t));
+ drvr_state_size += QL_ALIGN(size, 64);
+
+ size = ha->hw.num_sds_rings * (sizeof (qla_drvr_state_sds_t));
+ drvr_state_size += QL_ALIGN(size, 64);
+
+ size = sizeof(q80_tx_cmd_t) * NUM_TX_DESCRIPTORS * ha->hw.num_tx_rings;
+ drvr_state_size += QL_ALIGN(size, 64);
+
+ size = sizeof(q80_recv_desc_t) * NUM_RX_DESCRIPTORS * ha->hw.num_rds_rings;
+ drvr_state_size += QL_ALIGN(size, 64);
+
+ size = sizeof(q80_stat_desc_t) * NUM_STATUS_DESCRIPTORS *
+ ha->hw.num_sds_rings;
+ drvr_state_size += QL_ALIGN(size, 64);
+
+ return (drvr_state_size);
+}
+
+static void
+ql_get_tx_state(qla_host_t *ha, qla_drvr_state_tx_t *tx_state)
+{
+ int i;
+
+ for (i = 0; i < ha->hw.num_tx_rings; i++) {
+ tx_state->base_p_addr = ha->hw.tx_cntxt[i].tx_ring_paddr;
+ tx_state->cons_p_addr = ha->hw.tx_cntxt[i].tx_cons_paddr;
+ tx_state->tx_prod_reg = ha->hw.tx_cntxt[i].tx_prod_reg;
+ tx_state->tx_cntxt_id = ha->hw.tx_cntxt[i].tx_cntxt_id;
+ tx_state->txr_free = ha->hw.tx_cntxt[i].txr_free;
+ tx_state->txr_next = ha->hw.tx_cntxt[i].txr_next;
+ tx_state->txr_comp = ha->hw.tx_cntxt[i].txr_comp;
+ tx_state++;
+ }
+ return;
+}
+
+static void
+ql_get_rx_state(qla_host_t *ha, qla_drvr_state_rx_t *rx_state)
+{
+ int i;
+
+ for (i = 0; i < ha->hw.num_rds_rings; i++) {
+ rx_state->prod_std = ha->hw.rds[i].prod_std;
+ rx_state->rx_next = ha->hw.rds[i].rx_next;
+ rx_state++;
+ }
+ return;
+}
+
+static void
+ql_get_sds_state(qla_host_t *ha, qla_drvr_state_sds_t *sds_state)
+{
+ int i;
+
+ for (i = 0; i < ha->hw.num_sds_rings; i++) {
+ sds_state->sdsr_next = ha->hw.sds[i].sdsr_next;
+ sds_state->sds_consumer = ha->hw.sds[i].sds_consumer;
+ sds_state++;
+ }
+ return;
+}
+
+void
+ql_capture_drvr_state(qla_host_t *ha)
+{
+ uint8_t *state_buffer;
+ uint8_t *ptr;
+ uint32_t drvr_state_size;
+ qla_drvr_state_hdr_t *hdr;
+ uint32_t size;
+ int i;
+
+ drvr_state_size = ql_drvr_state_size(ha);
+
+ state_buffer = ha->hw.drvr_state;
+
+ if (state_buffer == NULL)
+ return;
+
+ bzero(state_buffer, drvr_state_size);
+
+ hdr = (qla_drvr_state_hdr_t *)state_buffer;
+
+ hdr->drvr_version_major = QLA_VERSION_MAJOR;
+ hdr->drvr_version_minor = QLA_VERSION_MINOR;
+ hdr->drvr_version_build = QLA_VERSION_BUILD;
+
+ bcopy(ha->hw.mac_addr, hdr->mac_addr, ETHER_ADDR_LEN);
+
+ hdr->link_speed = ha->hw.link_speed;
+ hdr->cable_length = ha->hw.cable_length;
+ hdr->cable_oui = ha->hw.cable_oui;
+ hdr->link_up = ha->hw.link_up;
+ hdr->module_type = ha->hw.module_type;
+ hdr->link_faults = ha->hw.link_faults;
+ hdr->rcv_intr_coalesce = ha->hw.rcv_intr_coalesce;
+ hdr->xmt_intr_coalesce = ha->hw.xmt_intr_coalesce;
+
+ size = sizeof (qla_drvr_state_hdr_t);
+ hdr->tx_state_offset = QL_ALIGN(size, 64);
+
+ ptr = state_buffer + hdr->tx_state_offset;
+
+ ql_get_tx_state(ha, (qla_drvr_state_tx_t *)ptr);
+
+ size = ha->hw.num_tx_rings * (sizeof (qla_drvr_state_tx_t));
+ hdr->rx_state_offset = hdr->tx_state_offset + QL_ALIGN(size, 64);
+ ptr = state_buffer + hdr->rx_state_offset;
+
+ ql_get_rx_state(ha, (qla_drvr_state_rx_t *)ptr);
+
+ size = ha->hw.num_rds_rings * (sizeof (qla_drvr_state_rx_t));
+ hdr->sds_state_offset = hdr->rx_state_offset + QL_ALIGN(size, 64);
+ ptr = state_buffer + hdr->sds_state_offset;
+
+ ql_get_sds_state(ha, (qla_drvr_state_sds_t *)ptr);
+
+ size = ha->hw.num_sds_rings * (sizeof (qla_drvr_state_sds_t));
+ hdr->txr_offset = hdr->sds_state_offset + QL_ALIGN(size, 64);
+ ptr = state_buffer + hdr->txr_offset;
+
+ hdr->num_tx_rings = ha->hw.num_tx_rings;
+ hdr->txr_size = sizeof(q80_tx_cmd_t) * NUM_TX_DESCRIPTORS;
+ hdr->txr_entries = NUM_TX_DESCRIPTORS;
+
+ size = hdr->num_tx_rings * hdr->txr_size;
+ bcopy(ha->hw.dma_buf.tx_ring.dma_b, ptr, size);
+
+ hdr->rxr_offset = hdr->txr_offset + QL_ALIGN(size, 64);
+ ptr = state_buffer + hdr->rxr_offset;
+
+ hdr->rxr_size = sizeof(q80_recv_desc_t) * NUM_RX_DESCRIPTORS;
+ hdr->rxr_entries = NUM_RX_DESCRIPTORS;
+ hdr->num_rx_rings = ha->hw.num_rds_rings;
+
+ for (i = 0; i < ha->hw.num_rds_rings; i++) {
+ bcopy(ha->hw.dma_buf.rds_ring[i].dma_b, ptr, hdr->rxr_size);
+ ptr += hdr->rxr_size;
+ }
+
+ size = hdr->rxr_size * hdr->num_rx_rings;
+ hdr->sds_offset = hdr->rxr_offset + QL_ALIGN(size, 64);
+ hdr->sds_ring_size = sizeof(q80_stat_desc_t) * NUM_STATUS_DESCRIPTORS;
+ hdr->sds_entries = NUM_STATUS_DESCRIPTORS;
+ hdr->num_sds_rings = ha->hw.num_sds_rings;
+
+ ptr = state_buffer + hdr->sds_offset;
+ for (i = 0; i < ha->hw.num_sds_rings; i++) {
+ bcopy(ha->hw.dma_buf.sds_ring[i].dma_b, ptr, hdr->sds_ring_size);
+ ptr += hdr->sds_ring_size;
+ }
+ return;
+}
+
+void
+ql_alloc_drvr_state_buffer(qla_host_t *ha)
+{
+ uint32_t drvr_state_size;
+
+ drvr_state_size = ql_drvr_state_size(ha);
+
+ ha->hw.drvr_state = malloc(drvr_state_size, M_QLA83XXBUF, M_NOWAIT);
+
+ return;
+}
+
+void
+ql_free_drvr_state_buffer(qla_host_t *ha)
+{
+ if (ha->hw.drvr_state != NULL)
+ free(ha->hw.drvr_state, M_QLA83XXBUF);
+ return;
}
Modified: stable/10/sys/dev/qlxgbe/ql_ioctl.h
==============================================================================
--- stable/10/sys/dev/qlxgbe/ql_ioctl.h Thu Oct 19 17:35:37 2017 (r324763)
+++ stable/10/sys/dev/qlxgbe/ql_ioctl.h Thu Oct 19 17:37:33 2017 (r324764)
@@ -93,6 +93,72 @@ struct qla_rd_fw_dump {
};
typedef struct qla_rd_fw_dump qla_rd_fw_dump_t;
+struct qla_drvr_state_tx {
+ uint64_t base_p_addr;
+ uint64_t cons_p_addr;
+ uint32_t tx_prod_reg;
+ uint32_t tx_cntxt_id;
+ uint32_t txr_free;
+ uint32_t txr_next;
+ uint32_t txr_comp;
+};
+typedef struct qla_drvr_state_tx qla_drvr_state_tx_t;
+
+struct qla_drvr_state_sds {
+ uint32_t sdsr_next; /* next entry in SDS ring to process */
+ uint32_t sds_consumer;
+};
+typedef struct qla_drvr_state_sds qla_drvr_state_sds_t;
+
+struct qla_drvr_state_rx {
+ uint32_t prod_std;
+ uint32_t rx_next; /* next standard rcv ring to arm fw */;
+};
+typedef struct qla_drvr_state_rx qla_drvr_state_rx_t;
+
+struct qla_drvr_state_hdr {
+ uint32_t drvr_version_major;
+ uint32_t drvr_version_minor;
+ uint32_t drvr_version_build;
+
+ uint8_t mac_addr[ETHER_ADDR_LEN];
+ uint16_t link_speed;
+ uint16_t cable_length;
+ uint32_t cable_oui;
+ uint8_t link_up;
+ uint8_t module_type;
+ uint8_t link_faults;
+ uint32_t rcv_intr_coalesce;
+ uint32_t xmt_intr_coalesce;
+
+ uint32_t tx_state_offset;/* size = sizeof (qla_drvr_state_tx_t) * num_tx_rings */
+ uint32_t rx_state_offset;/* size = sizeof (qla_drvr_state_rx_t) * num_rx_rings */
+ uint32_t sds_state_offset;/* size = sizeof (qla_drvr_state_sds_t) * num_sds_rings */
+
+ uint32_t num_tx_rings; /* number of tx rings */
+ uint32_t txr_size; /* size of each tx ring in bytes */
+ uint32_t txr_entries; /* number of descriptors in each tx ring */
+ uint32_t txr_offset; /* start of tx ring [0 - #rings] content */
+
+ uint32_t num_rx_rings; /* number of rx rings */
+ uint32_t rxr_size; /* size of each rx ring in bytes */
+ uint32_t rxr_entries; /* number of descriptors in each rx ring */
+ uint32_t rxr_offset; /* start of rx ring [0 - #rings] content */
+
+ uint32_t num_sds_rings; /* number of sds rings */
+ uint32_t sds_ring_size; /* size of each sds ring in bytes */
+ uint32_t sds_entries; /* number of descriptors in each sds ring */
+ uint32_t sds_offset; /* start of sds ring [0 - #rings] content */
+};
+
+typedef struct qla_drvr_state_hdr qla_drvr_state_hdr_t;
+
+struct qla_driver_state {
+ uint32_t size;
+ void *buffer;
+};
+typedef struct qla_driver_state qla_driver_state_t;
+
/*
* Read/Write Register
*/
@@ -132,5 +198,11 @@ typedef struct qla_rd_fw_dump qla_rd_fw_dump_t;
* Read Minidump Template
*/
#define QLA_RD_FW_DUMP _IOWR('q', 8, qla_rd_fw_dump_t)
+
+/*
+ * Read Driver State
+ */
+#define QLA_RD_DRVR_STATE _IOWR('q', 9, qla_driver_state_t)
+
#endif /* #ifndef _QL_IOCTL_H_ */
Modified: stable/10/sys/dev/qlxgbe/ql_os.c
==============================================================================
--- stable/10/sys/dev/qlxgbe/ql_os.c Thu Oct 19 17:35:37 2017 (r324763)
+++ stable/10/sys/dev/qlxgbe/ql_os.c Thu Oct 19 17:37:33 2017 (r324764)
@@ -492,6 +492,7 @@ qla_pci_attach(device_t dev)
device_printf(dev, "%s: ql_minidump_init failed\n", __func__);
goto qla_pci_attach_err;
}
+ ql_alloc_drvr_state_buffer(ha);
/* create the o.s ethernet interface */
qla_init_ifnet(dev, ha);
@@ -645,6 +646,7 @@ qla_release(qla_host_t *ha)
if (ha->ifp != NULL)
ether_ifdetach(ha->ifp);
+ ql_free_drvr_state_buffer(ha);
ql_free_dma(ha);
qla_free_parent_dma_tag(ha);
Modified: stable/10/sys/dev/qlxgbe/ql_ver.h
==============================================================================
--- stable/10/sys/dev/qlxgbe/ql_ver.h Thu Oct 19 17:35:37 2017 (r324763)
+++ stable/10/sys/dev/qlxgbe/ql_ver.h Thu Oct 19 17:37:33 2017 (r324764)
@@ -36,6 +36,6 @@
#define QLA_VERSION_MAJOR 3
#define QLA_VERSION_MINOR 10
-#define QLA_VERSION_BUILD 34
+#define QLA_VERSION_BUILD 35
#endif /* #ifndef _QL_VER_H_ */
More information about the svn-src-all
mailing list