Ejemplo n.º 1
0
cfg::PortSpeed BcmPort::getSpeed() const {
  int curSpeed{0};
  auto rv = opennsl_port_speed_get(unit_, port_, &curSpeed);
  bcmCheckError(
    rv, "Failed to get current speed for port ", port_);
  return cfg::PortSpeed(curSpeed);
}
Ejemplo n.º 2
0
void BcmPort::setSpeed(const shared_ptr<Port>& swPort) {
  if (isEnabled()) {
    LOG(ERROR) << "Cannot set port speed while the port is enabled. Port: "
               << swPort->getName() << " id: " << swPort->getID();
    return;
  }
  int ret;
  cfg::PortSpeed desiredPortSpeed;
  if (swPort->getSpeed() == cfg::PortSpeed::DEFAULT) {
    int speed;
    ret = opennsl_port_speed_max(unit_, port_, &speed);
    bcmCheckError(ret, "failed to get max speed for port", swPort->getID());
    desiredPortSpeed = cfg::PortSpeed(speed);
  } else {
    desiredPortSpeed = swPort->getSpeed();
  }

  opennsl_port_if_t desiredMode = getDesiredInterfaceMode(desiredPortSpeed,
                                                          swPort->getID(),
                                                          swPort->getName());

  opennsl_port_if_t curMode;
  ret = opennsl_port_interface_get(unit_, port_, &curMode);
  bcmCheckError(ret,
                "Failed to get current interface setting for port ",
                swPort->getID());

  bool updateSpeed = false;

  if (curMode != desiredMode) {
    ret = opennsl_port_interface_set(unit_, port_, desiredMode);
    bcmCheckError(
        ret, "failed to set interface type for port ", swPort->getID());
    // Changes to the interface setting only seem to take effect on the next
    // call to opennsl_port_speed_set().  Therefore make sure we update the
    // speed below, even if the speed is already at the desired setting.
    updateSpeed = true;
  }

  int desiredSpeed = static_cast<int>(desiredPortSpeed);
  // Unnecessarily updating BCM port speed actually causes
  // the port to flap, even if this should be a noop, so check current
  // speed before making speed related changes. Doing so fixes
  // the interface flaps we were seeing during warm boots
  if (!updateSpeed && desiredMode != OPENNSL_PORT_IF_KR4) {
    int curSpeed;
    ret = opennsl_port_speed_get(unit_, port_, &curSpeed);
    bcmCheckError(
        ret, "Failed to get current speed for port ", swPort->getID());
    updateSpeed |= (curSpeed != desiredSpeed);
  }

  if (updateSpeed) {
    if (desiredMode == OPENNSL_PORT_IF_KR4) {
      // We don't need to set speed when mode is KR4, since ports in KR4 mode
      // do autonegotiation to figure out the speed.
      setKR4Ability();
    } else {
      ret = opennsl_port_speed_set(unit_, port_, desiredSpeed);
      bcmCheckError(ret,
                    "failed to set speed, ",
                    desiredSpeed,
                    ", to port ",
                    swPort->getID());
    }
  }
}