.. | .. |
---|
25 | 25 | module_param(max_devices, int, 0644); |
---|
26 | 26 | MODULE_PARM_DESC(max_devices, "max number of switchtec device instances"); |
---|
27 | 27 | |
---|
| 28 | +static bool use_dma_mrpc = true; |
---|
| 29 | +module_param(use_dma_mrpc, bool, 0644); |
---|
| 30 | +MODULE_PARM_DESC(use_dma_mrpc, |
---|
| 31 | + "Enable the use of the DMA MRPC feature"); |
---|
| 32 | + |
---|
| 33 | +static int nirqs = 32; |
---|
| 34 | +module_param(nirqs, int, 0644); |
---|
| 35 | +MODULE_PARM_DESC(nirqs, "number of interrupts to allocate (more may be useful for NTB applications)"); |
---|
| 36 | + |
---|
28 | 37 | static dev_t switchtec_devt; |
---|
29 | 38 | static DEFINE_IDA(switchtec_minor_ida); |
---|
30 | 39 | |
---|
.. | .. |
---|
114 | 123 | |
---|
115 | 124 | static void mrpc_complete_cmd(struct switchtec_dev *stdev); |
---|
116 | 125 | |
---|
| 126 | +static void flush_wc_buf(struct switchtec_dev *stdev) |
---|
| 127 | +{ |
---|
| 128 | + struct ntb_dbmsg_regs __iomem *mmio_dbmsg; |
---|
| 129 | + |
---|
| 130 | + /* |
---|
| 131 | + * odb (outbound doorbell) register is processed by low latency |
---|
| 132 | + * hardware and w/o side effect |
---|
| 133 | + */ |
---|
| 134 | + mmio_dbmsg = (void __iomem *)stdev->mmio_ntb + |
---|
| 135 | + SWITCHTEC_NTB_REG_DBMSG_OFFSET; |
---|
| 136 | + ioread32(&mmio_dbmsg->odb); |
---|
| 137 | +} |
---|
| 138 | + |
---|
117 | 139 | static void mrpc_cmd_submit(struct switchtec_dev *stdev) |
---|
118 | 140 | { |
---|
119 | 141 | /* requires the mrpc_mutex to already be held when called */ |
---|
.. | .. |
---|
129 | 151 | stuser = list_entry(stdev->mrpc_queue.next, struct switchtec_user, |
---|
130 | 152 | list); |
---|
131 | 153 | |
---|
| 154 | + if (stdev->dma_mrpc) { |
---|
| 155 | + stdev->dma_mrpc->status = SWITCHTEC_MRPC_STATUS_INPROGRESS; |
---|
| 156 | + memset(stdev->dma_mrpc->data, 0xFF, SWITCHTEC_MRPC_PAYLOAD_SIZE); |
---|
| 157 | + } |
---|
| 158 | + |
---|
132 | 159 | stuser_set_state(stuser, MRPC_RUNNING); |
---|
133 | 160 | stdev->mrpc_busy = 1; |
---|
134 | 161 | memcpy_toio(&stdev->mmio_mrpc->input_data, |
---|
135 | 162 | stuser->data, stuser->data_len); |
---|
| 163 | + flush_wc_buf(stdev); |
---|
136 | 164 | iowrite32(stuser->cmd, &stdev->mmio_mrpc->cmd); |
---|
137 | 165 | |
---|
138 | 166 | schedule_delayed_work(&stdev->mrpc_timeout, |
---|
.. | .. |
---|
167 | 195 | stuser = list_entry(stdev->mrpc_queue.next, struct switchtec_user, |
---|
168 | 196 | list); |
---|
169 | 197 | |
---|
170 | | - stuser->status = ioread32(&stdev->mmio_mrpc->status); |
---|
| 198 | + if (stdev->dma_mrpc) |
---|
| 199 | + stuser->status = stdev->dma_mrpc->status; |
---|
| 200 | + else |
---|
| 201 | + stuser->status = ioread32(&stdev->mmio_mrpc->status); |
---|
| 202 | + |
---|
171 | 203 | if (stuser->status == SWITCHTEC_MRPC_STATUS_INPROGRESS) |
---|
172 | 204 | return; |
---|
173 | 205 | |
---|
.. | .. |
---|
177 | 209 | if (stuser->status != SWITCHTEC_MRPC_STATUS_DONE) |
---|
178 | 210 | goto out; |
---|
179 | 211 | |
---|
180 | | - stuser->return_code = ioread32(&stdev->mmio_mrpc->ret_value); |
---|
| 212 | + if (stdev->dma_mrpc) |
---|
| 213 | + stuser->return_code = stdev->dma_mrpc->rtn_code; |
---|
| 214 | + else |
---|
| 215 | + stuser->return_code = ioread32(&stdev->mmio_mrpc->ret_value); |
---|
181 | 216 | if (stuser->return_code != 0) |
---|
182 | 217 | goto out; |
---|
183 | 218 | |
---|
184 | | - memcpy_fromio(stuser->data, &stdev->mmio_mrpc->output_data, |
---|
185 | | - stuser->read_len); |
---|
186 | | - |
---|
| 219 | + if (stdev->dma_mrpc) |
---|
| 220 | + memcpy(stuser->data, &stdev->dma_mrpc->data, |
---|
| 221 | + stuser->read_len); |
---|
| 222 | + else |
---|
| 223 | + memcpy_fromio(stuser->data, &stdev->mmio_mrpc->output_data, |
---|
| 224 | + stuser->read_len); |
---|
187 | 225 | out: |
---|
188 | 226 | stuser->cmd_done = true; |
---|
189 | 227 | wake_up_interruptible(&stuser->cmd_comp); |
---|
.. | .. |
---|
219 | 257 | |
---|
220 | 258 | mutex_lock(&stdev->mrpc_mutex); |
---|
221 | 259 | |
---|
222 | | - status = ioread32(&stdev->mmio_mrpc->status); |
---|
| 260 | + if (stdev->dma_mrpc) |
---|
| 261 | + status = stdev->dma_mrpc->status; |
---|
| 262 | + else |
---|
| 263 | + status = ioread32(&stdev->mmio_mrpc->status); |
---|
223 | 264 | if (status == SWITCHTEC_MRPC_STATUS_INPROGRESS) { |
---|
224 | 265 | schedule_delayed_work(&stdev->mrpc_timeout, |
---|
225 | 266 | msecs_to_jiffies(500)); |
---|
.. | .. |
---|
227 | 268 | } |
---|
228 | 269 | |
---|
229 | 270 | mrpc_complete_cmd(stdev); |
---|
230 | | - |
---|
231 | 271 | out: |
---|
232 | 272 | mutex_unlock(&stdev->mrpc_mutex); |
---|
233 | 273 | } |
---|
.. | .. |
---|
279 | 319 | struct device_attribute *attr, char *buf) \ |
---|
280 | 320 | { \ |
---|
281 | 321 | struct switchtec_dev *stdev = to_stdev(dev); \ |
---|
282 | | - return io_string_show(buf, &stdev->mmio_sys_info->field, \ |
---|
283 | | - sizeof(stdev->mmio_sys_info->field)); \ |
---|
| 322 | + struct sys_info_regs __iomem *si = stdev->mmio_sys_info; \ |
---|
| 323 | + if (stdev->gen == SWITCHTEC_GEN3) \ |
---|
| 324 | + return io_string_show(buf, &si->gen3.field, \ |
---|
| 325 | + sizeof(si->gen3.field)); \ |
---|
| 326 | + else if (stdev->gen == SWITCHTEC_GEN4) \ |
---|
| 327 | + return io_string_show(buf, &si->gen4.field, \ |
---|
| 328 | + sizeof(si->gen4.field)); \ |
---|
| 329 | + else \ |
---|
| 330 | + return -ENOTSUPP; \ |
---|
284 | 331 | } \ |
---|
285 | 332 | \ |
---|
286 | 333 | static DEVICE_ATTR_RO(field) |
---|
.. | .. |
---|
288 | 335 | DEVICE_ATTR_SYS_INFO_STR(vendor_id); |
---|
289 | 336 | DEVICE_ATTR_SYS_INFO_STR(product_id); |
---|
290 | 337 | DEVICE_ATTR_SYS_INFO_STR(product_revision); |
---|
291 | | -DEVICE_ATTR_SYS_INFO_STR(component_vendor); |
---|
| 338 | + |
---|
| 339 | +static ssize_t component_vendor_show(struct device *dev, |
---|
| 340 | + struct device_attribute *attr, char *buf) |
---|
| 341 | +{ |
---|
| 342 | + struct switchtec_dev *stdev = to_stdev(dev); |
---|
| 343 | + struct sys_info_regs __iomem *si = stdev->mmio_sys_info; |
---|
| 344 | + |
---|
| 345 | + /* component_vendor field not supported after gen3 */ |
---|
| 346 | + if (stdev->gen != SWITCHTEC_GEN3) |
---|
| 347 | + return sprintf(buf, "none\n"); |
---|
| 348 | + |
---|
| 349 | + return io_string_show(buf, &si->gen3.component_vendor, |
---|
| 350 | + sizeof(si->gen3.component_vendor)); |
---|
| 351 | +} |
---|
| 352 | +static DEVICE_ATTR_RO(component_vendor); |
---|
292 | 353 | |
---|
293 | 354 | static ssize_t component_id_show(struct device *dev, |
---|
294 | 355 | struct device_attribute *attr, char *buf) |
---|
295 | 356 | { |
---|
296 | 357 | struct switchtec_dev *stdev = to_stdev(dev); |
---|
297 | | - int id = ioread16(&stdev->mmio_sys_info->component_id); |
---|
| 358 | + int id = ioread16(&stdev->mmio_sys_info->gen3.component_id); |
---|
| 359 | + |
---|
| 360 | + /* component_id field not supported after gen3 */ |
---|
| 361 | + if (stdev->gen != SWITCHTEC_GEN3) |
---|
| 362 | + return sprintf(buf, "none\n"); |
---|
298 | 363 | |
---|
299 | 364 | return sprintf(buf, "PM%04X\n", id); |
---|
300 | 365 | } |
---|
.. | .. |
---|
304 | 369 | struct device_attribute *attr, char *buf) |
---|
305 | 370 | { |
---|
306 | 371 | struct switchtec_dev *stdev = to_stdev(dev); |
---|
307 | | - int rev = ioread8(&stdev->mmio_sys_info->component_revision); |
---|
| 372 | + int rev = ioread8(&stdev->mmio_sys_info->gen3.component_revision); |
---|
| 373 | + |
---|
| 374 | + /* component_revision field not supported after gen3 */ |
---|
| 375 | + if (stdev->gen != SWITCHTEC_GEN3) |
---|
| 376 | + return sprintf(buf, "255\n"); |
---|
308 | 377 | |
---|
309 | 378 | return sprintf(buf, "%d\n", rev); |
---|
310 | 379 | } |
---|
.. | .. |
---|
412 | 481 | rc = -EFAULT; |
---|
413 | 482 | goto out; |
---|
414 | 483 | } |
---|
| 484 | + if (((MRPC_CMD_ID(stuser->cmd) == MRPC_GAS_WRITE) || |
---|
| 485 | + (MRPC_CMD_ID(stuser->cmd) == MRPC_GAS_READ)) && |
---|
| 486 | + !capable(CAP_SYS_ADMIN)) { |
---|
| 487 | + rc = -EPERM; |
---|
| 488 | + goto out; |
---|
| 489 | + } |
---|
415 | 490 | |
---|
416 | 491 | data += sizeof(stuser->cmd); |
---|
417 | 492 | rc = copy_from_user(&stuser->data, data, size - sizeof(stuser->cmd)); |
---|
.. | .. |
---|
456 | 531 | mutex_unlock(&stdev->mrpc_mutex); |
---|
457 | 532 | |
---|
458 | 533 | if (filp->f_flags & O_NONBLOCK) { |
---|
459 | | - if (!READ_ONCE(stuser->cmd_done)) |
---|
| 534 | + if (!stuser->cmd_done) |
---|
460 | 535 | return -EAGAIN; |
---|
461 | 536 | } else { |
---|
462 | 537 | rc = wait_event_interruptible(stuser->cmd_comp, |
---|
.. | .. |
---|
516 | 591 | |
---|
517 | 592 | mutex_unlock(&stdev->mrpc_mutex); |
---|
518 | 593 | |
---|
519 | | - if (READ_ONCE(stuser->cmd_done)) |
---|
| 594 | + if (stuser->cmd_done) |
---|
520 | 595 | ret |= EPOLLIN | EPOLLRDNORM; |
---|
521 | 596 | |
---|
522 | 597 | if (stuser->event_cnt != atomic_read(&stdev->event_cnt)) |
---|
.. | .. |
---|
531 | 606 | struct switchtec_ioctl_flash_info info = {0}; |
---|
532 | 607 | struct flash_info_regs __iomem *fi = stdev->mmio_flash_info; |
---|
533 | 608 | |
---|
534 | | - info.flash_length = ioread32(&fi->flash_length); |
---|
535 | | - info.num_partitions = SWITCHTEC_IOCTL_NUM_PARTITIONS; |
---|
| 609 | + if (stdev->gen == SWITCHTEC_GEN3) { |
---|
| 610 | + info.flash_length = ioread32(&fi->gen3.flash_length); |
---|
| 611 | + info.num_partitions = SWITCHTEC_NUM_PARTITIONS_GEN3; |
---|
| 612 | + } else if (stdev->gen == SWITCHTEC_GEN4) { |
---|
| 613 | + info.flash_length = ioread32(&fi->gen4.flash_length); |
---|
| 614 | + info.num_partitions = SWITCHTEC_NUM_PARTITIONS_GEN4; |
---|
| 615 | + } else { |
---|
| 616 | + return -ENOTSUPP; |
---|
| 617 | + } |
---|
536 | 618 | |
---|
537 | 619 | if (copy_to_user(uinfo, &info, sizeof(info))) |
---|
538 | 620 | return -EFAULT; |
---|
.. | .. |
---|
547 | 629 | info->length = ioread32(&pi->length); |
---|
548 | 630 | } |
---|
549 | 631 | |
---|
550 | | -static int ioctl_flash_part_info(struct switchtec_dev *stdev, |
---|
551 | | - struct switchtec_ioctl_flash_part_info __user *uinfo) |
---|
| 632 | +static int flash_part_info_gen3(struct switchtec_dev *stdev, |
---|
| 633 | + struct switchtec_ioctl_flash_part_info *info) |
---|
552 | 634 | { |
---|
553 | | - struct switchtec_ioctl_flash_part_info info = {0}; |
---|
554 | | - struct flash_info_regs __iomem *fi = stdev->mmio_flash_info; |
---|
555 | | - struct sys_info_regs __iomem *si = stdev->mmio_sys_info; |
---|
| 635 | + struct flash_info_regs_gen3 __iomem *fi = |
---|
| 636 | + &stdev->mmio_flash_info->gen3; |
---|
| 637 | + struct sys_info_regs_gen3 __iomem *si = &stdev->mmio_sys_info->gen3; |
---|
556 | 638 | u32 active_addr = -1; |
---|
557 | 639 | |
---|
558 | | - if (copy_from_user(&info, uinfo, sizeof(info))) |
---|
559 | | - return -EFAULT; |
---|
560 | | - |
---|
561 | | - switch (info.flash_partition) { |
---|
| 640 | + switch (info->flash_partition) { |
---|
562 | 641 | case SWITCHTEC_IOCTL_PART_CFG0: |
---|
563 | 642 | active_addr = ioread32(&fi->active_cfg); |
---|
564 | | - set_fw_info_part(&info, &fi->cfg0); |
---|
565 | | - if (ioread16(&si->cfg_running) == SWITCHTEC_CFG0_RUNNING) |
---|
566 | | - info.active |= SWITCHTEC_IOCTL_PART_RUNNING; |
---|
| 643 | + set_fw_info_part(info, &fi->cfg0); |
---|
| 644 | + if (ioread16(&si->cfg_running) == SWITCHTEC_GEN3_CFG0_RUNNING) |
---|
| 645 | + info->active |= SWITCHTEC_IOCTL_PART_RUNNING; |
---|
567 | 646 | break; |
---|
568 | 647 | case SWITCHTEC_IOCTL_PART_CFG1: |
---|
569 | 648 | active_addr = ioread32(&fi->active_cfg); |
---|
570 | | - set_fw_info_part(&info, &fi->cfg1); |
---|
571 | | - if (ioread16(&si->cfg_running) == SWITCHTEC_CFG1_RUNNING) |
---|
572 | | - info.active |= SWITCHTEC_IOCTL_PART_RUNNING; |
---|
| 649 | + set_fw_info_part(info, &fi->cfg1); |
---|
| 650 | + if (ioread16(&si->cfg_running) == SWITCHTEC_GEN3_CFG1_RUNNING) |
---|
| 651 | + info->active |= SWITCHTEC_IOCTL_PART_RUNNING; |
---|
573 | 652 | break; |
---|
574 | 653 | case SWITCHTEC_IOCTL_PART_IMG0: |
---|
575 | 654 | active_addr = ioread32(&fi->active_img); |
---|
576 | | - set_fw_info_part(&info, &fi->img0); |
---|
577 | | - if (ioread16(&si->img_running) == SWITCHTEC_IMG0_RUNNING) |
---|
578 | | - info.active |= SWITCHTEC_IOCTL_PART_RUNNING; |
---|
| 655 | + set_fw_info_part(info, &fi->img0); |
---|
| 656 | + if (ioread16(&si->img_running) == SWITCHTEC_GEN3_IMG0_RUNNING) |
---|
| 657 | + info->active |= SWITCHTEC_IOCTL_PART_RUNNING; |
---|
579 | 658 | break; |
---|
580 | 659 | case SWITCHTEC_IOCTL_PART_IMG1: |
---|
581 | 660 | active_addr = ioread32(&fi->active_img); |
---|
582 | | - set_fw_info_part(&info, &fi->img1); |
---|
583 | | - if (ioread16(&si->img_running) == SWITCHTEC_IMG1_RUNNING) |
---|
584 | | - info.active |= SWITCHTEC_IOCTL_PART_RUNNING; |
---|
| 661 | + set_fw_info_part(info, &fi->img1); |
---|
| 662 | + if (ioread16(&si->img_running) == SWITCHTEC_GEN3_IMG1_RUNNING) |
---|
| 663 | + info->active |= SWITCHTEC_IOCTL_PART_RUNNING; |
---|
585 | 664 | break; |
---|
586 | 665 | case SWITCHTEC_IOCTL_PART_NVLOG: |
---|
587 | | - set_fw_info_part(&info, &fi->nvlog); |
---|
| 666 | + set_fw_info_part(info, &fi->nvlog); |
---|
588 | 667 | break; |
---|
589 | 668 | case SWITCHTEC_IOCTL_PART_VENDOR0: |
---|
590 | | - set_fw_info_part(&info, &fi->vendor[0]); |
---|
| 669 | + set_fw_info_part(info, &fi->vendor[0]); |
---|
591 | 670 | break; |
---|
592 | 671 | case SWITCHTEC_IOCTL_PART_VENDOR1: |
---|
593 | | - set_fw_info_part(&info, &fi->vendor[1]); |
---|
| 672 | + set_fw_info_part(info, &fi->vendor[1]); |
---|
594 | 673 | break; |
---|
595 | 674 | case SWITCHTEC_IOCTL_PART_VENDOR2: |
---|
596 | | - set_fw_info_part(&info, &fi->vendor[2]); |
---|
| 675 | + set_fw_info_part(info, &fi->vendor[2]); |
---|
597 | 676 | break; |
---|
598 | 677 | case SWITCHTEC_IOCTL_PART_VENDOR3: |
---|
599 | | - set_fw_info_part(&info, &fi->vendor[3]); |
---|
| 678 | + set_fw_info_part(info, &fi->vendor[3]); |
---|
600 | 679 | break; |
---|
601 | 680 | case SWITCHTEC_IOCTL_PART_VENDOR4: |
---|
602 | | - set_fw_info_part(&info, &fi->vendor[4]); |
---|
| 681 | + set_fw_info_part(info, &fi->vendor[4]); |
---|
603 | 682 | break; |
---|
604 | 683 | case SWITCHTEC_IOCTL_PART_VENDOR5: |
---|
605 | | - set_fw_info_part(&info, &fi->vendor[5]); |
---|
| 684 | + set_fw_info_part(info, &fi->vendor[5]); |
---|
606 | 685 | break; |
---|
607 | 686 | case SWITCHTEC_IOCTL_PART_VENDOR6: |
---|
608 | | - set_fw_info_part(&info, &fi->vendor[6]); |
---|
| 687 | + set_fw_info_part(info, &fi->vendor[6]); |
---|
609 | 688 | break; |
---|
610 | 689 | case SWITCHTEC_IOCTL_PART_VENDOR7: |
---|
611 | | - set_fw_info_part(&info, &fi->vendor[7]); |
---|
| 690 | + set_fw_info_part(info, &fi->vendor[7]); |
---|
612 | 691 | break; |
---|
613 | 692 | default: |
---|
614 | 693 | return -EINVAL; |
---|
615 | 694 | } |
---|
616 | 695 | |
---|
617 | | - if (info.address == active_addr) |
---|
618 | | - info.active |= SWITCHTEC_IOCTL_PART_ACTIVE; |
---|
| 696 | + if (info->address == active_addr) |
---|
| 697 | + info->active |= SWITCHTEC_IOCTL_PART_ACTIVE; |
---|
| 698 | + |
---|
| 699 | + return 0; |
---|
| 700 | +} |
---|
| 701 | + |
---|
| 702 | +static int flash_part_info_gen4(struct switchtec_dev *stdev, |
---|
| 703 | + struct switchtec_ioctl_flash_part_info *info) |
---|
| 704 | +{ |
---|
| 705 | + struct flash_info_regs_gen4 __iomem *fi = &stdev->mmio_flash_info->gen4; |
---|
| 706 | + struct sys_info_regs_gen4 __iomem *si = &stdev->mmio_sys_info->gen4; |
---|
| 707 | + struct active_partition_info_gen4 __iomem *af = &fi->active_flag; |
---|
| 708 | + |
---|
| 709 | + switch (info->flash_partition) { |
---|
| 710 | + case SWITCHTEC_IOCTL_PART_MAP_0: |
---|
| 711 | + set_fw_info_part(info, &fi->map0); |
---|
| 712 | + break; |
---|
| 713 | + case SWITCHTEC_IOCTL_PART_MAP_1: |
---|
| 714 | + set_fw_info_part(info, &fi->map1); |
---|
| 715 | + break; |
---|
| 716 | + case SWITCHTEC_IOCTL_PART_KEY_0: |
---|
| 717 | + set_fw_info_part(info, &fi->key0); |
---|
| 718 | + if (ioread8(&af->key) == SWITCHTEC_GEN4_KEY0_ACTIVE) |
---|
| 719 | + info->active |= SWITCHTEC_IOCTL_PART_ACTIVE; |
---|
| 720 | + if (ioread16(&si->key_running) == SWITCHTEC_GEN4_KEY0_RUNNING) |
---|
| 721 | + info->active |= SWITCHTEC_IOCTL_PART_RUNNING; |
---|
| 722 | + break; |
---|
| 723 | + case SWITCHTEC_IOCTL_PART_KEY_1: |
---|
| 724 | + set_fw_info_part(info, &fi->key1); |
---|
| 725 | + if (ioread8(&af->key) == SWITCHTEC_GEN4_KEY1_ACTIVE) |
---|
| 726 | + info->active |= SWITCHTEC_IOCTL_PART_ACTIVE; |
---|
| 727 | + if (ioread16(&si->key_running) == SWITCHTEC_GEN4_KEY1_RUNNING) |
---|
| 728 | + info->active |= SWITCHTEC_IOCTL_PART_RUNNING; |
---|
| 729 | + break; |
---|
| 730 | + case SWITCHTEC_IOCTL_PART_BL2_0: |
---|
| 731 | + set_fw_info_part(info, &fi->bl2_0); |
---|
| 732 | + if (ioread8(&af->bl2) == SWITCHTEC_GEN4_BL2_0_ACTIVE) |
---|
| 733 | + info->active |= SWITCHTEC_IOCTL_PART_ACTIVE; |
---|
| 734 | + if (ioread16(&si->bl2_running) == SWITCHTEC_GEN4_BL2_0_RUNNING) |
---|
| 735 | + info->active |= SWITCHTEC_IOCTL_PART_RUNNING; |
---|
| 736 | + break; |
---|
| 737 | + case SWITCHTEC_IOCTL_PART_BL2_1: |
---|
| 738 | + set_fw_info_part(info, &fi->bl2_1); |
---|
| 739 | + if (ioread8(&af->bl2) == SWITCHTEC_GEN4_BL2_1_ACTIVE) |
---|
| 740 | + info->active |= SWITCHTEC_IOCTL_PART_ACTIVE; |
---|
| 741 | + if (ioread16(&si->bl2_running) == SWITCHTEC_GEN4_BL2_1_RUNNING) |
---|
| 742 | + info->active |= SWITCHTEC_IOCTL_PART_RUNNING; |
---|
| 743 | + break; |
---|
| 744 | + case SWITCHTEC_IOCTL_PART_CFG0: |
---|
| 745 | + set_fw_info_part(info, &fi->cfg0); |
---|
| 746 | + if (ioread8(&af->cfg) == SWITCHTEC_GEN4_CFG0_ACTIVE) |
---|
| 747 | + info->active |= SWITCHTEC_IOCTL_PART_ACTIVE; |
---|
| 748 | + if (ioread16(&si->cfg_running) == SWITCHTEC_GEN4_CFG0_RUNNING) |
---|
| 749 | + info->active |= SWITCHTEC_IOCTL_PART_RUNNING; |
---|
| 750 | + break; |
---|
| 751 | + case SWITCHTEC_IOCTL_PART_CFG1: |
---|
| 752 | + set_fw_info_part(info, &fi->cfg1); |
---|
| 753 | + if (ioread8(&af->cfg) == SWITCHTEC_GEN4_CFG1_ACTIVE) |
---|
| 754 | + info->active |= SWITCHTEC_IOCTL_PART_ACTIVE; |
---|
| 755 | + if (ioread16(&si->cfg_running) == SWITCHTEC_GEN4_CFG1_RUNNING) |
---|
| 756 | + info->active |= SWITCHTEC_IOCTL_PART_RUNNING; |
---|
| 757 | + break; |
---|
| 758 | + case SWITCHTEC_IOCTL_PART_IMG0: |
---|
| 759 | + set_fw_info_part(info, &fi->img0); |
---|
| 760 | + if (ioread8(&af->img) == SWITCHTEC_GEN4_IMG0_ACTIVE) |
---|
| 761 | + info->active |= SWITCHTEC_IOCTL_PART_ACTIVE; |
---|
| 762 | + if (ioread16(&si->img_running) == SWITCHTEC_GEN4_IMG0_RUNNING) |
---|
| 763 | + info->active |= SWITCHTEC_IOCTL_PART_RUNNING; |
---|
| 764 | + break; |
---|
| 765 | + case SWITCHTEC_IOCTL_PART_IMG1: |
---|
| 766 | + set_fw_info_part(info, &fi->img1); |
---|
| 767 | + if (ioread8(&af->img) == SWITCHTEC_GEN4_IMG1_ACTIVE) |
---|
| 768 | + info->active |= SWITCHTEC_IOCTL_PART_ACTIVE; |
---|
| 769 | + if (ioread16(&si->img_running) == SWITCHTEC_GEN4_IMG1_RUNNING) |
---|
| 770 | + info->active |= SWITCHTEC_IOCTL_PART_RUNNING; |
---|
| 771 | + break; |
---|
| 772 | + case SWITCHTEC_IOCTL_PART_NVLOG: |
---|
| 773 | + set_fw_info_part(info, &fi->nvlog); |
---|
| 774 | + break; |
---|
| 775 | + case SWITCHTEC_IOCTL_PART_VENDOR0: |
---|
| 776 | + set_fw_info_part(info, &fi->vendor[0]); |
---|
| 777 | + break; |
---|
| 778 | + case SWITCHTEC_IOCTL_PART_VENDOR1: |
---|
| 779 | + set_fw_info_part(info, &fi->vendor[1]); |
---|
| 780 | + break; |
---|
| 781 | + case SWITCHTEC_IOCTL_PART_VENDOR2: |
---|
| 782 | + set_fw_info_part(info, &fi->vendor[2]); |
---|
| 783 | + break; |
---|
| 784 | + case SWITCHTEC_IOCTL_PART_VENDOR3: |
---|
| 785 | + set_fw_info_part(info, &fi->vendor[3]); |
---|
| 786 | + break; |
---|
| 787 | + case SWITCHTEC_IOCTL_PART_VENDOR4: |
---|
| 788 | + set_fw_info_part(info, &fi->vendor[4]); |
---|
| 789 | + break; |
---|
| 790 | + case SWITCHTEC_IOCTL_PART_VENDOR5: |
---|
| 791 | + set_fw_info_part(info, &fi->vendor[5]); |
---|
| 792 | + break; |
---|
| 793 | + case SWITCHTEC_IOCTL_PART_VENDOR6: |
---|
| 794 | + set_fw_info_part(info, &fi->vendor[6]); |
---|
| 795 | + break; |
---|
| 796 | + case SWITCHTEC_IOCTL_PART_VENDOR7: |
---|
| 797 | + set_fw_info_part(info, &fi->vendor[7]); |
---|
| 798 | + break; |
---|
| 799 | + default: |
---|
| 800 | + return -EINVAL; |
---|
| 801 | + } |
---|
| 802 | + |
---|
| 803 | + return 0; |
---|
| 804 | +} |
---|
| 805 | + |
---|
| 806 | +static int ioctl_flash_part_info(struct switchtec_dev *stdev, |
---|
| 807 | + struct switchtec_ioctl_flash_part_info __user *uinfo) |
---|
| 808 | +{ |
---|
| 809 | + int ret; |
---|
| 810 | + struct switchtec_ioctl_flash_part_info info = {0}; |
---|
| 811 | + |
---|
| 812 | + if (copy_from_user(&info, uinfo, sizeof(info))) |
---|
| 813 | + return -EFAULT; |
---|
| 814 | + |
---|
| 815 | + if (stdev->gen == SWITCHTEC_GEN3) { |
---|
| 816 | + ret = flash_part_info_gen3(stdev, &info); |
---|
| 817 | + if (ret) |
---|
| 818 | + return ret; |
---|
| 819 | + } else if (stdev->gen == SWITCHTEC_GEN4) { |
---|
| 820 | + ret = flash_part_info_gen4(stdev, &info); |
---|
| 821 | + if (ret) |
---|
| 822 | + return ret; |
---|
| 823 | + } else { |
---|
| 824 | + return -ENOTSUPP; |
---|
| 825 | + } |
---|
619 | 826 | |
---|
620 | 827 | if (copy_to_user(uinfo, &info, sizeof(info))) |
---|
621 | 828 | return -EFAULT; |
---|
.. | .. |
---|
625 | 832 | |
---|
626 | 833 | static int ioctl_event_summary(struct switchtec_dev *stdev, |
---|
627 | 834 | struct switchtec_user *stuser, |
---|
628 | | - struct switchtec_ioctl_event_summary __user *usum) |
---|
| 835 | + struct switchtec_ioctl_event_summary __user *usum, |
---|
| 836 | + size_t size) |
---|
629 | 837 | { |
---|
630 | | - struct switchtec_ioctl_event_summary s = {0}; |
---|
| 838 | + struct switchtec_ioctl_event_summary *s; |
---|
631 | 839 | int i; |
---|
632 | 840 | u32 reg; |
---|
| 841 | + int ret = 0; |
---|
633 | 842 | |
---|
634 | | - s.global = ioread32(&stdev->mmio_sw_event->global_summary); |
---|
635 | | - s.part_bitmap = readq(&stdev->mmio_sw_event->part_event_bitmap); |
---|
636 | | - s.local_part = ioread32(&stdev->mmio_part_cfg->part_event_summary); |
---|
| 843 | + s = kzalloc(sizeof(*s), GFP_KERNEL); |
---|
| 844 | + if (!s) |
---|
| 845 | + return -ENOMEM; |
---|
| 846 | + |
---|
| 847 | + s->global = ioread32(&stdev->mmio_sw_event->global_summary); |
---|
| 848 | + s->part_bitmap = ioread64(&stdev->mmio_sw_event->part_event_bitmap); |
---|
| 849 | + s->local_part = ioread32(&stdev->mmio_part_cfg->part_event_summary); |
---|
637 | 850 | |
---|
638 | 851 | for (i = 0; i < stdev->partition_count; i++) { |
---|
639 | 852 | reg = ioread32(&stdev->mmio_part_cfg_all[i].part_event_summary); |
---|
640 | | - s.part[i] = reg; |
---|
| 853 | + s->part[i] = reg; |
---|
641 | 854 | } |
---|
642 | 855 | |
---|
643 | | - for (i = 0; i < SWITCHTEC_MAX_PFF_CSR; i++) { |
---|
644 | | - reg = ioread16(&stdev->mmio_pff_csr[i].vendor_id); |
---|
645 | | - if (reg != PCI_VENDOR_ID_MICROSEMI) |
---|
646 | | - break; |
---|
647 | | - |
---|
| 856 | + for (i = 0; i < stdev->pff_csr_count; i++) { |
---|
648 | 857 | reg = ioread32(&stdev->mmio_pff_csr[i].pff_event_summary); |
---|
649 | | - s.pff[i] = reg; |
---|
| 858 | + s->pff[i] = reg; |
---|
650 | 859 | } |
---|
651 | 860 | |
---|
652 | | - if (copy_to_user(usum, &s, sizeof(s))) |
---|
653 | | - return -EFAULT; |
---|
| 861 | + if (copy_to_user(usum, s, size)) { |
---|
| 862 | + ret = -EFAULT; |
---|
| 863 | + goto error_case; |
---|
| 864 | + } |
---|
654 | 865 | |
---|
655 | 866 | stuser->event_cnt = atomic_read(&stdev->event_cnt); |
---|
656 | 867 | |
---|
657 | | - return 0; |
---|
| 868 | +error_case: |
---|
| 869 | + kfree(s); |
---|
| 870 | + return ret; |
---|
658 | 871 | } |
---|
659 | 872 | |
---|
660 | 873 | static u32 __iomem *global_ev_reg(struct switchtec_dev *stdev, |
---|
.. | .. |
---|
704 | 917 | EV_PAR(SWITCHTEC_IOCTL_EVENT_MRPC_COMP, mrpc_comp_hdr), |
---|
705 | 918 | EV_PAR(SWITCHTEC_IOCTL_EVENT_MRPC_COMP_ASYNC, mrpc_comp_async_hdr), |
---|
706 | 919 | EV_PAR(SWITCHTEC_IOCTL_EVENT_DYN_PART_BIND_COMP, dyn_binding_hdr), |
---|
| 920 | + EV_PAR(SWITCHTEC_IOCTL_EVENT_INTERCOMM_REQ_NOTIFY, |
---|
| 921 | + intercomm_notify_hdr), |
---|
707 | 922 | EV_PFF(SWITCHTEC_IOCTL_EVENT_AER_IN_P2P, aer_in_p2p_hdr), |
---|
708 | 923 | EV_PFF(SWITCHTEC_IOCTL_EVENT_AER_IN_VEP, aer_in_vep_hdr), |
---|
709 | 924 | EV_PFF(SWITCHTEC_IOCTL_EVENT_DPC, dpc_hdr), |
---|
710 | 925 | EV_PFF(SWITCHTEC_IOCTL_EVENT_CTS, cts_hdr), |
---|
| 926 | + EV_PFF(SWITCHTEC_IOCTL_EVENT_UEC, uec_hdr), |
---|
711 | 927 | EV_PFF(SWITCHTEC_IOCTL_EVENT_HOTPLUG, hotplug_hdr), |
---|
712 | 928 | EV_PFF(SWITCHTEC_IOCTL_EVENT_IER, ier_hdr), |
---|
713 | 929 | EV_PFF(SWITCHTEC_IOCTL_EVENT_THRESH, threshold_hdr), |
---|
.. | .. |
---|
724 | 940 | size_t off; |
---|
725 | 941 | |
---|
726 | 942 | if (event_id < 0 || event_id >= SWITCHTEC_IOCTL_MAX_EVENTS) |
---|
727 | | - return ERR_PTR(-EINVAL); |
---|
| 943 | + return (u32 __iomem *)ERR_PTR(-EINVAL); |
---|
728 | 944 | |
---|
729 | 945 | off = event_regs[event_id].offset; |
---|
730 | 946 | |
---|
.. | .. |
---|
732 | 948 | if (index == SWITCHTEC_IOCTL_EVENT_LOCAL_PART_IDX) |
---|
733 | 949 | index = stdev->partition; |
---|
734 | 950 | else if (index < 0 || index >= stdev->partition_count) |
---|
735 | | - return ERR_PTR(-EINVAL); |
---|
| 951 | + return (u32 __iomem *)ERR_PTR(-EINVAL); |
---|
736 | 952 | } else if (event_regs[event_id].map_reg == pff_ev_reg) { |
---|
737 | 953 | if (index < 0 || index >= stdev->pff_csr_count) |
---|
738 | | - return ERR_PTR(-EINVAL); |
---|
| 954 | + return (u32 __iomem *)ERR_PTR(-EINVAL); |
---|
739 | 955 | } |
---|
740 | 956 | |
---|
741 | 957 | return event_regs[event_id].map_reg(stdev, off, index); |
---|
.. | .. |
---|
841 | 1057 | } |
---|
842 | 1058 | |
---|
843 | 1059 | static int ioctl_pff_to_port(struct switchtec_dev *stdev, |
---|
844 | | - struct switchtec_ioctl_pff_port *up) |
---|
| 1060 | + struct switchtec_ioctl_pff_port __user *up) |
---|
845 | 1061 | { |
---|
846 | 1062 | int i, part; |
---|
847 | 1063 | u32 reg; |
---|
848 | | - struct part_cfg_regs *pcfg; |
---|
| 1064 | + struct part_cfg_regs __iomem *pcfg; |
---|
849 | 1065 | struct switchtec_ioctl_pff_port p; |
---|
850 | 1066 | |
---|
851 | 1067 | if (copy_from_user(&p, up, sizeof(p))) |
---|
.. | .. |
---|
888 | 1104 | } |
---|
889 | 1105 | |
---|
890 | 1106 | static int ioctl_port_to_pff(struct switchtec_dev *stdev, |
---|
891 | | - struct switchtec_ioctl_pff_port *up) |
---|
| 1107 | + struct switchtec_ioctl_pff_port __user *up) |
---|
892 | 1108 | { |
---|
893 | 1109 | struct switchtec_ioctl_pff_port p; |
---|
894 | | - struct part_cfg_regs *pcfg; |
---|
| 1110 | + struct part_cfg_regs __iomem *pcfg; |
---|
895 | 1111 | |
---|
896 | 1112 | if (copy_from_user(&p, up, sizeof(p))) |
---|
897 | 1113 | return -EFAULT; |
---|
.. | .. |
---|
944 | 1160 | case SWITCHTEC_IOCTL_FLASH_PART_INFO: |
---|
945 | 1161 | rc = ioctl_flash_part_info(stdev, argp); |
---|
946 | 1162 | break; |
---|
947 | | - case SWITCHTEC_IOCTL_EVENT_SUMMARY: |
---|
948 | | - rc = ioctl_event_summary(stdev, stuser, argp); |
---|
| 1163 | + case SWITCHTEC_IOCTL_EVENT_SUMMARY_LEGACY: |
---|
| 1164 | + rc = ioctl_event_summary(stdev, stuser, argp, |
---|
| 1165 | + sizeof(struct switchtec_ioctl_event_summary_legacy)); |
---|
949 | 1166 | break; |
---|
950 | 1167 | case SWITCHTEC_IOCTL_EVENT_CTL: |
---|
951 | 1168 | rc = ioctl_event_ctl(stdev, argp); |
---|
.. | .. |
---|
955 | 1172 | break; |
---|
956 | 1173 | case SWITCHTEC_IOCTL_PORT_TO_PFF: |
---|
957 | 1174 | rc = ioctl_port_to_pff(stdev, argp); |
---|
| 1175 | + break; |
---|
| 1176 | + case SWITCHTEC_IOCTL_EVENT_SUMMARY: |
---|
| 1177 | + rc = ioctl_event_summary(stdev, stuser, argp, |
---|
| 1178 | + sizeof(struct switchtec_ioctl_event_summary)); |
---|
958 | 1179 | break; |
---|
959 | 1180 | default: |
---|
960 | 1181 | rc = -ENOTTY; |
---|
.. | .. |
---|
973 | 1194 | .read = switchtec_dev_read, |
---|
974 | 1195 | .poll = switchtec_dev_poll, |
---|
975 | 1196 | .unlocked_ioctl = switchtec_dev_ioctl, |
---|
976 | | - .compat_ioctl = switchtec_dev_ioctl, |
---|
| 1197 | + .compat_ioctl = compat_ptr_ioctl, |
---|
977 | 1198 | }; |
---|
978 | 1199 | |
---|
979 | 1200 | static void link_event_work(struct work_struct *work) |
---|
.. | .. |
---|
1019 | 1240 | } |
---|
1020 | 1241 | } |
---|
1021 | 1242 | |
---|
| 1243 | +static void enable_dma_mrpc(struct switchtec_dev *stdev) |
---|
| 1244 | +{ |
---|
| 1245 | + writeq(stdev->dma_mrpc_dma_addr, &stdev->mmio_mrpc->dma_addr); |
---|
| 1246 | + flush_wc_buf(stdev); |
---|
| 1247 | + iowrite32(SWITCHTEC_DMA_MRPC_EN, &stdev->mmio_mrpc->dma_en); |
---|
| 1248 | +} |
---|
| 1249 | + |
---|
1022 | 1250 | static void stdev_release(struct device *dev) |
---|
1023 | 1251 | { |
---|
1024 | 1252 | struct switchtec_dev *stdev = to_stdev(dev); |
---|
1025 | 1253 | |
---|
| 1254 | + if (stdev->dma_mrpc) { |
---|
| 1255 | + iowrite32(0, &stdev->mmio_mrpc->dma_en); |
---|
| 1256 | + flush_wc_buf(stdev); |
---|
| 1257 | + writeq(0, &stdev->mmio_mrpc->dma_addr); |
---|
| 1258 | + dma_free_coherent(&stdev->pdev->dev, sizeof(*stdev->dma_mrpc), |
---|
| 1259 | + stdev->dma_mrpc, stdev->dma_mrpc_dma_addr); |
---|
| 1260 | + } |
---|
1026 | 1261 | kfree(stdev); |
---|
1027 | 1262 | } |
---|
1028 | 1263 | |
---|
.. | .. |
---|
1116 | 1351 | if (!(hdr & SWITCHTEC_EVENT_OCCURRED && hdr & SWITCHTEC_EVENT_EN_IRQ)) |
---|
1117 | 1352 | return 0; |
---|
1118 | 1353 | |
---|
1119 | | - if (eid == SWITCHTEC_IOCTL_EVENT_LINK_STATE || |
---|
1120 | | - eid == SWITCHTEC_IOCTL_EVENT_MRPC_COMP) |
---|
1121 | | - return 0; |
---|
1122 | | - |
---|
1123 | 1354 | dev_dbg(&stdev->dev, "%s: %d %d %x\n", __func__, eid, idx, hdr); |
---|
1124 | 1355 | hdr &= ~(SWITCHTEC_EVENT_EN_IRQ | SWITCHTEC_EVENT_OCCURRED); |
---|
1125 | 1356 | iowrite32(hdr, hdr_reg); |
---|
.. | .. |
---|
1166 | 1397 | |
---|
1167 | 1398 | check_link_state_events(stdev); |
---|
1168 | 1399 | |
---|
1169 | | - for (eid = 0; eid < SWITCHTEC_IOCTL_MAX_EVENTS; eid++) |
---|
| 1400 | + for (eid = 0; eid < SWITCHTEC_IOCTL_MAX_EVENTS; eid++) { |
---|
| 1401 | + if (eid == SWITCHTEC_IOCTL_EVENT_LINK_STATE || |
---|
| 1402 | + eid == SWITCHTEC_IOCTL_EVENT_MRPC_COMP) |
---|
| 1403 | + continue; |
---|
| 1404 | + |
---|
1170 | 1405 | event_count += mask_all_events(stdev, eid); |
---|
| 1406 | + } |
---|
1171 | 1407 | |
---|
1172 | 1408 | if (event_count) { |
---|
1173 | 1409 | atomic_inc(&stdev->event_cnt); |
---|
.. | .. |
---|
1180 | 1416 | return ret; |
---|
1181 | 1417 | } |
---|
1182 | 1418 | |
---|
| 1419 | + |
---|
| 1420 | +static irqreturn_t switchtec_dma_mrpc_isr(int irq, void *dev) |
---|
| 1421 | +{ |
---|
| 1422 | + struct switchtec_dev *stdev = dev; |
---|
| 1423 | + irqreturn_t ret = IRQ_NONE; |
---|
| 1424 | + |
---|
| 1425 | + iowrite32(SWITCHTEC_EVENT_CLEAR | |
---|
| 1426 | + SWITCHTEC_EVENT_EN_IRQ, |
---|
| 1427 | + &stdev->mmio_part_cfg->mrpc_comp_hdr); |
---|
| 1428 | + schedule_work(&stdev->mrpc_work); |
---|
| 1429 | + |
---|
| 1430 | + ret = IRQ_HANDLED; |
---|
| 1431 | + return ret; |
---|
| 1432 | +} |
---|
| 1433 | + |
---|
1183 | 1434 | static int switchtec_init_isr(struct switchtec_dev *stdev) |
---|
1184 | 1435 | { |
---|
1185 | 1436 | int nvecs; |
---|
1186 | 1437 | int event_irq; |
---|
| 1438 | + int dma_mrpc_irq; |
---|
| 1439 | + int rc; |
---|
1187 | 1440 | |
---|
1188 | | - nvecs = pci_alloc_irq_vectors(stdev->pdev, 1, 4, |
---|
1189 | | - PCI_IRQ_MSIX | PCI_IRQ_MSI); |
---|
| 1441 | + if (nirqs < 4) |
---|
| 1442 | + nirqs = 4; |
---|
| 1443 | + |
---|
| 1444 | + nvecs = pci_alloc_irq_vectors(stdev->pdev, 1, nirqs, |
---|
| 1445 | + PCI_IRQ_MSIX | PCI_IRQ_MSI | |
---|
| 1446 | + PCI_IRQ_VIRTUAL); |
---|
1190 | 1447 | if (nvecs < 0) |
---|
1191 | 1448 | return nvecs; |
---|
1192 | 1449 | |
---|
.. | .. |
---|
1198 | 1455 | if (event_irq < 0) |
---|
1199 | 1456 | return event_irq; |
---|
1200 | 1457 | |
---|
1201 | | - return devm_request_irq(&stdev->pdev->dev, event_irq, |
---|
| 1458 | + rc = devm_request_irq(&stdev->pdev->dev, event_irq, |
---|
1202 | 1459 | switchtec_event_isr, 0, |
---|
1203 | 1460 | KBUILD_MODNAME, stdev); |
---|
| 1461 | + |
---|
| 1462 | + if (rc) |
---|
| 1463 | + return rc; |
---|
| 1464 | + |
---|
| 1465 | + if (!stdev->dma_mrpc) |
---|
| 1466 | + return rc; |
---|
| 1467 | + |
---|
| 1468 | + dma_mrpc_irq = ioread32(&stdev->mmio_mrpc->dma_vector); |
---|
| 1469 | + if (dma_mrpc_irq < 0 || dma_mrpc_irq >= nvecs) |
---|
| 1470 | + return -EFAULT; |
---|
| 1471 | + |
---|
| 1472 | + dma_mrpc_irq = pci_irq_vector(stdev->pdev, dma_mrpc_irq); |
---|
| 1473 | + if (dma_mrpc_irq < 0) |
---|
| 1474 | + return dma_mrpc_irq; |
---|
| 1475 | + |
---|
| 1476 | + rc = devm_request_irq(&stdev->pdev->dev, dma_mrpc_irq, |
---|
| 1477 | + switchtec_dma_mrpc_isr, 0, |
---|
| 1478 | + KBUILD_MODNAME, stdev); |
---|
| 1479 | + |
---|
| 1480 | + return rc; |
---|
1204 | 1481 | } |
---|
1205 | 1482 | |
---|
1206 | 1483 | static void init_pff(struct switchtec_dev *stdev) |
---|
1207 | 1484 | { |
---|
1208 | 1485 | int i; |
---|
1209 | 1486 | u32 reg; |
---|
1210 | | - struct part_cfg_regs *pcfg = stdev->mmio_part_cfg; |
---|
| 1487 | + struct part_cfg_regs __iomem *pcfg = stdev->mmio_part_cfg; |
---|
1211 | 1488 | |
---|
1212 | 1489 | for (i = 0; i < SWITCHTEC_MAX_PFF_CSR; i++) { |
---|
1213 | 1490 | reg = ioread16(&stdev->mmio_pff_csr[i].vendor_id); |
---|
.. | .. |
---|
1218 | 1495 | stdev->pff_csr_count = i; |
---|
1219 | 1496 | |
---|
1220 | 1497 | reg = ioread32(&pcfg->usp_pff_inst_id); |
---|
1221 | | - if (reg < SWITCHTEC_MAX_PFF_CSR) |
---|
| 1498 | + if (reg < stdev->pff_csr_count) |
---|
1222 | 1499 | stdev->pff_local[reg] = 1; |
---|
1223 | 1500 | |
---|
1224 | 1501 | reg = ioread32(&pcfg->vep_pff_inst_id); |
---|
1225 | | - if (reg < SWITCHTEC_MAX_PFF_CSR) |
---|
| 1502 | + if (reg < stdev->pff_csr_count) |
---|
1226 | 1503 | stdev->pff_local[reg] = 1; |
---|
1227 | 1504 | |
---|
1228 | 1505 | for (i = 0; i < ARRAY_SIZE(pcfg->dsp_pff_inst_id); i++) { |
---|
1229 | 1506 | reg = ioread32(&pcfg->dsp_pff_inst_id[i]); |
---|
1230 | | - if (reg < SWITCHTEC_MAX_PFF_CSR) |
---|
| 1507 | + if (reg < stdev->pff_csr_count) |
---|
1231 | 1508 | stdev->pff_local[reg] = 1; |
---|
1232 | 1509 | } |
---|
1233 | 1510 | } |
---|
.. | .. |
---|
1236 | 1513 | struct pci_dev *pdev) |
---|
1237 | 1514 | { |
---|
1238 | 1515 | int rc; |
---|
| 1516 | + void __iomem *map; |
---|
| 1517 | + unsigned long res_start, res_len; |
---|
| 1518 | + u32 __iomem *part_id; |
---|
1239 | 1519 | |
---|
1240 | 1520 | rc = pcim_enable_device(pdev); |
---|
1241 | 1521 | if (rc) |
---|
1242 | 1522 | return rc; |
---|
1243 | 1523 | |
---|
1244 | | - rc = pcim_iomap_regions(pdev, 0x1, KBUILD_MODNAME); |
---|
| 1524 | + rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); |
---|
1245 | 1525 | if (rc) |
---|
1246 | 1526 | return rc; |
---|
1247 | 1527 | |
---|
1248 | 1528 | pci_set_master(pdev); |
---|
1249 | 1529 | |
---|
1250 | | - stdev->mmio = pcim_iomap_table(pdev)[0]; |
---|
1251 | | - stdev->mmio_mrpc = stdev->mmio + SWITCHTEC_GAS_MRPC_OFFSET; |
---|
| 1530 | + res_start = pci_resource_start(pdev, 0); |
---|
| 1531 | + res_len = pci_resource_len(pdev, 0); |
---|
| 1532 | + |
---|
| 1533 | + if (!devm_request_mem_region(&pdev->dev, res_start, |
---|
| 1534 | + res_len, KBUILD_MODNAME)) |
---|
| 1535 | + return -EBUSY; |
---|
| 1536 | + |
---|
| 1537 | + stdev->mmio_mrpc = devm_ioremap_wc(&pdev->dev, res_start, |
---|
| 1538 | + SWITCHTEC_GAS_TOP_CFG_OFFSET); |
---|
| 1539 | + if (!stdev->mmio_mrpc) |
---|
| 1540 | + return -ENOMEM; |
---|
| 1541 | + |
---|
| 1542 | + map = devm_ioremap(&pdev->dev, |
---|
| 1543 | + res_start + SWITCHTEC_GAS_TOP_CFG_OFFSET, |
---|
| 1544 | + res_len - SWITCHTEC_GAS_TOP_CFG_OFFSET); |
---|
| 1545 | + if (!map) |
---|
| 1546 | + return -ENOMEM; |
---|
| 1547 | + |
---|
| 1548 | + stdev->mmio = map - SWITCHTEC_GAS_TOP_CFG_OFFSET; |
---|
1252 | 1549 | stdev->mmio_sw_event = stdev->mmio + SWITCHTEC_GAS_SW_EVENT_OFFSET; |
---|
1253 | 1550 | stdev->mmio_sys_info = stdev->mmio + SWITCHTEC_GAS_SYS_INFO_OFFSET; |
---|
1254 | 1551 | stdev->mmio_flash_info = stdev->mmio + SWITCHTEC_GAS_FLASH_INFO_OFFSET; |
---|
1255 | 1552 | stdev->mmio_ntb = stdev->mmio + SWITCHTEC_GAS_NTB_OFFSET; |
---|
1256 | | - stdev->partition = ioread8(&stdev->mmio_sys_info->partition_id); |
---|
| 1553 | + |
---|
| 1554 | + if (stdev->gen == SWITCHTEC_GEN3) |
---|
| 1555 | + part_id = &stdev->mmio_sys_info->gen3.partition_id; |
---|
| 1556 | + else if (stdev->gen == SWITCHTEC_GEN4) |
---|
| 1557 | + part_id = &stdev->mmio_sys_info->gen4.partition_id; |
---|
| 1558 | + else |
---|
| 1559 | + return -ENOTSUPP; |
---|
| 1560 | + |
---|
| 1561 | + stdev->partition = ioread8(part_id); |
---|
1257 | 1562 | stdev->partition_count = ioread8(&stdev->mmio_ntb->partition_count); |
---|
1258 | 1563 | stdev->mmio_part_cfg_all = stdev->mmio + SWITCHTEC_GAS_PART_CFG_OFFSET; |
---|
1259 | 1564 | stdev->mmio_part_cfg = &stdev->mmio_part_cfg_all[stdev->partition]; |
---|
.. | .. |
---|
1265 | 1570 | init_pff(stdev); |
---|
1266 | 1571 | |
---|
1267 | 1572 | pci_set_drvdata(pdev, stdev); |
---|
| 1573 | + |
---|
| 1574 | + if (!use_dma_mrpc) |
---|
| 1575 | + return 0; |
---|
| 1576 | + |
---|
| 1577 | + if (ioread32(&stdev->mmio_mrpc->dma_ver) == 0) |
---|
| 1578 | + return 0; |
---|
| 1579 | + |
---|
| 1580 | + stdev->dma_mrpc = dma_alloc_coherent(&stdev->pdev->dev, |
---|
| 1581 | + sizeof(*stdev->dma_mrpc), |
---|
| 1582 | + &stdev->dma_mrpc_dma_addr, |
---|
| 1583 | + GFP_KERNEL); |
---|
| 1584 | + if (stdev->dma_mrpc == NULL) |
---|
| 1585 | + return -ENOMEM; |
---|
1268 | 1586 | |
---|
1269 | 1587 | return 0; |
---|
1270 | 1588 | } |
---|
.. | .. |
---|
1282 | 1600 | if (IS_ERR(stdev)) |
---|
1283 | 1601 | return PTR_ERR(stdev); |
---|
1284 | 1602 | |
---|
| 1603 | + stdev->gen = id->driver_data; |
---|
| 1604 | + |
---|
1285 | 1605 | rc = switchtec_init_pci(stdev, pdev); |
---|
1286 | 1606 | if (rc) |
---|
1287 | 1607 | goto err_put; |
---|
.. | .. |
---|
1296 | 1616 | SWITCHTEC_EVENT_EN_IRQ, |
---|
1297 | 1617 | &stdev->mmio_part_cfg->mrpc_comp_hdr); |
---|
1298 | 1618 | enable_link_state_events(stdev); |
---|
| 1619 | + |
---|
| 1620 | + if (stdev->dma_mrpc) |
---|
| 1621 | + enable_dma_mrpc(stdev); |
---|
1299 | 1622 | |
---|
1300 | 1623 | rc = cdev_device_add(&stdev->cdev, &stdev->dev); |
---|
1301 | 1624 | if (rc) |
---|
.. | .. |
---|
1322 | 1645 | cdev_device_del(&stdev->cdev, &stdev->dev); |
---|
1323 | 1646 | ida_simple_remove(&switchtec_minor_ida, MINOR(stdev->dev.devt)); |
---|
1324 | 1647 | dev_info(&stdev->dev, "unregistered.\n"); |
---|
1325 | | - |
---|
1326 | 1648 | stdev_kill(stdev); |
---|
1327 | 1649 | put_device(&stdev->dev); |
---|
1328 | 1650 | } |
---|
1329 | 1651 | |
---|
1330 | | -#define SWITCHTEC_PCI_DEVICE(device_id) \ |
---|
| 1652 | +#define SWITCHTEC_PCI_DEVICE(device_id, gen) \ |
---|
1331 | 1653 | { \ |
---|
1332 | 1654 | .vendor = PCI_VENDOR_ID_MICROSEMI, \ |
---|
1333 | 1655 | .device = device_id, \ |
---|
.. | .. |
---|
1335 | 1657 | .subdevice = PCI_ANY_ID, \ |
---|
1336 | 1658 | .class = (PCI_CLASS_MEMORY_OTHER << 8), \ |
---|
1337 | 1659 | .class_mask = 0xFFFFFFFF, \ |
---|
| 1660 | + .driver_data = gen, \ |
---|
1338 | 1661 | }, \ |
---|
1339 | 1662 | { \ |
---|
1340 | 1663 | .vendor = PCI_VENDOR_ID_MICROSEMI, \ |
---|
.. | .. |
---|
1343 | 1666 | .subdevice = PCI_ANY_ID, \ |
---|
1344 | 1667 | .class = (PCI_CLASS_BRIDGE_OTHER << 8), \ |
---|
1345 | 1668 | .class_mask = 0xFFFFFFFF, \ |
---|
| 1669 | + .driver_data = gen, \ |
---|
1346 | 1670 | } |
---|
1347 | 1671 | |
---|
1348 | 1672 | static const struct pci_device_id switchtec_pci_tbl[] = { |
---|
1349 | | - SWITCHTEC_PCI_DEVICE(0x8531), //PFX 24xG3 |
---|
1350 | | - SWITCHTEC_PCI_DEVICE(0x8532), //PFX 32xG3 |
---|
1351 | | - SWITCHTEC_PCI_DEVICE(0x8533), //PFX 48xG3 |
---|
1352 | | - SWITCHTEC_PCI_DEVICE(0x8534), //PFX 64xG3 |
---|
1353 | | - SWITCHTEC_PCI_DEVICE(0x8535), //PFX 80xG3 |
---|
1354 | | - SWITCHTEC_PCI_DEVICE(0x8536), //PFX 96xG3 |
---|
1355 | | - SWITCHTEC_PCI_DEVICE(0x8541), //PSX 24xG3 |
---|
1356 | | - SWITCHTEC_PCI_DEVICE(0x8542), //PSX 32xG3 |
---|
1357 | | - SWITCHTEC_PCI_DEVICE(0x8543), //PSX 48xG3 |
---|
1358 | | - SWITCHTEC_PCI_DEVICE(0x8544), //PSX 64xG3 |
---|
1359 | | - SWITCHTEC_PCI_DEVICE(0x8545), //PSX 80xG3 |
---|
1360 | | - SWITCHTEC_PCI_DEVICE(0x8546), //PSX 96xG3 |
---|
1361 | | - SWITCHTEC_PCI_DEVICE(0x8551), //PAX 24XG3 |
---|
1362 | | - SWITCHTEC_PCI_DEVICE(0x8552), //PAX 32XG3 |
---|
1363 | | - SWITCHTEC_PCI_DEVICE(0x8553), //PAX 48XG3 |
---|
1364 | | - SWITCHTEC_PCI_DEVICE(0x8554), //PAX 64XG3 |
---|
1365 | | - SWITCHTEC_PCI_DEVICE(0x8555), //PAX 80XG3 |
---|
1366 | | - SWITCHTEC_PCI_DEVICE(0x8556), //PAX 96XG3 |
---|
1367 | | - SWITCHTEC_PCI_DEVICE(0x8561), //PFXL 24XG3 |
---|
1368 | | - SWITCHTEC_PCI_DEVICE(0x8562), //PFXL 32XG3 |
---|
1369 | | - SWITCHTEC_PCI_DEVICE(0x8563), //PFXL 48XG3 |
---|
1370 | | - SWITCHTEC_PCI_DEVICE(0x8564), //PFXL 64XG3 |
---|
1371 | | - SWITCHTEC_PCI_DEVICE(0x8565), //PFXL 80XG3 |
---|
1372 | | - SWITCHTEC_PCI_DEVICE(0x8566), //PFXL 96XG3 |
---|
1373 | | - SWITCHTEC_PCI_DEVICE(0x8571), //PFXI 24XG3 |
---|
1374 | | - SWITCHTEC_PCI_DEVICE(0x8572), //PFXI 32XG3 |
---|
1375 | | - SWITCHTEC_PCI_DEVICE(0x8573), //PFXI 48XG3 |
---|
1376 | | - SWITCHTEC_PCI_DEVICE(0x8574), //PFXI 64XG3 |
---|
1377 | | - SWITCHTEC_PCI_DEVICE(0x8575), //PFXI 80XG3 |
---|
1378 | | - SWITCHTEC_PCI_DEVICE(0x8576), //PFXI 96XG3 |
---|
| 1673 | + SWITCHTEC_PCI_DEVICE(0x8531, SWITCHTEC_GEN3), //PFX 24xG3 |
---|
| 1674 | + SWITCHTEC_PCI_DEVICE(0x8532, SWITCHTEC_GEN3), //PFX 32xG3 |
---|
| 1675 | + SWITCHTEC_PCI_DEVICE(0x8533, SWITCHTEC_GEN3), //PFX 48xG3 |
---|
| 1676 | + SWITCHTEC_PCI_DEVICE(0x8534, SWITCHTEC_GEN3), //PFX 64xG3 |
---|
| 1677 | + SWITCHTEC_PCI_DEVICE(0x8535, SWITCHTEC_GEN3), //PFX 80xG3 |
---|
| 1678 | + SWITCHTEC_PCI_DEVICE(0x8536, SWITCHTEC_GEN3), //PFX 96xG3 |
---|
| 1679 | + SWITCHTEC_PCI_DEVICE(0x8541, SWITCHTEC_GEN3), //PSX 24xG3 |
---|
| 1680 | + SWITCHTEC_PCI_DEVICE(0x8542, SWITCHTEC_GEN3), //PSX 32xG3 |
---|
| 1681 | + SWITCHTEC_PCI_DEVICE(0x8543, SWITCHTEC_GEN3), //PSX 48xG3 |
---|
| 1682 | + SWITCHTEC_PCI_DEVICE(0x8544, SWITCHTEC_GEN3), //PSX 64xG3 |
---|
| 1683 | + SWITCHTEC_PCI_DEVICE(0x8545, SWITCHTEC_GEN3), //PSX 80xG3 |
---|
| 1684 | + SWITCHTEC_PCI_DEVICE(0x8546, SWITCHTEC_GEN3), //PSX 96xG3 |
---|
| 1685 | + SWITCHTEC_PCI_DEVICE(0x8551, SWITCHTEC_GEN3), //PAX 24XG3 |
---|
| 1686 | + SWITCHTEC_PCI_DEVICE(0x8552, SWITCHTEC_GEN3), //PAX 32XG3 |
---|
| 1687 | + SWITCHTEC_PCI_DEVICE(0x8553, SWITCHTEC_GEN3), //PAX 48XG3 |
---|
| 1688 | + SWITCHTEC_PCI_DEVICE(0x8554, SWITCHTEC_GEN3), //PAX 64XG3 |
---|
| 1689 | + SWITCHTEC_PCI_DEVICE(0x8555, SWITCHTEC_GEN3), //PAX 80XG3 |
---|
| 1690 | + SWITCHTEC_PCI_DEVICE(0x8556, SWITCHTEC_GEN3), //PAX 96XG3 |
---|
| 1691 | + SWITCHTEC_PCI_DEVICE(0x8561, SWITCHTEC_GEN3), //PFXL 24XG3 |
---|
| 1692 | + SWITCHTEC_PCI_DEVICE(0x8562, SWITCHTEC_GEN3), //PFXL 32XG3 |
---|
| 1693 | + SWITCHTEC_PCI_DEVICE(0x8563, SWITCHTEC_GEN3), //PFXL 48XG3 |
---|
| 1694 | + SWITCHTEC_PCI_DEVICE(0x8564, SWITCHTEC_GEN3), //PFXL 64XG3 |
---|
| 1695 | + SWITCHTEC_PCI_DEVICE(0x8565, SWITCHTEC_GEN3), //PFXL 80XG3 |
---|
| 1696 | + SWITCHTEC_PCI_DEVICE(0x8566, SWITCHTEC_GEN3), //PFXL 96XG3 |
---|
| 1697 | + SWITCHTEC_PCI_DEVICE(0x8571, SWITCHTEC_GEN3), //PFXI 24XG3 |
---|
| 1698 | + SWITCHTEC_PCI_DEVICE(0x8572, SWITCHTEC_GEN3), //PFXI 32XG3 |
---|
| 1699 | + SWITCHTEC_PCI_DEVICE(0x8573, SWITCHTEC_GEN3), //PFXI 48XG3 |
---|
| 1700 | + SWITCHTEC_PCI_DEVICE(0x8574, SWITCHTEC_GEN3), //PFXI 64XG3 |
---|
| 1701 | + SWITCHTEC_PCI_DEVICE(0x8575, SWITCHTEC_GEN3), //PFXI 80XG3 |
---|
| 1702 | + SWITCHTEC_PCI_DEVICE(0x8576, SWITCHTEC_GEN3), //PFXI 96XG3 |
---|
| 1703 | + SWITCHTEC_PCI_DEVICE(0x4000, SWITCHTEC_GEN4), //PFX 100XG4 |
---|
| 1704 | + SWITCHTEC_PCI_DEVICE(0x4084, SWITCHTEC_GEN4), //PFX 84XG4 |
---|
| 1705 | + SWITCHTEC_PCI_DEVICE(0x4068, SWITCHTEC_GEN4), //PFX 68XG4 |
---|
| 1706 | + SWITCHTEC_PCI_DEVICE(0x4052, SWITCHTEC_GEN4), //PFX 52XG4 |
---|
| 1707 | + SWITCHTEC_PCI_DEVICE(0x4036, SWITCHTEC_GEN4), //PFX 36XG4 |
---|
| 1708 | + SWITCHTEC_PCI_DEVICE(0x4028, SWITCHTEC_GEN4), //PFX 28XG4 |
---|
| 1709 | + SWITCHTEC_PCI_DEVICE(0x4100, SWITCHTEC_GEN4), //PSX 100XG4 |
---|
| 1710 | + SWITCHTEC_PCI_DEVICE(0x4184, SWITCHTEC_GEN4), //PSX 84XG4 |
---|
| 1711 | + SWITCHTEC_PCI_DEVICE(0x4168, SWITCHTEC_GEN4), //PSX 68XG4 |
---|
| 1712 | + SWITCHTEC_PCI_DEVICE(0x4152, SWITCHTEC_GEN4), //PSX 52XG4 |
---|
| 1713 | + SWITCHTEC_PCI_DEVICE(0x4136, SWITCHTEC_GEN4), //PSX 36XG4 |
---|
| 1714 | + SWITCHTEC_PCI_DEVICE(0x4128, SWITCHTEC_GEN4), //PSX 28XG4 |
---|
| 1715 | + SWITCHTEC_PCI_DEVICE(0x4200, SWITCHTEC_GEN4), //PAX 100XG4 |
---|
| 1716 | + SWITCHTEC_PCI_DEVICE(0x4284, SWITCHTEC_GEN4), //PAX 84XG4 |
---|
| 1717 | + SWITCHTEC_PCI_DEVICE(0x4268, SWITCHTEC_GEN4), //PAX 68XG4 |
---|
| 1718 | + SWITCHTEC_PCI_DEVICE(0x4252, SWITCHTEC_GEN4), //PAX 52XG4 |
---|
| 1719 | + SWITCHTEC_PCI_DEVICE(0x4236, SWITCHTEC_GEN4), //PAX 36XG4 |
---|
| 1720 | + SWITCHTEC_PCI_DEVICE(0x4228, SWITCHTEC_GEN4), //PAX 28XG4 |
---|
1379 | 1721 | {0} |
---|
1380 | 1722 | }; |
---|
1381 | 1723 | MODULE_DEVICE_TABLE(pci, switchtec_pci_tbl); |
---|