root/drivers/rapidio/switches/idtcps.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. idtcps_route_add_entry
  2. idtcps_route_get_entry
  3. idtcps_route_clr_table
  4. idtcps_set_domain
  5. idtcps_get_domain
  6. idtcps_probe
  7. idtcps_remove
  8. idtcps_init
  9. idtcps_exit

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * IDT CPS RapidIO switches support
   4  *
   5  * Copyright 2009-2010 Integrated Device Technology, Inc.
   6  * Alexandre Bounine <alexandre.bounine@idt.com>
   7  */
   8 
   9 #include <linux/rio.h>
  10 #include <linux/rio_drv.h>
  11 #include <linux/rio_ids.h>
  12 #include <linux/module.h>
  13 #include "../rio.h"
  14 
  15 #define CPS_DEFAULT_ROUTE       0xde
  16 #define CPS_NO_ROUTE            0xdf
  17 
  18 #define IDTCPS_RIO_DOMAIN 0xf20020
  19 
  20 static int
  21 idtcps_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
  22                        u16 table, u16 route_destid, u8 route_port)
  23 {
  24         u32 result;
  25 
  26         if (route_port == RIO_INVALID_ROUTE)
  27                 route_port = CPS_DEFAULT_ROUTE;
  28 
  29         if (table == RIO_GLOBAL_TABLE) {
  30                 rio_mport_write_config_32(mport, destid, hopcount,
  31                                 RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid);
  32 
  33                 rio_mport_read_config_32(mport, destid, hopcount,
  34                                 RIO_STD_RTE_CONF_PORT_SEL_CSR, &result);
  35 
  36                 result = (0xffffff00 & result) | (u32)route_port;
  37                 rio_mport_write_config_32(mport, destid, hopcount,
  38                                 RIO_STD_RTE_CONF_PORT_SEL_CSR, result);
  39         }
  40 
  41         return 0;
  42 }
  43 
  44 static int
  45 idtcps_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount,
  46                        u16 table, u16 route_destid, u8 *route_port)
  47 {
  48         u32 result;
  49 
  50         if (table == RIO_GLOBAL_TABLE) {
  51                 rio_mport_write_config_32(mport, destid, hopcount,
  52                                 RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid);
  53 
  54                 rio_mport_read_config_32(mport, destid, hopcount,
  55                                 RIO_STD_RTE_CONF_PORT_SEL_CSR, &result);
  56 
  57                 if (CPS_DEFAULT_ROUTE == (u8)result ||
  58                     CPS_NO_ROUTE == (u8)result)
  59                         *route_port = RIO_INVALID_ROUTE;
  60                 else
  61                         *route_port = (u8)result;
  62         }
  63 
  64         return 0;
  65 }
  66 
  67 static int
  68 idtcps_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount,
  69                        u16 table)
  70 {
  71         u32 i;
  72 
  73         if (table == RIO_GLOBAL_TABLE) {
  74                 for (i = 0x80000000; i <= 0x800000ff;) {
  75                         rio_mport_write_config_32(mport, destid, hopcount,
  76                                 RIO_STD_RTE_CONF_DESTID_SEL_CSR, i);
  77                         rio_mport_write_config_32(mport, destid, hopcount,
  78                                 RIO_STD_RTE_CONF_PORT_SEL_CSR,
  79                                 (CPS_DEFAULT_ROUTE << 24) |
  80                                 (CPS_DEFAULT_ROUTE << 16) |
  81                                 (CPS_DEFAULT_ROUTE << 8) | CPS_DEFAULT_ROUTE);
  82                         i += 4;
  83                 }
  84         }
  85 
  86         return 0;
  87 }
  88 
  89 static int
  90 idtcps_set_domain(struct rio_mport *mport, u16 destid, u8 hopcount,
  91                        u8 sw_domain)
  92 {
  93         /*
  94          * Switch domain configuration operates only at global level
  95          */
  96         rio_mport_write_config_32(mport, destid, hopcount,
  97                                   IDTCPS_RIO_DOMAIN, (u32)sw_domain);
  98         return 0;
  99 }
 100 
 101 static int
 102 idtcps_get_domain(struct rio_mport *mport, u16 destid, u8 hopcount,
 103                        u8 *sw_domain)
 104 {
 105         u32 regval;
 106 
 107         /*
 108          * Switch domain configuration operates only at global level
 109          */
 110         rio_mport_read_config_32(mport, destid, hopcount,
 111                                 IDTCPS_RIO_DOMAIN, &regval);
 112 
 113         *sw_domain = (u8)(regval & 0xff);
 114 
 115         return 0;
 116 }
 117 
 118 static struct rio_switch_ops idtcps_switch_ops = {
 119         .owner = THIS_MODULE,
 120         .add_entry = idtcps_route_add_entry,
 121         .get_entry = idtcps_route_get_entry,
 122         .clr_table = idtcps_route_clr_table,
 123         .set_domain = idtcps_set_domain,
 124         .get_domain = idtcps_get_domain,
 125         .em_init = NULL,
 126         .em_handle = NULL,
 127 };
 128 
 129 static int idtcps_probe(struct rio_dev *rdev, const struct rio_device_id *id)
 130 {
 131         pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
 132 
 133         spin_lock(&rdev->rswitch->lock);
 134 
 135         if (rdev->rswitch->ops) {
 136                 spin_unlock(&rdev->rswitch->lock);
 137                 return -EINVAL;
 138         }
 139 
 140         rdev->rswitch->ops = &idtcps_switch_ops;
 141 
 142         if (rdev->do_enum) {
 143                 /* set TVAL = ~50us */
 144                 rio_write_config_32(rdev,
 145                         rdev->phys_efptr + RIO_PORT_LINKTO_CTL_CSR, 0x8e << 8);
 146                 /* Ensure that default routing is disabled on startup */
 147                 rio_write_config_32(rdev,
 148                                     RIO_STD_RTE_DEFAULT_PORT, CPS_NO_ROUTE);
 149         }
 150 
 151         spin_unlock(&rdev->rswitch->lock);
 152         return 0;
 153 }
 154 
 155 static void idtcps_remove(struct rio_dev *rdev)
 156 {
 157         pr_debug("RIO: %s for %s\n", __func__, rio_name(rdev));
 158         spin_lock(&rdev->rswitch->lock);
 159         if (rdev->rswitch->ops != &idtcps_switch_ops) {
 160                 spin_unlock(&rdev->rswitch->lock);
 161                 return;
 162         }
 163         rdev->rswitch->ops = NULL;
 164         spin_unlock(&rdev->rswitch->lock);
 165 }
 166 
 167 static const struct rio_device_id idtcps_id_table[] = {
 168         {RIO_DEVICE(RIO_DID_IDTCPS6Q, RIO_VID_IDT)},
 169         {RIO_DEVICE(RIO_DID_IDTCPS8, RIO_VID_IDT)},
 170         {RIO_DEVICE(RIO_DID_IDTCPS10Q, RIO_VID_IDT)},
 171         {RIO_DEVICE(RIO_DID_IDTCPS12, RIO_VID_IDT)},
 172         {RIO_DEVICE(RIO_DID_IDTCPS16, RIO_VID_IDT)},
 173         {RIO_DEVICE(RIO_DID_IDT70K200, RIO_VID_IDT)},
 174         { 0, }  /* terminate list */
 175 };
 176 
 177 static struct rio_driver idtcps_driver = {
 178         .name = "idtcps",
 179         .id_table = idtcps_id_table,
 180         .probe = idtcps_probe,
 181         .remove = idtcps_remove,
 182 };
 183 
 184 static int __init idtcps_init(void)
 185 {
 186         return rio_register_driver(&idtcps_driver);
 187 }
 188 
 189 static void __exit idtcps_exit(void)
 190 {
 191         rio_unregister_driver(&idtcps_driver);
 192 }
 193 
 194 device_initcall(idtcps_init);
 195 module_exit(idtcps_exit);
 196 
 197 MODULE_DESCRIPTION("IDT CPS Gen.1 Serial RapidIO switch family driver");
 198 MODULE_AUTHOR("Integrated Device Technology, Inc.");
 199 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */