1 /* 2 * Microsemi Switchtec(tm) PCIe Management Driver 3 * Copyright (c) 2017, Microsemi Corporation 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms and conditions of the GNU General Public License, 7 * version 2, as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 */ 15 16 #include <linux/switchtec.h> 17 #include <linux/module.h> 18 #include <linux/delay.h> 19 #include <linux/kthread.h> 20 21 MODULE_DESCRIPTION("Microsemi Switchtec(tm) NTB Driver"); 22 MODULE_VERSION("0.1"); 23 MODULE_LICENSE("GPL"); 24 MODULE_AUTHOR("Microsemi Corporation"); 25 26 static bool use_lut_mws; 27 module_param(use_lut_mws, bool, 0644); 28 MODULE_PARM_DESC(use_lut_mws, 29 "Enable the use of the LUT based memory windows"); 30 31 #ifndef ioread64 32 #ifdef readq 33 #define ioread64 readq 34 #else 35 #define ioread64 _ioread64 36 static inline u64 _ioread64(void __iomem *mmio) 37 { 38 u64 low, high; 39 40 low = ioread32(mmio); 41 high = ioread32(mmio + sizeof(u32)); 42 return low | (high << 32); 43 } 44 #endif 45 #endif 46 47 #ifndef iowrite64 48 #ifdef writeq 49 #define iowrite64 writeq 50 #else 51 #define iowrite64 _iowrite64 52 static inline void _iowrite64(u64 val, void __iomem *mmio) 53 { 54 iowrite32(val, mmio); 55 iowrite32(val >> 32, mmio + sizeof(u32)); 56 } 57 #endif 58 #endif 59 60 #define SWITCHTEC_NTB_MAGIC 0x45CC0001 61 #define MAX_MWS 128 62 63 struct shared_mw { 64 u32 magic; 65 u32 partition_id; 66 u64 mw_sizes[MAX_MWS]; 67 }; 68 69 #define MAX_DIRECT_MW ARRAY_SIZE(((struct ntb_ctrl_regs *)(0))->bar_entry) 70 #define LUT_SIZE SZ_64K 71 72 struct switchtec_ntb { 73 struct switchtec_dev *stdev; 74 75 int self_partition; 76 int peer_partition; 77 78 struct ntb_info_regs __iomem *mmio_ntb; 79 struct ntb_ctrl_regs __iomem *mmio_ctrl; 80 struct ntb_dbmsg_regs __iomem *mmio_dbmsg; 81 struct ntb_ctrl_regs __iomem *mmio_self_ctrl; 82 struct ntb_ctrl_regs __iomem *mmio_peer_ctrl; 83 struct ntb_dbmsg_regs __iomem *mmio_self_dbmsg; 84 85 struct shared_mw *self_shared; 86 struct shared_mw __iomem *peer_shared; 87 dma_addr_t self_shared_dma; 88 89 int nr_direct_mw; 90 int nr_lut_mw; 91 int direct_mw_to_bar[MAX_DIRECT_MW]; 92 93 int peer_nr_direct_mw; 94 int peer_nr_lut_mw; 95 int peer_direct_mw_to_bar[MAX_DIRECT_MW]; 96 }; 97 98 static int switchtec_ntb_part_op(struct switchtec_ntb *sndev, 99 struct ntb_ctrl_regs __iomem *ctl, 100 u32 op, int wait_status) 101 { 102 static const char * const op_text[] = { 103 [NTB_CTRL_PART_OP_LOCK] = "lock", 104 [NTB_CTRL_PART_OP_CFG] = "configure", 105 [NTB_CTRL_PART_OP_RESET] = "reset", 106 }; 107 108 int i; 109 u32 ps; 110 int status; 111 112 switch (op) { 113 case NTB_CTRL_PART_OP_LOCK: 114 status = NTB_CTRL_PART_STATUS_LOCKING; 115 break; 116 case NTB_CTRL_PART_OP_CFG: 117 status = NTB_CTRL_PART_STATUS_CONFIGURING; 118 break; 119 case NTB_CTRL_PART_OP_RESET: 120 status = NTB_CTRL_PART_STATUS_RESETTING; 121 break; 122 default: 123 return -EINVAL; 124 } 125 126 iowrite32(op, &ctl->partition_op); 127 128 for (i = 0; i < 1000; i++) { 129 if (msleep_interruptible(50) != 0) { 130 iowrite32(NTB_CTRL_PART_OP_RESET, &ctl->partition_op); 131 return -EINTR; 132 } 133 134 ps = ioread32(&ctl->partition_status) & 0xFFFF; 135 136 if (ps != status) 137 break; 138 } 139 140 if (ps == wait_status) 141 return 0; 142 143 if (ps == status) { 144 dev_err(&sndev->stdev->dev, 145 "Timed out while peforming %s (%d). (%08x)", 146 op_text[op], op, 147 ioread32(&ctl->partition_status)); 148 149 return -ETIMEDOUT; 150 } 151 152 return -EIO; 153 } 154 155 static void switchtec_ntb_init_sndev(struct switchtec_ntb *sndev) 156 { 157 u64 part_map; 158 159 sndev->self_partition = sndev->stdev->partition; 160 161 sndev->mmio_ntb = sndev->stdev->mmio_ntb; 162 part_map = ioread64(&sndev->mmio_ntb->ep_map); 163 part_map &= ~(1 << sndev->self_partition); 164 sndev->peer_partition = ffs(part_map) - 1; 165 166 dev_dbg(&sndev->stdev->dev, "Partition ID %d of %d (%llx)", 167 sndev->self_partition, sndev->stdev->partition_count, 168 part_map); 169 170 sndev->mmio_ctrl = (void * __iomem)sndev->mmio_ntb + 171 SWITCHTEC_NTB_REG_CTRL_OFFSET; 172 sndev->mmio_dbmsg = (void * __iomem)sndev->mmio_ntb + 173 SWITCHTEC_NTB_REG_DBMSG_OFFSET; 174 175 sndev->mmio_self_ctrl = &sndev->mmio_ctrl[sndev->self_partition]; 176 sndev->mmio_peer_ctrl = &sndev->mmio_ctrl[sndev->peer_partition]; 177 sndev->mmio_self_dbmsg = &sndev->mmio_dbmsg[sndev->self_partition]; 178 } 179 180 static int map_bars(int *map, struct ntb_ctrl_regs __iomem *ctrl) 181 { 182 int i; 183 int cnt = 0; 184 185 for (i = 0; i < ARRAY_SIZE(ctrl->bar_entry); i++) { 186 u32 r = ioread32(&ctrl->bar_entry[i].ctl); 187 188 if (r & NTB_CTRL_BAR_VALID) 189 map[cnt++] = i; 190 } 191 192 return cnt; 193 } 194 195 static void switchtec_ntb_init_mw(struct switchtec_ntb *sndev) 196 { 197 sndev->nr_direct_mw = map_bars(sndev->direct_mw_to_bar, 198 sndev->mmio_self_ctrl); 199 200 sndev->nr_lut_mw = ioread16(&sndev->mmio_self_ctrl->lut_table_entries); 201 sndev->nr_lut_mw = rounddown_pow_of_two(sndev->nr_lut_mw); 202 203 dev_dbg(&sndev->stdev->dev, "MWs: %d direct, %d lut", 204 sndev->nr_direct_mw, sndev->nr_lut_mw); 205 206 sndev->peer_nr_direct_mw = map_bars(sndev->peer_direct_mw_to_bar, 207 sndev->mmio_peer_ctrl); 208 209 sndev->peer_nr_lut_mw = 210 ioread16(&sndev->mmio_peer_ctrl->lut_table_entries); 211 sndev->peer_nr_lut_mw = rounddown_pow_of_two(sndev->peer_nr_lut_mw); 212 213 dev_dbg(&sndev->stdev->dev, "Peer MWs: %d direct, %d lut", 214 sndev->peer_nr_direct_mw, sndev->peer_nr_lut_mw); 215 216 } 217 218 static int switchtec_ntb_init_req_id_table(struct switchtec_ntb *sndev) 219 { 220 int rc = 0; 221 u16 req_id; 222 u32 error; 223 224 req_id = ioread16(&sndev->mmio_ntb->requester_id); 225 226 if (ioread32(&sndev->mmio_self_ctrl->req_id_table_size) < 2) { 227 dev_err(&sndev->stdev->dev, 228 "Not enough requester IDs available."); 229 return -EFAULT; 230 } 231 232 rc = switchtec_ntb_part_op(sndev, sndev->mmio_self_ctrl, 233 NTB_CTRL_PART_OP_LOCK, 234 NTB_CTRL_PART_STATUS_LOCKED); 235 if (rc) 236 return rc; 237 238 iowrite32(NTB_PART_CTRL_ID_PROT_DIS, 239 &sndev->mmio_self_ctrl->partition_ctrl); 240 241 /* 242 * Root Complex Requester ID (which is 0:00.0) 243 */ 244 iowrite32(0 << 16 | NTB_CTRL_REQ_ID_EN, 245 &sndev->mmio_self_ctrl->req_id_table[0]); 246 247 /* 248 * Host Bridge Requester ID (as read from the mmap address) 249 */ 250 iowrite32(req_id << 16 | NTB_CTRL_REQ_ID_EN, 251 &sndev->mmio_self_ctrl->req_id_table[1]); 252 253 rc = switchtec_ntb_part_op(sndev, sndev->mmio_self_ctrl, 254 NTB_CTRL_PART_OP_CFG, 255 NTB_CTRL_PART_STATUS_NORMAL); 256 if (rc == -EIO) { 257 error = ioread32(&sndev->mmio_self_ctrl->req_id_error); 258 dev_err(&sndev->stdev->dev, 259 "Error setting up the requester ID table: %08x", 260 error); 261 } 262 263 return rc; 264 } 265 266 static void switchtec_ntb_init_shared(struct switchtec_ntb *sndev) 267 { 268 int i; 269 270 memset(sndev->self_shared, 0, LUT_SIZE); 271 sndev->self_shared->magic = SWITCHTEC_NTB_MAGIC; 272 sndev->self_shared->partition_id = sndev->stdev->partition; 273 274 for (i = 0; i < sndev->nr_direct_mw; i++) { 275 int bar = sndev->direct_mw_to_bar[i]; 276 resource_size_t sz = pci_resource_len(sndev->stdev->pdev, bar); 277 278 if (i == 0) 279 sz = min_t(resource_size_t, sz, 280 LUT_SIZE * sndev->nr_lut_mw); 281 282 sndev->self_shared->mw_sizes[i] = sz; 283 } 284 285 for (i = 0; i < sndev->nr_lut_mw; i++) { 286 int idx = sndev->nr_direct_mw + i; 287 288 sndev->self_shared->mw_sizes[idx] = LUT_SIZE; 289 } 290 } 291 292 static int switchtec_ntb_init_shared_mw(struct switchtec_ntb *sndev) 293 { 294 struct ntb_ctrl_regs __iomem *ctl = sndev->mmio_peer_ctrl; 295 int bar = sndev->direct_mw_to_bar[0]; 296 u32 ctl_val; 297 int rc; 298 299 sndev->self_shared = dma_zalloc_coherent(&sndev->stdev->pdev->dev, 300 LUT_SIZE, 301 &sndev->self_shared_dma, 302 GFP_KERNEL); 303 if (!sndev->self_shared) { 304 dev_err(&sndev->stdev->dev, 305 "unable to allocate memory for shared mw"); 306 return -ENOMEM; 307 } 308 309 switchtec_ntb_init_shared(sndev); 310 311 rc = switchtec_ntb_part_op(sndev, ctl, NTB_CTRL_PART_OP_LOCK, 312 NTB_CTRL_PART_STATUS_LOCKED); 313 if (rc) 314 goto unalloc_and_exit; 315 316 ctl_val = ioread32(&ctl->bar_entry[bar].ctl); 317 ctl_val &= 0xFF; 318 ctl_val |= NTB_CTRL_BAR_LUT_WIN_EN; 319 ctl_val |= ilog2(LUT_SIZE) << 8; 320 ctl_val |= (sndev->nr_lut_mw - 1) << 14; 321 iowrite32(ctl_val, &ctl->bar_entry[bar].ctl); 322 323 iowrite64((NTB_CTRL_LUT_EN | (sndev->self_partition << 1) | 324 sndev->self_shared_dma), 325 &ctl->lut_entry[0]); 326 327 rc = switchtec_ntb_part_op(sndev, ctl, NTB_CTRL_PART_OP_CFG, 328 NTB_CTRL_PART_STATUS_NORMAL); 329 if (rc) { 330 u32 bar_error, lut_error; 331 332 bar_error = ioread32(&ctl->bar_error); 333 lut_error = ioread32(&ctl->lut_error); 334 dev_err(&sndev->stdev->dev, 335 "Error setting up shared MW: %08x / %08x", 336 bar_error, lut_error); 337 goto unalloc_and_exit; 338 } 339 340 sndev->peer_shared = pci_iomap(sndev->stdev->pdev, bar, LUT_SIZE); 341 if (!sndev->peer_shared) { 342 rc = -ENOMEM; 343 goto unalloc_and_exit; 344 } 345 346 dev_dbg(&sndev->stdev->dev, "Shared MW Ready"); 347 return 0; 348 349 unalloc_and_exit: 350 dma_free_coherent(&sndev->stdev->pdev->dev, LUT_SIZE, 351 sndev->self_shared, sndev->self_shared_dma); 352 353 return rc; 354 } 355 356 static void switchtec_ntb_deinit_shared_mw(struct switchtec_ntb *sndev) 357 { 358 if (sndev->peer_shared) 359 pci_iounmap(sndev->stdev->pdev, sndev->peer_shared); 360 361 if (sndev->self_shared) 362 dma_free_coherent(&sndev->stdev->pdev->dev, LUT_SIZE, 363 sndev->self_shared, 364 sndev->self_shared_dma); 365 } 366 367 static int switchtec_ntb_add(struct device *dev, 368 struct class_interface *class_intf) 369 { 370 struct switchtec_dev *stdev = to_stdev(dev); 371 struct switchtec_ntb *sndev; 372 int rc; 373 374 stdev->sndev = NULL; 375 376 if (stdev->pdev->class != MICROSEMI_NTB_CLASSCODE) 377 return -ENODEV; 378 379 if (stdev->partition_count != 2) 380 dev_warn(dev, "ntb driver only supports 2 partitions"); 381 382 sndev = kzalloc_node(sizeof(*sndev), GFP_KERNEL, dev_to_node(dev)); 383 if (!sndev) 384 return -ENOMEM; 385 386 sndev->stdev = stdev; 387 388 switchtec_ntb_init_sndev(sndev); 389 switchtec_ntb_init_mw(sndev); 390 391 rc = switchtec_ntb_init_req_id_table(sndev); 392 if (rc) 393 goto free_and_exit; 394 395 rc = switchtec_ntb_init_shared_mw(sndev); 396 if (rc) 397 goto free_and_exit; 398 399 stdev->sndev = sndev; 400 dev_info(dev, "NTB device registered"); 401 402 return 0; 403 404 free_and_exit: 405 kfree(sndev); 406 dev_err(dev, "failed to register ntb device: %d", rc); 407 return rc; 408 } 409 410 void switchtec_ntb_remove(struct device *dev, 411 struct class_interface *class_intf) 412 { 413 struct switchtec_dev *stdev = to_stdev(dev); 414 struct switchtec_ntb *sndev = stdev->sndev; 415 416 if (!sndev) 417 return; 418 419 stdev->sndev = NULL; 420 switchtec_ntb_deinit_shared_mw(sndev); 421 kfree(sndev); 422 dev_info(dev, "ntb device unregistered"); 423 } 424 425 static struct class_interface switchtec_interface = { 426 .add_dev = switchtec_ntb_add, 427 .remove_dev = switchtec_ntb_remove, 428 }; 429 430 static int __init switchtec_ntb_init(void) 431 { 432 switchtec_interface.class = switchtec_class; 433 return class_interface_register(&switchtec_interface); 434 } 435 module_init(switchtec_ntb_init); 436 437 static void __exit switchtec_ntb_exit(void) 438 { 439 class_interface_unregister(&switchtec_interface); 440 } 441 module_exit(switchtec_ntb_exit); 442