summaryrefslogtreecommitdiffstats
path: root/drivers/ntb
diff options
context:
space:
mode:
authorLogan Gunthorpe <logang@deltatee.com>2017-11-29 12:55:30 -0500
committerJon Mason <jdmason@kudzu.us>2018-01-28 22:17:23 -0500
commit270d32e63c70c808a91449da24324e0009827c5f (patch)
tree231ff4460926ea111fdcf71d6901e0e97b15bb6b /drivers/ntb
parent01752501820277d217a7b52548d9c948f98d2c56 (diff)
ntb_hw_switchtec: Crosslink doorbells and messages
In a crosslink configuration doorbells and messages largely work the same but the NTB registers must be accessed through the reserved LUT window. Also, as a bonus, seeing there are now two independent sets of NTB links, both partitions can actually use all 60 doorbell registers instead of them having to be split into two for each partition. Signed-off-by: Logan Gunthorpe <logang@deltatee.com> Signed-off-by: Jon Mason <jdmason@kudzu.us>
Diffstat (limited to 'drivers/ntb')
-rw-r--r--drivers/ntb/hw/mscc/ntb_hw_switchtec.c65
1 files changed, 55 insertions, 10 deletions
diff --git a/drivers/ntb/hw/mscc/ntb_hw_switchtec.c b/drivers/ntb/hw/mscc/ntb_hw_switchtec.c
index 17db0f50bb22..145b31209f20 100644
--- a/drivers/ntb/hw/mscc/ntb_hw_switchtec.c
+++ b/drivers/ntb/hw/mscc/ntb_hw_switchtec.c
@@ -94,6 +94,7 @@ struct switchtec_ntb {
94 struct ntb_ctrl_regs __iomem *mmio_self_ctrl; 94 struct ntb_ctrl_regs __iomem *mmio_self_ctrl;
95 struct ntb_ctrl_regs __iomem *mmio_peer_ctrl; 95 struct ntb_ctrl_regs __iomem *mmio_peer_ctrl;
96 struct ntb_dbmsg_regs __iomem *mmio_self_dbmsg; 96 struct ntb_dbmsg_regs __iomem *mmio_self_dbmsg;
97 struct ntb_dbmsg_regs __iomem *mmio_peer_dbmsg;
97 98
98 void __iomem *mmio_xlink_win; 99 void __iomem *mmio_xlink_win;
99 100
@@ -188,10 +189,10 @@ static int switchtec_ntb_part_op(struct switchtec_ntb *sndev,
188static int switchtec_ntb_send_msg(struct switchtec_ntb *sndev, int idx, 189static int switchtec_ntb_send_msg(struct switchtec_ntb *sndev, int idx,
189 u32 val) 190 u32 val)
190{ 191{
191 if (idx < 0 || idx >= ARRAY_SIZE(sndev->mmio_self_dbmsg->omsg)) 192 if (idx < 0 || idx >= ARRAY_SIZE(sndev->mmio_peer_dbmsg->omsg))
192 return -EINVAL; 193 return -EINVAL;
193 194
194 iowrite32(val, &sndev->mmio_self_dbmsg->omsg[idx].msg); 195 iowrite32(val, &sndev->mmio_peer_dbmsg->omsg[idx].msg);
195 196
196 return 0; 197 return 0;
197} 198}
@@ -474,6 +475,25 @@ static int crosslink_is_enabled(struct switchtec_ntb *sndev)
474 return ioread8(&inf->ntp_info[sndev->peer_partition].xlink_enabled); 475 return ioread8(&inf->ntp_info[sndev->peer_partition].xlink_enabled);
475} 476}
476 477
478static void crosslink_init_dbmsgs(struct switchtec_ntb *sndev)
479{
480 int i;
481 u32 msg_map = 0;
482
483 if (!crosslink_is_enabled(sndev))
484 return;
485
486 for (i = 0; i < ARRAY_SIZE(sndev->mmio_peer_dbmsg->imsg); i++) {
487 int m = i | sndev->self_partition << 2;
488
489 msg_map |= m << i * 8;
490 }
491
492 iowrite32(msg_map, &sndev->mmio_peer_dbmsg->msg_map);
493 iowrite64(sndev->db_valid_mask << sndev->db_peer_shift,
494 &sndev->mmio_peer_dbmsg->odb_mask);
495}
496
477enum { 497enum {
478 LINK_MESSAGE = 0, 498 LINK_MESSAGE = 0,
479 MSG_LINK_UP = 1, 499 MSG_LINK_UP = 1,
@@ -504,6 +524,9 @@ static void switchtec_ntb_check_link(struct switchtec_ntb *sndev)
504 ntb_link_event(&sndev->ntb); 524 ntb_link_event(&sndev->ntb);
505 dev_info(&sndev->stdev->dev, "ntb link %s\n", 525 dev_info(&sndev->stdev->dev, "ntb link %s\n",
506 link_sta ? "up" : "down"); 526 link_sta ? "up" : "down");
527
528 if (link_sta)
529 crosslink_init_dbmsgs(sndev);
507 } 530 }
508} 531}
509 532
@@ -649,7 +672,7 @@ static int switchtec_ntb_peer_db_addr(struct ntb_dev *ntb,
649 struct switchtec_ntb *sndev = ntb_sndev(ntb); 672 struct switchtec_ntb *sndev = ntb_sndev(ntb);
650 unsigned long offset; 673 unsigned long offset;
651 674
652 offset = (unsigned long)sndev->mmio_self_dbmsg->odb - 675 offset = (unsigned long)sndev->mmio_peer_dbmsg->odb -
653 (unsigned long)sndev->stdev->mmio; 676 (unsigned long)sndev->stdev->mmio;
654 677
655 offset += sndev->db_shift / 8; 678 offset += sndev->db_shift / 8;
@@ -667,7 +690,7 @@ static int switchtec_ntb_peer_db_set(struct ntb_dev *ntb, u64 db_bits)
667 struct switchtec_ntb *sndev = ntb_sndev(ntb); 690 struct switchtec_ntb *sndev = ntb_sndev(ntb);
668 691
669 iowrite64(db_bits << sndev->db_peer_shift, 692 iowrite64(db_bits << sndev->db_peer_shift,
670 &sndev->mmio_self_dbmsg->odb); 693 &sndev->mmio_peer_dbmsg->odb);
671 694
672 return 0; 695 return 0;
673} 696}
@@ -852,6 +875,7 @@ static int switchtec_ntb_init_sndev(struct switchtec_ntb *sndev)
852 sndev->mmio_self_ctrl = &sndev->mmio_ctrl[sndev->self_partition]; 875 sndev->mmio_self_ctrl = &sndev->mmio_ctrl[sndev->self_partition];
853 sndev->mmio_peer_ctrl = &sndev->mmio_ctrl[sndev->peer_partition]; 876 sndev->mmio_peer_ctrl = &sndev->mmio_ctrl[sndev->peer_partition];
854 sndev->mmio_self_dbmsg = &sndev->mmio_dbmsg[sndev->self_partition]; 877 sndev->mmio_self_dbmsg = &sndev->mmio_dbmsg[sndev->self_partition];
878 sndev->mmio_peer_dbmsg = sndev->mmio_self_dbmsg;
855 879
856 return 0; 880 return 0;
857} 881}
@@ -1072,6 +1096,7 @@ static int switchtec_ntb_init_crosslink(struct switchtec_ntb *sndev)
1072 const int ntb_lut_idx = 1; 1096 const int ntb_lut_idx = 1;
1073 u64 bar_addrs[6]; 1097 u64 bar_addrs[6];
1074 u64 addr; 1098 u64 addr;
1099 int offset;
1075 int bar_cnt; 1100 int bar_cnt;
1076 1101
1077 if (!crosslink_is_enabled(sndev)) 1102 if (!crosslink_is_enabled(sndev))
@@ -1087,7 +1112,13 @@ static int switchtec_ntb_init_crosslink(struct switchtec_ntb *sndev)
1087 return -EINVAL; 1112 return -EINVAL;
1088 } 1113 }
1089 1114
1090 addr = bar_addrs[0]; 1115 addr = (bar_addrs[0] + SWITCHTEC_GAS_NTB_OFFSET +
1116 SWITCHTEC_NTB_REG_DBMSG_OFFSET +
1117 sizeof(struct ntb_dbmsg_regs) * sndev->peer_partition);
1118
1119 offset = addr & (LUT_SIZE - 1);
1120 addr -= offset;
1121
1091 rc = config_rsvd_lut_win(sndev, sndev->mmio_self_ctrl, ntb_lut_idx, 1122 rc = config_rsvd_lut_win(sndev, sndev->mmio_self_ctrl, ntb_lut_idx,
1092 sndev->peer_partition, addr); 1123 sndev->peer_partition, addr);
1093 if (rc) 1124 if (rc)
@@ -1109,8 +1140,11 @@ static int switchtec_ntb_init_crosslink(struct switchtec_ntb *sndev)
1109 return rc; 1140 return rc;
1110 } 1141 }
1111 1142
1143 sndev->mmio_peer_dbmsg = sndev->mmio_xlink_win + offset;
1112 sndev->nr_rsvd_luts++; 1144 sndev->nr_rsvd_luts++;
1113 1145
1146 crosslink_init_dbmsgs(sndev);
1147
1114 return 0; 1148 return 0;
1115} 1149}
1116 1150
@@ -1163,24 +1197,35 @@ static void switchtec_ntb_init_mw(struct switchtec_ntb *sndev)
1163 * shared among all partitions. So we must split them in half 1197 * shared among all partitions. So we must split them in half
1164 * (32 for each partition). However, the message interrupts are 1198 * (32 for each partition). However, the message interrupts are
1165 * also shared with the top 4 doorbells so we just limit this to 1199 * also shared with the top 4 doorbells so we just limit this to
1166 * 28 doorbells per partition 1200 * 28 doorbells per partition.
1201 *
1202 * In crosslink mode, each side has it's own dbmsg register so
1203 * they can each use all 60 of the available doorbells.
1167 */ 1204 */
1168static void switchtec_ntb_init_db(struct switchtec_ntb *sndev) 1205static void switchtec_ntb_init_db(struct switchtec_ntb *sndev)
1169{ 1206{
1170 sndev->db_valid_mask = 0x0FFFFFFF; 1207 sndev->db_mask = 0x0FFFFFFFFFFFFFFFULL;
1171 1208
1172 if (sndev->self_partition < sndev->peer_partition) { 1209 if (sndev->mmio_peer_dbmsg != sndev->mmio_self_dbmsg) {
1210 sndev->db_shift = 0;
1211 sndev->db_peer_shift = 0;
1212 sndev->db_valid_mask = sndev->db_mask;
1213 } else if (sndev->self_partition < sndev->peer_partition) {
1173 sndev->db_shift = 0; 1214 sndev->db_shift = 0;
1174 sndev->db_peer_shift = 32; 1215 sndev->db_peer_shift = 32;
1216 sndev->db_valid_mask = 0x0FFFFFFF;
1175 } else { 1217 } else {
1176 sndev->db_shift = 32; 1218 sndev->db_shift = 32;
1177 sndev->db_peer_shift = 0; 1219 sndev->db_peer_shift = 0;
1220 sndev->db_valid_mask = 0x0FFFFFFF;
1178 } 1221 }
1179 1222
1180 sndev->db_mask = 0x0FFFFFFFFFFFFFFFULL;
1181 iowrite64(~sndev->db_mask, &sndev->mmio_self_dbmsg->idb_mask); 1223 iowrite64(~sndev->db_mask, &sndev->mmio_self_dbmsg->idb_mask);
1182 iowrite64(sndev->db_valid_mask << sndev->db_peer_shift, 1224 iowrite64(sndev->db_valid_mask << sndev->db_peer_shift,
1183 &sndev->mmio_self_dbmsg->odb_mask); 1225 &sndev->mmio_peer_dbmsg->odb_mask);
1226
1227 dev_dbg(&sndev->stdev->dev, "dbs: shift %d/%d, mask %016llx\n",
1228 sndev->db_shift, sndev->db_peer_shift, sndev->db_valid_mask);
1184} 1229}
1185 1230
1186static void switchtec_ntb_init_msgs(struct switchtec_ntb *sndev) 1231static void switchtec_ntb_init_msgs(struct switchtec_ntb *sndev)