Upgrade FW to 5.4.66
sysctls to display stats, stats polled every 2 seconds Modify QLA_LOCK()/QLA_UNLOCK() to not sleep after acquiring mtx_lock Add support to turn OFF/ON error recovery following heartbeat failure for debug purposes. Set default max values to 32 Tx/Rx/SDS rings MFC after:5 days
This commit is contained in:
parent
5b8ad1c5d4
commit
3920ce9668
@ -61,14 +61,17 @@ following OS platforms:
|
||||
- kldunload if_qlxgbe
|
||||
|
||||
5. Parameters to set prior to installing the driver
|
||||
Please run "sysctl kern.ipc" and "sysctl net.inet.tcp" and see if these
|
||||
values are already greater than shown below. Change only those which
|
||||
are less than shown below.
|
||||
|
||||
- Add the following lines to /etc/sysctl.conf and reboot the machine prior
|
||||
to installing the driver
|
||||
|
||||
kern.ipc.nmbjumbo9=262144
|
||||
kern.ipc.nmbjumbo9=2000000
|
||||
kern.ipc.nmbclusters=1000000
|
||||
net.inet.tcp.recvbuf_max=262144
|
||||
net.inet.tcp.recvbuf_inc=16384
|
||||
kern.ipc.nmbclusters=1000000
|
||||
kern.ipc.maxsockbuf=2097152
|
||||
net.inet.tcp.recvspace=131072
|
||||
net.inet.tcp.sendbuf_max=262144
|
||||
@ -78,10 +81,10 @@ following OS platforms:
|
||||
|
||||
login or su to root
|
||||
|
||||
sysctl kern.ipc.nmbjumbo9=262144
|
||||
sysctl kern.ipc.nmbjumbo9=2000000
|
||||
sysctl kern.ipc.nmbclusters=1000000
|
||||
sysctl net.inet.tcp.recvbuf_max=262144
|
||||
sysctl net.inet.tcp.recvbuf_inc=16384
|
||||
sysctl kern.ipc.nmbclusters=1000000
|
||||
sysctl kern.ipc.maxsockbuf=2097152
|
||||
sysctl net.inet.tcp.recvspace=131072
|
||||
sysctl net.inet.tcp.sendbuf_max=262144
|
||||
|
@ -35,7 +35,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
unsigned int ql83xx_bootloader_version_major = 5;
|
||||
unsigned int ql83xx_bootloader_version_minor = 4;
|
||||
unsigned int ql83xx_bootloader_version_sub = 64;
|
||||
unsigned int ql83xx_bootloader_version_sub = 66;
|
||||
unsigned char ql83xx_bootloader[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
@ -10957,9 +10957,8 @@ unsigned char ql83xx_bootloader[] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x02, 0x00, 0x40, 0x40, 0x05, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x40, 0x40, 0x05, 0x04, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xe0, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x9b, 0x64, 0x95, 0x0e
|
||||
0x00, 0x00, 0x00, 0x00, 0x9b, 0x64, 0x93, 0x0e
|
||||
};
|
||||
unsigned int ql83xx_bootloader_len = 131072;
|
||||
|
||||
|
@ -110,6 +110,7 @@ typedef struct qla_ivec qla_ivec_t;
|
||||
typedef struct _qla_tx_ring {
|
||||
qla_tx_buf_t tx_buf[NUM_TX_DESCRIPTORS];
|
||||
uint64_t count;
|
||||
uint64_t iscsi_pkt_count;
|
||||
} qla_tx_ring_t;
|
||||
|
||||
typedef struct _qla_tx_fp {
|
||||
@ -123,25 +124,26 @@ typedef struct _qla_tx_fp {
|
||||
} qla_tx_fp_t;
|
||||
|
||||
/*
|
||||
* Adapter structure contains the hardware independent information of the
|
||||
* Adapter structure contains the hardware independant information of the
|
||||
* pci function.
|
||||
*/
|
||||
struct qla_host {
|
||||
volatile struct {
|
||||
volatile uint32_t
|
||||
qla_interface_up :1,
|
||||
qla_callout_init :1,
|
||||
qla_watchdog_active :1,
|
||||
qla_watchdog_exit :1,
|
||||
qla_watchdog_pause :1,
|
||||
stop_rcv :1,
|
||||
parent_tag :1,
|
||||
lock_init :1;
|
||||
} flags;
|
||||
|
||||
volatile uint32_t qla_interface_up;
|
||||
volatile uint32_t stop_rcv;
|
||||
volatile uint32_t qla_watchdog_exit;
|
||||
volatile uint32_t qla_watchdog_exited;
|
||||
volatile uint32_t qla_watchdog_pause;
|
||||
volatile uint32_t qla_watchdog_paused;
|
||||
volatile uint32_t qla_initiate_recovery;
|
||||
volatile uint32_t qla_detach_active;
|
||||
|
||||
device_t pci_dev;
|
||||
|
||||
@ -182,6 +184,7 @@ struct qla_host {
|
||||
|
||||
struct mtx hw_lock;
|
||||
volatile uint32_t hw_lock_held;
|
||||
uint64_t hw_lock_failed;
|
||||
|
||||
/* transmit and receive buffers */
|
||||
uint32_t txr_idx; /* index of the current tx ring */
|
||||
@ -221,6 +224,9 @@ struct qla_host {
|
||||
uint64_t tx_tso_frames;
|
||||
uint64_t hw_vlan_tx_frames;
|
||||
|
||||
struct task stats_task;
|
||||
struct taskqueue *stats_tq;
|
||||
|
||||
uint32_t fw_ver_major;
|
||||
uint32_t fw_ver_minor;
|
||||
uint32_t fw_ver_sub;
|
||||
@ -260,9 +266,7 @@ typedef struct qla_host qla_host_t;
|
||||
#define QL_ALIGN(size, align) (size + (align - 1)) & ~(align - 1);
|
||||
#define QL_MIN(x, y) ((x < y) ? x : y)
|
||||
|
||||
#define QL_RUNNING(ifp) \
|
||||
((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) == \
|
||||
IFF_DRV_RUNNING)
|
||||
#define QL_RUNNING(ifp) (ifp->if_drv_flags & IFF_DRV_RUNNING)
|
||||
|
||||
/* Return 0, if identical, else 1 */
|
||||
#define QL_MAC_CMP(mac1, mac2) \
|
||||
|
297260
sys/dev/qlxgbe/ql_fw.c
297260
sys/dev/qlxgbe/ql_fw.c
File diff suppressed because it is too large
Load Diff
@ -69,7 +69,6 @@ extern void qla_reset_allmulti(qla_host_t *ha);
|
||||
extern void ql_update_link_state(qla_host_t *ha);
|
||||
extern void ql_hw_tx_done_locked(qla_host_t *ha, uint32_t txr_idx);
|
||||
extern int ql_set_max_mtu(qla_host_t *ha, uint32_t mtu, uint16_t cntxt_id);
|
||||
extern void ql_hw_stop_rcv(qla_host_t *ha);
|
||||
extern void ql_get_stats(qla_host_t *ha);
|
||||
extern void ql_hw_link_status(qla_host_t *ha);
|
||||
extern int ql_hw_check_health(qla_host_t *ha);
|
||||
@ -78,7 +77,6 @@ extern int qla_get_nic_partition(qla_host_t *ha, uint32_t *supports_9kb,
|
||||
uint32_t *num_rcvq);
|
||||
|
||||
extern int ql_iscsi_pdu(qla_host_t *ha, struct mbuf *mp);
|
||||
|
||||
extern void ql_minidump(qla_host_t *ha);
|
||||
extern int ql_minidump_init(qla_host_t *ha);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1217,7 +1217,7 @@ typedef struct _q80_tx_cmd {
|
||||
#define MAX_SDS_RINGS 32 /* Max# of Status Descriptor Rings */
|
||||
#define NUM_TX_RINGS (MAX_SDS_RINGS * 2)
|
||||
#else
|
||||
#define MAX_SDS_RINGS 4 /* Max# of Status Descriptor Rings */
|
||||
#define MAX_SDS_RINGS 32 /* Max# of Status Descriptor Rings */
|
||||
#define NUM_TX_RINGS MAX_SDS_RINGS
|
||||
#endif /* #ifdef QL_ENABLE_ISCSI_TLV */
|
||||
#define MAX_RDS_RINGS MAX_SDS_RINGS /* Max# of Rcv Descriptor Rings */
|
||||
@ -1557,7 +1557,9 @@ typedef struct _qla_rdesc {
|
||||
volatile uint32_t prod_jumbo;
|
||||
volatile uint32_t rx_next; /* next standard rcv ring to arm fw */
|
||||
volatile int32_t rx_in; /* next standard rcv ring to add mbufs */
|
||||
volatile uint64_t count;
|
||||
uint64_t count;
|
||||
uint64_t lro_pkt_count;
|
||||
uint64_t lro_bytes;
|
||||
} qla_rdesc_t;
|
||||
|
||||
typedef struct _qla_flash_desc_table {
|
||||
@ -1682,11 +1684,15 @@ typedef struct _qla_hw {
|
||||
|
||||
uint32_t user_pri_nic;
|
||||
uint32_t user_pri_iscsi;
|
||||
uint64_t iscsi_pkt_count;
|
||||
|
||||
/* Flash Descriptor Table */
|
||||
qla_flash_desc_table_t fdt;
|
||||
|
||||
/* stats */
|
||||
q80_mac_stats_t mac;
|
||||
q80_rcv_stats_t rcv;
|
||||
q80_xmt_stats_t xmt[NUM_TX_RINGS];
|
||||
|
||||
/* Minidump Related */
|
||||
uint32_t mdump_init;
|
||||
uint32_t mdump_done;
|
||||
|
@ -151,13 +151,26 @@ qla_init_hw_rcv_descriptors(qla_host_t *ha)
|
||||
(sizeof(q80_recv_desc_t) * NUM_RX_DESCRIPTORS));
|
||||
}
|
||||
|
||||
#define QLA_LOCK_DEFAULT_MS_TIMEOUT 3000
|
||||
|
||||
#ifndef QLA_LOCK_NO_SLEEP
|
||||
#define QLA_LOCK_NO_SLEEP 0
|
||||
#endif
|
||||
|
||||
static __inline int
|
||||
qla_lock(qla_host_t *ha, const char *str, uint32_t no_delay)
|
||||
qla_lock(qla_host_t *ha, const char *str, uint32_t timeout_ms,
|
||||
uint32_t no_sleep)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
while (1) {
|
||||
mtx_lock(&ha->hw_lock);
|
||||
|
||||
if (ha->qla_detach_active) {
|
||||
mtx_unlock(&ha->hw_lock);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ha->hw_lock_held) {
|
||||
ha->hw_lock_held = 1;
|
||||
ha->qla_lock = str;
|
||||
@ -167,11 +180,18 @@ qla_lock(qla_host_t *ha, const char *str, uint32_t no_delay)
|
||||
}
|
||||
mtx_unlock(&ha->hw_lock);
|
||||
|
||||
if (no_delay)
|
||||
if (--timeout_ms == 0) {
|
||||
ha->hw_lock_failed++;
|
||||
break;
|
||||
else
|
||||
qla_mdelay(__func__, 1);
|
||||
} else {
|
||||
if (no_sleep)
|
||||
DELAY(1000);
|
||||
else
|
||||
qla_mdelay(__func__, 1);
|
||||
}
|
||||
}
|
||||
|
||||
//device_printf(ha->pci_dev, "%s: %s ret = %d\n", __func__, str,ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -182,6 +202,9 @@ qla_unlock(qla_host_t *ha, const char *str)
|
||||
ha->hw_lock_held = 0;
|
||||
ha->qla_unlock = str;
|
||||
mtx_unlock(&ha->hw_lock);
|
||||
//device_printf(ha->pci_dev, "%s: %s\n", __func__, str);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* #ifndef _QL_INLINE_H_ */
|
||||
|
@ -143,7 +143,7 @@ ql_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
|
||||
break;
|
||||
}
|
||||
|
||||
if (ifp->if_drv_flags & (IFF_DRV_OACTIVE | IFF_DRV_RUNNING)) {
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
|
||||
rval = ENXIO;
|
||||
break;
|
||||
}
|
||||
@ -170,7 +170,7 @@ ql_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
|
||||
break;
|
||||
}
|
||||
|
||||
if (ifp->if_drv_flags & (IFF_DRV_OACTIVE | IFF_DRV_RUNNING)) {
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
|
||||
rval = ENXIO;
|
||||
break;
|
||||
}
|
||||
@ -233,10 +233,14 @@ ql_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
|
||||
break;
|
||||
}
|
||||
|
||||
QLA_LOCK(ha);
|
||||
if (!ha->hw.mdump_done)
|
||||
ha->qla_initiate_recovery = 1;
|
||||
QLA_UNLOCK(ha);
|
||||
if (QLA_LOCK(ha, __func__, QLA_LOCK_DEFAULT_MS_TIMEOUT, 0) == 0) {
|
||||
if (!ha->hw.mdump_done)
|
||||
ha->qla_initiate_recovery = 1;
|
||||
QLA_UNLOCK(ha, __func__);
|
||||
} else {
|
||||
rval = ENXIO;
|
||||
break;
|
||||
}
|
||||
|
||||
#define QLNX_DUMP_WAIT_SECS 30
|
||||
|
||||
@ -254,9 +258,13 @@ ql_eioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
|
||||
break;
|
||||
}
|
||||
|
||||
QLA_LOCK(ha);
|
||||
ha->hw.mdump_done = 0;
|
||||
QLA_UNLOCK(ha);
|
||||
if (QLA_LOCK(ha, __func__, QLA_LOCK_DEFAULT_MS_TIMEOUT, 0) == 0) {
|
||||
ha->hw.mdump_done = 0;
|
||||
QLA_UNLOCK(ha, __func__);
|
||||
} else {
|
||||
rval = ENXIO;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((rval = copyout(ha->hw.mdump_template,
|
||||
fw_dump->minidump, ha->hw.mdump_template_size))) {
|
||||
|
@ -48,7 +48,7 @@ static void qla_replenish_normal_rx(qla_host_t *ha, qla_sds_t *sdsp,
|
||||
static void
|
||||
qla_rcv_error(qla_host_t *ha)
|
||||
{
|
||||
ha->flags.stop_rcv = 1;
|
||||
ha->stop_rcv = 1;
|
||||
ha->qla_initiate_recovery = 1;
|
||||
}
|
||||
|
||||
@ -166,7 +166,11 @@ qla_rx_intr(qla_host_t *ha, qla_sgl_rcv_t *sgc, uint32_t sds_idx)
|
||||
#if __FreeBSD_version >= 1100000
|
||||
M_HASHTYPE_SET(mpf, M_HASHTYPE_OPAQUE_HASH);
|
||||
#else
|
||||
M_HASHTYPE_SET(mpf, M_HASHTYPE_NONE);
|
||||
#if (__FreeBSD_version >= 903511 && __FreeBSD_version < 1100000)
|
||||
M_HASHTYPE_SET(mpf, M_HASHTYPE_OPAQUE);
|
||||
#else
|
||||
M_HASHTYPE_SET(mpf, M_HASHTYPE_NONE);
|
||||
#endif
|
||||
#endif /* #if __FreeBSD_version >= 1100000 */
|
||||
|
||||
if (ha->hw.enable_soft_lro) {
|
||||
@ -222,7 +226,7 @@ qla_lro_intr(qla_host_t *ha, qla_sgl_lro_t *sgc, uint32_t sds_idx)
|
||||
|
||||
rx_ring = &ha->rx_ring[r_idx];
|
||||
|
||||
ha->lro_pkt_count++;
|
||||
ha->hw.rds[r_idx].lro_pkt_count++;
|
||||
|
||||
sdsp = &ha->hw.sds[sds_idx];
|
||||
|
||||
@ -233,7 +237,7 @@ qla_lro_intr(qla_host_t *ha, qla_sgl_lro_t *sgc, uint32_t sds_idx)
|
||||
} else {
|
||||
pkt_length += QLA_TCP_HDR_SIZE;
|
||||
}
|
||||
ha->lro_bytes += pkt_length;
|
||||
ha->hw.rds[r_idx].lro_bytes += pkt_length;
|
||||
|
||||
for (i = 0; i < sgc->num_handles; i++) {
|
||||
rxb = &rx_ring->rx_buf[sgc->handle[i] & 0x7FFF];
|
||||
@ -493,7 +497,7 @@ ql_rcv_isr(qla_host_t *ha, uint32_t sds_idx, uint32_t count)
|
||||
hw = &ha->hw;
|
||||
|
||||
hw->sds[sds_idx].rcv_active = 1;
|
||||
if (ha->flags.stop_rcv) {
|
||||
if (ha->stop_rcv) {
|
||||
hw->sds[sds_idx].rcv_active = 0;
|
||||
return 0;
|
||||
}
|
||||
@ -505,7 +509,7 @@ ql_rcv_isr(qla_host_t *ha, uint32_t sds_idx, uint32_t count)
|
||||
*/
|
||||
comp_idx = hw->sds[sds_idx].sdsr_next;
|
||||
|
||||
while (count-- && !ha->flags.stop_rcv) {
|
||||
while (count-- && !ha->stop_rcv) {
|
||||
|
||||
sdesc = (q80_stat_desc_t *)
|
||||
&hw->sds[sds_idx].sds_ring_base[comp_idx];
|
||||
@ -515,7 +519,6 @@ ql_rcv_isr(qla_host_t *ha, uint32_t sds_idx, uint32_t count)
|
||||
if (!opcode)
|
||||
break;
|
||||
|
||||
hw->sds[sds_idx].intr_count++;
|
||||
switch (opcode) {
|
||||
|
||||
case Q8_STAT_DESC_OPCODE_RCV_PKT:
|
||||
@ -747,15 +750,13 @@ ql_rcv_isr(qla_host_t *ha, uint32_t sds_idx, uint32_t count)
|
||||
|
||||
}
|
||||
|
||||
if (ha->flags.stop_rcv)
|
||||
if (ha->stop_rcv)
|
||||
goto ql_rcv_isr_exit;
|
||||
|
||||
if (hw->sds[sds_idx].sdsr_next != comp_idx) {
|
||||
QL_UPDATE_SDS_CONSUMER_INDEX(ha, sds_idx, comp_idx);
|
||||
hw->sds[sds_idx].sdsr_next = comp_idx;
|
||||
} else {
|
||||
hw->sds[sds_idx].spurious_intr_count++;
|
||||
|
||||
if (ha->hw.num_rds_rings > 1)
|
||||
r_idx = sds_idx;
|
||||
|
||||
@ -984,8 +985,8 @@ ql_isr(void *arg)
|
||||
if ((idx = ivec->sds_idx) >= ha->hw.num_sds_rings)
|
||||
return;
|
||||
|
||||
|
||||
fp = &ha->tx_fp[idx];
|
||||
hw->sds[idx].intr_count++;
|
||||
|
||||
if ((fp->fp_taskqueue != NULL) &&
|
||||
(ifp->if_drv_flags & IFF_DRV_RUNNING))
|
||||
|
@ -36,7 +36,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
unsigned int ql83xx_minidump_version_major = 5;
|
||||
unsigned int ql83xx_minidump_version_minor = 4;
|
||||
unsigned int ql83xx_minidump_version_sub = 64;
|
||||
unsigned int ql83xx_minidump_version_sub = 66;
|
||||
|
||||
unsigned char ql83xx_minidump[] = {
|
||||
0x63, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00,
|
||||
@ -10959,8 +10959,8 @@ unsigned char ql83xx_minidump[] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x05, 0x00, 0x40, 0x40, 0x05, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x05, 0x00, 0x40, 0x40, 0x05, 0x04, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xe0, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x34, 0x39, 0x7e, 0xbf
|
||||
0x00, 0x00, 0x00, 0x00, 0x34, 0x39, 0x7c, 0xbf
|
||||
};
|
||||
unsigned int ql83xx_minidump_len = 131072;
|
||||
|
@ -70,7 +70,6 @@ static void qla_free_rcv_bufs(qla_host_t *ha);
|
||||
static void qla_clear_tx_buf(qla_host_t *ha, qla_tx_buf_t *txb);
|
||||
|
||||
static void qla_init_ifnet(device_t dev, qla_host_t *ha);
|
||||
static int qla_sysctl_get_stats(SYSCTL_HANDLER_ARGS);
|
||||
static int qla_sysctl_get_link_status(SYSCTL_HANDLER_ARGS);
|
||||
static void qla_release(qla_host_t *ha);
|
||||
static void qla_dmamap_callback(void *arg, bus_dma_segment_t *segs, int nsegs,
|
||||
@ -79,6 +78,7 @@ static void qla_stop(qla_host_t *ha);
|
||||
static void qla_get_peer(qla_host_t *ha);
|
||||
static void qla_error_recovery(void *context, int pending);
|
||||
static void qla_async_event(void *context, int pending);
|
||||
static void qla_stats(void *context, int pending);
|
||||
static int qla_send(qla_host_t *ha, struct mbuf **m_headp, uint32_t txr_idx,
|
||||
uint32_t iscsi_pdu);
|
||||
|
||||
@ -168,12 +168,6 @@ qla_add_sysctls(qla_host_t *ha)
|
||||
OID_AUTO, "version", CTLFLAG_RD,
|
||||
ver_str, 0, "Driver Version");
|
||||
|
||||
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
|
||||
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
|
||||
OID_AUTO, "stats", CTLTYPE_INT | CTLFLAG_RW,
|
||||
(void *)ha, 0,
|
||||
qla_sysctl_get_stats, "I", "Statistics");
|
||||
|
||||
SYSCTL_ADD_STRING(device_get_sysctl_ctx(dev),
|
||||
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
|
||||
OID_AUTO, "fw_version", CTLFLAG_RD,
|
||||
@ -222,6 +216,12 @@ qla_add_sysctls(qla_host_t *ha)
|
||||
CTLFLAG_RD, &ha->hw_vlan_tx_frames,
|
||||
"number of Tx VLAN Frames");
|
||||
|
||||
SYSCTL_ADD_QUAD(device_get_sysctl_ctx(dev),
|
||||
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
|
||||
OID_AUTO, "hw_lock_failed",
|
||||
CTLFLAG_RD, &ha->hw_lock_failed,
|
||||
"number of hw_lock failures");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -231,43 +231,58 @@ qla_watchdog(void *arg)
|
||||
qla_host_t *ha = arg;
|
||||
qla_hw_t *hw;
|
||||
struct ifnet *ifp;
|
||||
uint32_t i;
|
||||
|
||||
hw = &ha->hw;
|
||||
ifp = ha->ifp;
|
||||
|
||||
if (ha->flags.qla_watchdog_exit) {
|
||||
if (ha->qla_watchdog_exit) {
|
||||
ha->qla_watchdog_exited = 1;
|
||||
return;
|
||||
}
|
||||
ha->qla_watchdog_exited = 0;
|
||||
|
||||
if (!ha->flags.qla_watchdog_pause) {
|
||||
if (!ha->qla_watchdog_pause) {
|
||||
if (ql_hw_check_health(ha) || ha->qla_initiate_recovery ||
|
||||
(ha->msg_from_peer == QL_PEER_MSG_RESET)) {
|
||||
ha->qla_watchdog_paused = 1;
|
||||
ha->flags.qla_watchdog_pause = 1;
|
||||
ha->qla_initiate_recovery = 0;
|
||||
ha->err_inject = 0;
|
||||
device_printf(ha->pci_dev,
|
||||
"%s: taskqueue_enqueue(err_task) \n", __func__);
|
||||
taskqueue_enqueue(ha->err_tq, &ha->err_task);
|
||||
} else if (ha->flags.qla_interface_up) {
|
||||
|
||||
if (!(ha->dbg_level & 0x8000)) {
|
||||
ha->qla_watchdog_paused = 1;
|
||||
ha->qla_watchdog_pause = 1;
|
||||
ha->qla_initiate_recovery = 0;
|
||||
ha->err_inject = 0;
|
||||
device_printf(ha->pci_dev,
|
||||
"%s: taskqueue_enqueue(err_task) \n",
|
||||
__func__);
|
||||
taskqueue_enqueue(ha->err_tq, &ha->err_task);
|
||||
return;
|
||||
}
|
||||
|
||||
} else if (ha->qla_interface_up) {
|
||||
|
||||
ha->watchdog_ticks++;
|
||||
|
||||
if (ha->watchdog_ticks > 1000)
|
||||
ha->watchdog_ticks = 0;
|
||||
|
||||
if (!ha->watchdog_ticks && QL_RUNNING(ifp)) {
|
||||
taskqueue_enqueue(ha->stats_tq, &ha->stats_task);
|
||||
}
|
||||
|
||||
if (ha->async_event) {
|
||||
ha->async_event = 0;
|
||||
taskqueue_enqueue(ha->async_event_tq,
|
||||
&ha->async_event_task);
|
||||
}
|
||||
|
||||
for (i = 0; i < ha->hw.num_sds_rings; i++) {
|
||||
#if 0
|
||||
for (i = 0; ((i < ha->hw.num_sds_rings) &&
|
||||
!ha->watchdog_ticks); i++) {
|
||||
qla_tx_fp_t *fp = &ha->tx_fp[i];
|
||||
|
||||
if (fp->fp_taskqueue != NULL)
|
||||
taskqueue_enqueue(fp->fp_taskqueue,
|
||||
&fp->fp_task);
|
||||
}
|
||||
|
||||
#endif
|
||||
ha->qla_watchdog_paused = 0;
|
||||
} else {
|
||||
ha->qla_watchdog_paused = 0;
|
||||
@ -276,7 +291,6 @@ qla_watchdog(void *arg)
|
||||
ha->qla_watchdog_paused = 1;
|
||||
}
|
||||
|
||||
ha->watchdog_ticks = ha->watchdog_ticks++ % 500;
|
||||
callout_reset(&ha->tx_callout, QLA_WATCHDOG_CALLOUT_TICKS,
|
||||
qla_watchdog, ha);
|
||||
}
|
||||
@ -324,11 +338,13 @@ qla_pci_attach(device_t dev)
|
||||
ha->reg_rid);
|
||||
|
||||
mtx_init(&ha->hw_lock, "qla83xx_hw_lock", MTX_NETWORK_LOCK, MTX_DEF);
|
||||
ha->flags.lock_init = 1;
|
||||
|
||||
qla_add_sysctls(ha);
|
||||
ql_hw_add_sysctls(ha);
|
||||
|
||||
ha->flags.lock_init = 1;
|
||||
ha->hw.num_sds_rings = MAX_SDS_RINGS;
|
||||
ha->hw.num_rds_rings = MAX_RDS_RINGS;
|
||||
ha->hw.num_tx_rings = NUM_TX_RINGS;
|
||||
|
||||
ha->reg_rid1 = PCIR_BAR(2);
|
||||
ha->pci_reg1 = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
|
||||
@ -336,12 +352,16 @@ qla_pci_attach(device_t dev)
|
||||
|
||||
ha->msix_count = pci_msix_count(dev);
|
||||
|
||||
if (ha->msix_count < (ha->hw.num_sds_rings + 1)) {
|
||||
if (ha->msix_count < 1 ) {
|
||||
device_printf(dev, "%s: msix_count[%d] not enough\n", __func__,
|
||||
ha->msix_count);
|
||||
goto qla_pci_attach_err;
|
||||
}
|
||||
|
||||
if (ha->msix_count < (ha->hw.num_sds_rings + 1)) {
|
||||
ha->hw.num_sds_rings = ha->msix_count - 1;
|
||||
}
|
||||
|
||||
QL_DPRINT2(ha, (dev, "%s: ha %p pci_func 0x%x rsrc_count 0x%08x"
|
||||
" msix_count 0x%x pci_reg %p pci_reg1 %p\n", __func__, ha,
|
||||
ha->pci_func, rsrc_len, ha->msix_count, ha->pci_reg,
|
||||
@ -370,14 +390,20 @@ qla_pci_attach(device_t dev)
|
||||
__func__, ha, ha->pci_func, rsrc_len, ha->msix_count,
|
||||
ha->pci_reg, ha->pci_reg1, num_rcvq);
|
||||
|
||||
if ((ha->msix_count < 64) || (num_rcvq != 32)) {
|
||||
if (ha->hw.num_sds_rings > 15) {
|
||||
ha->hw.num_sds_rings = 15;
|
||||
}
|
||||
}
|
||||
|
||||
ha->hw.num_rds_rings = ha->hw.num_sds_rings;
|
||||
ha->hw.num_tx_rings = ha->hw.num_sds_rings;
|
||||
|
||||
#ifdef QL_ENABLE_ISCSI_TLV
|
||||
if ((ha->msix_count < 64) || (num_rcvq != 32)) {
|
||||
ha->hw.num_sds_rings = 15;
|
||||
ha->hw.num_tx_rings = ha->hw.num_sds_rings * 2;
|
||||
}
|
||||
ha->hw.num_tx_rings = ha->hw.num_sds_rings * 2;
|
||||
#endif /* #ifdef QL_ENABLE_ISCSI_TLV */
|
||||
ha->hw.num_rds_rings = ha->hw.num_sds_rings;
|
||||
|
||||
ql_hw_add_sysctls(ha);
|
||||
|
||||
ha->msix_count = ha->hw.num_sds_rings + 1;
|
||||
|
||||
@ -463,7 +489,7 @@ qla_pci_attach(device_t dev)
|
||||
qla_init_ifnet(dev, ha);
|
||||
|
||||
ha->flags.qla_watchdog_active = 1;
|
||||
ha->flags.qla_watchdog_pause = 0;
|
||||
ha->qla_watchdog_pause = 0;
|
||||
|
||||
callout_init(&ha->tx_callout, TRUE);
|
||||
ha->flags.qla_callout_init = 1;
|
||||
@ -489,6 +515,12 @@ qla_pci_attach(device_t dev)
|
||||
taskqueue_start_threads(&ha->async_event_tq, 1, PI_NET, "%s asyncq",
|
||||
device_get_nameunit(ha->pci_dev));
|
||||
|
||||
TASK_INIT(&ha->stats_task, 0, qla_stats, ha);
|
||||
ha->stats_tq = taskqueue_create("qla_statsq", M_NOWAIT,
|
||||
taskqueue_thread_enqueue, &ha->stats_tq);
|
||||
taskqueue_start_threads(&ha->stats_tq, 1, PI_NET, "%s taskq",
|
||||
device_get_nameunit(ha->pci_dev));
|
||||
|
||||
QL_DPRINT2(ha, (dev, "%s: exit 0\n", __func__));
|
||||
return (0);
|
||||
|
||||
@ -496,6 +528,10 @@ qla_pci_attach(device_t dev)
|
||||
|
||||
qla_release(ha);
|
||||
|
||||
if (ha->flags.lock_init) {
|
||||
mtx_destroy(&ha->hw_lock);
|
||||
}
|
||||
|
||||
QL_DPRINT2(ha, (dev, "%s: exit ENXIO\n", __func__));
|
||||
return (ENXIO);
|
||||
}
|
||||
@ -510,21 +546,30 @@ qla_pci_detach(device_t dev)
|
||||
qla_host_t *ha = NULL;
|
||||
struct ifnet *ifp;
|
||||
|
||||
QL_DPRINT2(ha, (dev, "%s: enter\n", __func__));
|
||||
|
||||
if ((ha = device_get_softc(dev)) == NULL) {
|
||||
device_printf(dev, "cannot get softc\n");
|
||||
return (ENOMEM);
|
||||
}
|
||||
|
||||
QL_DPRINT2(ha, (dev, "%s: enter\n", __func__));
|
||||
|
||||
ifp = ha->ifp;
|
||||
|
||||
QLA_LOCK(ha);
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
QLA_LOCK(ha, __func__, -1, 0);
|
||||
|
||||
ha->qla_detach_active = 1;
|
||||
qla_stop(ha);
|
||||
QLA_UNLOCK(ha);
|
||||
|
||||
qla_release(ha);
|
||||
|
||||
QLA_UNLOCK(ha, __func__);
|
||||
|
||||
if (ha->flags.lock_init) {
|
||||
mtx_destroy(&ha->hw_lock);
|
||||
}
|
||||
|
||||
QL_DPRINT2(ha, (dev, "%s: exit\n", __func__));
|
||||
|
||||
return (0);
|
||||
@ -534,23 +579,6 @@ qla_pci_detach(device_t dev)
|
||||
* SYSCTL Related Callbacks
|
||||
*/
|
||||
static int
|
||||
qla_sysctl_get_stats(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
int err, ret = 0;
|
||||
qla_host_t *ha;
|
||||
|
||||
err = sysctl_handle_int(oidp, &ret, 0, req);
|
||||
|
||||
if (err || !req->newptr)
|
||||
return (err);
|
||||
|
||||
if (ret == 1) {
|
||||
ha = (qla_host_t *)arg1;
|
||||
ql_get_stats(ha);
|
||||
}
|
||||
return (err);
|
||||
}
|
||||
static int
|
||||
qla_sysctl_get_link_status(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
int err, ret = 0;
|
||||
@ -590,10 +618,15 @@ qla_release(qla_host_t *ha)
|
||||
taskqueue_free(ha->err_tq);
|
||||
}
|
||||
|
||||
if (ha->stats_tq) {
|
||||
taskqueue_drain(ha->stats_tq, &ha->stats_task);
|
||||
taskqueue_free(ha->stats_tq);
|
||||
}
|
||||
|
||||
ql_del_cdev(ha);
|
||||
|
||||
if (ha->flags.qla_watchdog_active) {
|
||||
ha->flags.qla_watchdog_exit = 1;
|
||||
ha->qla_watchdog_exit = 1;
|
||||
|
||||
while (ha->qla_watchdog_exited == 0)
|
||||
qla_mdelay(__func__, 1);
|
||||
@ -635,9 +668,9 @@ qla_release(qla_host_t *ha)
|
||||
if (ha->msix_count)
|
||||
pci_release_msi(dev);
|
||||
|
||||
if (ha->flags.lock_init) {
|
||||
mtx_destroy(&ha->hw_lock);
|
||||
}
|
||||
// if (ha->flags.lock_init) {
|
||||
// mtx_destroy(&ha->hw_lock);
|
||||
// }
|
||||
|
||||
if (ha->pci_reg)
|
||||
(void) bus_release_resource(dev, SYS_RES_MEMORY, ha->reg_rid,
|
||||
@ -646,6 +679,8 @@ qla_release(qla_host_t *ha)
|
||||
if (ha->pci_reg1)
|
||||
(void) bus_release_resource(dev, SYS_RES_MEMORY, ha->reg_rid1,
|
||||
ha->pci_reg1);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -866,16 +901,17 @@ qla_init_locked(qla_host_t *ha)
|
||||
bcopy(IF_LLADDR(ha->ifp), ha->hw.mac_addr, ETHER_ADDR_LEN);
|
||||
|
||||
ifp->if_hwassist = CSUM_TCP | CSUM_UDP | CSUM_TSO;
|
||||
ifp->if_hwassist |= CSUM_TCP_IPV6 | CSUM_UDP_IPV6;
|
||||
|
||||
ha->flags.stop_rcv = 0;
|
||||
ha->stop_rcv = 0;
|
||||
if (ql_init_hw_if(ha) == 0) {
|
||||
ifp = ha->ifp;
|
||||
ifp->if_drv_flags |= IFF_DRV_RUNNING;
|
||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
||||
ha->flags.qla_watchdog_pause = 0;
|
||||
ha->qla_watchdog_pause = 0;
|
||||
ha->hw_vlan_tx_frames = 0;
|
||||
ha->tx_tso_frames = 0;
|
||||
ha->flags.qla_interface_up = 1;
|
||||
ha->qla_interface_up = 1;
|
||||
ql_update_link_state(ha);
|
||||
}
|
||||
|
||||
return;
|
||||
@ -890,9 +926,12 @@ qla_init(void *arg)
|
||||
|
||||
QL_DPRINT2(ha, (ha->pci_dev, "%s: enter\n", __func__));
|
||||
|
||||
QLA_LOCK(ha);
|
||||
if (QLA_LOCK(ha, __func__, -1, 0) != 0)
|
||||
return;
|
||||
|
||||
qla_init_locked(ha);
|
||||
QLA_UNLOCK(ha);
|
||||
|
||||
QLA_UNLOCK(ha, __func__);
|
||||
|
||||
QL_DPRINT2(ha, (ha->pci_dev, "%s: exit\n", __func__));
|
||||
}
|
||||
@ -924,11 +963,15 @@ qla_set_multi(qla_host_t *ha, uint32_t add_multi)
|
||||
|
||||
if_maddr_runlock(ifp);
|
||||
|
||||
QLA_LOCK(ha);
|
||||
if (QLA_LOCK(ha, __func__, QLA_LOCK_DEFAULT_MS_TIMEOUT,
|
||||
QLA_LOCK_NO_SLEEP) != 0)
|
||||
return (-1);
|
||||
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
|
||||
ret = ql_hw_set_multi(ha, mta, mcnt, add_multi);
|
||||
}
|
||||
QLA_UNLOCK(ha);
|
||||
|
||||
QLA_UNLOCK(ha, __func__);
|
||||
|
||||
return (ret);
|
||||
}
|
||||
@ -949,12 +992,20 @@ qla_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
__func__, cmd));
|
||||
|
||||
if (ifa->ifa_addr->sa_family == AF_INET) {
|
||||
|
||||
ret = QLA_LOCK(ha, __func__,
|
||||
QLA_LOCK_DEFAULT_MS_TIMEOUT,
|
||||
QLA_LOCK_NO_SLEEP);
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ifp->if_flags |= IFF_UP;
|
||||
|
||||
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
|
||||
QLA_LOCK(ha);
|
||||
qla_init_locked(ha);
|
||||
QLA_UNLOCK(ha);
|
||||
}
|
||||
|
||||
QLA_UNLOCK(ha, __func__);
|
||||
QL_DPRINT4(ha, (ha->pci_dev,
|
||||
"%s: SIOCSIFADDR (0x%lx) ipv4 [0x%08x]\n",
|
||||
__func__, cmd,
|
||||
@ -973,13 +1024,17 @@ qla_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
if (ifr->ifr_mtu > QLA_MAX_MTU) {
|
||||
ret = EINVAL;
|
||||
} else {
|
||||
QLA_LOCK(ha);
|
||||
ret = QLA_LOCK(ha, __func__, QLA_LOCK_DEFAULT_MS_TIMEOUT,
|
||||
QLA_LOCK_NO_SLEEP);
|
||||
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
ifp->if_mtu = ifr->ifr_mtu;
|
||||
ha->max_frame_size =
|
||||
ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN;
|
||||
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING)) {
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
|
||||
qla_init_locked(ha);
|
||||
}
|
||||
|
||||
@ -989,10 +1044,7 @@ qla_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
ha->std_replenish = QL_STD_REPLENISH_THRES;
|
||||
|
||||
|
||||
QLA_UNLOCK(ha);
|
||||
|
||||
if (ret)
|
||||
ret = EINVAL;
|
||||
QLA_UNLOCK(ha, __func__);
|
||||
}
|
||||
|
||||
break;
|
||||
@ -1001,10 +1053,19 @@ qla_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
QL_DPRINT4(ha, (ha->pci_dev, "%s: SIOCSIFFLAGS (0x%lx)\n",
|
||||
__func__, cmd));
|
||||
|
||||
QLA_LOCK(ha);
|
||||
ret = QLA_LOCK(ha, __func__, QLA_LOCK_DEFAULT_MS_TIMEOUT,
|
||||
QLA_LOCK_NO_SLEEP);
|
||||
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
if (ifp->if_flags & IFF_UP) {
|
||||
if ((ifp->if_drv_flags & IFF_DRV_RUNNING)) {
|
||||
|
||||
ha->max_frame_size = ifp->if_mtu +
|
||||
ETHER_HDR_LEN + ETHER_CRC_LEN;
|
||||
qla_init_locked(ha);
|
||||
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
|
||||
if ((ifp->if_flags ^ ha->if_flags) &
|
||||
IFF_PROMISC) {
|
||||
ret = ql_set_promisc(ha);
|
||||
@ -1012,10 +1073,6 @@ qla_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
IFF_ALLMULTI) {
|
||||
ret = ql_set_allmulti(ha);
|
||||
}
|
||||
} else {
|
||||
ha->max_frame_size = ifp->if_mtu +
|
||||
ETHER_HDR_LEN + ETHER_CRC_LEN;
|
||||
qla_init_locked(ha);
|
||||
}
|
||||
} else {
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING)
|
||||
@ -1023,7 +1080,7 @@ qla_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
ha->if_flags = ifp->if_flags;
|
||||
}
|
||||
|
||||
QLA_UNLOCK(ha);
|
||||
QLA_UNLOCK(ha, __func__);
|
||||
break;
|
||||
|
||||
case SIOCADDMULTI:
|
||||
@ -1061,6 +1118,8 @@ qla_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
ifp->if_capenable ^= IFCAP_HWCSUM;
|
||||
if (mask & IFCAP_TSO4)
|
||||
ifp->if_capenable ^= IFCAP_TSO4;
|
||||
if (mask & IFCAP_TSO6)
|
||||
ifp->if_capenable ^= IFCAP_TSO6;
|
||||
if (mask & IFCAP_VLAN_HWTAGGING)
|
||||
ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
|
||||
if (mask & IFCAP_VLAN_HWTSO)
|
||||
@ -1068,9 +1127,18 @@ qla_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
if (mask & IFCAP_LRO)
|
||||
ifp->if_capenable ^= IFCAP_LRO;
|
||||
|
||||
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
|
||||
qla_init(ha);
|
||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
|
||||
ret = QLA_LOCK(ha, __func__, QLA_LOCK_DEFAULT_MS_TIMEOUT,
|
||||
QLA_LOCK_NO_SLEEP);
|
||||
|
||||
if (ret)
|
||||
break;
|
||||
|
||||
qla_init_locked(ha);
|
||||
|
||||
QLA_UNLOCK(ha, __func__);
|
||||
|
||||
}
|
||||
VLAN_CAPABILITIES(ifp);
|
||||
break;
|
||||
}
|
||||
@ -1208,6 +1276,8 @@ qla_send(qla_host_t *ha, struct mbuf **m_headp, uint32_t txr_idx,
|
||||
if (!(ret = ql_hw_send(ha, segs, nsegs, tx_idx, m_head, txr_idx,
|
||||
iscsi_pdu))) {
|
||||
ha->tx_ring[txr_idx].count++;
|
||||
if (iscsi_pdu)
|
||||
ha->tx_ring[txr_idx].iscsi_pkt_count++;
|
||||
ha->tx_ring[txr_idx].tx_buf[tx_idx].m_head = m_head;
|
||||
} else {
|
||||
if (ret == EINVAL) {
|
||||
@ -1275,7 +1345,7 @@ qla_fp_taskqueue(void *context, int pending)
|
||||
int ret;
|
||||
uint32_t txr_idx;
|
||||
uint32_t iscsi_pdu = 0;
|
||||
uint32_t rx_pkts_left;
|
||||
uint32_t rx_pkts_left = -1;
|
||||
|
||||
fp = context;
|
||||
|
||||
@ -1290,53 +1360,57 @@ qla_fp_taskqueue(void *context, int pending)
|
||||
|
||||
mtx_lock(&fp->tx_mtx);
|
||||
|
||||
if (((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
|
||||
IFF_DRV_RUNNING) || (!ha->hw.link_up)) {
|
||||
if (!(ifp->if_drv_flags & IFF_DRV_RUNNING) || (!ha->hw.link_up)) {
|
||||
mtx_unlock(&fp->tx_mtx);
|
||||
goto qla_fp_taskqueue_exit;
|
||||
}
|
||||
|
||||
rx_pkts_left = ql_rcv_isr(ha, fp->txr_idx, 64);
|
||||
while (rx_pkts_left && !ha->stop_rcv) {
|
||||
rx_pkts_left = ql_rcv_isr(ha, fp->txr_idx, 64);
|
||||
|
||||
#ifdef QL_ENABLE_ISCSI_TLV
|
||||
ql_hw_tx_done_locked(ha, fp->txr_idx);
|
||||
ql_hw_tx_done_locked(ha, (fp->txr_idx + (ha->hw.num_tx_rings >> 1)));
|
||||
txr_idx = txr_idx + (ha->hw.num_tx_rings >> 1);
|
||||
ql_hw_tx_done_locked(ha, fp->txr_idx);
|
||||
ql_hw_tx_done_locked(ha, (fp->txr_idx + (ha->hw.num_tx_rings >> 1)));
|
||||
#else
|
||||
ql_hw_tx_done_locked(ha, fp->txr_idx);
|
||||
ql_hw_tx_done_locked(ha, fp->txr_idx);
|
||||
#endif /* #ifdef QL_ENABLE_ISCSI_TLV */
|
||||
|
||||
mp = drbr_peek(ifp, fp->tx_br);
|
||||
mp = drbr_peek(ifp, fp->tx_br);
|
||||
|
||||
while (mp != NULL) {
|
||||
while (mp != NULL) {
|
||||
|
||||
if (M_HASHTYPE_GET(mp) != M_HASHTYPE_NONE) {
|
||||
if (M_HASHTYPE_GET(mp) != M_HASHTYPE_NONE) {
|
||||
#ifdef QL_ENABLE_ISCSI_TLV
|
||||
if (ql_iscsi_pdu(ha, mp) == 0) {
|
||||
iscsi_pdu = 1;
|
||||
}
|
||||
if (ql_iscsi_pdu(ha, mp) == 0) {
|
||||
txr_idx = txr_idx +
|
||||
(ha->hw.num_tx_rings >> 1);
|
||||
iscsi_pdu = 1;
|
||||
} else {
|
||||
iscsi_pdu = 0;
|
||||
txr_idx = fp->txr_idx;
|
||||
}
|
||||
#endif /* #ifdef QL_ENABLE_ISCSI_TLV */
|
||||
}
|
||||
|
||||
ret = qla_send(ha, &mp, txr_idx, iscsi_pdu);
|
||||
|
||||
if (ret) {
|
||||
if (mp != NULL)
|
||||
drbr_putback(ifp, fp->tx_br, mp);
|
||||
else {
|
||||
drbr_advance(ifp, fp->tx_br);
|
||||
}
|
||||
|
||||
mtx_unlock(&fp->tx_mtx);
|
||||
|
||||
goto qla_fp_taskqueue_exit0;
|
||||
} else {
|
||||
drbr_advance(ifp, fp->tx_br);
|
||||
}
|
||||
|
||||
mp = drbr_peek(ifp, fp->tx_br);
|
||||
}
|
||||
|
||||
ret = qla_send(ha, &mp, txr_idx, iscsi_pdu);
|
||||
|
||||
if (ret) {
|
||||
if (mp != NULL)
|
||||
drbr_putback(ifp, fp->tx_br, mp);
|
||||
else {
|
||||
drbr_advance(ifp, fp->tx_br);
|
||||
}
|
||||
|
||||
mtx_unlock(&fp->tx_mtx);
|
||||
|
||||
goto qla_fp_taskqueue_exit0;
|
||||
} else {
|
||||
drbr_advance(ifp, fp->tx_br);
|
||||
}
|
||||
|
||||
mp = drbr_peek(ifp, fp->tx_br);
|
||||
}
|
||||
|
||||
}
|
||||
mtx_unlock(&fp->tx_mtx);
|
||||
|
||||
qla_fp_taskqueue_exit0:
|
||||
@ -1344,7 +1418,7 @@ qla_fp_taskqueue(void *context, int pending)
|
||||
if (rx_pkts_left || ((mp != NULL) && ret)) {
|
||||
taskqueue_enqueue(fp->fp_taskqueue, &fp->fp_task);
|
||||
} else {
|
||||
if (!ha->flags.stop_rcv) {
|
||||
if (!ha->stop_rcv) {
|
||||
QL_ENABLE_INTERRUPTS(ha, fp->txr_idx);
|
||||
}
|
||||
}
|
||||
@ -1501,7 +1575,8 @@ qla_stop(qla_host_t *ha)
|
||||
|
||||
dev = ha->pci_dev;
|
||||
|
||||
ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE | IFF_DRV_RUNNING);
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
ha->qla_watchdog_pause = 1;
|
||||
|
||||
for (i = 0; i < ha->hw.num_sds_rings; i++) {
|
||||
qla_tx_fp_t *fp;
|
||||
@ -1517,19 +1592,12 @@ qla_stop(qla_host_t *ha)
|
||||
}
|
||||
}
|
||||
|
||||
ha->flags.qla_watchdog_pause = 1;
|
||||
|
||||
while (!ha->qla_watchdog_paused) {
|
||||
QLA_UNLOCK(ha);
|
||||
while (!ha->qla_watchdog_paused)
|
||||
qla_mdelay(__func__, 1);
|
||||
QLA_LOCK(ha);
|
||||
}
|
||||
|
||||
ha->flags.qla_interface_up = 0;
|
||||
ha->qla_interface_up = 0;
|
||||
|
||||
QLA_UNLOCK(ha);
|
||||
qla_drain_fp_taskqueues(ha);
|
||||
QLA_LOCK(ha);
|
||||
|
||||
ql_del_hw_if(ha);
|
||||
|
||||
@ -1797,7 +1865,7 @@ qla_free_rcv_bufs(qla_host_t *ha)
|
||||
int
|
||||
ql_get_mbuf(qla_host_t *ha, qla_rx_buf_t *rxb, struct mbuf *nmp)
|
||||
{
|
||||
struct mbuf *mp = nmp;
|
||||
register struct mbuf *mp = nmp;
|
||||
struct ifnet *ifp;
|
||||
int ret = 0;
|
||||
uint32_t offset;
|
||||
@ -1913,17 +1981,19 @@ qla_error_recovery(void *context, int pending)
|
||||
struct ifnet *ifp = ha->ifp;
|
||||
int i = 0;
|
||||
|
||||
QLA_LOCK(ha);
|
||||
device_printf(ha->pci_dev, "%s: \n", __func__);
|
||||
ha->hw.imd_compl = 1;
|
||||
|
||||
if (ha->flags.qla_interface_up) {
|
||||
if (QLA_LOCK(ha, __func__, -1, 0) != 0)
|
||||
return;
|
||||
|
||||
ha->hw.imd_compl = 1;
|
||||
device_printf(ha->pci_dev, "%s: enter\n", __func__);
|
||||
|
||||
if (ha->qla_interface_up) {
|
||||
|
||||
QLA_UNLOCK(ha);
|
||||
qla_mdelay(__func__, 300);
|
||||
QLA_LOCK(ha);
|
||||
|
||||
ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE | IFF_DRV_RUNNING);
|
||||
ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
|
||||
|
||||
for (i = 0; i < ha->hw.num_sds_rings; i++) {
|
||||
qla_tx_fp_t *fp;
|
||||
@ -1940,7 +2010,6 @@ qla_error_recovery(void *context, int pending)
|
||||
}
|
||||
}
|
||||
|
||||
QLA_UNLOCK(ha);
|
||||
|
||||
qla_drain_fp_taskqueues(ha);
|
||||
|
||||
@ -1956,23 +2025,15 @@ qla_error_recovery(void *context, int pending)
|
||||
|
||||
ha->msg_from_peer = 0;
|
||||
|
||||
QLA_LOCK(ha);
|
||||
|
||||
ql_minidump(ha);
|
||||
|
||||
QLA_UNLOCK(ha);
|
||||
|
||||
(void) ql_init_hw(ha);
|
||||
|
||||
QLA_LOCK(ha);
|
||||
|
||||
if (ha->flags.qla_interface_up) {
|
||||
if (ha->qla_interface_up) {
|
||||
qla_free_xmt_bufs(ha);
|
||||
qla_free_rcv_bufs(ha);
|
||||
}
|
||||
|
||||
QLA_UNLOCK(ha);
|
||||
|
||||
qla_send_msg_to_peer(ha, QL_PEER_MSG_ACK);
|
||||
|
||||
} else {
|
||||
@ -1991,43 +2052,44 @@ qla_error_recovery(void *context, int pending)
|
||||
|
||||
(void) ql_init_hw(ha);
|
||||
|
||||
QLA_LOCK(ha);
|
||||
qla_mdelay(__func__, 1000);
|
||||
|
||||
if (ha->flags.qla_interface_up) {
|
||||
if (ha->qla_interface_up) {
|
||||
qla_free_xmt_bufs(ha);
|
||||
qla_free_rcv_bufs(ha);
|
||||
}
|
||||
|
||||
QLA_UNLOCK(ha);
|
||||
}
|
||||
|
||||
QLA_LOCK(ha);
|
||||
|
||||
if (ha->flags.qla_interface_up) {
|
||||
if (ha->qla_interface_up) {
|
||||
|
||||
if (qla_alloc_xmt_bufs(ha) != 0) {
|
||||
QLA_UNLOCK(ha);
|
||||
return;
|
||||
goto qla_error_recovery_exit;
|
||||
}
|
||||
qla_confirm_9kb_enable(ha);
|
||||
|
||||
if (qla_alloc_rcv_bufs(ha) != 0) {
|
||||
QLA_UNLOCK(ha);
|
||||
return;
|
||||
goto qla_error_recovery_exit;
|
||||
}
|
||||
|
||||
ha->flags.stop_rcv = 0;
|
||||
ha->stop_rcv = 0;
|
||||
|
||||
if (ql_init_hw_if(ha) == 0) {
|
||||
ifp = ha->ifp;
|
||||
ifp->if_drv_flags |= IFF_DRV_RUNNING;
|
||||
ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
|
||||
ha->flags.qla_watchdog_pause = 0;
|
||||
ha->qla_watchdog_pause = 0;
|
||||
}
|
||||
} else
|
||||
ha->flags.qla_watchdog_pause = 0;
|
||||
ha->qla_watchdog_pause = 0;
|
||||
|
||||
QLA_UNLOCK(ha);
|
||||
qla_error_recovery_exit:
|
||||
|
||||
device_printf(ha->pci_dev, "%s: exit\n", __func__);
|
||||
|
||||
QLA_UNLOCK(ha, __func__);
|
||||
|
||||
callout_reset(&ha->tx_callout, QLA_WATCHDOG_CALLOUT_TICKS,
|
||||
qla_watchdog, ha);
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2035,8 +2097,27 @@ qla_async_event(void *context, int pending)
|
||||
{
|
||||
qla_host_t *ha = context;
|
||||
|
||||
QLA_LOCK(ha);
|
||||
qla_hw_async_event(ha);
|
||||
QLA_UNLOCK(ha);
|
||||
if (QLA_LOCK(ha, __func__, -1, 0) != 0)
|
||||
return;
|
||||
|
||||
if (ha->async_event) {
|
||||
ha->async_event = 0;
|
||||
qla_hw_async_event(ha);
|
||||
}
|
||||
|
||||
QLA_UNLOCK(ha, __func__);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
qla_stats(void *context, int pending)
|
||||
{
|
||||
qla_host_t *ha;
|
||||
|
||||
ha = context;
|
||||
|
||||
ql_get_stats(ha);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -148,8 +148,8 @@ MALLOC_DECLARE(M_QLA83XXBUF);
|
||||
/*
|
||||
* Locks
|
||||
*/
|
||||
#define QLA_LOCK(ha) mtx_lock(&ha->hw_lock)
|
||||
#define QLA_UNLOCK(ha) mtx_unlock(&ha->hw_lock)
|
||||
#define QLA_LOCK(ha, str, to_ms, no_sleep) qla_lock(ha, str, to_ms, no_sleep)
|
||||
#define QLA_UNLOCK(ha, str) qla_unlock(ha, str)
|
||||
|
||||
/*
|
||||
* structure encapsulating a DMA buffer
|
||||
|
@ -36,7 +36,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
unsigned int ql83xx_resetseq_version_major = 5;
|
||||
unsigned int ql83xx_resetseq_version_minor = 4;
|
||||
unsigned int ql83xx_resetseq_version_sub = 64;
|
||||
unsigned int ql83xx_resetseq_version_sub = 66;
|
||||
|
||||
unsigned char ql83xx_resetseq[] = {
|
||||
0x01, 0x01, 0xfe, 0xca, 0xf0, 0x05, 0x2f, 0x00, 0x10, 0x00, 0x74, 0x70,
|
||||
@ -1402,8 +1402,8 @@ unsigned char ql83xx_resetseq[] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x04, 0x00, 0x40, 0x40,
|
||||
0x05, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00,
|
||||
0x05, 0x04, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xdf, 0xfa, 0x92, 0x87
|
||||
0xdf, 0xfa, 0x90, 0x87
|
||||
};
|
||||
unsigned int ql83xx_resetseq_len = 16384;
|
||||
|
@ -36,6 +36,6 @@
|
||||
|
||||
#define QLA_VERSION_MAJOR 3
|
||||
#define QLA_VERSION_MINOR 10
|
||||
#define QLA_VERSION_BUILD 33
|
||||
#define QLA_VERSION_BUILD 34
|
||||
|
||||
#endif /* #ifndef _QL_VER_H_ */
|
||||
|
@ -33,6 +33,7 @@
|
||||
#
|
||||
|
||||
.PATH: ${SRCTOP}/sys/dev/qlxgbe
|
||||
#.PATH: ${.CURDIR}
|
||||
|
||||
KMOD=if_qlxgbe
|
||||
SRCS=ql_os.c ql_dbg.c ql_hw.c ql_misc.c ql_isr.c ql_ioctl.c
|
||||
@ -43,7 +44,8 @@ SRCS+= ql_minidump.c
|
||||
|
||||
SRCS+= device_if.h bus_if.h pci_if.h
|
||||
|
||||
#CFLAGS += -DQL_DBG
|
||||
CFLAGS += -DQLA_LOCK_NO_SLEEP=1
|
||||
#CFLAGS += -DQL_DBG -g
|
||||
# Please turn off QL_LDFLASH_FW when you enable QL_ENABLE_ISCSI_TLV
|
||||
# You may comment out both QL_LDFLASH_FW and QL_ENABLE_ISCSI_TLV if you like
|
||||
# the firmware and boot loader compiled into the driver
|
||||
|
Loading…
Reference in New Issue
Block a user