static int tsi568_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 *route_port) { int ret = 0; u32 result; if (table == RIO_GLOBAL_TABLE) { rio_mport_write_config_32(mport, destid, hopcount, SPBC_ROUTE_CFG_DESTID, route_destid); rio_mport_read_config_32(mport, destid, hopcount, SPBC_ROUTE_CFG_PORT, &result); } else { rio_mport_write_config_32(mport, destid, hopcount, SPP_ROUTE_CFG_DESTID(table), route_destid); rio_mport_read_config_32(mport, destid, hopcount, SPP_ROUTE_CFG_PORT(table), &result); } *route_port = result; if (*route_port > 15) ret = -1; return ret; }
static int idtg2_em_handler(struct rio_dev *rdev, u8 portnum) { struct rio_mport *mport = rdev->net->hport; u16 destid = rdev->rswitch->destid; u8 hopcount = rdev->rswitch->hopcount; u32 regval, em_perrdet, em_ltlerrdet; rio_mport_read_config_32(mport, destid, hopcount, rdev->em_efptr + RIO_EM_LTL_ERR_DETECT, &em_ltlerrdet); if (em_ltlerrdet) { /* Service Logical/Transport Layer Error(s) */ if (em_ltlerrdet & REM_LTL_ERR_IMPSPEC) { /* Implementation specific error reported */ rio_mport_read_config_32(mport, destid, hopcount, IDT_ISLTL_ADDRESS_CAP, ®val); pr_debug("RIO: %s Implementation Specific LTL errors" \ " 0x%x @(0x%x)\n", rio_name(rdev), em_ltlerrdet, regval); /* Clear implementation specific address capture CSR */ rio_mport_write_config_32(mport, destid, hopcount, IDT_ISLTL_ADDRESS_CAP, 0); } } rio_mport_read_config_32(mport, destid, hopcount, rdev->em_efptr + RIO_EM_PN_ERR_DETECT(portnum), &em_perrdet); if (em_perrdet) { /* Service Port-Level Error(s) */ if (em_perrdet & REM_PED_IMPL_SPEC) { /* Implementation Specific port error reported */ /* Get IS errors reported */ rio_mport_read_config_32(mport, destid, hopcount, IDT_PORT_ISERR_DET(portnum), ®val); pr_debug("RIO: %s Implementation Specific Port" \ " errors 0x%x\n", rio_name(rdev), regval); /* Clear all implementation specific events */ rio_mport_write_config_32(mport, destid, hopcount, IDT_PORT_ISERR_DET(portnum), 0); } } return 0; }
static int idtg2_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 *route_port) { u32 result; /* * Select routing table to read */ if (table == RIO_GLOBAL_TABLE) table = 0; else table++; rio_mport_write_config_32(mport, destid, hopcount, LOCAL_RTE_CONF_DESTID_SEL, table); rio_mport_write_config_32(mport, destid, hopcount, RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid); rio_mport_read_config_32(mport, destid, hopcount, RIO_STD_RTE_CONF_PORT_SEL_CSR, &result); if (IDT_DEFAULT_ROUTE == (u8)result || IDT_NO_ROUTE == (u8)result) *route_port = RIO_INVALID_ROUTE; else *route_port = (u8)result; return 0; }
static int tsi500_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 *route_port) { int ret = 0; u32 offset = 0x10000 + 0xa00 + ((route_destid / 2)&~0x3); u32 result; if (table == 0xff) rio_mport_read_config_32(mport, destid, hopcount, offset, &result); else rio_mport_read_config_32(mport, destid, hopcount, offset + (0x20000*table), &result); result &= 0xf << (4*(route_destid & 0x7)); *route_port = result >> (4*(route_destid & 0x7)); if (*route_port > 3) ret = -1; return ret; }
static int tsi500_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 route_port) { int i; u32 offset = 0x10000 + 0xa00 + ((route_destid / 2)&~0x3); u32 result; if (table == 0xff) { rio_mport_read_config_32(mport, destid, hopcount, offset, &result); result &= ~(0xf << (4*(route_destid & 0x7))); for (i=0;i<4;i++) rio_mport_write_config_32(mport, destid, hopcount, offset + (0x20000*i), result | (route_port << (4*(route_destid & 0x7)))); } else { rio_mport_read_config_32(mport, destid, hopcount, offset + (0x20000*table), &result); result &= ~(0xf << (4*(route_destid & 0x7))); rio_mport_write_config_32(mport, destid, hopcount, offset + (0x20000*table), result | (route_port << (4*(route_destid & 0x7)))); } return 0; }
static int idtg2_get_domain(struct rio_mport *mport, u16 destid, u8 hopcount, u8 *sw_domain) { u32 regval; rio_mport_read_config_32(mport, destid, hopcount, IDT_RIO_DOMAIN, ®val); *sw_domain = (u8)(regval & 0xff); return 0; }
static int idtg3_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 *route_port) { u32 rval; int err; if (route_destid > 0xFF) return -EINVAL; err = rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR, &rval); if (err) return err; /* * This switch device does not have the dedicated global routing table. * It is substituted by reading routing table of the ingress port of * maintenance read requests. */ if (table == RIO_GLOBAL_TABLE) table = RIO_GET_PORT_NUM(rval); else if (table >= RIO_GET_TOTAL_PORTS(rval)) return -EINVAL; err = rio_mport_read_config_32(mport, destid, hopcount, RIO_SPx_L2_Gn_ENTRYy_CSR(table, 0, route_destid), &rval); if (err) return err; if (rval == RIO_RT_ENTRY_DROP_PKT) *route_port = RIO_INVALID_ROUTE; else *route_port = (u8)rval; return 0; }
static int idtcps_get_domain(struct rio_mport *mport, u16 destid, u8 hopcount, u8 *sw_domain) { u32 regval; /* * Switch domain configuration operates only at global level */ rio_mport_read_config_32(mport, destid, hopcount, IDTCPS_RIO_DOMAIN, ®val); *sw_domain = (u8)(regval & 0xff); return 0; }
static int idtg2_get_domain(struct rio_mport *mport, UINT16 destid, UINT8 hopcount, UINT8 *sw_domain) { UINT32 regval; /* * Switch domain configuration operates only at global level */ rio_mport_read_config_32(mport, destid, hopcount, IDT_RIO_DOMAIN, ®val); *sw_domain = (UINT8)(regval & 0xff); return 0; }
static int idtcps_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 route_port) { u32 result; if (table == RIO_GLOBAL_TABLE) { rio_mport_write_config_32(mport, destid, hopcount, RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid); rio_mport_read_config_32(mport, destid, hopcount, RIO_STD_RTE_CONF_PORT_SEL_CSR, &result); result = (0xffffff00 & result) | (u32)route_port; rio_mport_write_config_32(mport, destid, hopcount, RIO_STD_RTE_CONF_PORT_SEL_CSR, result); } return 0; }
static int idtg3_route_add_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 route_port) { u32 rval; u32 entry = route_port; int err = 0; pr_debug("RIO: %s t=0x%x did_%x to p_%x\n", __func__, table, route_destid, entry); if (route_destid > 0xFF) return -EINVAL; if (route_port == RIO_INVALID_ROUTE) entry = RIO_RT_ENTRY_DROP_PKT; if (table == RIO_GLOBAL_TABLE) { /* Use broadcast register to update all per-port tables */ err = rio_mport_write_config_32(mport, destid, hopcount, RIO_BC_L2_Gn_ENTRYx_CSR(0, route_destid), entry); return err; } /* * Verify that specified port/table number is valid */ err = rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR, &rval); if (err) return err; if (table >= RIO_GET_TOTAL_PORTS(rval)) return -EINVAL; err = rio_mport_write_config_32(mport, destid, hopcount, RIO_SPx_L2_Gn_ENTRYy_CSR(table, 0, route_destid), entry); return err; }
static int idtcps_route_get_entry(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table, u16 route_destid, u8 *route_port) { u32 result; if (table == RIO_GLOBAL_TABLE) { rio_mport_write_config_32(mport, destid, hopcount, RIO_STD_RTE_CONF_DESTID_SEL_CSR, route_destid); rio_mport_read_config_32(mport, destid, hopcount, RIO_STD_RTE_CONF_PORT_SEL_CSR, &result); if (CPS_DEFAULT_ROUTE == (u8)result || CPS_NO_ROUTE == (u8)result) *route_port = RIO_INVALID_ROUTE; else *route_port = (u8)result; } return 0; }
static ssize_t idtg2_show_errlog(struct device *dev, struct device_attribute *attr, char *buf) { struct rio_dev *rdev = to_rio_dev(dev); struct rio_mport *mport = rdev->net->hport; u16 destid = rdev->rswitch->destid; u8 hopcount = rdev->rswitch->hopcount; ssize_t len = 0; u32 regval; while (!rio_mport_read_config_32(mport, destid, hopcount, IDT_ERR_RD, ®val)) { if (!regval) /* 0 = end of log */ break; len += snprintf(buf + len, PAGE_SIZE - len, "%08x\n", regval); if (len >= (PAGE_SIZE - 10)) break; } return len; }
static int idtg3_route_clr_table(struct rio_mport *mport, u16 destid, u8 hopcount, u16 table) { u32 i; u32 rval; int err; if (table == RIO_GLOBAL_TABLE) { for (i = 0; i <= 0xff; i++) { err = rio_mport_write_config_32(mport, destid, hopcount, RIO_BC_L2_Gn_ENTRYx_CSR(0, i), RIO_RT_ENTRY_DROP_PKT); if (err) break; } return err; } err = rio_mport_read_config_32(mport, destid, hopcount, RIO_SWP_INFO_CAR, &rval); if (err) return err; if (table >= RIO_GET_TOTAL_PORTS(rval)) return -EINVAL; for (i = 0; i <= 0xff; i++) { err = rio_mport_write_config_32(mport, destid, hopcount, RIO_SPx_L2_Gn_ENTRYy_CSR(table, 0, i), RIO_RT_ENTRY_DROP_PKT); if (err) break; } return err; }
static int idtg2_em_init(struct rio_dev *rdev) { struct rio_mport *mport = rdev->net->hport; u16 destid = rdev->rswitch->destid; u8 hopcount = rdev->rswitch->hopcount; u32 regval; int i, tmp; /* * This routine performs device-specific initialization only. * All standard EM configuration should be performed at upper level. */ pr_debug("RIO: %s [%d:%d]\n", __func__, destid, hopcount); /* Set Port-Write info CSR: PRIO=3 and CRF=1 */ rio_mport_write_config_32(mport, destid, hopcount, IDT_PW_INFO_CSR, 0x0000e000); /* * Configure LT LAYER error reporting. */ /* Enable standard (RIO.p8) error reporting */ rio_mport_write_config_32(mport, destid, hopcount, IDT_LT_ERR_REPORT_EN, REM_LTL_ERR_ILLTRAN | REM_LTL_ERR_UNSOLR | REM_LTL_ERR_UNSUPTR); /* Use Port-Writes for LT layer error reporting. * Enable per-port reset */ rio_mport_read_config_32(mport, destid, hopcount, IDT_DEV_CTRL_1, ®val); rio_mport_write_config_32(mport, destid, hopcount, IDT_DEV_CTRL_1, regval | IDT_DEV_CTRL_1_GENPW | IDT_DEV_CTRL_1_PRSTBEH); /* * Configure PORT error reporting. */ /* Report all RIO.p8 errors supported by device */ rio_mport_write_config_32(mport, destid, hopcount, IDT_PORT_ERR_REPORT_EN_BC, 0x807e8037); /* Configure reporting of implementation specific errors/events */ rio_mport_write_config_32(mport, destid, hopcount, IDT_PORT_ISERR_REPORT_EN_BC, IDT_PORT_INIT_TX_ACQUIRED); /* Use Port-Writes for port error reporting and enable error logging */ tmp = (rdev->did == RIO_DID_IDTCPS1848) ? 48 : 16; for (i = 0; i < rdev->rswitch->nports; i++) { rio_mport_read_config_32(mport, destid, hopcount, IDT_PORT_OPS(i), ®val); rio_mport_write_config_32(mport, destid, hopcount, IDT_PORT_OPS(i), regval | IDT_PORT_OPS_GENPW | IDT_PORT_OPS_PL_ELOG | IDT_PORT_OPS_LL_ELOG | IDT_PORT_OPS_LT_ELOG); } /* Overwrite error log if full */ rio_mport_write_config_32(mport, destid, hopcount, IDT_ERR_CAP, IDT_ERR_CAP_LOG_OVERWR); /* * Configure LANE error reporting. */ /* Disable line error reporting */ rio_mport_write_config_32(mport, destid, hopcount, IDT_LANE_ERR_REPORT_EN_BC, 0); /* Use Port-Writes for lane error reporting (when enabled) * (do per-lane update because lanes may have different configuration) */ tmp = (rdev->did == RIO_DID_IDTCPS1848) ? 48 : 16; for (i = 0; i < tmp; i++) { rio_mport_read_config_32(mport, destid, hopcount, IDT_LANE_CTRL(i), ®val); rio_mport_write_config_32(mport, destid, hopcount, IDT_LANE_CTRL(i), regval | IDT_LANE_CTRL_GENPW); } /* * Configure AUX error reporting. */ /* Disable JTAG and I2C Error capture */ rio_mport_write_config_32(mport, destid, hopcount, IDT_AUX_PORT_ERR_CAP_EN, 0); /* Disable JTAG and I2C Error reporting/logging */ rio_mport_write_config_32(mport, destid, hopcount, IDT_AUX_ERR_REPORT_EN, 0); /* Disable Port-Write notification from JTAG */ rio_mport_write_config_32(mport, destid, hopcount, IDT_JTAG_CTRL, 0); /* Disable Port-Write notification from I2C */ rio_mport_read_config_32(mport, destid, hopcount, IDT_I2C_MCTRL, ®val); rio_mport_write_config_32(mport, destid, hopcount, IDT_I2C_MCTRL, regval & ~IDT_I2C_MCTRL_GENPW); /* * Configure CFG_BLK error reporting. */ /* Disable Configuration Block error capture */ rio_mport_write_config_32(mport, destid, hopcount, IDT_CFGBLK_ERR_CAPTURE_EN, 0); /* Disable Port-Writes for Configuration Block error reporting */ rio_mport_read_config_32(mport, destid, hopcount, IDT_CFGBLK_ERR_REPORT, ®val); rio_mport_write_config_32(mport, destid, hopcount, IDT_CFGBLK_ERR_REPORT, regval & ~IDT_CFGBLK_ERR_REPORT_GENPW); /* set TVAL = ~50us */ rio_mport_write_config_32(mport, destid, hopcount, rdev->phys_efptr + RIO_PORT_LINKTO_CTL_CSR, 0x8e << 8); return 0; }