Updated Copyright information

Added support for the following:
        - iSCSI TLV (requires 64 Tx and 32 Rx rings
        - 9K receive buffers for jumbo frames (feature may be enabled/disabled)
        - builtin firmware, bootloader and minidump template
        - quick stats
        - async event handling for SFP insertion/removal and DCBX changes
        - Configuring DCBX and interrupt coalescing parameters
This commit is contained in:
David C Somayajulu 2015-06-23 22:22:36 +00:00
parent c197bf4fe1
commit 35291c2247
20 changed files with 172158 additions and 164 deletions

10964
sys/dev/qlxgbe/ql_boot.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2014 Qlogic Corporation * Copyright (c) 2013-2016 Qlogic Corporation
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2014 Qlogic Corporation * Copyright (c) 2013-2016 Qlogic Corporation
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2014 Qlogic Corporation * Copyright (c) 2013-2016 Qlogic Corporation
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -232,6 +232,11 @@ struct qla_host {
struct task err_task; struct task err_task;
struct taskqueue *err_tq; struct taskqueue *err_tq;
/* Async Event Related */
uint32_t async_event;
struct task async_event_task;
struct taskqueue *async_event_tq;
/* Peer Device */ /* Peer Device */
device_t peer_dev; device_t peer_dev;

148964
sys/dev/qlxgbe/ql_fw.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2014 Qlogic Corporation * Copyright (c) 2013-2016 Qlogic Corporation
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -54,13 +54,17 @@ extern int ql_alloc_dma(qla_host_t *ha);
extern void ql_free_dma(qla_host_t *ha); extern void ql_free_dma(qla_host_t *ha);
extern void ql_hw_add_sysctls(qla_host_t *ha); extern void ql_hw_add_sysctls(qla_host_t *ha);
extern int ql_hw_send(qla_host_t *ha, bus_dma_segment_t *segs, int nsegs, extern int ql_hw_send(qla_host_t *ha, bus_dma_segment_t *segs, int nsegs,
uint32_t tx_idx, struct mbuf *mp, uint32_t txr_idx); uint32_t tx_idx, struct mbuf *mp, uint32_t txr_idx,
uint32_t iscsi_pdu);
extern void qla_confirm_9kb_enable(qla_host_t *ha);
extern int ql_init_hw_if(qla_host_t *ha); extern int ql_init_hw_if(qla_host_t *ha);
extern int ql_hw_set_multi(qla_host_t *ha, uint8_t *mta, uint32_t mcnt, extern int ql_hw_set_multi(qla_host_t *ha, uint8_t *mta, uint32_t mcnt,
uint32_t add_multi); uint32_t add_multi);
extern void ql_del_hw_if(qla_host_t *ha); extern void ql_del_hw_if(qla_host_t *ha);
extern int ql_set_promisc(qla_host_t *ha); extern int ql_set_promisc(qla_host_t *ha);
extern void qla_reset_promisc(qla_host_t *ha);
extern int ql_set_allmulti(qla_host_t *ha); extern int ql_set_allmulti(qla_host_t *ha);
extern void qla_reset_allmulti(qla_host_t *ha);
extern void ql_update_link_state(qla_host_t *ha); extern void ql_update_link_state(qla_host_t *ha);
extern void ql_hw_tx_done(qla_host_t *ha); extern void ql_hw_tx_done(qla_host_t *ha);
extern int ql_set_max_mtu(qla_host_t *ha, uint32_t mtu, uint16_t cntxt_id); extern int ql_set_max_mtu(qla_host_t *ha, uint32_t mtu, uint16_t cntxt_id);
@ -68,6 +72,12 @@ extern void ql_hw_stop_rcv(qla_host_t *ha);
extern void ql_get_stats(qla_host_t *ha); extern void ql_get_stats(qla_host_t *ha);
extern void ql_hw_link_status(qla_host_t *ha); extern void ql_hw_link_status(qla_host_t *ha);
extern int ql_hw_check_health(qla_host_t *ha); extern int ql_hw_check_health(qla_host_t *ha);
extern void qla_hw_async_event(qla_host_t *ha);
extern int qla_get_nic_partition(qla_host_t *ha, uint32_t *supports_9kb,
uint32_t *num_rcvq);
extern int qla_iscsi_pdu(qla_host_t *ha, struct mbuf *mp);
extern void ql_minidump(qla_host_t *ha); extern void ql_minidump(qla_host_t *ha);
/* /*
@ -92,4 +102,13 @@ extern int ql_start_sequence(qla_host_t *ha, uint16_t index);
extern int ql_make_cdev(qla_host_t *ha); extern int ql_make_cdev(qla_host_t *ha);
extern void ql_del_cdev(qla_host_t *ha); extern void ql_del_cdev(qla_host_t *ha);
extern unsigned char ql83xx_firmware[];
extern unsigned int ql83xx_firmware_len;
extern unsigned char ql83xx_bootloader[];
extern unsigned int ql83xx_bootloader_len;
extern unsigned char ql83xx_resetseq[];
extern unsigned int ql83xx_resetseq_len;
extern unsigned char ql83xx_minidump[];
extern unsigned int ql83xx_minidump_len;
#endif /* #ifndef_QL_GLBL_H_ */ #endif /* #ifndef_QL_GLBL_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2014 Qlogic Corporation * Copyright (c) 2013-2016 Qlogic Corporation
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -257,6 +257,8 @@
#define Q8_MBX_CONFIG_FW_LRO 0x004A #define Q8_MBX_CONFIG_FW_LRO 0x004A
#define Q8_MBX_INIT_NIC_FUNC 0x0060 #define Q8_MBX_INIT_NIC_FUNC 0x0060
#define Q8_MBX_STOP_NIC_FUNC 0x0061 #define Q8_MBX_STOP_NIC_FUNC 0x0061
#define Q8_MBX_IDC_REQ 0x0062
#define Q8_MBX_IDC_ACK 0x0063
#define Q8_MBX_SET_PORT_CONFIG 0x0066 #define Q8_MBX_SET_PORT_CONFIG 0x0066
#define Q8_MBX_GET_PORT_CONFIG 0x0067 #define Q8_MBX_GET_PORT_CONFIG 0x0067
#define Q8_MBX_GET_LINK_STATUS 0x0068 #define Q8_MBX_GET_LINK_STATUS 0x0068
@ -426,7 +428,11 @@ typedef struct _q80_config_rss {
uint16_t rsrvd; uint16_t rsrvd;
uint8_t hash_type; uint8_t hash_type;
#define Q8_MBX_RSS_HASH_TYPE_IPV4_IP (0x1 << 4)
#define Q8_MBX_RSS_HASH_TYPE_IPV4_TCP (0x2 << 4)
#define Q8_MBX_RSS_HASH_TYPE_IPV4_TCP_IP (0x3 << 4) #define Q8_MBX_RSS_HASH_TYPE_IPV4_TCP_IP (0x3 << 4)
#define Q8_MBX_RSS_HASH_TYPE_IPV6_IP (0x1 << 6)
#define Q8_MBX_RSS_HASH_TYPE_IPV6_TCP (0x2 << 6)
#define Q8_MBX_RSS_HASH_TYPE_IPV6_TCP_IP (0x3 << 6) #define Q8_MBX_RSS_HASH_TYPE_IPV6_TCP_IP (0x3 << 6)
uint8_t flags; uint8_t flags;
@ -463,7 +469,7 @@ typedef struct _q80_config_rss_ind_table {
uint8_t start_idx; uint8_t start_idx;
uint8_t end_idx; uint8_t end_idx;
uint16_t cntxt_id; uint16_t cntxt_id;
uint8_t ind_table[40]; uint8_t ind_table[Q8_RSS_IND_TBL_SIZE];
} __packed q80_config_rss_ind_table_t; } __packed q80_config_rss_ind_table_t;
typedef struct _q80_config_rss_ind_table_rsp { typedef struct _q80_config_rss_ind_table_rsp {
@ -706,6 +712,13 @@ typedef struct _q80_mac_stats {
uint64_t rcv_dropped; uint64_t rcv_dropped;
uint64_t fcs_error; uint64_t fcs_error;
uint64_t align_error; uint64_t align_error;
uint64_t eswitched_frames;
uint64_t eswitched_bytes;
uint64_t eswitched_mcast_frames;
uint64_t eswitched_bcast_frames;
uint64_t eswitched_ucast_frames;
uint64_t eswitched_err_free_frames;
uint64_t eswitched_err_free_bytes;
} __packed q80_mac_stats_t; } __packed q80_mac_stats_t;
typedef struct _q80_get_stats { typedef struct _q80_get_stats {
@ -720,6 +733,7 @@ typedef struct _q80_get_stats {
#define Q8_GET_STATS_CMD_TYPE_MAC 0x04 #define Q8_GET_STATS_CMD_TYPE_MAC 0x04
#define Q8_GET_STATS_CMD_TYPE_FUNC 0x08 #define Q8_GET_STATS_CMD_TYPE_FUNC 0x08
#define Q8_GET_STATS_CMD_TYPE_VPORT 0x0C #define Q8_GET_STATS_CMD_TYPE_VPORT 0x0C
#define Q8_GET_STATS_CMD_TYPE_ALL (0x7 << 2)
} __packed q80_get_stats_t; } __packed q80_get_stats_t;
@ -734,6 +748,15 @@ typedef struct _q80_get_stats_rsp {
} u; } u;
} __packed q80_get_stats_rsp_t; } __packed q80_get_stats_rsp_t;
typedef struct _q80_get_mac_rcv_xmt_stats_rsp {
uint16_t opcode;
uint16_t regcnt_status;
uint32_t cmd;
q80_mac_stats_t mac;
q80_rcv_stats_t rcv;
q80_xmt_stats_t xmt;
} __packed q80_get_mac_rcv_xmt_stats_rsp_t;
/* /*
* Init NIC Function * Init NIC Function
* Used to Register DCBX Configuration Change AEN * Used to Register DCBX Configuration Change AEN
@ -743,6 +766,7 @@ typedef struct _q80_init_nic_func {
uint16_t count_version; uint16_t count_version;
uint32_t options; uint32_t options;
#define Q8_INIT_NIC_REG_IDC_AEN 0x01
#define Q8_INIT_NIC_REG_DCBX_CHNG_AEN 0x02 #define Q8_INIT_NIC_REG_DCBX_CHNG_AEN 0x02
#define Q8_INIT_NIC_REG_SFP_CHNG_AEN 0x04 #define Q8_INIT_NIC_REG_SFP_CHNG_AEN 0x04
@ -795,6 +819,27 @@ typedef struct _q80_query_fw_dcbx_caps_rsp {
} __packed q80_query_fw_dcbx_caps_rsp_t; } __packed q80_query_fw_dcbx_caps_rsp_t;
/*
* IDC Ack Cmd
*/
typedef struct _q80_idc_ack {
uint16_t opcode;
uint16_t count_version;
uint32_t aen_mb1;
uint32_t aen_mb2;
uint32_t aen_mb3;
uint32_t aen_mb4;
} __packed q80_idc_ack_t;
typedef struct _q80_idc_ack_rsp {
uint16_t opcode;
uint16_t regcnt_status;
} __packed q80_idc_ack_rsp_t;
/* /*
* Set Port Configuration command * Set Port Configuration command
* Used to set Ethernet Standard Pause values * Used to set Ethernet Standard Pause values
@ -1083,7 +1128,16 @@ typedef struct _q80_tx_cmd {
* Receive Related Definitions * Receive Related Definitions
*/ */
#define MAX_RDS_RING_SETS 8 /* Max# of Receive Descriptor Rings */ #define MAX_RDS_RING_SETS 8 /* Max# of Receive Descriptor Rings */
#ifdef QL_ENABLE_ISCSI_TLV
#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 4 /* 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 */
typedef struct _q80_rq_sds_ring { typedef struct _q80_rq_sds_ring {
uint64_t paddr; /* physical addr of status ring in system memory */ uint64_t paddr; /* physical addr of status ring in system memory */
@ -1122,6 +1176,7 @@ typedef struct _q80_rq_rcv_cntxt {
#define Q8_RCV_CNTXT_CAP0_MSFT_RSS (1 << 16) #define Q8_RCV_CNTXT_CAP0_MSFT_RSS (1 << 16)
#define Q8_RCV_CNTXT_CAP0_SGL_JUMBO (1 << 18) #define Q8_RCV_CNTXT_CAP0_SGL_JUMBO (1 << 18)
#define Q8_RCV_CNTXT_CAP0_SGL_LRO (1 << 19) #define Q8_RCV_CNTXT_CAP0_SGL_LRO (1 << 19)
#define Q8_RCV_CNTXT_CAP0_SINGLE_JUMBO (1 << 26)
uint32_t cap1; uint32_t cap1;
uint32_t cap2; uint32_t cap2;
@ -1324,7 +1379,6 @@ typedef struct _q80_stat_desc {
#define NUM_RX_DESCRIPTORS 2048 #define NUM_RX_DESCRIPTORS 2048
#define MAX_RDS_RINGS MAX_SDS_RINGS /* Max# of Rcv Descriptor Rings */
/* /*
* structure describing various dma buffers * structure describing various dma buffers
@ -1452,8 +1506,6 @@ typedef struct _qla_flash_desc_table {
uint8_t resvd[65]; uint8_t resvd[65];
} __packed qla_flash_desc_table_t; } __packed qla_flash_desc_table_t;
#define NUM_TX_RINGS 4
/* /*
* struct for storing hardware specific information for a given interface * struct for storing hardware specific information for a given interface
*/ */
@ -1511,6 +1563,17 @@ typedef struct _qla_hw {
uint32_t rds_pidx_thres; uint32_t rds_pidx_thres;
uint32_t sds_cidx_thres; uint32_t sds_cidx_thres;
uint32_t rcv_intr_coalesce;
uint32_t xmt_intr_coalesce;
/* Immediate Completion */
volatile uint32_t imd_compl;
volatile uint32_t aen_mb0;
volatile uint32_t aen_mb1;
volatile uint32_t aen_mb2;
volatile uint32_t aen_mb3;
volatile uint32_t aen_mb4;
/* multicast address list */ /* multicast address list */
uint32_t nmcast; uint32_t nmcast;
qla_mcast_t mcast[Q8_MAX_NUM_MULTICAST_ADDRS]; qla_mcast_t mcast[Q8_MAX_NUM_MULTICAST_ADDRS];
@ -1527,6 +1590,12 @@ typedef struct _qla_hw {
uint32_t max_tx_segs; uint32_t max_tx_segs;
uint32_t min_lro_pkt_size; uint32_t min_lro_pkt_size;
uint32_t enable_9kb;
uint32_t user_pri_nic;
uint32_t user_pri_iscsi;
uint64_t iscsi_pkt_count;
/* Flash Descriptor Table */ /* Flash Descriptor Table */
qla_flash_desc_table_t fdt; qla_flash_desc_table_t fdt;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2014 Qlogic Corporation * Copyright (c) 2013-2016 Qlogic Corporation
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2014 Qlogic Corporation * Copyright (c) 2013-2016 Qlogic Corporation
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2014 Qlogic Corporation * Copyright (c) 2013-2016 Qlogic Corporation
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2014 Qlogic Corporation * Copyright (c) 2013-2016 Qlogic Corporation
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -776,16 +776,57 @@ ql_mbx_isr(void *arg)
ha->hw.link_faults = (data >> 3) & 0xFF; ha->hw.link_faults = (data >> 3) & 0xFF;
WRITE_REG32(ha, Q8_FW_MBOX_CNTRL, 0x0);
WRITE_REG32(ha, ha->hw.mbx_intr_mask_offset, 0x0);
break; break;
case 0x8100:
ha->hw.imd_compl=1;
break;
case 0x8101:
ha->async_event = 1;
ha->hw.aen_mb0 = 0x8101;
ha->hw.aen_mb1 = READ_REG32(ha, (Q8_FW_MBOX0 + 4));
ha->hw.aen_mb2 = READ_REG32(ha, (Q8_FW_MBOX0 + 8));
ha->hw.aen_mb3 = READ_REG32(ha, (Q8_FW_MBOX0 + 12));
ha->hw.aen_mb4 = READ_REG32(ha, (Q8_FW_MBOX0 + 16));
break;
case 0x8110:
/* for now just dump the registers */
{
uint32_t ombx[5];
ombx[0] = READ_REG32(ha, (Q8_FW_MBOX0 + 4));
ombx[1] = READ_REG32(ha, (Q8_FW_MBOX0 + 8));
ombx[2] = READ_REG32(ha, (Q8_FW_MBOX0 + 12));
ombx[3] = READ_REG32(ha, (Q8_FW_MBOX0 + 16));
ombx[4] = READ_REG32(ha, (Q8_FW_MBOX0 + 20));
device_printf(ha->pci_dev, "%s: "
"0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
__func__, data, ombx[0], ombx[1], ombx[2],
ombx[3], ombx[4]);
}
break;
case 0x8130:
/* sfp insertion aen */
device_printf(ha->pci_dev, "%s: sfp inserted [0x%08x]\n",
__func__, READ_REG32(ha, (Q8_FW_MBOX0 + 4)));
break;
case 0x8131:
/* sfp removal aen */
device_printf(ha->pci_dev, "%s: sfp removed]\n", __func__);
break;
default: default:
device_printf(ha->pci_dev, "%s: AEN[0x%08x]\n", __func__, data); device_printf(ha->pci_dev, "%s: AEN[0x%08x]\n", __func__, data);
WRITE_REG32(ha, Q8_FW_MBOX_CNTRL, 0x0);
WRITE_REG32(ha, ha->hw.mbx_intr_mask_offset, 0x0);
break; break;
} }
WRITE_REG32(ha, Q8_FW_MBOX_CNTRL, 0x0);
WRITE_REG32(ha, ha->hw.mbx_intr_mask_offset, 0x0);
return; return;
} }

10966
sys/dev/qlxgbe/ql_minidump.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2014 Qlogic Corporation * Copyright (c) 2013-2016 Qlogic Corporation
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -661,6 +661,7 @@ ql_wr_flash_buffer(qla_host_t *ha, uint32_t off, uint32_t size, void *buf)
return (rval); return (rval);
} }
#ifdef QL_LDFLASH_FW
/* /*
* Name: qla_load_fw_from_flash * Name: qla_load_fw_from_flash
* Function: Reads the Bootloader from Flash and Loads into Offchip Memory * Function: Reads the Bootloader from Flash and Loads into Offchip Memory
@ -704,6 +705,7 @@ qla_load_fw_from_flash(qla_host_t *ha)
return; return;
} }
#endif /* #ifdef QL_LDFLASH_FW */
/* /*
* Name: qla_init_from_flash * Name: qla_init_from_flash
@ -1179,6 +1181,93 @@ qla_tmplt_execute(qla_host_t *ha, uint8_t *buf, int start_idx, int *end_idx,
return (ret); return (ret);
} }
#ifndef QL_LDFLASH_FW
static int
qla_load_offchip_mem(qla_host_t *ha, uint64_t addr, uint32_t *data32,
uint32_t len32)
{
q80_offchip_mem_val_t val;
int ret = 0;
while (len32) {
if (len32 > 4) {
val.data_lo = *data32++;
val.data_hi = *data32++;
val.data_ulo = *data32++;
val.data_uhi = *data32++;
len32 -= 4;
if (ql_rdwr_offchip_mem(ha, addr, &val, 0))
return -1;
addr += (uint64_t)16;
} else {
break;
}
}
bzero(&val, sizeof(q80_offchip_mem_val_t));
switch (len32) {
case 3:
val.data_lo = *data32++;
val.data_hi = *data32++;
val.data_ulo = *data32++;
ret = ql_rdwr_offchip_mem(ha, addr, &val, 0);
break;
case 2:
val.data_lo = *data32++;
val.data_hi = *data32++;
ret = ql_rdwr_offchip_mem(ha, addr, &val, 0);
break;
case 1:
val.data_lo = *data32++;
ret = ql_rdwr_offchip_mem(ha, addr, &val, 0);
break;
default:
break;
}
return ret;
}
static int
qla_load_bootldr(qla_host_t *ha)
{
uint64_t addr;
uint32_t *data32;
uint32_t len32;
int ret;
addr = (uint64_t)(READ_REG32(ha, Q8_BOOTLD_ADDR));
data32 = (uint32_t *)ql83xx_bootloader;
len32 = ql83xx_bootloader_len >> 2;
ret = qla_load_offchip_mem(ha, addr, data32, len32);
return (ret);
}
static int
qla_load_fwimage(qla_host_t *ha)
{
uint64_t addr;
uint32_t *data32;
uint32_t len32;
int ret;
addr = (uint64_t)(READ_REG32(ha, Q8_FW_IMAGE_ADDR));
data32 = (uint32_t *)ql83xx_firmware;
len32 = ql83xx_firmware_len >> 2;
ret = qla_load_offchip_mem(ha, addr, data32, len32);
return (ret);
}
#endif /* #ifndef QL_LDFLASH_FW */
static int static int
qla_ld_fw_init(qla_host_t *ha) qla_ld_fw_init(qla_host_t *ha)
@ -1217,8 +1306,18 @@ qla_ld_fw_init(qla_host_t *ha)
return -1; return -1;
} }
#ifdef QL_LDFLASH_FW
qla_load_fw_from_flash(ha); qla_load_fw_from_flash(ha);
WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0); WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0);
#else
if (qla_load_bootldr(ha))
return -1;
if (qla_load_fwimage(ha))
return -1;
WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0x12345678);
#endif /* #ifdef QL_LDFLASH_FW */
index = end_idx; index = end_idx;
buf = ql83xx_resetseq + hdr->start_seq_off; buf = ql83xx_resetseq + hdr->start_seq_off;
@ -1287,8 +1386,19 @@ ql_start_sequence(qla_host_t *ha, uint16_t index)
return (-1); return (-1);
} }
#ifdef QL_LDFLASH_FW
qla_load_fw_from_flash(ha); qla_load_fw_from_flash(ha);
WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0); WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0);
#else
if (qla_load_bootldr(ha))
return -1;
if (qla_load_fwimage(ha))
return -1;
WRITE_REG32(ha, Q8_FW_IMAGE_VALID, 0x12345678);
#endif /* #ifdef QL_LDFLASH_FW */
index = end_idx; index = end_idx;
buf = ql83xx_resetseq + hdr->start_seq_off; buf = ql83xx_resetseq + hdr->start_seq_off;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2014 Qlogic Corporation * Copyright (c) 2013-2016 Qlogic Corporation
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -80,6 +80,7 @@ static int qla_send(qla_host_t *ha, struct mbuf **m_headp);
static void qla_tx_done(void *context, int pending); static void qla_tx_done(void *context, int pending);
static void qla_get_peer(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_error_recovery(void *context, int pending);
static void qla_async_event(void *context, int pending);
/* /*
* Hooks to the Operating Systems * Hooks to the Operating Systems
@ -120,6 +121,7 @@ MALLOC_DEFINE(M_QLA83XXBUF, "qla83xxbuf", "Buffers for qla83xx driver");
static char dev_str[64]; static char dev_str[64];
static char ver_str[64];
/* /*
* Name: qla_pci_probe * Name: qla_pci_probe
@ -134,6 +136,9 @@ qla_pci_probe(device_t dev)
"Qlogic ISP 83xx PCI CNA Adapter-Ethernet Function", "Qlogic ISP 83xx PCI CNA Adapter-Ethernet Function",
QLA_VERSION_MAJOR, QLA_VERSION_MINOR, QLA_VERSION_MAJOR, QLA_VERSION_MINOR,
QLA_VERSION_BUILD); QLA_VERSION_BUILD);
snprintf(ver_str, sizeof(ver_str), "v%d.%d.%d",
QLA_VERSION_MAJOR, QLA_VERSION_MINOR,
QLA_VERSION_BUILD);
device_set_desc(dev, dev_str); device_set_desc(dev, dev_str);
break; break;
default: default:
@ -151,6 +156,11 @@ qla_add_sysctls(qla_host_t *ha)
{ {
device_t dev = ha->pci_dev; device_t dev = ha->pci_dev;
SYSCTL_ADD_STRING(device_get_sysctl_ctx(dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
OID_AUTO, "version", CTLFLAG_RD,
ver_str, 0, "Driver Version");
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
OID_AUTO, "stats", CTLTYPE_INT | CTLFLAG_RW, OID_AUTO, "stats", CTLTYPE_INT | CTLFLAG_RW,
@ -235,6 +245,13 @@ qla_watchdog(void *arg)
ha->err_inject = 0; ha->err_inject = 0;
taskqueue_enqueue(ha->err_tq, &ha->err_task); taskqueue_enqueue(ha->err_tq, &ha->err_task);
} else { } else {
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_tx_rings; i++) { for (i = 0; i < ha->hw.num_tx_rings; i++) {
hw_tx_cntxt = &hw->tx_cntxt[i]; hw_tx_cntxt = &hw->tx_cntxt[i];
if (qla_le32_to_host(*(hw_tx_cntxt->tx_cons)) != if (qla_le32_to_host(*(hw_tx_cntxt->tx_cons)) !=
@ -270,6 +287,7 @@ qla_pci_attach(device_t dev)
qla_host_t *ha = NULL; qla_host_t *ha = NULL;
uint32_t rsrc_len; uint32_t rsrc_len;
int i; int i;
uint32_t num_rcvq = 0;
QL_DPRINT2(ha, (dev, "%s: enter\n", __func__)); QL_DPRINT2(ha, (dev, "%s: enter\n", __func__));
@ -328,6 +346,37 @@ qla_pci_attach(device_t dev)
" msix_count 0x%x pci_reg %p\n", __func__, ha, " msix_count 0x%x pci_reg %p\n", __func__, ha,
ha->pci_func, rsrc_len, ha->msix_count, ha->pci_reg)); ha->pci_func, rsrc_len, ha->msix_count, ha->pci_reg));
/* initialize hardware */
if (ql_init_hw(ha)) {
device_printf(dev, "%s: ql_init_hw failed\n", __func__);
goto qla_pci_attach_err;
}
device_printf(dev, "%s: firmware[%d.%d.%d.%d]\n", __func__,
ha->fw_ver_major, ha->fw_ver_minor, ha->fw_ver_sub,
ha->fw_ver_build);
snprintf(ha->fw_ver_str, sizeof(ha->fw_ver_str), "%d.%d.%d.%d",
ha->fw_ver_major, ha->fw_ver_minor, ha->fw_ver_sub,
ha->fw_ver_build);
if (qla_get_nic_partition(ha, NULL, &num_rcvq)) {
device_printf(dev, "%s: qla_get_nic_partition failed\n",
__func__);
goto qla_pci_attach_err;
}
device_printf(dev, "%s: ha %p pci_func 0x%x rsrc_count 0x%08x"
" msix_count 0x%x pci_reg %p num_rcvq = %d\n", __func__, ha,
ha->pci_func, rsrc_len, ha->msix_count, ha->pci_reg, num_rcvq);
#ifdef QL_ENABLE_ISCSI_TLV
if ((ha->msix_count < 64) || (num_rcvq != 32)) {
ha->hw.num_sds_rings = 15;
ha->hw.num_tx_rings = 32;
}
#endif /* #ifdef QL_ENABLE_ISCSI_TLV */
ha->hw.num_rds_rings = ha->hw.num_sds_rings;
ha->msix_count = ha->hw.num_sds_rings + 1; ha->msix_count = ha->hw.num_sds_rings + 1;
if (pci_alloc_msix(dev, &ha->msix_count)) { if (pci_alloc_msix(dev, &ha->msix_count)) {
@ -377,19 +426,6 @@ qla_pci_attach(device_t dev)
printf("%s: mp__ncpus %d sds %d rds %d msi-x %d\n", __func__, mp_ncpus, printf("%s: mp__ncpus %d sds %d rds %d msi-x %d\n", __func__, mp_ncpus,
ha->hw.num_sds_rings, ha->hw.num_rds_rings, ha->msix_count); ha->hw.num_sds_rings, ha->hw.num_rds_rings, ha->msix_count);
/* initialize hardware */
if (ql_init_hw(ha)) {
device_printf(dev, "%s: ql_init_hw failed\n", __func__);
goto qla_pci_attach_err;
}
device_printf(dev, "%s: firmware[%d.%d.%d.%d]\n", __func__,
ha->fw_ver_major, ha->fw_ver_minor, ha->fw_ver_sub,
ha->fw_ver_build);
snprintf(ha->fw_ver_str, sizeof(ha->fw_ver_str), "%d.%d.%d.%d",
ha->fw_ver_major, ha->fw_ver_minor, ha->fw_ver_sub,
ha->fw_ver_build);
ql_read_mac_addr(ha); ql_read_mac_addr(ha);
/* allocate parent dma tag */ /* allocate parent dma tag */
@ -437,6 +473,12 @@ qla_pci_attach(device_t dev)
taskqueue_start_threads(&ha->err_tq, 1, PI_NET, "%s errq", taskqueue_start_threads(&ha->err_tq, 1, PI_NET, "%s errq",
device_get_nameunit(ha->pci_dev)); device_get_nameunit(ha->pci_dev));
TASK_INIT(&ha->async_event_task, 0, qla_async_event, ha);
ha->async_event_tq = taskqueue_create_fast("qla_asyncq", M_NOWAIT,
taskqueue_thread_enqueue, &ha->async_event_tq);
taskqueue_start_threads(&ha->async_event_tq, 1, PI_NET, "%s asyncq",
device_get_nameunit(ha->pci_dev));
QL_DPRINT2(ha, (dev, "%s: exit 0\n", __func__)); QL_DPRINT2(ha, (dev, "%s: exit 0\n", __func__));
return (0); return (0);
@ -528,6 +570,11 @@ qla_release(qla_host_t *ha)
dev = ha->pci_dev; dev = ha->pci_dev;
if (ha->async_event_tq) {
taskqueue_drain(ha->async_event_tq, &ha->async_event_task);
taskqueue_free(ha->async_event_tq);
}
if (ha->err_tq) { if (ha->err_tq) {
taskqueue_drain(ha->err_tq, &ha->err_task); taskqueue_drain(ha->err_tq, &ha->err_task);
taskqueue_free(ha->err_tq); taskqueue_free(ha->err_tq);
@ -800,6 +847,8 @@ qla_init_locked(qla_host_t *ha)
if (qla_alloc_xmt_bufs(ha) != 0) if (qla_alloc_xmt_bufs(ha) != 0)
return; return;
qla_confirm_9kb_enable(ha);
if (qla_alloc_rcv_bufs(ha) != 0) if (qla_alloc_rcv_bufs(ha) != 0)
return; return;
@ -1093,7 +1142,7 @@ qla_start(struct ifnet *ifp)
return; return;
} }
if (!ha->watchdog_ticks) if (!ha->hw.link_up || !ha->watchdog_ticks)
ql_update_link_state(ha); ql_update_link_state(ha);
if (!ha->hw.link_up) { if (!ha->hw.link_up) {
@ -1137,12 +1186,27 @@ qla_send(qla_host_t *ha, struct mbuf **m_headp)
uint32_t tx_idx; uint32_t tx_idx;
struct mbuf *m_head = *m_headp; struct mbuf *m_head = *m_headp;
uint32_t txr_idx = ha->txr_idx; uint32_t txr_idx = ha->txr_idx;
uint32_t iscsi_pdu = 0;
QL_DPRINT8(ha, (ha->pci_dev, "%s: enter\n", __func__)); QL_DPRINT8(ha, (ha->pci_dev, "%s: enter\n", __func__));
/* check if flowid is set */ /* check if flowid is set */
if (M_HASHTYPE_GET(m_head) != M_HASHTYPE_NONE)
if (M_HASHTYPE_GET(m_head) != M_HASHTYPE_NONE) {
#ifdef QL_ENABLE_ISCSI_TLV
if (qla_iscsi_pdu(ha, m_head) == 0) {
iscsi_pdu = 1;
txr_idx = m_head->m_pkthdr.flowid &
((ha->hw.num_tx_rings >> 1) - 1);
} else {
txr_idx = m_head->m_pkthdr.flowid &
(ha->hw.num_tx_rings - 1);
}
#else
txr_idx = m_head->m_pkthdr.flowid & (ha->hw.num_tx_rings - 1); txr_idx = m_head->m_pkthdr.flowid & (ha->hw.num_tx_rings - 1);
#endif /* #ifdef QL_ENABLE_ISCSI_TLV */
}
tx_idx = ha->hw.tx_cntxt[txr_idx].txr_next; tx_idx = ha->hw.tx_cntxt[txr_idx].txr_next;
map = ha->tx_ring[txr_idx].tx_buf[tx_idx].map; map = ha->tx_ring[txr_idx].tx_buf[tx_idx].map;
@ -1205,8 +1269,8 @@ qla_send(qla_host_t *ha, struct mbuf **m_headp)
bus_dmamap_sync(ha->tx_tag, map, BUS_DMASYNC_PREWRITE); bus_dmamap_sync(ha->tx_tag, map, BUS_DMASYNC_PREWRITE);
if (!(ret = ql_hw_send(ha, segs, nsegs, tx_idx, m_head, txr_idx))) { if (!(ret = ql_hw_send(ha, segs, nsegs, tx_idx, m_head, txr_idx,
iscsi_pdu))) {
ha->tx_ring[txr_idx].count++; ha->tx_ring[txr_idx].count++;
ha->tx_ring[txr_idx].tx_buf[tx_idx].m_head = m_head; ha->tx_ring[txr_idx].tx_buf[tx_idx].m_head = m_head;
} else { } else {
@ -1510,15 +1574,23 @@ ql_get_mbuf(qla_host_t *ha, qla_rx_buf_t *rxb, struct mbuf *nmp)
int ret = 0; int ret = 0;
uint32_t offset; uint32_t offset;
bus_dma_segment_t segs[1]; bus_dma_segment_t segs[1];
int nsegs; int nsegs, mbuf_size;
QL_DPRINT2(ha, (ha->pci_dev, "%s: enter\n", __func__)); QL_DPRINT2(ha, (ha->pci_dev, "%s: enter\n", __func__));
ifp = ha->ifp; ifp = ha->ifp;
if (ha->hw.enable_9kb)
mbuf_size = MJUM9BYTES;
else
mbuf_size = MCLBYTES;
if (mp == NULL) { if (mp == NULL) {
mp = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR); if (ha->hw.enable_9kb)
mp = m_getjcl(M_NOWAIT, MT_DATA, M_PKTHDR, mbuf_size);
else
mp = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
if (mp == NULL) { if (mp == NULL) {
ha->err_m_getcl++; ha->err_m_getcl++;
@ -1527,9 +1599,9 @@ ql_get_mbuf(qla_host_t *ha, qla_rx_buf_t *rxb, struct mbuf *nmp)
"%s: m_getcl failed\n", __func__); "%s: m_getcl failed\n", __func__);
goto exit_ql_get_mbuf; goto exit_ql_get_mbuf;
} }
mp->m_len = mp->m_pkthdr.len = MCLBYTES; mp->m_len = mp->m_pkthdr.len = mbuf_size;
} else { } else {
mp->m_len = mp->m_pkthdr.len = MCLBYTES; mp->m_len = mp->m_pkthdr.len = mbuf_size;
mp->m_data = mp->m_ext.ext_buf; mp->m_data = mp->m_ext.ext_buf;
mp->m_next = NULL; mp->m_next = NULL;
} }
@ -1630,6 +1702,9 @@ qla_error_recovery(void *context, int pending)
(void)QLA_LOCK(ha, __func__, 0); (void)QLA_LOCK(ha, __func__, 0);
ha->hw.imd_compl = 1;
qla_mdelay(__func__, 300);
ha->flags.stop_rcv = 1; ha->flags.stop_rcv = 1;
ql_hw_stop_rcv(ha); ql_hw_stop_rcv(ha);
@ -1682,6 +1757,7 @@ qla_error_recovery(void *context, int pending)
QLA_UNLOCK(ha, __func__); QLA_UNLOCK(ha, __func__);
return; return;
} }
qla_confirm_9kb_enable(ha);
if (qla_alloc_rcv_bufs(ha) != 0) { if (qla_alloc_rcv_bufs(ha) != 0) {
QLA_UNLOCK(ha, __func__); QLA_UNLOCK(ha, __func__);
@ -1699,3 +1775,13 @@ qla_error_recovery(void *context, int pending)
QLA_UNLOCK(ha, __func__); QLA_UNLOCK(ha, __func__);
} }
static void
qla_async_event(void *context, int pending)
{
qla_host_t *ha = context;
(void)QLA_LOCK(ha, __func__, 0);
qla_hw_async_event(ha);
QLA_UNLOCK(ha, __func__);
}

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2014 Qlogic Corporation * Copyright (c) 2013-2016 Qlogic Corporation
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2014 Qlogic Corporation * Copyright (c) 2013-2016 Qlogic Corporation
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2014 Qlogic Corporation * Copyright (c) 2013-2016 Qlogic Corporation
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -140,8 +140,4 @@ typedef struct _q8_rdmwr_e {
uint32_t wr_addr; uint32_t wr_addr;
} q8_rdmwr_e_t; } q8_rdmwr_e_t;
extern unsigned char ql83xx_resetseq[];
extern unsigned int ql83xx_resetseq_len;
#endif /* #ifndef _QL_TMPLT_H_ */ #endif /* #ifndef _QL_TMPLT_H_ */

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013-2014 Qlogic Corporation * Copyright (c) 2013-2016 Qlogic Corporation
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -36,6 +36,6 @@
#define QLA_VERSION_MAJOR 3 #define QLA_VERSION_MAJOR 3
#define QLA_VERSION_MINOR 10 #define QLA_VERSION_MINOR 10
#define QLA_VERSION_BUILD 10 #define QLA_VERSION_BUILD 24
#endif /* #ifndef _QL_VER_H_ */ #endif /* #ifndef _QL_VER_H_ */

View File

@ -1,5 +1,5 @@
#/* #/*
# * Copyright (c) 2011-2012 Qlogic Corporation # * Copyright (c) 2011-2016 Qlogic Corporation
# * All rights reserved. # * All rights reserved.
# * # *
# * Redistribution and use in source and binary forms, with or without # * Redistribution and use in source and binary forms, with or without
@ -37,8 +37,18 @@
KMOD=if_qlxgbe KMOD=if_qlxgbe
SRCS=ql_os.c ql_dbg.c ql_hw.c ql_misc.c ql_isr.c ql_ioctl.c SRCS=ql_os.c ql_dbg.c ql_hw.c ql_misc.c ql_isr.c ql_ioctl.c
SRCS+= ql_reset.c SRCS+= ql_reset.c
SRCS+= ql_fw.c
SRCS+= ql_boot.c
SRCS+= ql_minidump.c
SRCS+= device_if.h bus_if.h pci_if.h SRCS+= device_if.h bus_if.h pci_if.h
#CFLAGS += -DQL_DBG #CFLAGS += -DQL_DBG
# 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
#CFLAGS += -DQL_ENABLE_ISCSI_TLV
#CFLAGS += -DQL_LDFLASH_FW
.include <bsd.kmod.mk> .include <bsd.kmod.mk>