|
@@ -6096,6 +6096,59 @@ int t4_fw_upgrade(struct adapter *adap, unsigned int mbox,
|
|
|
return t4_fw_restart(adap, mbox, reset);
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * t4_fl_pkt_align - return the fl packet alignment
|
|
|
+ * @adap: the adapter
|
|
|
+ *
|
|
|
+ * T4 has a single field to specify the packing and padding boundary.
|
|
|
+ * T5 onwards has separate fields for this and hence the alignment for
|
|
|
+ * next packet offset is maximum of these two.
|
|
|
+ *
|
|
|
+ */
|
|
|
+int t4_fl_pkt_align(struct adapter *adap)
|
|
|
+{
|
|
|
+ u32 sge_control, sge_control2;
|
|
|
+ unsigned int ingpadboundary, ingpackboundary, fl_align, ingpad_shift;
|
|
|
+
|
|
|
+ sge_control = t4_read_reg(adap, SGE_CONTROL_A);
|
|
|
+
|
|
|
+ /* T4 uses a single control field to specify both the PCIe Padding and
|
|
|
+ * Packing Boundary. T5 introduced the ability to specify these
|
|
|
+ * separately. The actual Ingress Packet Data alignment boundary
|
|
|
+ * within Packed Buffer Mode is the maximum of these two
|
|
|
+ * specifications. (Note that it makes no real practical sense to
|
|
|
+ * have the Pading Boudary be larger than the Packing Boundary but you
|
|
|
+ * could set the chip up that way and, in fact, legacy T4 code would
|
|
|
+ * end doing this because it would initialize the Padding Boundary and
|
|
|
+ * leave the Packing Boundary initialized to 0 (16 bytes).)
|
|
|
+ * Padding Boundary values in T6 starts from 8B,
|
|
|
+ * where as it is 32B for T4 and T5.
|
|
|
+ */
|
|
|
+ if (CHELSIO_CHIP_VERSION(adap->params.chip) <= CHELSIO_T5)
|
|
|
+ ingpad_shift = INGPADBOUNDARY_SHIFT_X;
|
|
|
+ else
|
|
|
+ ingpad_shift = T6_INGPADBOUNDARY_SHIFT_X;
|
|
|
+
|
|
|
+ ingpadboundary = 1 << (INGPADBOUNDARY_G(sge_control) + ingpad_shift);
|
|
|
+
|
|
|
+ fl_align = ingpadboundary;
|
|
|
+ if (!is_t4(adap->params.chip)) {
|
|
|
+ /* T5 has a weird interpretation of one of the PCIe Packing
|
|
|
+ * Boundary values. No idea why ...
|
|
|
+ */
|
|
|
+ sge_control2 = t4_read_reg(adap, SGE_CONTROL2_A);
|
|
|
+ ingpackboundary = INGPACKBOUNDARY_G(sge_control2);
|
|
|
+ if (ingpackboundary == INGPACKBOUNDARY_16B_X)
|
|
|
+ ingpackboundary = 16;
|
|
|
+ else
|
|
|
+ ingpackboundary = 1 << (ingpackboundary +
|
|
|
+ INGPACKBOUNDARY_SHIFT_X);
|
|
|
+
|
|
|
+ fl_align = max(ingpadboundary, ingpackboundary);
|
|
|
+ }
|
|
|
+ return fl_align;
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* t4_fixup_host_params - fix up host-dependent parameters
|
|
|
* @adap: the adapter
|
|
@@ -6114,6 +6167,7 @@ int t4_fixup_host_params(struct adapter *adap, unsigned int page_size,
|
|
|
unsigned int stat_len = cache_line_size > 64 ? 128 : 64;
|
|
|
unsigned int fl_align = cache_line_size < 32 ? 32 : cache_line_size;
|
|
|
unsigned int fl_align_log = fls(fl_align) - 1;
|
|
|
+ unsigned int ingpad;
|
|
|
|
|
|
t4_write_reg(adap, SGE_HOST_PAGE_SIZE_A,
|
|
|
HOSTPAGESIZEPF0_V(sge_hps) |
|
|
@@ -6161,10 +6215,16 @@ int t4_fixup_host_params(struct adapter *adap, unsigned int page_size,
|
|
|
fl_align = 64;
|
|
|
fl_align_log = 6;
|
|
|
}
|
|
|
+
|
|
|
+ if (is_t5(adap->params.chip))
|
|
|
+ ingpad = INGPCIEBOUNDARY_32B_X;
|
|
|
+ else
|
|
|
+ ingpad = T6_INGPADBOUNDARY_32B_X;
|
|
|
+
|
|
|
t4_set_reg_field(adap, SGE_CONTROL_A,
|
|
|
INGPADBOUNDARY_V(INGPADBOUNDARY_M) |
|
|
|
EGRSTATUSPAGESIZE_F,
|
|
|
- INGPADBOUNDARY_V(INGPCIEBOUNDARY_32B_X) |
|
|
|
+ INGPADBOUNDARY_V(ingpad) |
|
|
|
EGRSTATUSPAGESIZE_V(stat_len != 64));
|
|
|
t4_set_reg_field(adap, SGE_CONTROL2_A,
|
|
|
INGPACKBOUNDARY_V(INGPACKBOUNDARY_M),
|