int cvm_oct_sgmii_open(struct net_device *dev) { union cvmx_gmxx_prtx_cfg gmx_cfg; struct octeon_ethernet *priv = netdev_priv(dev); cvmx_helper_link_info_t link_info; int rv; rv = cvm_oct_phy_setup_device(dev); if (rv) return rv; gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(priv->interface_port, priv->interface)); gmx_cfg.s.en = 1; cvmx_write_csr(CVMX_GMXX_PRTX_CFG(priv->interface_port, priv->interface), gmx_cfg.u64); if (octeon_is_simulation()) return 0; if (priv->phydev) { int r = phy_read_status(priv->phydev); if (r == 0 && priv->phydev->link == 0) netif_carrier_off(dev); cvm_oct_adjust_link(dev); } else { link_info = cvmx_helper_link_get(priv->ipd_port); if (!link_info.s.link_up) netif_carrier_off(dev); priv->poll = cvm_oct_sgmii_poll; cvm_oct_sgmii_poll(dev); } return 0; }
int cvm_oct_common_open(struct net_device *dev, void (*link_poll)(struct net_device *)) { union cvmx_gmxx_prtx_cfg gmx_cfg; struct octeon_ethernet *priv = netdev_priv(dev); int interface = INTERFACE(priv->port); int index = INDEX(priv->port); cvmx_helper_link_info_t link_info; int rv; rv = cvm_oct_phy_setup_device(dev); if (rv) return rv; gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); gmx_cfg.s.en = 1; if (octeon_has_feature(OCTEON_FEATURE_PKND)) gmx_cfg.s.pknd = priv->port; cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); if (octeon_is_simulation()) return 0; if (dev->phydev) { int r = phy_read_status(dev->phydev); if (r == 0 && dev->phydev->link == 0) netif_carrier_off(dev); cvm_oct_adjust_link(dev); } else { link_info = cvmx_helper_link_get(priv->port); if (!link_info.s.link_up) netif_carrier_off(dev); priv->poll = link_poll; link_poll(dev); } return 0; }
int cvm_oct_sgmii_open(struct net_device *dev) { struct octeon_hw_status_reg sr[3]; union cvmx_gmxx_prtx_cfg gmx_cfg; struct octeon_ethernet *priv = netdev_priv(dev); cvmx_helper_link_info_t link_info; cvmx_helper_interface_mode_t imode; int rv, i; u64 en_mask; rv = cvm_oct_phy_setup_device(dev); if (rv) return rv; gmx_cfg.u64 = cvmx_read_csr(priv->gmx_base + GMX_PRT_CFG); gmx_cfg.s.en = 1; cvmx_write_csr(priv->gmx_base + GMX_PRT_CFG, gmx_cfg.u64); if (octeon_is_simulation()) return 0; if (priv->phydev) { int r = phy_read_status(priv->phydev); if (r == 0 && priv->phydev->link == 0) netif_carrier_off(dev); cvm_oct_adjust_link(dev); } else { link_info = cvmx_helper_link_get(priv->ipd_port); if (!link_info.s.link_up) netif_carrier_off(dev); priv->poll = cvm_oct_sgmii_poll; cvm_oct_sgmii_poll(dev); } imode = cvmx_helper_interface_get_mode(priv->interface); switch (imode) { case CVMX_HELPER_INTERFACE_MODE_XAUI: case CVMX_HELPER_INTERFACE_MODE_RXAUI: /* Handle GMXX_RXX_INT_REG[LOC_FAULT,REM_FAULT]*/ priv->hw_status_notifier.priority = 10; priv->hw_status_notifier.notifier_call = cvm_oct_sgmii_hw_status; octeon_hw_status_notifier_register(&priv->hw_status_notifier); memset(sr, 0, sizeof(sr)); i = 0; en_mask = 0; if (OCTEON_IS_OCTEONPLUS()) { sr[i].reg = 46; /* RML */ sr[i].reg_is_hwint = 1; sr[i].has_child = 1; i++; sr[i].reg = CVMX_NPEI_RSL_INT_BLOCKS; /* GMX[priv->interface]*/ sr[i].bit = priv->interface + 1; sr[i].has_child = 1; i++; } else if (octeon_has_feature(OCTEON_FEATURE_CIU2)) { /* PKT[AGX[priv->interface]]*/ sr[i].reg = (6 << 6) | priv->interface; sr[i].reg_is_hwint = 1; sr[i].has_child = 1; i++; } else { /* INT_SUM1[AGX[priv->interface]]*/ sr[i].reg = (1 << 6) | (priv->interface + 36); sr[i].reg_is_hwint = 1; sr[i].has_child = 1; i++; } sr[i].reg = CVMX_GMXX_RXX_INT_REG(priv->interface_port, priv->interface); sr[i].mask_reg = CVMX_GMXX_RXX_INT_EN(priv->interface_port, priv->interface); sr[i].ack_w1c = 1; sr[i].bit = INT_BIT_LOC_FAULT; en_mask |= 1ull << sr[i].bit; octeon_hw_status_add_source(sr); sr[i].bit = INT_BIT_REM_FAULT; en_mask |= 1ull << sr[i].bit; octeon_hw_status_add_source(sr); octeon_hw_status_enable(sr[i].reg, en_mask); break; default: break; } return 0; }