aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorByczkowski, Jakub <jakub.byczkowski@intel.com>2017-05-12 12:01:37 -0400
committerDoug Ledford <dledford@redhat.com>2017-06-01 17:04:20 -0400
commitb3e6b4bdbb609762d8401ac4a959d590b4e4e3b8 (patch)
tree87997267ddfad332c0773f2adf807eea6e9803a4
parente4785b0633574a607daaa04bf2fe43550055194f (diff)
RDMA/hfi1: Defer setting VL15 credits to link-up interrupt
Keep VL15 credits at 0 during LNI, before link-up. Store VL15 credits value during verify cap interrupt and set in after link-up. This addresses an issue where VL15 MAD packets could be sent by one side of the link before the other side is ready to receive them. Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com> Reviewed-by: Dean Luick <dean.luick@intel.com> Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Jakub Byczkowski <jakub.byczkowski@intel.com> Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
-rw-r--r--drivers/infiniband/hw/hfi1/chip.c67
-rw-r--r--drivers/infiniband/hw/hfi1/chip_registers.h2
-rw-r--r--drivers/infiniband/hw/hfi1/hfi.h11
-rw-r--r--drivers/infiniband/hw/hfi1/intr.c3
4 files changed, 64 insertions, 19 deletions
diff --git a/drivers/infiniband/hw/hfi1/chip.c b/drivers/infiniband/hw/hfi1/chip.c
index 5d6b1eeaa9a0..2ba00b89df6a 100644
--- a/drivers/infiniband/hw/hfi1/chip.c
+++ b/drivers/infiniband/hw/hfi1/chip.c
@@ -6312,25 +6312,38 @@ static void handle_8051_request(struct hfi1_pportdata *ppd)
6312 } 6312 }
6313} 6313}
6314 6314
6315static void write_global_credit(struct hfi1_devdata *dd, 6315/*
6316 u8 vau, u16 total, u16 shared) 6316 * Set up allocation unit vaulue.
6317 */
6318void set_up_vau(struct hfi1_devdata *dd, u8 vau)
6317{ 6319{
6318 write_csr(dd, SEND_CM_GLOBAL_CREDIT, 6320 u64 reg = read_csr(dd, SEND_CM_GLOBAL_CREDIT);
6319 ((u64)total << 6321
6320 SEND_CM_GLOBAL_CREDIT_TOTAL_CREDIT_LIMIT_SHIFT) | 6322 /* do not modify other values in the register */
6321 ((u64)shared << 6323 reg &= ~SEND_CM_GLOBAL_CREDIT_AU_SMASK;
6322 SEND_CM_GLOBAL_CREDIT_SHARED_LIMIT_SHIFT) | 6324 reg |= (u64)vau << SEND_CM_GLOBAL_CREDIT_AU_SHIFT;
6323 ((u64)vau << SEND_CM_GLOBAL_CREDIT_AU_SHIFT)); 6325 write_csr(dd, SEND_CM_GLOBAL_CREDIT, reg);
6324} 6326}
6325 6327
6326/* 6328/*
6327 * Set up initial VL15 credits of the remote. Assumes the rest of 6329 * Set up initial VL15 credits of the remote. Assumes the rest of
6328 * the CM credit registers are zero from a previous global or credit reset . 6330 * the CM credit registers are zero from a previous global or credit reset.
6331 * Shared limit for VL15 will always be 0.
6329 */ 6332 */
6330void set_up_vl15(struct hfi1_devdata *dd, u8 vau, u16 vl15buf) 6333void set_up_vl15(struct hfi1_devdata *dd, u16 vl15buf)
6331{ 6334{
6332 /* leave shared count at zero for both global and VL15 */ 6335 u64 reg = read_csr(dd, SEND_CM_GLOBAL_CREDIT);
6333 write_global_credit(dd, vau, vl15buf, 0); 6336
6337 /* set initial values for total and shared credit limit */
6338 reg &= ~(SEND_CM_GLOBAL_CREDIT_TOTAL_CREDIT_LIMIT_SMASK |
6339 SEND_CM_GLOBAL_CREDIT_SHARED_LIMIT_SMASK);
6340
6341 /*
6342 * Set total limit to be equal to VL15 credits.
6343 * Leave shared limit at 0.
6344 */
6345 reg |= (u64)vl15buf << SEND_CM_GLOBAL_CREDIT_TOTAL_CREDIT_LIMIT_SHIFT;
6346 write_csr(dd, SEND_CM_GLOBAL_CREDIT, reg);
6334 6347
6335 write_csr(dd, SEND_CM_CREDIT_VL15, (u64)vl15buf 6348 write_csr(dd, SEND_CM_CREDIT_VL15, (u64)vl15buf
6336 << SEND_CM_CREDIT_VL15_DEDICATED_LIMIT_VL_SHIFT); 6349 << SEND_CM_CREDIT_VL15_DEDICATED_LIMIT_VL_SHIFT);
@@ -6348,9 +6361,11 @@ void reset_link_credits(struct hfi1_devdata *dd)
6348 for (i = 0; i < TXE_NUM_DATA_VL; i++) 6361 for (i = 0; i < TXE_NUM_DATA_VL; i++)
6349 write_csr(dd, SEND_CM_CREDIT_VL + (8 * i), 0); 6362 write_csr(dd, SEND_CM_CREDIT_VL + (8 * i), 0);
6350 write_csr(dd, SEND_CM_CREDIT_VL15, 0); 6363 write_csr(dd, SEND_CM_CREDIT_VL15, 0);
6351 write_global_credit(dd, 0, 0, 0); 6364 write_csr(dd, SEND_CM_GLOBAL_CREDIT, 0);
6352 /* reset the CM block */ 6365 /* reset the CM block */
6353 pio_send_control(dd, PSC_CM_RESET); 6366 pio_send_control(dd, PSC_CM_RESET);
6367 /* reset cached value */
6368 dd->vl15buf_cached = 0;
6354} 6369}
6355 6370
6356/* convert a vCU to a CU */ 6371/* convert a vCU to a CU */
@@ -6839,24 +6854,35 @@ void handle_link_up(struct work_struct *work)
6839{ 6854{
6840 struct hfi1_pportdata *ppd = container_of(work, struct hfi1_pportdata, 6855 struct hfi1_pportdata *ppd = container_of(work, struct hfi1_pportdata,
6841 link_up_work); 6856 link_up_work);
6857 struct hfi1_devdata *dd = ppd->dd;
6858
6842 set_link_state(ppd, HLS_UP_INIT); 6859 set_link_state(ppd, HLS_UP_INIT);
6843 6860
6844 /* cache the read of DC_LCB_STS_ROUND_TRIP_LTP_CNT */ 6861 /* cache the read of DC_LCB_STS_ROUND_TRIP_LTP_CNT */
6845 read_ltp_rtt(ppd->dd); 6862 read_ltp_rtt(dd);
6846 /* 6863 /*
6847 * OPA specifies that certain counters are cleared on a transition 6864 * OPA specifies that certain counters are cleared on a transition
6848 * to link up, so do that. 6865 * to link up, so do that.
6849 */ 6866 */
6850 clear_linkup_counters(ppd->dd); 6867 clear_linkup_counters(dd);
6851 /* 6868 /*
6852 * And (re)set link up default values. 6869 * And (re)set link up default values.
6853 */ 6870 */
6854 set_linkup_defaults(ppd); 6871 set_linkup_defaults(ppd);
6855 6872
6873 /*
6874 * Set VL15 credits. Use cached value from verify cap interrupt.
6875 * In case of quick linkup or simulator, vl15 value will be set by
6876 * handle_linkup_change. VerifyCap interrupt handler will not be
6877 * called in those scenarios.
6878 */
6879 if (!(quick_linkup || dd->icode == ICODE_FUNCTIONAL_SIMULATOR))
6880 set_up_vl15(dd, dd->vl15buf_cached);
6881
6856 /* enforce link speed enabled */ 6882 /* enforce link speed enabled */
6857 if ((ppd->link_speed_active & ppd->link_speed_enabled) == 0) { 6883 if ((ppd->link_speed_active & ppd->link_speed_enabled) == 0) {
6858 /* oops - current speed is not enabled, bounce */ 6884 /* oops - current speed is not enabled, bounce */
6859 dd_dev_err(ppd->dd, 6885 dd_dev_err(dd,
6860 "Link speed active 0x%x is outside enabled 0x%x, downing link\n", 6886 "Link speed active 0x%x is outside enabled 0x%x, downing link\n",
6861 ppd->link_speed_active, ppd->link_speed_enabled); 6887 ppd->link_speed_active, ppd->link_speed_enabled);
6862 set_link_down_reason(ppd, OPA_LINKDOWN_REASON_SPEED_POLICY, 0, 6888 set_link_down_reason(ppd, OPA_LINKDOWN_REASON_SPEED_POLICY, 0,
@@ -7357,7 +7383,14 @@ void handle_verify_cap(struct work_struct *work)
7357 */ 7383 */
7358 if (vau == 0) 7384 if (vau == 0)
7359 vau = 1; 7385 vau = 1;
7360 set_up_vl15(dd, vau, vl15buf); 7386 set_up_vau(dd, vau);
7387
7388 /*
7389 * Set VL15 credits to 0 in global credit register. Cache remote VL15
7390 * credits value and wait for link-up interrupt ot set it.
7391 */
7392 set_up_vl15(dd, 0);
7393 dd->vl15buf_cached = vl15buf;
7361 7394
7362 /* set up the LCB CRC mode */ 7395 /* set up the LCB CRC mode */
7363 crc_mask = ppd->port_crc_mode_enabled & partner_supported_crc; 7396 crc_mask = ppd->port_crc_mode_enabled & partner_supported_crc;
diff --git a/drivers/infiniband/hw/hfi1/chip_registers.h b/drivers/infiniband/hw/hfi1/chip_registers.h
index 5bfa839d1c48..793514f1d15f 100644
--- a/drivers/infiniband/hw/hfi1/chip_registers.h
+++ b/drivers/infiniband/hw/hfi1/chip_registers.h
@@ -839,7 +839,9 @@
839#define SEND_CM_CTRL_FORCE_CREDIT_MODE_SMASK 0x8ull 839#define SEND_CM_CTRL_FORCE_CREDIT_MODE_SMASK 0x8ull
840#define SEND_CM_CTRL_RESETCSR 0x0000000000000020ull 840#define SEND_CM_CTRL_RESETCSR 0x0000000000000020ull
841#define SEND_CM_GLOBAL_CREDIT (TXE + 0x000000000508) 841#define SEND_CM_GLOBAL_CREDIT (TXE + 0x000000000508)
842#define SEND_CM_GLOBAL_CREDIT_AU_MASK 0x7ull
842#define SEND_CM_GLOBAL_CREDIT_AU_SHIFT 16 843#define SEND_CM_GLOBAL_CREDIT_AU_SHIFT 16
844#define SEND_CM_GLOBAL_CREDIT_AU_SMASK 0x70000ull
843#define SEND_CM_GLOBAL_CREDIT_RESETCSR 0x0000094000030000ull 845#define SEND_CM_GLOBAL_CREDIT_RESETCSR 0x0000094000030000ull
844#define SEND_CM_GLOBAL_CREDIT_SHARED_LIMIT_MASK 0xFFFFull 846#define SEND_CM_GLOBAL_CREDIT_SHARED_LIMIT_MASK 0xFFFFull
845#define SEND_CM_GLOBAL_CREDIT_SHARED_LIMIT_SHIFT 0 847#define SEND_CM_GLOBAL_CREDIT_SHARED_LIMIT_SHIFT 0
diff --git a/drivers/infiniband/hw/hfi1/hfi.h b/drivers/infiniband/hw/hfi1/hfi.h
index da322e6668cc..414a04a481c2 100644
--- a/drivers/infiniband/hw/hfi1/hfi.h
+++ b/drivers/infiniband/hw/hfi1/hfi.h
@@ -1045,6 +1045,14 @@ struct hfi1_devdata {
1045 /* initial vl15 credits to use */ 1045 /* initial vl15 credits to use */
1046 u16 vl15_init; 1046 u16 vl15_init;
1047 1047
1048 /*
1049 * Cached value for vl15buf, read during verify cap interrupt. VL15
1050 * credits are to be kept at 0 and set when handling the link-up
1051 * interrupt. This removes the possibility of receiving VL15 MAD
1052 * packets before this HFI is ready.
1053 */
1054 u16 vl15buf_cached;
1055
1048 /* Misc small ints */ 1056 /* Misc small ints */
1049 u8 n_krcv_queues; 1057 u8 n_krcv_queues;
1050 u8 qos_shift; 1058 u8 qos_shift;
@@ -1598,7 +1606,8 @@ int hfi1_rcvbuf_validate(u32 size, u8 type, u16 *encode);
1598int fm_get_table(struct hfi1_pportdata *ppd, int which, void *t); 1606int fm_get_table(struct hfi1_pportdata *ppd, int which, void *t);
1599int fm_set_table(struct hfi1_pportdata *ppd, int which, void *t); 1607int fm_set_table(struct hfi1_pportdata *ppd, int which, void *t);
1600 1608
1601void set_up_vl15(struct hfi1_devdata *dd, u8 vau, u16 vl15buf); 1609void set_up_vau(struct hfi1_devdata *dd, u8 vau);
1610void set_up_vl15(struct hfi1_devdata *dd, u16 vl15buf);
1602void reset_link_credits(struct hfi1_devdata *dd); 1611void reset_link_credits(struct hfi1_devdata *dd);
1603void assign_remote_cm_au_table(struct hfi1_devdata *dd, u8 vcu); 1612void assign_remote_cm_au_table(struct hfi1_devdata *dd, u8 vcu);
1604 1613
diff --git a/drivers/infiniband/hw/hfi1/intr.c b/drivers/infiniband/hw/hfi1/intr.c
index ba265d0ae93b..04a5082d5ac5 100644
--- a/drivers/infiniband/hw/hfi1/intr.c
+++ b/drivers/infiniband/hw/hfi1/intr.c
@@ -130,7 +130,8 @@ void handle_linkup_change(struct hfi1_devdata *dd, u32 linkup)
130 * the remote values. Both sides must be using the values. 130 * the remote values. Both sides must be using the values.
131 */ 131 */
132 if (quick_linkup || dd->icode == ICODE_FUNCTIONAL_SIMULATOR) { 132 if (quick_linkup || dd->icode == ICODE_FUNCTIONAL_SIMULATOR) {
133 set_up_vl15(dd, dd->vau, dd->vl15_init); 133 set_up_vau(dd, dd->vau);
134 set_up_vl15(dd, dd->vl15_init);
134 assign_remote_cm_au_table(dd, dd->vcu); 135 assign_remote_cm_au_table(dd, dd->vcu);
135 } 136 }
136 137