diff options
author | Alexandre Bounine <alexandre.bounine@idt.com> | 2016-08-02 17:06:57 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-02 19:35:37 -0400 |
commit | 1ae842de1dd8051cbb65b396b6f029d07f992641 (patch) | |
tree | 8611cc33a11229df919f3d87561d803d5e5986a9 /drivers | |
parent | a057a52e94e15d89be8af557584e0144a496b6c6 (diff) |
rapidio: modify for rev.3 specification changes
Implement changes made in RapidIO specification rev.3 to LP-Serial Physical
Layer register definitions:
- use per-port register offset calculations based on LP-Serial Extended
Features Block (EFB) Register Map type (I or II) with different
per-port offset step (0x20 vs 0x40 respectfully).
- remove deprecated Parallel Physical layer definitions and related
code.
[alexandre.bounine@idt.com: fix DocBook warning for gen3 update]
Link: http://lkml.kernel.org/r/1469191173-19338-1-git-send-email-alexandre.bounine@idt.com
Link: http://lkml.kernel.org/r/1469125134-16523-12-git-send-email-alexandre.bounine@idt.com
Signed-off-by: Alexandre Bounine <alexandre.bounine@idt.com>
Tested-by: Barry Wood <barry.wood@idt.com>
Cc: Matt Porter <mporter@kernel.crashing.org>
Cc: Andre van Herk <andre.van.herk@prodrive-technologies.com>
Cc: Barry Wood <barry.wood@idt.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/rapidio/devices/rio_mport_cdev.c | 2 | ||||
-rw-r--r-- | drivers/rapidio/devices/tsi721.c | 8 | ||||
-rw-r--r-- | drivers/rapidio/rio-scan.c | 74 | ||||
-rw-r--r-- | drivers/rapidio/rio.c | 150 | ||||
-rw-r--r-- | drivers/rapidio/rio.h | 2 | ||||
-rw-r--r-- | drivers/rapidio/switches/tsi57x.c | 26 |
6 files changed, 113 insertions, 149 deletions
diff --git a/drivers/rapidio/devices/rio_mport_cdev.c b/drivers/rapidio/devices/rio_mport_cdev.c index de0c692587dd..436dfe871d32 100644 --- a/drivers/rapidio/devices/rio_mport_cdev.c +++ b/drivers/rapidio/devices/rio_mport_cdev.c | |||
@@ -1813,7 +1813,7 @@ static int rio_mport_add_riodev(struct mport_cdev_priv *priv, | |||
1813 | if (rdev->pef & RIO_PEF_EXT_FEATURES) { | 1813 | if (rdev->pef & RIO_PEF_EXT_FEATURES) { |
1814 | rdev->efptr = rval & 0xffff; | 1814 | rdev->efptr = rval & 0xffff; |
1815 | rdev->phys_efptr = rio_mport_get_physefb(mport, 0, destid, | 1815 | rdev->phys_efptr = rio_mport_get_physefb(mport, 0, destid, |
1816 | hopcount); | 1816 | hopcount, &rdev->phys_rmap); |
1817 | 1817 | ||
1818 | rdev->em_efptr = rio_mport_get_feature(mport, 0, destid, | 1818 | rdev->em_efptr = rio_mport_get_feature(mport, 0, destid, |
1819 | hopcount, RIO_EFB_ERR_MGMNT); | 1819 | hopcount, RIO_EFB_ERR_MGMNT); |
diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c index 53daf634a1ac..32f0f014a067 100644 --- a/drivers/rapidio/devices/tsi721.c +++ b/drivers/rapidio/devices/tsi721.c | |||
@@ -2555,11 +2555,11 @@ static int tsi721_query_mport(struct rio_mport *mport, | |||
2555 | struct tsi721_device *priv = mport->priv; | 2555 | struct tsi721_device *priv = mport->priv; |
2556 | u32 rval; | 2556 | u32 rval; |
2557 | 2557 | ||
2558 | rval = ioread32(priv->regs + (0x100 + RIO_PORT_N_ERR_STS_CSR(0))); | 2558 | rval = ioread32(priv->regs + 0x100 + RIO_PORT_N_ERR_STS_CSR(0, 0)); |
2559 | if (rval & RIO_PORT_N_ERR_STS_PORT_OK) { | 2559 | if (rval & RIO_PORT_N_ERR_STS_PORT_OK) { |
2560 | rval = ioread32(priv->regs + (0x100 + RIO_PORT_N_CTL2_CSR(0))); | 2560 | rval = ioread32(priv->regs + 0x100 + RIO_PORT_N_CTL2_CSR(0, 0)); |
2561 | attr->link_speed = (rval & RIO_PORT_N_CTL2_SEL_BAUD) >> 28; | 2561 | attr->link_speed = (rval & RIO_PORT_N_CTL2_SEL_BAUD) >> 28; |
2562 | rval = ioread32(priv->regs + (0x100 + RIO_PORT_N_CTL_CSR(0))); | 2562 | rval = ioread32(priv->regs + 0x100 + RIO_PORT_N_CTL_CSR(0, 0)); |
2563 | attr->link_width = (rval & RIO_PORT_N_CTL_IPW) >> 27; | 2563 | attr->link_width = (rval & RIO_PORT_N_CTL_IPW) >> 27; |
2564 | } else | 2564 | } else |
2565 | attr->link_speed = RIO_LINK_DOWN; | 2565 | attr->link_speed = RIO_LINK_DOWN; |
@@ -2673,9 +2673,9 @@ static int tsi721_setup_mport(struct tsi721_device *priv) | |||
2673 | mport->ops = &tsi721_rio_ops; | 2673 | mport->ops = &tsi721_rio_ops; |
2674 | mport->index = 0; | 2674 | mport->index = 0; |
2675 | mport->sys_size = 0; /* small system */ | 2675 | mport->sys_size = 0; /* small system */ |
2676 | mport->phy_type = RIO_PHY_SERIAL; | ||
2677 | mport->priv = (void *)priv; | 2676 | mport->priv = (void *)priv; |
2678 | mport->phys_efptr = 0x100; | 2677 | mport->phys_efptr = 0x100; |
2678 | mport->phys_rmap = 1; | ||
2679 | mport->dev.parent = &pdev->dev; | 2679 | mport->dev.parent = &pdev->dev; |
2680 | mport->dev.release = tsi721_mport_release; | 2680 | mport->dev.release = tsi721_mport_release; |
2681 | 2681 | ||
diff --git a/drivers/rapidio/rio-scan.c b/drivers/rapidio/rio-scan.c index a63a380809d1..23429bdaca84 100644 --- a/drivers/rapidio/rio-scan.c +++ b/drivers/rapidio/rio-scan.c | |||
@@ -49,15 +49,6 @@ struct rio_id_table { | |||
49 | static int next_destid = 0; | 49 | static int next_destid = 0; |
50 | static int next_comptag = 1; | 50 | static int next_comptag = 1; |
51 | 51 | ||
52 | static int rio_mport_phys_table[] = { | ||
53 | RIO_EFB_PAR_EP_ID, | ||
54 | RIO_EFB_PAR_EP_REC_ID, | ||
55 | RIO_EFB_SER_EP_ID, | ||
56 | RIO_EFB_SER_EP_REC_ID, | ||
57 | -1, | ||
58 | }; | ||
59 | |||
60 | |||
61 | /** | 52 | /** |
62 | * rio_destid_alloc - Allocate next available destID for given network | 53 | * rio_destid_alloc - Allocate next available destID for given network |
63 | * @net: RIO network | 54 | * @net: RIO network |
@@ -380,10 +371,15 @@ static struct rio_dev *rio_setup_device(struct rio_net *net, | |||
380 | if (rdev->pef & RIO_PEF_EXT_FEATURES) { | 371 | if (rdev->pef & RIO_PEF_EXT_FEATURES) { |
381 | rdev->efptr = result & 0xffff; | 372 | rdev->efptr = result & 0xffff; |
382 | rdev->phys_efptr = rio_mport_get_physefb(port, 0, destid, | 373 | rdev->phys_efptr = rio_mport_get_physefb(port, 0, destid, |
383 | hopcount); | 374 | hopcount, &rdev->phys_rmap); |
375 | pr_debug("RIO: %s Register Map %d device\n", | ||
376 | __func__, rdev->phys_rmap); | ||
384 | 377 | ||
385 | rdev->em_efptr = rio_mport_get_feature(port, 0, destid, | 378 | rdev->em_efptr = rio_mport_get_feature(port, 0, destid, |
386 | hopcount, RIO_EFB_ERR_MGMNT); | 379 | hopcount, RIO_EFB_ERR_MGMNT); |
380 | if (!rdev->em_efptr) | ||
381 | rdev->em_efptr = rio_mport_get_feature(port, 0, destid, | ||
382 | hopcount, RIO_EFB_ERR_MGMNT_HS); | ||
387 | } | 383 | } |
388 | 384 | ||
389 | rio_mport_read_config_32(port, destid, hopcount, RIO_SRC_OPS_CAR, | 385 | rio_mport_read_config_32(port, destid, hopcount, RIO_SRC_OPS_CAR, |
@@ -445,7 +441,7 @@ static struct rio_dev *rio_setup_device(struct rio_net *net, | |||
445 | rio_route_clr_table(rdev, RIO_GLOBAL_TABLE, 0); | 441 | rio_route_clr_table(rdev, RIO_GLOBAL_TABLE, 0); |
446 | } else { | 442 | } else { |
447 | if (do_enum) | 443 | if (do_enum) |
448 | /*Enable Input Output Port (transmitter reviever)*/ | 444 | /*Enable Input Output Port (transmitter receiver)*/ |
449 | rio_enable_rx_tx_port(port, 0, destid, hopcount, 0); | 445 | rio_enable_rx_tx_port(port, 0, destid, hopcount, 0); |
450 | 446 | ||
451 | dev_set_name(&rdev->dev, "%02x:e:%04x", rdev->net->id, | 447 | dev_set_name(&rdev->dev, "%02x:e:%04x", rdev->net->id, |
@@ -481,10 +477,8 @@ cleanup: | |||
481 | 477 | ||
482 | /** | 478 | /** |
483 | * rio_sport_is_active- Tests if a switch port has an active connection. | 479 | * rio_sport_is_active- Tests if a switch port has an active connection. |
484 | * @port: Master port to send transaction | 480 | * @rdev: RapidIO device object |
485 | * @destid: Associated destination ID for switch | 481 | * @sp: Switch port number |
486 | * @hopcount: Hopcount to reach switch | ||
487 | * @sport: Switch port number | ||
488 | * | 482 | * |
489 | * Reads the port error status CSR for a particular switch port to | 483 | * Reads the port error status CSR for a particular switch port to |
490 | * determine if the port has an active link. Returns | 484 | * determine if the port has an active link. Returns |
@@ -492,31 +486,12 @@ cleanup: | |||
492 | * inactive. | 486 | * inactive. |
493 | */ | 487 | */ |
494 | static int | 488 | static int |
495 | rio_sport_is_active(struct rio_mport *port, u16 destid, u8 hopcount, int sport) | 489 | rio_sport_is_active(struct rio_dev *rdev, int sp) |
496 | { | 490 | { |
497 | u32 result = 0; | 491 | u32 result = 0; |
498 | u32 ext_ftr_ptr; | ||
499 | 492 | ||
500 | ext_ftr_ptr = rio_mport_get_efb(port, 0, destid, hopcount, 0); | 493 | rio_read_config_32(rdev, RIO_DEV_PORT_N_ERR_STS_CSR(rdev, sp), |
501 | 494 | &result); | |
502 | while (ext_ftr_ptr) { | ||
503 | rio_mport_read_config_32(port, destid, hopcount, | ||
504 | ext_ftr_ptr, &result); | ||
505 | result = RIO_GET_BLOCK_ID(result); | ||
506 | if ((result == RIO_EFB_SER_EP_FREE_ID) || | ||
507 | (result == RIO_EFB_SER_EP_FREE_ID_V13P) || | ||
508 | (result == RIO_EFB_SER_EP_FREC_ID)) | ||
509 | break; | ||
510 | |||
511 | ext_ftr_ptr = rio_mport_get_efb(port, 0, destid, hopcount, | ||
512 | ext_ftr_ptr); | ||
513 | } | ||
514 | |||
515 | if (ext_ftr_ptr) | ||
516 | rio_mport_read_config_32(port, destid, hopcount, | ||
517 | ext_ftr_ptr + | ||
518 | RIO_PORT_N_ERR_STS_CSR(sport), | ||
519 | &result); | ||
520 | 495 | ||
521 | return result & RIO_PORT_N_ERR_STS_PORT_OK; | 496 | return result & RIO_PORT_N_ERR_STS_PORT_OK; |
522 | } | 497 | } |
@@ -655,9 +630,7 @@ static int rio_enum_peer(struct rio_net *net, struct rio_mport *port, | |||
655 | 630 | ||
656 | cur_destid = next_destid; | 631 | cur_destid = next_destid; |
657 | 632 | ||
658 | if (rio_sport_is_active | 633 | if (rio_sport_is_active(rdev, port_num)) { |
659 | (port, RIO_ANY_DESTID(port->sys_size), hopcount, | ||
660 | port_num)) { | ||
661 | pr_debug( | 634 | pr_debug( |
662 | "RIO: scanning device on port %d\n", | 635 | "RIO: scanning device on port %d\n", |
663 | port_num); | 636 | port_num); |
@@ -785,8 +758,7 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid, | |||
785 | if (RIO_GET_PORT_NUM(rdev->swpinfo) == port_num) | 758 | if (RIO_GET_PORT_NUM(rdev->swpinfo) == port_num) |
786 | continue; | 759 | continue; |
787 | 760 | ||
788 | if (rio_sport_is_active | 761 | if (rio_sport_is_active(rdev, port_num)) { |
789 | (port, destid, hopcount, port_num)) { | ||
790 | pr_debug( | 762 | pr_debug( |
791 | "RIO: scanning device on port %d\n", | 763 | "RIO: scanning device on port %d\n", |
792 | port_num); | 764 | port_num); |
@@ -831,21 +803,11 @@ rio_disc_peer(struct rio_net *net, struct rio_mport *port, u16 destid, | |||
831 | static int rio_mport_is_active(struct rio_mport *port) | 803 | static int rio_mport_is_active(struct rio_mport *port) |
832 | { | 804 | { |
833 | u32 result = 0; | 805 | u32 result = 0; |
834 | u32 ext_ftr_ptr; | ||
835 | int *entry = rio_mport_phys_table; | ||
836 | |||
837 | do { | ||
838 | if ((ext_ftr_ptr = | ||
839 | rio_mport_get_feature(port, 1, 0, 0, *entry))) | ||
840 | break; | ||
841 | } while (*++entry >= 0); | ||
842 | |||
843 | if (ext_ftr_ptr) | ||
844 | rio_local_read_config_32(port, | ||
845 | ext_ftr_ptr + | ||
846 | RIO_PORT_N_ERR_STS_CSR(port->index), | ||
847 | &result); | ||
848 | 806 | ||
807 | rio_local_read_config_32(port, | ||
808 | port->phys_efptr + | ||
809 | RIO_PORT_N_ERR_STS_CSR(port->index, port->phys_rmap), | ||
810 | &result); | ||
849 | return result & RIO_PORT_N_ERR_STS_PORT_OK; | 811 | return result & RIO_PORT_N_ERR_STS_PORT_OK; |
850 | } | 812 | } |
851 | 813 | ||
diff --git a/drivers/rapidio/rio.c b/drivers/rapidio/rio.c index 1cd32603259f..37042858c2db 100644 --- a/drivers/rapidio/rio.c +++ b/drivers/rapidio/rio.c | |||
@@ -786,10 +786,11 @@ EXPORT_SYMBOL_GPL(rio_unmap_outb_region); | |||
786 | * @local: Indicate a local master port or remote device access | 786 | * @local: Indicate a local master port or remote device access |
787 | * @destid: Destination ID of the device | 787 | * @destid: Destination ID of the device |
788 | * @hopcount: Number of switch hops to the device | 788 | * @hopcount: Number of switch hops to the device |
789 | * @rmap: pointer to location to store register map type info | ||
789 | */ | 790 | */ |
790 | u32 | 791 | u32 |
791 | rio_mport_get_physefb(struct rio_mport *port, int local, | 792 | rio_mport_get_physefb(struct rio_mport *port, int local, |
792 | u16 destid, u8 hopcount) | 793 | u16 destid, u8 hopcount, u32 *rmap) |
793 | { | 794 | { |
794 | u32 ext_ftr_ptr; | 795 | u32 ext_ftr_ptr; |
795 | u32 ftr_header; | 796 | u32 ftr_header; |
@@ -807,14 +808,21 @@ rio_mport_get_physefb(struct rio_mport *port, int local, | |||
807 | ftr_header = RIO_GET_BLOCK_ID(ftr_header); | 808 | ftr_header = RIO_GET_BLOCK_ID(ftr_header); |
808 | switch (ftr_header) { | 809 | switch (ftr_header) { |
809 | 810 | ||
810 | case RIO_EFB_SER_EP_ID_V13P: | ||
811 | case RIO_EFB_SER_EP_REC_ID_V13P: | ||
812 | case RIO_EFB_SER_EP_FREE_ID_V13P: | ||
813 | case RIO_EFB_SER_EP_ID: | 811 | case RIO_EFB_SER_EP_ID: |
814 | case RIO_EFB_SER_EP_REC_ID: | 812 | case RIO_EFB_SER_EP_REC_ID: |
815 | case RIO_EFB_SER_EP_FREE_ID: | 813 | case RIO_EFB_SER_EP_FREE_ID: |
816 | case RIO_EFB_SER_EP_FREC_ID: | 814 | case RIO_EFB_SER_EP_M1_ID: |
815 | case RIO_EFB_SER_EP_SW_M1_ID: | ||
816 | case RIO_EFB_SER_EPF_M1_ID: | ||
817 | case RIO_EFB_SER_EPF_SW_M1_ID: | ||
818 | *rmap = 1; | ||
819 | return ext_ftr_ptr; | ||
817 | 820 | ||
821 | case RIO_EFB_SER_EP_M2_ID: | ||
822 | case RIO_EFB_SER_EP_SW_M2_ID: | ||
823 | case RIO_EFB_SER_EPF_M2_ID: | ||
824 | case RIO_EFB_SER_EPF_SW_M2_ID: | ||
825 | *rmap = 2; | ||
818 | return ext_ftr_ptr; | 826 | return ext_ftr_ptr; |
819 | 827 | ||
820 | default: | 828 | default: |
@@ -873,16 +881,16 @@ int rio_set_port_lockout(struct rio_dev *rdev, u32 pnum, int lock) | |||
873 | u32 regval; | 881 | u32 regval; |
874 | 882 | ||
875 | rio_read_config_32(rdev, | 883 | rio_read_config_32(rdev, |
876 | rdev->phys_efptr + RIO_PORT_N_CTL_CSR(pnum), | 884 | RIO_DEV_PORT_N_CTL_CSR(rdev, pnum), |
877 | ®val); | 885 | ®val); |
878 | if (lock) | 886 | if (lock) |
879 | regval |= RIO_PORT_N_CTL_LOCKOUT; | 887 | regval |= RIO_PORT_N_CTL_LOCKOUT; |
880 | else | 888 | else |
881 | regval &= ~RIO_PORT_N_CTL_LOCKOUT; | 889 | regval &= ~RIO_PORT_N_CTL_LOCKOUT; |
882 | 890 | ||
883 | rio_write_config_32(rdev, | 891 | rio_write_config_32(rdev, |
884 | rdev->phys_efptr + RIO_PORT_N_CTL_CSR(pnum), | 892 | RIO_DEV_PORT_N_CTL_CSR(rdev, pnum), |
885 | regval); | 893 | regval); |
886 | return 0; | 894 | return 0; |
887 | } | 895 | } |
888 | EXPORT_SYMBOL_GPL(rio_set_port_lockout); | 896 | EXPORT_SYMBOL_GPL(rio_set_port_lockout); |
@@ -906,6 +914,7 @@ int rio_enable_rx_tx_port(struct rio_mport *port, | |||
906 | #ifdef CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS | 914 | #ifdef CONFIG_RAPIDIO_ENABLE_RX_TX_PORTS |
907 | u32 regval; | 915 | u32 regval; |
908 | u32 ext_ftr_ptr; | 916 | u32 ext_ftr_ptr; |
917 | u32 rmap; | ||
909 | 918 | ||
910 | /* | 919 | /* |
911 | * enable rx input tx output port | 920 | * enable rx input tx output port |
@@ -913,34 +922,29 @@ int rio_enable_rx_tx_port(struct rio_mport *port, | |||
913 | pr_debug("rio_enable_rx_tx_port(local = %d, destid = %d, hopcount = " | 922 | pr_debug("rio_enable_rx_tx_port(local = %d, destid = %d, hopcount = " |
914 | "%d, port_num = %d)\n", local, destid, hopcount, port_num); | 923 | "%d, port_num = %d)\n", local, destid, hopcount, port_num); |
915 | 924 | ||
916 | ext_ftr_ptr = rio_mport_get_physefb(port, local, destid, hopcount); | 925 | ext_ftr_ptr = rio_mport_get_physefb(port, local, destid, |
926 | hopcount, &rmap); | ||
917 | 927 | ||
918 | if (local) { | 928 | if (local) { |
919 | rio_local_read_config_32(port, ext_ftr_ptr + | 929 | rio_local_read_config_32(port, |
920 | RIO_PORT_N_CTL_CSR(0), | 930 | ext_ftr_ptr + RIO_PORT_N_CTL_CSR(0, rmap), |
921 | ®val); | 931 | ®val); |
922 | } else { | 932 | } else { |
923 | if (rio_mport_read_config_32(port, destid, hopcount, | 933 | if (rio_mport_read_config_32(port, destid, hopcount, |
924 | ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), ®val) < 0) | 934 | ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num, rmap), |
935 | ®val) < 0) | ||
925 | return -EIO; | 936 | return -EIO; |
926 | } | 937 | } |
927 | 938 | ||
928 | if (regval & RIO_PORT_N_CTL_P_TYP_SER) { | 939 | regval = regval | RIO_PORT_N_CTL_EN_RX | RIO_PORT_N_CTL_EN_TX; |
929 | /* serial */ | ||
930 | regval = regval | RIO_PORT_N_CTL_EN_RX_SER | ||
931 | | RIO_PORT_N_CTL_EN_TX_SER; | ||
932 | } else { | ||
933 | /* parallel */ | ||
934 | regval = regval | RIO_PORT_N_CTL_EN_RX_PAR | ||
935 | | RIO_PORT_N_CTL_EN_TX_PAR; | ||
936 | } | ||
937 | 940 | ||
938 | if (local) { | 941 | if (local) { |
939 | rio_local_write_config_32(port, ext_ftr_ptr + | 942 | rio_local_write_config_32(port, |
940 | RIO_PORT_N_CTL_CSR(0), regval); | 943 | ext_ftr_ptr + RIO_PORT_N_CTL_CSR(0, rmap), regval); |
941 | } else { | 944 | } else { |
942 | if (rio_mport_write_config_32(port, destid, hopcount, | 945 | if (rio_mport_write_config_32(port, destid, hopcount, |
943 | ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num), regval) < 0) | 946 | ext_ftr_ptr + RIO_PORT_N_CTL_CSR(port_num, rmap), |
947 | regval) < 0) | ||
944 | return -EIO; | 948 | return -EIO; |
945 | } | 949 | } |
946 | #endif | 950 | #endif |
@@ -1042,14 +1046,14 @@ rio_get_input_status(struct rio_dev *rdev, int pnum, u32 *lnkresp) | |||
1042 | /* Read from link maintenance response register | 1046 | /* Read from link maintenance response register |
1043 | * to clear valid bit */ | 1047 | * to clear valid bit */ |
1044 | rio_read_config_32(rdev, | 1048 | rio_read_config_32(rdev, |
1045 | rdev->phys_efptr + RIO_PORT_N_MNT_RSP_CSR(pnum), | 1049 | RIO_DEV_PORT_N_MNT_RSP_CSR(rdev, pnum), |
1046 | ®val); | 1050 | ®val); |
1047 | udelay(50); | 1051 | udelay(50); |
1048 | } | 1052 | } |
1049 | 1053 | ||
1050 | /* Issue Input-status command */ | 1054 | /* Issue Input-status command */ |
1051 | rio_write_config_32(rdev, | 1055 | rio_write_config_32(rdev, |
1052 | rdev->phys_efptr + RIO_PORT_N_MNT_REQ_CSR(pnum), | 1056 | RIO_DEV_PORT_N_MNT_REQ_CSR(rdev, pnum), |
1053 | RIO_MNT_REQ_CMD_IS); | 1057 | RIO_MNT_REQ_CMD_IS); |
1054 | 1058 | ||
1055 | /* Exit if the response is not expected */ | 1059 | /* Exit if the response is not expected */ |
@@ -1060,7 +1064,7 @@ rio_get_input_status(struct rio_dev *rdev, int pnum, u32 *lnkresp) | |||
1060 | while (checkcount--) { | 1064 | while (checkcount--) { |
1061 | udelay(50); | 1065 | udelay(50); |
1062 | rio_read_config_32(rdev, | 1066 | rio_read_config_32(rdev, |
1063 | rdev->phys_efptr + RIO_PORT_N_MNT_RSP_CSR(pnum), | 1067 | RIO_DEV_PORT_N_MNT_RSP_CSR(rdev, pnum), |
1064 | ®val); | 1068 | ®val); |
1065 | if (regval & RIO_PORT_N_MNT_RSP_RVAL) { | 1069 | if (regval & RIO_PORT_N_MNT_RSP_RVAL) { |
1066 | *lnkresp = regval; | 1070 | *lnkresp = regval; |
@@ -1076,6 +1080,13 @@ rio_get_input_status(struct rio_dev *rdev, int pnum, u32 *lnkresp) | |||
1076 | * @rdev: Pointer to RIO device control structure | 1080 | * @rdev: Pointer to RIO device control structure |
1077 | * @pnum: Switch port number to clear errors | 1081 | * @pnum: Switch port number to clear errors |
1078 | * @err_status: port error status (if 0 reads register from device) | 1082 | * @err_status: port error status (if 0 reads register from device) |
1083 | * | ||
1084 | * TODO: Currently this routine is not compatible with recovery process | ||
1085 | * specified for idt_gen3 RapidIO switch devices. It has to be reviewed | ||
1086 | * to implement universal recovery process that is compatible full range | ||
1087 | * off available devices. | ||
1088 | * IDT gen3 switch driver now implements HW-specific error handler that | ||
1089 | * issues soft port reset to the port to reset ERR_STOP bits and ackIDs. | ||
1079 | */ | 1090 | */ |
1080 | static int rio_clr_err_stopped(struct rio_dev *rdev, u32 pnum, u32 err_status) | 1091 | static int rio_clr_err_stopped(struct rio_dev *rdev, u32 pnum, u32 err_status) |
1081 | { | 1092 | { |
@@ -1085,10 +1096,10 @@ static int rio_clr_err_stopped(struct rio_dev *rdev, u32 pnum, u32 err_status) | |||
1085 | 1096 | ||
1086 | if (err_status == 0) | 1097 | if (err_status == 0) |
1087 | rio_read_config_32(rdev, | 1098 | rio_read_config_32(rdev, |
1088 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(pnum), | 1099 | RIO_DEV_PORT_N_ERR_STS_CSR(rdev, pnum), |
1089 | &err_status); | 1100 | &err_status); |
1090 | 1101 | ||
1091 | if (err_status & RIO_PORT_N_ERR_STS_PW_OUT_ES) { | 1102 | if (err_status & RIO_PORT_N_ERR_STS_OUT_ES) { |
1092 | pr_debug("RIO_EM: servicing Output Error-Stopped state\n"); | 1103 | pr_debug("RIO_EM: servicing Output Error-Stopped state\n"); |
1093 | /* | 1104 | /* |
1094 | * Send a Link-Request/Input-Status control symbol | 1105 | * Send a Link-Request/Input-Status control symbol |
@@ -1103,7 +1114,7 @@ static int rio_clr_err_stopped(struct rio_dev *rdev, u32 pnum, u32 err_status) | |||
1103 | far_ackid = (regval & RIO_PORT_N_MNT_RSP_ASTAT) >> 5; | 1114 | far_ackid = (regval & RIO_PORT_N_MNT_RSP_ASTAT) >> 5; |
1104 | far_linkstat = regval & RIO_PORT_N_MNT_RSP_LSTAT; | 1115 | far_linkstat = regval & RIO_PORT_N_MNT_RSP_LSTAT; |
1105 | rio_read_config_32(rdev, | 1116 | rio_read_config_32(rdev, |
1106 | rdev->phys_efptr + RIO_PORT_N_ACK_STS_CSR(pnum), | 1117 | RIO_DEV_PORT_N_ACK_STS_CSR(rdev, pnum), |
1107 | ®val); | 1118 | ®val); |
1108 | pr_debug("RIO_EM: SP%d_ACK_STS_CSR=0x%08x\n", pnum, regval); | 1119 | pr_debug("RIO_EM: SP%d_ACK_STS_CSR=0x%08x\n", pnum, regval); |
1109 | near_ackid = (regval & RIO_PORT_N_ACK_INBOUND) >> 24; | 1120 | near_ackid = (regval & RIO_PORT_N_ACK_INBOUND) >> 24; |
@@ -1121,43 +1132,43 @@ static int rio_clr_err_stopped(struct rio_dev *rdev, u32 pnum, u32 err_status) | |||
1121 | * far inbound. | 1132 | * far inbound. |
1122 | */ | 1133 | */ |
1123 | rio_write_config_32(rdev, | 1134 | rio_write_config_32(rdev, |
1124 | rdev->phys_efptr + RIO_PORT_N_ACK_STS_CSR(pnum), | 1135 | RIO_DEV_PORT_N_ACK_STS_CSR(rdev, pnum), |
1125 | (near_ackid << 24) | | 1136 | (near_ackid << 24) | |
1126 | (far_ackid << 8) | far_ackid); | 1137 | (far_ackid << 8) | far_ackid); |
1127 | /* Align far outstanding/outbound ackIDs with | 1138 | /* Align far outstanding/outbound ackIDs with |
1128 | * near inbound. | 1139 | * near inbound. |
1129 | */ | 1140 | */ |
1130 | far_ackid++; | 1141 | far_ackid++; |
1131 | if (nextdev) | 1142 | if (!nextdev) { |
1132 | rio_write_config_32(nextdev, | 1143 | pr_debug("RIO_EM: nextdev pointer == NULL\n"); |
1133 | nextdev->phys_efptr + | 1144 | goto rd_err; |
1134 | RIO_PORT_N_ACK_STS_CSR(RIO_GET_PORT_NUM(nextdev->swpinfo)), | 1145 | } |
1135 | (far_ackid << 24) | | 1146 | |
1136 | (near_ackid << 8) | near_ackid); | 1147 | rio_write_config_32(nextdev, |
1137 | else | 1148 | RIO_DEV_PORT_N_ACK_STS_CSR(nextdev, |
1138 | pr_debug("RIO_EM: Invalid nextdev pointer (NULL)\n"); | 1149 | RIO_GET_PORT_NUM(nextdev->swpinfo)), |
1150 | (far_ackid << 24) | | ||
1151 | (near_ackid << 8) | near_ackid); | ||
1139 | } | 1152 | } |
1140 | rd_err: | 1153 | rd_err: |
1141 | rio_read_config_32(rdev, | 1154 | rio_read_config_32(rdev, RIO_DEV_PORT_N_ERR_STS_CSR(rdev, pnum), |
1142 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(pnum), | 1155 | &err_status); |
1143 | &err_status); | ||
1144 | pr_debug("RIO_EM: SP%d_ERR_STS_CSR=0x%08x\n", pnum, err_status); | 1156 | pr_debug("RIO_EM: SP%d_ERR_STS_CSR=0x%08x\n", pnum, err_status); |
1145 | } | 1157 | } |
1146 | 1158 | ||
1147 | if ((err_status & RIO_PORT_N_ERR_STS_PW_INP_ES) && nextdev) { | 1159 | if ((err_status & RIO_PORT_N_ERR_STS_INP_ES) && nextdev) { |
1148 | pr_debug("RIO_EM: servicing Input Error-Stopped state\n"); | 1160 | pr_debug("RIO_EM: servicing Input Error-Stopped state\n"); |
1149 | rio_get_input_status(nextdev, | 1161 | rio_get_input_status(nextdev, |
1150 | RIO_GET_PORT_NUM(nextdev->swpinfo), NULL); | 1162 | RIO_GET_PORT_NUM(nextdev->swpinfo), NULL); |
1151 | udelay(50); | 1163 | udelay(50); |
1152 | 1164 | ||
1153 | rio_read_config_32(rdev, | 1165 | rio_read_config_32(rdev, RIO_DEV_PORT_N_ERR_STS_CSR(rdev, pnum), |
1154 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(pnum), | 1166 | &err_status); |
1155 | &err_status); | ||
1156 | pr_debug("RIO_EM: SP%d_ERR_STS_CSR=0x%08x\n", pnum, err_status); | 1167 | pr_debug("RIO_EM: SP%d_ERR_STS_CSR=0x%08x\n", pnum, err_status); |
1157 | } | 1168 | } |
1158 | 1169 | ||
1159 | return (err_status & (RIO_PORT_N_ERR_STS_PW_OUT_ES | | 1170 | return (err_status & (RIO_PORT_N_ERR_STS_OUT_ES | |
1160 | RIO_PORT_N_ERR_STS_PW_INP_ES)) ? 1 : 0; | 1171 | RIO_PORT_N_ERR_STS_INP_ES)) ? 1 : 0; |
1161 | } | 1172 | } |
1162 | 1173 | ||
1163 | /** | 1174 | /** |
@@ -1257,9 +1268,8 @@ int rio_inb_pwrite_handler(struct rio_mport *mport, union rio_pw_msg *pw_msg) | |||
1257 | if (rdev->rswitch->ops && rdev->rswitch->ops->em_handle) | 1268 | if (rdev->rswitch->ops && rdev->rswitch->ops->em_handle) |
1258 | rdev->rswitch->ops->em_handle(rdev, portnum); | 1269 | rdev->rswitch->ops->em_handle(rdev, portnum); |
1259 | 1270 | ||
1260 | rio_read_config_32(rdev, | 1271 | rio_read_config_32(rdev, RIO_DEV_PORT_N_ERR_STS_CSR(rdev, portnum), |
1261 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(portnum), | 1272 | &err_status); |
1262 | &err_status); | ||
1263 | pr_debug("RIO_PW: SP%d_ERR_STS_CSR=0x%08x\n", portnum, err_status); | 1273 | pr_debug("RIO_PW: SP%d_ERR_STS_CSR=0x%08x\n", portnum, err_status); |
1264 | 1274 | ||
1265 | if (err_status & RIO_PORT_N_ERR_STS_PORT_OK) { | 1275 | if (err_status & RIO_PORT_N_ERR_STS_PORT_OK) { |
@@ -1276,8 +1286,8 @@ int rio_inb_pwrite_handler(struct rio_mport *mport, union rio_pw_msg *pw_msg) | |||
1276 | * Depending on the link partner state, two attempts | 1286 | * Depending on the link partner state, two attempts |
1277 | * may be needed for successful recovery. | 1287 | * may be needed for successful recovery. |
1278 | */ | 1288 | */ |
1279 | if (err_status & (RIO_PORT_N_ERR_STS_PW_OUT_ES | | 1289 | if (err_status & (RIO_PORT_N_ERR_STS_OUT_ES | |
1280 | RIO_PORT_N_ERR_STS_PW_INP_ES)) { | 1290 | RIO_PORT_N_ERR_STS_INP_ES)) { |
1281 | if (rio_clr_err_stopped(rdev, portnum, err_status)) | 1291 | if (rio_clr_err_stopped(rdev, portnum, err_status)) |
1282 | rio_clr_err_stopped(rdev, portnum, 0); | 1292 | rio_clr_err_stopped(rdev, portnum, 0); |
1283 | } | 1293 | } |
@@ -1287,10 +1297,18 @@ int rio_inb_pwrite_handler(struct rio_mport *mport, union rio_pw_msg *pw_msg) | |||
1287 | rdev->rswitch->port_ok &= ~(1 << portnum); | 1297 | rdev->rswitch->port_ok &= ~(1 << portnum); |
1288 | rio_set_port_lockout(rdev, portnum, 1); | 1298 | rio_set_port_lockout(rdev, portnum, 1); |
1289 | 1299 | ||
1300 | if (rdev->phys_rmap == 1) { | ||
1290 | rio_write_config_32(rdev, | 1301 | rio_write_config_32(rdev, |
1291 | rdev->phys_efptr + | 1302 | RIO_DEV_PORT_N_ACK_STS_CSR(rdev, portnum), |
1292 | RIO_PORT_N_ACK_STS_CSR(portnum), | ||
1293 | RIO_PORT_N_ACK_CLEAR); | 1303 | RIO_PORT_N_ACK_CLEAR); |
1304 | } else { | ||
1305 | rio_write_config_32(rdev, | ||
1306 | RIO_DEV_PORT_N_OB_ACK_CSR(rdev, portnum), | ||
1307 | RIO_PORT_N_OB_ACK_CLEAR); | ||
1308 | rio_write_config_32(rdev, | ||
1309 | RIO_DEV_PORT_N_IB_ACK_CSR(rdev, portnum), | ||
1310 | 0); | ||
1311 | } | ||
1294 | 1312 | ||
1295 | /* Schedule Extraction Service */ | 1313 | /* Schedule Extraction Service */ |
1296 | pr_debug("RIO_PW: Device Extraction on [%s]-P%d\n", | 1314 | pr_debug("RIO_PW: Device Extraction on [%s]-P%d\n", |
@@ -1319,9 +1337,8 @@ int rio_inb_pwrite_handler(struct rio_mport *mport, union rio_pw_msg *pw_msg) | |||
1319 | } | 1337 | } |
1320 | 1338 | ||
1321 | /* Clear remaining error bits and Port-Write Pending bit */ | 1339 | /* Clear remaining error bits and Port-Write Pending bit */ |
1322 | rio_write_config_32(rdev, | 1340 | rio_write_config_32(rdev, RIO_DEV_PORT_N_ERR_STS_CSR(rdev, portnum), |
1323 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(portnum), | 1341 | err_status); |
1324 | err_status); | ||
1325 | 1342 | ||
1326 | return 0; | 1343 | return 0; |
1327 | } | 1344 | } |
@@ -1372,20 +1389,7 @@ EXPORT_SYMBOL_GPL(rio_mport_get_efb); | |||
1372 | * Tell if a device supports a given RapidIO capability. | 1389 | * Tell if a device supports a given RapidIO capability. |
1373 | * Returns the offset of the requested extended feature | 1390 | * Returns the offset of the requested extended feature |
1374 | * block within the device's RIO configuration space or | 1391 | * block within the device's RIO configuration space or |
1375 | * 0 in case the device does not support it. Possible | 1392 | * 0 in case the device does not support it. |
1376 | * values for @ftr: | ||
1377 | * | ||
1378 | * %RIO_EFB_PAR_EP_ID LP/LVDS EP Devices | ||
1379 | * | ||
1380 | * %RIO_EFB_PAR_EP_REC_ID LP/LVDS EP Recovery Devices | ||
1381 | * | ||
1382 | * %RIO_EFB_PAR_EP_FREE_ID LP/LVDS EP Free Devices | ||
1383 | * | ||
1384 | * %RIO_EFB_SER_EP_ID LP/Serial EP Devices | ||
1385 | * | ||
1386 | * %RIO_EFB_SER_EP_REC_ID LP/Serial EP Recovery Devices | ||
1387 | * | ||
1388 | * %RIO_EFB_SER_EP_FREE_ID LP/Serial EP Free Devices | ||
1389 | */ | 1393 | */ |
1390 | u32 | 1394 | u32 |
1391 | rio_mport_get_feature(struct rio_mport * port, int local, u16 destid, | 1395 | rio_mport_get_feature(struct rio_mport * port, int local, u16 destid, |
diff --git a/drivers/rapidio/rio.h b/drivers/rapidio/rio.h index 625d09add001..9796b3fee70d 100644 --- a/drivers/rapidio/rio.h +++ b/drivers/rapidio/rio.h | |||
@@ -22,7 +22,7 @@ | |||
22 | extern u32 rio_mport_get_feature(struct rio_mport *mport, int local, u16 destid, | 22 | extern u32 rio_mport_get_feature(struct rio_mport *mport, int local, u16 destid, |
23 | u8 hopcount, int ftr); | 23 | u8 hopcount, int ftr); |
24 | extern u32 rio_mport_get_physefb(struct rio_mport *port, int local, | 24 | extern u32 rio_mport_get_physefb(struct rio_mport *port, int local, |
25 | u16 destid, u8 hopcount); | 25 | u16 destid, u8 hopcount, u32 *rmap); |
26 | extern u32 rio_mport_get_efb(struct rio_mport *port, int local, u16 destid, | 26 | extern u32 rio_mport_get_efb(struct rio_mport *port, int local, u16 destid, |
27 | u8 hopcount, u32 from); | 27 | u8 hopcount, u32 from); |
28 | extern int rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, | 28 | extern int rio_mport_chk_dev_access(struct rio_mport *mport, u16 destid, |
diff --git a/drivers/rapidio/switches/tsi57x.c b/drivers/rapidio/switches/tsi57x.c index 42c8b014fe15..2700d15f7584 100644 --- a/drivers/rapidio/switches/tsi57x.c +++ b/drivers/rapidio/switches/tsi57x.c | |||
@@ -175,12 +175,10 @@ tsi57x_em_init(struct rio_dev *rdev) | |||
175 | 175 | ||
176 | /* Clear all pending interrupts */ | 176 | /* Clear all pending interrupts */ |
177 | rio_read_config_32(rdev, | 177 | rio_read_config_32(rdev, |
178 | rdev->phys_efptr + | 178 | RIO_DEV_PORT_N_ERR_STS_CSR(rdev, portnum), |
179 | RIO_PORT_N_ERR_STS_CSR(portnum), | ||
180 | ®val); | 179 | ®val); |
181 | rio_write_config_32(rdev, | 180 | rio_write_config_32(rdev, |
182 | rdev->phys_efptr + | 181 | RIO_DEV_PORT_N_ERR_STS_CSR(rdev, portnum), |
183 | RIO_PORT_N_ERR_STS_CSR(portnum), | ||
184 | regval & 0x07120214); | 182 | regval & 0x07120214); |
185 | 183 | ||
186 | rio_read_config_32(rdev, | 184 | rio_read_config_32(rdev, |
@@ -198,7 +196,7 @@ tsi57x_em_init(struct rio_dev *rdev) | |||
198 | 196 | ||
199 | /* Skip next (odd) port if the current port is in x4 mode */ | 197 | /* Skip next (odd) port if the current port is in x4 mode */ |
200 | rio_read_config_32(rdev, | 198 | rio_read_config_32(rdev, |
201 | rdev->phys_efptr + RIO_PORT_N_CTL_CSR(portnum), | 199 | RIO_DEV_PORT_N_CTL_CSR(rdev, portnum), |
202 | ®val); | 200 | ®val); |
203 | if ((regval & RIO_PORT_N_CTL_PWIDTH) == RIO_PORT_N_CTL_PWIDTH_4) | 201 | if ((regval & RIO_PORT_N_CTL_PWIDTH) == RIO_PORT_N_CTL_PWIDTH_4) |
204 | portnum++; | 202 | portnum++; |
@@ -221,23 +219,23 @@ tsi57x_em_handler(struct rio_dev *rdev, u8 portnum) | |||
221 | u32 regval; | 219 | u32 regval; |
222 | 220 | ||
223 | rio_read_config_32(rdev, | 221 | rio_read_config_32(rdev, |
224 | rdev->phys_efptr + RIO_PORT_N_ERR_STS_CSR(portnum), | 222 | RIO_DEV_PORT_N_ERR_STS_CSR(rdev, portnum), |
225 | &err_status); | 223 | &err_status); |
226 | 224 | ||
227 | if ((err_status & RIO_PORT_N_ERR_STS_PORT_OK) && | 225 | if ((err_status & RIO_PORT_N_ERR_STS_PORT_OK) && |
228 | (err_status & (RIO_PORT_N_ERR_STS_PW_OUT_ES | | 226 | (err_status & (RIO_PORT_N_ERR_STS_OUT_ES | |
229 | RIO_PORT_N_ERR_STS_PW_INP_ES))) { | 227 | RIO_PORT_N_ERR_STS_INP_ES))) { |
230 | /* Remove any queued packets by locking/unlocking port */ | 228 | /* Remove any queued packets by locking/unlocking port */ |
231 | rio_read_config_32(rdev, | 229 | rio_read_config_32(rdev, |
232 | rdev->phys_efptr + RIO_PORT_N_CTL_CSR(portnum), | 230 | RIO_DEV_PORT_N_CTL_CSR(rdev, portnum), |
233 | ®val); | 231 | ®val); |
234 | if (!(regval & RIO_PORT_N_CTL_LOCKOUT)) { | 232 | if (!(regval & RIO_PORT_N_CTL_LOCKOUT)) { |
235 | rio_write_config_32(rdev, | 233 | rio_write_config_32(rdev, |
236 | rdev->phys_efptr + RIO_PORT_N_CTL_CSR(portnum), | 234 | RIO_DEV_PORT_N_CTL_CSR(rdev, portnum), |
237 | regval | RIO_PORT_N_CTL_LOCKOUT); | 235 | regval | RIO_PORT_N_CTL_LOCKOUT); |
238 | udelay(50); | 236 | udelay(50); |
239 | rio_write_config_32(rdev, | 237 | rio_write_config_32(rdev, |
240 | rdev->phys_efptr + RIO_PORT_N_CTL_CSR(portnum), | 238 | RIO_DEV_PORT_N_CTL_CSR(rdev, portnum), |
241 | regval); | 239 | regval); |
242 | } | 240 | } |
243 | 241 | ||
@@ -245,7 +243,7 @@ tsi57x_em_handler(struct rio_dev *rdev, u8 portnum) | |||
245 | * valid bit | 243 | * valid bit |
246 | */ | 244 | */ |
247 | rio_read_config_32(rdev, | 245 | rio_read_config_32(rdev, |
248 | rdev->phys_efptr + RIO_PORT_N_MNT_RSP_CSR(portnum), | 246 | RIO_DEV_PORT_N_MNT_RSP_CSR(rdev, portnum), |
249 | ®val); | 247 | ®val); |
250 | 248 | ||
251 | /* Send a Packet-Not-Accepted/Link-Request-Input-Status control | 249 | /* Send a Packet-Not-Accepted/Link-Request-Input-Status control |
@@ -259,8 +257,8 @@ tsi57x_em_handler(struct rio_dev *rdev, u8 portnum) | |||
259 | while (checkcount--) { | 257 | while (checkcount--) { |
260 | udelay(50); | 258 | udelay(50); |
261 | rio_read_config_32(rdev, | 259 | rio_read_config_32(rdev, |
262 | rdev->phys_efptr + | 260 | RIO_DEV_PORT_N_MNT_RSP_CSR(rdev, |
263 | RIO_PORT_N_MNT_RSP_CSR(portnum), | 261 | portnum), |
264 | ®val); | 262 | ®val); |
265 | if (regval & RIO_PORT_N_MNT_RSP_RVAL) | 263 | if (regval & RIO_PORT_N_MNT_RSP_RVAL) |
266 | goto exit_es; | 264 | goto exit_es; |