summaryrefslogtreecommitdiffstats
path: root/sys/dev/cxgbe/common
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/cxgbe/common')
-rw-r--r--sys/dev/cxgbe/common/common.h18
-rw-r--r--sys/dev/cxgbe/common/t4_hw.c145
-rw-r--r--sys/dev/cxgbe/common/t4_hw.h18
-rw-r--r--sys/dev/cxgbe/common/t4_msg.h13
-rw-r--r--sys/dev/cxgbe/common/t4_regs_values.h53
5 files changed, 207 insertions, 40 deletions
diff --git a/sys/dev/cxgbe/common/common.h b/sys/dev/cxgbe/common/common.h
index 1e58c38..22edff6 100644
--- a/sys/dev/cxgbe/common/common.h
+++ b/sys/dev/cxgbe/common/common.h
@@ -67,16 +67,6 @@ enum {
PAUSE_AUTONEG = 1 << 2
};
-#define FW_VERSION_MAJOR_T4 1
-#define FW_VERSION_MINOR_T4 8
-#define FW_VERSION_MICRO_T4 4
-#define FW_VERSION_BUILD_T4 0
-
-#define FW_VERSION_MAJOR_T5 0
-#define FW_VERSION_MINOR_T5 5
-#define FW_VERSION_MICRO_T5 18
-#define FW_VERSION_BUILD_T5 0
-
struct memwin {
uint32_t base;
uint32_t aperture;
@@ -229,6 +219,12 @@ struct tp_params {
unsigned int dack_re; /* DACK timer resolution */
unsigned int la_mask; /* what events are recorded by TP LA */
unsigned short tx_modq[NCHAN]; /* channel to modulation queue map */
+ uint32_t vlan_pri_map;
+ uint32_t ingress_config;
+ int8_t vlan_shift;
+ int8_t vnic_shift;
+ int8_t port_shift;
+ int8_t protocol_shift;
};
struct vpd_params {
@@ -431,6 +427,8 @@ int t4_get_tp_version(struct adapter *adapter, u32 *vers);
int t4_check_fw_version(struct adapter *adapter);
int t4_init_hw(struct adapter *adapter, u32 fw_params);
int t4_prep_adapter(struct adapter *adapter);
+int t4_init_tp_params(struct adapter *adap);
+int t4_filter_field_shift(const struct adapter *adap, int filter_sel);
int t4_port_init(struct port_info *p, int mbox, int pf, int vf);
int t4_reinit_adapter(struct adapter *adap);
void t4_fatal_err(struct adapter *adapter);
diff --git a/sys/dev/cxgbe/common/t4_hw.c b/sys/dev/cxgbe/common/t4_hw.c
index d1f8fd7..3005f63 100644
--- a/sys/dev/cxgbe/common/t4_hw.c
+++ b/sys/dev/cxgbe/common/t4_hw.c
@@ -975,14 +975,14 @@ int t4_check_fw_version(struct adapter *adapter)
switch (chip_id(adapter)) {
case CHELSIO_T4:
- exp_major = FW_VERSION_MAJOR_T4;
- exp_minor = FW_VERSION_MINOR_T4;
- exp_micro = FW_VERSION_MICRO_T4;
+ exp_major = T4FW_VERSION_MAJOR;
+ exp_minor = T4FW_VERSION_MINOR;
+ exp_micro = T4FW_VERSION_MICRO;
break;
case CHELSIO_T5:
- exp_major = FW_VERSION_MAJOR_T5;
- exp_minor = FW_VERSION_MINOR_T5;
- exp_micro = FW_VERSION_MICRO_T5;
+ exp_major = T5FW_VERSION_MAJOR;
+ exp_minor = T5FW_VERSION_MINOR;
+ exp_micro = T5FW_VERSION_MICRO;
break;
default:
CH_ERR(adapter, "Unsupported chip type, %x\n",
@@ -1128,7 +1128,19 @@ int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size)
const u32 *p = (const u32 *)fw_data;
const struct fw_hdr *hdr = (const struct fw_hdr *)fw_data;
unsigned int sf_sec_size = adap->params.sf_size / adap->params.sf_nsec;
-
+ unsigned int fw_start_sec;
+ unsigned int fw_start;
+ unsigned int fw_size;
+
+ if (ntohl(hdr->magic) == FW_HDR_MAGIC_BOOTSTRAP) {
+ fw_start_sec = FLASH_FWBOOTSTRAP_START_SEC;
+ fw_start = FLASH_FWBOOTSTRAP_START;
+ fw_size = FLASH_FWBOOTSTRAP_MAX_SIZE;
+ } else {
+ fw_start_sec = FLASH_FW_START_SEC;
+ fw_start = FLASH_FW_START;
+ fw_size = FLASH_FW_MAX_SIZE;
+ }
if (!size) {
CH_ERR(adap, "FW image has no data\n");
return -EINVAL;
@@ -1141,9 +1153,8 @@ int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size)
CH_ERR(adap, "FW image size differs from size in FW header\n");
return -EINVAL;
}
- if (size > FLASH_FW_MAX_SIZE) {
- CH_ERR(adap, "FW image too large, max is %u bytes\n",
- FLASH_FW_MAX_SIZE);
+ if (size > fw_size) {
+ CH_ERR(adap, "FW image too large, max is %u bytes\n", fw_size);
return -EFBIG;
}
if ((is_t4(adap) && hdr->chip != FW_HDR_CHIP_T4) ||
@@ -1164,8 +1175,7 @@ int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size)
}
i = DIV_ROUND_UP(size, sf_sec_size); /* # of sectors spanned */
- ret = t4_flash_erase_sectors(adap, FLASH_FW_START_SEC,
- FLASH_FW_START_SEC + i - 1);
+ ret = t4_flash_erase_sectors(adap, fw_start_sec, fw_start_sec + i - 1);
if (ret)
goto out;
@@ -1176,11 +1186,11 @@ int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size)
*/
memcpy(first_page, fw_data, SF_PAGE_SIZE);
((struct fw_hdr *)first_page)->fw_ver = htonl(0xffffffff);
- ret = t4_write_flash(adap, FLASH_FW_START, SF_PAGE_SIZE, first_page, 1);
+ ret = t4_write_flash(adap, fw_start, SF_PAGE_SIZE, first_page, 1);
if (ret)
goto out;
- addr = FLASH_FW_START;
+ addr = fw_start;
for (size -= SF_PAGE_SIZE; size; size -= SF_PAGE_SIZE) {
addr += SF_PAGE_SIZE;
fw_data += SF_PAGE_SIZE;
@@ -1190,7 +1200,7 @@ int t4_load_fw(struct adapter *adap, const u8 *fw_data, unsigned int size)
}
ret = t4_write_flash(adap,
- FLASH_FW_START + offsetof(struct fw_hdr, fw_ver),
+ fw_start + offsetof(struct fw_hdr, fw_ver),
sizeof(hdr->fw_ver), (const u8 *)&hdr->fw_ver, 1);
out:
if (ret)
@@ -4622,14 +4632,17 @@ int t4_fw_upgrade(struct adapter *adap, unsigned int mbox,
const u8 *fw_data, unsigned int size, int force)
{
const struct fw_hdr *fw_hdr = (const struct fw_hdr *)fw_data;
+ unsigned int bootstrap = ntohl(fw_hdr->magic) == FW_HDR_MAGIC_BOOTSTRAP;
int reset, ret;
- ret = t4_fw_halt(adap, mbox, force);
- if (ret < 0 && !force)
- return ret;
+ if (!bootstrap) {
+ ret = t4_fw_halt(adap, mbox, force);
+ if (ret < 0 && !force)
+ return ret;
+ }
ret = t4_load_fw(adap, fw_data, size);
- if (ret < 0)
+ if (ret < 0 || bootstrap)
return ret;
/*
@@ -5338,11 +5351,18 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
if (link_ok != lc->link_ok || speed != lc->speed ||
fc != lc->fc) { /* something changed */
+ int reason;
+
+ if (!link_ok && lc->link_ok)
+ reason = G_FW_PORT_CMD_LINKDNRC(stat);
+ else
+ reason = -1;
+
lc->link_ok = link_ok;
lc->speed = speed;
lc->fc = fc;
lc->supported = ntohs(p->u.info.pcap);
- t4_os_link_changed(adap, i, link_ok);
+ t4_os_link_changed(adap, i, link_ok, reason);
}
if (mod != pi->mod_type) {
pi->mod_type = mod;
@@ -5508,6 +5528,91 @@ int __devinit t4_prep_adapter(struct adapter *adapter)
return 0;
}
+/**
+ * t4_init_tp_params - initialize adap->params.tp
+ * @adap: the adapter
+ *
+ * Initialize various fields of the adapter's TP Parameters structure.
+ */
+int __devinit t4_init_tp_params(struct adapter *adap)
+{
+ int chan;
+ u32 v;
+
+ v = t4_read_reg(adap, A_TP_TIMER_RESOLUTION);
+ adap->params.tp.tre = G_TIMERRESOLUTION(v);
+ adap->params.tp.dack_re = G_DELAYEDACKRESOLUTION(v);
+
+ /* MODQ_REQ_MAP defaults to setting queues 0-3 to chan 0-3 */
+ for (chan = 0; chan < NCHAN; chan++)
+ adap->params.tp.tx_modq[chan] = chan;
+
+ /*
+ * Cache the adapter's Compressed Filter Mode and global Incress
+ * Configuration.
+ */
+ t4_read_indirect(adap, A_TP_PIO_ADDR, A_TP_PIO_DATA,
+ &adap->params.tp.vlan_pri_map, 1,
+ A_TP_VLAN_PRI_MAP);
+ t4_read_indirect(adap, A_TP_PIO_ADDR, A_TP_PIO_DATA,
+ &adap->params.tp.ingress_config, 1,
+ A_TP_INGRESS_CONFIG);
+
+ /*
+ * Now that we have TP_VLAN_PRI_MAP cached, we can calculate the field
+ * shift positions of several elements of the Compressed Filter Tuple
+ * for this adapter which we need frequently ...
+ */
+ adap->params.tp.vlan_shift = t4_filter_field_shift(adap, F_VLAN);
+ adap->params.tp.vnic_shift = t4_filter_field_shift(adap, F_VNIC_ID);
+ adap->params.tp.port_shift = t4_filter_field_shift(adap, F_PORT);
+ adap->params.tp.protocol_shift = t4_filter_field_shift(adap, F_PROTOCOL);
+
+ /*
+ * If TP_INGRESS_CONFIG.VNID == 0, then TP_VLAN_PRI_MAP.VNIC_ID
+ * represents the presense of an Outer VLAN instead of a VNIC ID.
+ */
+ if ((adap->params.tp.ingress_config & F_VNIC) == 0)
+ adap->params.tp.vnic_shift = -1;
+
+ return 0;
+}
+
+/**
+ * t4_filter_field_shift - calculate filter field shift
+ * @adap: the adapter
+ * @filter_sel: the desired field (from TP_VLAN_PRI_MAP bits)
+ *
+ * Return the shift position of a filter field within the Compressed
+ * Filter Tuple. The filter field is specified via its selection bit
+ * within TP_VLAN_PRI_MAL (filter mode). E.g. F_VLAN.
+ */
+int t4_filter_field_shift(const struct adapter *adap, int filter_sel)
+{
+ unsigned int filter_mode = adap->params.tp.vlan_pri_map;
+ unsigned int sel;
+ int field_shift;
+
+ if ((filter_mode & filter_sel) == 0)
+ return -1;
+
+ for (sel = 1, field_shift = 0; sel < filter_sel; sel <<= 1) {
+ switch (filter_mode & sel) {
+ case F_FCOE: field_shift += W_FT_FCOE; break;
+ case F_PORT: field_shift += W_FT_PORT; break;
+ case F_VNIC_ID: field_shift += W_FT_VNIC_ID; break;
+ case F_VLAN: field_shift += W_FT_VLAN; break;
+ case F_TOS: field_shift += W_FT_TOS; break;
+ case F_PROTOCOL: field_shift += W_FT_PROTOCOL; break;
+ case F_ETHERTYPE: field_shift += W_FT_ETHERTYPE; break;
+ case F_MACMATCH: field_shift += W_FT_MACMATCH; break;
+ case F_MPSHITTYPE: field_shift += W_FT_MPSHITTYPE; break;
+ case F_FRAGMENTATION: field_shift += W_FT_FRAGMENTATION; break;
+ }
+ }
+ return field_shift;
+}
+
int __devinit t4_port_init(struct port_info *p, int mbox, int pf, int vf)
{
u8 addr[6];
diff --git a/sys/dev/cxgbe/common/t4_hw.h b/sys/dev/cxgbe/common/t4_hw.h
index 8b94169..3bc2096 100644
--- a/sys/dev/cxgbe/common/t4_hw.h
+++ b/sys/dev/cxgbe/common/t4_hw.h
@@ -230,7 +230,15 @@ enum {
FLASH_FW_NSECS = 16,
FLASH_FW_START = FLASH_START(FLASH_FW_START_SEC),
FLASH_FW_MAX_SIZE = FLASH_MAX_SIZE(FLASH_FW_NSECS),
-
+
+ /*
+ * Location of bootstrap firmware image in FLASH.
+ */
+ FLASH_FWBOOTSTRAP_START_SEC = 27,
+ FLASH_FWBOOTSTRAP_NSECS = 1,
+ FLASH_FWBOOTSTRAP_START = FLASH_START(FLASH_FWBOOTSTRAP_START_SEC),
+ FLASH_FWBOOTSTRAP_MAX_SIZE = FLASH_MAX_SIZE(FLASH_FWBOOTSTRAP_NSECS),
+
/*
* iSCSI persistent/crash information.
*/
@@ -248,19 +256,13 @@ enum {
FLASH_FCOE_CRASH_MAX_SIZE = FLASH_MAX_SIZE(FLASH_FCOE_CRASH_NSECS),
/*
- * Location of Firmware Configuration File in FLASH. Since the FPGA
- * "FLASH" is smaller we need to store the Configuration File in a
- * different location -- which will overlap the end of the firmware
- * image if firmware ever gets that large ...
+ * Location of Firmware Configuration File in FLASH.
*/
FLASH_CFG_START_SEC = 31,
FLASH_CFG_NSECS = 1,
FLASH_CFG_START = FLASH_START(FLASH_CFG_START_SEC),
FLASH_CFG_MAX_SIZE = FLASH_MAX_SIZE(FLASH_CFG_NSECS),
- FLASH_FPGA_CFG_START_SEC = 15,
- FLASH_FPGA_CFG_START = FLASH_START(FLASH_FPGA_CFG_START_SEC),
-
/*
* Sectors 32-63 are reserved for FLASH failover.
*/
diff --git a/sys/dev/cxgbe/common/t4_msg.h b/sys/dev/cxgbe/common/t4_msg.h
index 5988070..ef8fbe6 100644
--- a/sys/dev/cxgbe/common/t4_msg.h
+++ b/sys/dev/cxgbe/common/t4_msg.h
@@ -678,6 +678,15 @@ struct cpl_pass_accept_rpl {
__be64 opt0;
};
+struct cpl_t5_pass_accept_rpl {
+ WR_HDR;
+ union opcode_tid ot;
+ __be32 opt2;
+ __be64 opt0;
+ __be32 iss;
+ __be32 rsvd;
+};
+
struct cpl_act_open_req {
WR_HDR;
union opcode_tid ot;
@@ -702,7 +711,7 @@ struct cpl_t5_act_open_req {
__be32 local_ip;
__be32 peer_ip;
__be64 opt0;
- __be32 rsvd;
+ __be32 iss;
__be32 opt2;
__be64 params;
};
@@ -731,7 +740,7 @@ struct cpl_t5_act_open_req6 {
__be64 peer_ip_hi;
__be64 peer_ip_lo;
__be64 opt0;
- __be32 rsvd;
+ __be32 iss;
__be32 opt2;
__be64 params;
};
diff --git a/sys/dev/cxgbe/common/t4_regs_values.h b/sys/dev/cxgbe/common/t4_regs_values.h
index aacda81..40dabf1 100644
--- a/sys/dev/cxgbe/common/t4_regs_values.h
+++ b/sys/dev/cxgbe/common/t4_regs_values.h
@@ -189,4 +189,57 @@
#define X_MBOWNER_FW 1
#define X_MBOWNER_PL 2
+/*
+ * PCI-E definitions.
+ * ==================
+ */
+
+#define X_WINDOW_SHIFT 10
+#define X_PCIEOFST_SHIFT 10
+
+/*
+ * TP definitions.
+ * ===============
+ */
+
+/*
+ * TP_VLAN_PRI_MAP controls which subset of fields will be present in the
+ * Compressed Filter Tuple for LE filters. Each bit set in TP_VLAN_PRI_MAP
+ * selects for a particular field being present. These fields, when present
+ * in the Compressed Filter Tuple, have the following widths in bits.
+ */
+#define W_FT_FCOE 1
+#define W_FT_PORT 3
+#define W_FT_VNIC_ID 17
+#define W_FT_VLAN 17
+#define W_FT_TOS 8
+#define W_FT_PROTOCOL 8
+#define W_FT_ETHERTYPE 16
+#define W_FT_MACMATCH 9
+#define W_FT_MPSHITTYPE 3
+#define W_FT_FRAGMENTATION 1
+
+/*
+ * Some of the Compressed Filter Tuple fields have internal structure. These
+ * bit shifts/masks describe those structures. All shifts are relative to the
+ * base position of the fields within the Compressed Filter Tuple
+ */
+#define S_FT_VLAN_VLD 16
+#define V_FT_VLAN_VLD(x) ((x) << S_FT_VLAN_VLD)
+#define F_FT_VLAN_VLD V_FT_VLAN_VLD(1U)
+
+#define S_FT_VNID_ID_VF 0
+#define M_FT_VNID_ID_VF 0x7fU
+#define V_FT_VNID_ID_VF(x) ((x) << S_FT_VNID_ID_VF)
+#define G_FT_VNID_ID_VF(x) (((x) >> S_FT_VNID_ID_VF) & M_FT_VNID_ID_VF)
+
+#define S_FT_VNID_ID_PF 7
+#define M_FT_VNID_ID_PF 0x7U
+#define V_FT_VNID_ID_PF(x) ((x) << S_FT_VNID_ID_PF)
+#define G_FT_VNID_ID_PF(x) (((x) >> S_FT_VNID_ID_PF) & M_FT_VNID_ID_PF)
+
+#define S_FT_VNID_ID_VLD 16
+#define V_FT_VNID_ID_VLD(x) ((x) << S_FT_VNID_ID_VLD)
+#define F_FT_VNID_ID_VLD(x) V_FT_VNID_ID_VLD(1U)
+
#endif /* __T4_REGS_VALUES_H__ */
OpenPOWER on IntegriCloud