Print this page
6064 ixgbe needs X550 support
@@ -295,17 +295,28 @@
int err = 0;
uint32_t flow_control;
uint32_t cur_mtu, new_mtu;
uint32_t rx_size;
uint32_t tx_size;
+ ixgbe_link_speed speeds = 0;
mutex_enter(&ixgbe->gen_lock);
if (ixgbe->ixgbe_state & IXGBE_SUSPENDED) {
mutex_exit(&ixgbe->gen_lock);
return (ECANCELED);
}
+ /*
+ * We cannot always rely on the common code maintaining
+ * hw->phy.speeds_supported, therefore we fall back to use the recorded
+ * supported speeds which were obtained during instance init in
+ * ixgbe_init_params().
+ */
+ speeds = hw->phy.speeds_supported;
+ if (speeds == 0)
+ speeds = ixgbe->speeds_supported;
+
if (ixgbe->loopback_mode != IXGBE_LB_NONE &&
ixgbe_param_locked(pr_num)) {
/*
* All en_* parameters are locked (read-only)
* while the device is in any sort of loopback mode.
@@ -312,43 +323,61 @@
*/
mutex_exit(&ixgbe->gen_lock);
return (EBUSY);
}
+ /*
+ * We allow speed changes only on baseT PHYs. MAC_PROP_EN_* are marked
+ * read-only on non-baseT PHYs.
+ */
switch (pr_num) {
case MAC_PROP_EN_10GFDX_CAP:
- /* read/write on copper, read-only on serdes */
- if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) {
- err = ENOTSUP;
- break;
- } else {
+ if (hw->phy.media_type == ixgbe_media_type_copper &&
+ speeds & IXGBE_LINK_SPEED_10GB_FULL) {
ixgbe->param_en_10000fdx_cap = *(uint8_t *)pr_val;
- ixgbe->param_adv_10000fdx_cap = *(uint8_t *)pr_val;
goto setup_link;
+ } else {
+ err = ENOTSUP;
+ break;
}
- case MAC_PROP_EN_1000FDX_CAP:
- /* read/write on copper, read-only on serdes */
- if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) {
+ case MAC_PROP_EN_5000FDX_CAP:
+ if (hw->phy.media_type == ixgbe_media_type_copper &&
+ speeds & IXGBE_LINK_SPEED_5GB_FULL) {
+ ixgbe->param_en_5000fdx_cap = *(uint8_t *)pr_val;
+ goto setup_link;
+ } else {
err = ENOTSUP;
break;
+ }
+ case MAC_PROP_EN_2500FDX_CAP:
+ if (hw->phy.media_type == ixgbe_media_type_copper &&
+ speeds & IXGBE_LINK_SPEED_2_5GB_FULL) {
+ ixgbe->param_en_2500fdx_cap = *(uint8_t *)pr_val;
+ goto setup_link;
} else {
+ err = ENOTSUP;
+ break;
+ }
+ case MAC_PROP_EN_1000FDX_CAP:
+ if (hw->phy.media_type == ixgbe_media_type_copper &&
+ speeds & IXGBE_LINK_SPEED_1GB_FULL) {
ixgbe->param_en_1000fdx_cap = *(uint8_t *)pr_val;
- ixgbe->param_adv_1000fdx_cap = *(uint8_t *)pr_val;
goto setup_link;
- }
- case MAC_PROP_EN_100FDX_CAP:
- /* read/write on copper, read-only on serdes */
- if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) {
+ } else {
err = ENOTSUP;
break;
- } else {
+ }
+ case MAC_PROP_EN_100FDX_CAP:
+ if (hw->phy.media_type == ixgbe_media_type_copper &&
+ speeds & IXGBE_LINK_SPEED_100_FULL) {
ixgbe->param_en_100fdx_cap = *(uint8_t *)pr_val;
- ixgbe->param_adv_100fdx_cap = *(uint8_t *)pr_val;
goto setup_link;
+ } else {
+ err = ENOTSUP;
+ break;
}
case MAC_PROP_AUTONEG:
- /* read/write on copper, read-only on serdes */
if (ixgbe->hw.phy.media_type != ixgbe_media_type_copper) {
err = ENOTSUP;
break;
} else {
ixgbe->param_adv_autoneg_cap = *(uint8_t *)pr_val;
@@ -380,10 +409,12 @@
IXGBE_SUCCESS)
err = EINVAL;
}
break;
case MAC_PROP_ADV_10GFDX_CAP:
+ case MAC_PROP_ADV_5000FDX_CAP:
+ case MAC_PROP_ADV_2500FDX_CAP:
case MAC_PROP_ADV_1000FDX_CAP:
case MAC_PROP_ADV_100FDX_CAP:
case MAC_PROP_STATUS:
case MAC_PROP_SPEED:
case MAC_PROP_DUPLEX:
@@ -446,11 +477,22 @@
ixgbe_t *ixgbe = (ixgbe_t *)arg;
struct ixgbe_hw *hw = &ixgbe->hw;
int err = 0;
uint32_t flow_control;
uint64_t tmp = 0;
+ ixgbe_link_speed speeds = 0;
+ /*
+ * We cannot always rely on the common code maintaining
+ * hw->phy.speeds_supported, therefore we fall back to use the recorded
+ * supported speeds which were obtained during instance init in
+ * ixgbe_init_params().
+ */
+ speeds = hw->phy.speeds_supported;
+ if (speeds == 0)
+ speeds = ixgbe->speeds_supported;
+
switch (pr_num) {
case MAC_PROP_DUPLEX:
ASSERT(pr_valsize >= sizeof (link_duplex_t));
bcopy(&ixgbe->link_duplex, pr_val,
sizeof (link_duplex_t));
@@ -481,26 +523,68 @@
break;
}
bcopy(&flow_control, pr_val, sizeof (flow_control));
break;
case MAC_PROP_ADV_10GFDX_CAP:
+ if (speeds & IXGBE_LINK_SPEED_10GB_FULL)
*(uint8_t *)pr_val = ixgbe->param_adv_10000fdx_cap;
+ else
+ err = ENOTSUP;
break;
case MAC_PROP_EN_10GFDX_CAP:
+ if (speeds & IXGBE_LINK_SPEED_10GB_FULL)
*(uint8_t *)pr_val = ixgbe->param_en_10000fdx_cap;
+ else
+ err = ENOTSUP;
break;
+ case MAC_PROP_ADV_5000FDX_CAP:
+ if (speeds & IXGBE_LINK_SPEED_5GB_FULL)
+ *(uint8_t *)pr_val = ixgbe->param_adv_5000fdx_cap;
+ else
+ err = ENOTSUP;
+ break;
+ case MAC_PROP_EN_5000FDX_CAP:
+ if (speeds & IXGBE_LINK_SPEED_5GB_FULL)
+ *(uint8_t *)pr_val = ixgbe->param_en_5000fdx_cap;
+ else
+ err = ENOTSUP;
+ break;
+ case MAC_PROP_ADV_2500FDX_CAP:
+ if (speeds & IXGBE_LINK_SPEED_2_5GB_FULL)
+ *(uint8_t *)pr_val = ixgbe->param_adv_2500fdx_cap;
+ else
+ err = ENOTSUP;
+ break;
+ case MAC_PROP_EN_2500FDX_CAP:
+ if (speeds & IXGBE_LINK_SPEED_2_5GB_FULL)
+ *(uint8_t *)pr_val = ixgbe->param_en_2500fdx_cap;
+ else
+ err = ENOTSUP;
+ break;
case MAC_PROP_ADV_1000FDX_CAP:
+ if (speeds & IXGBE_LINK_SPEED_1GB_FULL)
*(uint8_t *)pr_val = ixgbe->param_adv_1000fdx_cap;
+ else
+ err = ENOTSUP;
break;
case MAC_PROP_EN_1000FDX_CAP:
+ if (speeds & IXGBE_LINK_SPEED_1GB_FULL)
*(uint8_t *)pr_val = ixgbe->param_en_1000fdx_cap;
+ else
+ err = ENOTSUP;
break;
case MAC_PROP_ADV_100FDX_CAP:
+ if (speeds & IXGBE_LINK_SPEED_100_FULL)
*(uint8_t *)pr_val = ixgbe->param_adv_100fdx_cap;
+ else
+ err = ENOTSUP;
break;
case MAC_PROP_EN_100FDX_CAP:
+ if (speeds & IXGBE_LINK_SPEED_100_FULL)
*(uint8_t *)pr_val = ixgbe->param_en_100fdx_cap;
+ else
+ err = ENOTSUP;
break;
case MAC_PROP_PRIVATE:
err = ixgbe_get_priv_prop(ixgbe, pr_name,
pr_valsize, pr_val);
break;
@@ -514,33 +598,115 @@
void
ixgbe_m_propinfo(void *arg, const char *pr_name, mac_prop_id_t pr_num,
mac_prop_info_handle_t prh)
{
ixgbe_t *ixgbe = (ixgbe_t *)arg;
+ struct ixgbe_hw *hw = &ixgbe->hw;
uint_t perm;
+ uint8_t value;
+ ixgbe_link_speed speeds = 0;
+ /*
+ * We cannot always rely on the common code maintaining
+ * hw->phy.speeds_supported, therefore we fall back to use the
+ * recorded supported speeds which were obtained during instance init in
+ * ixgbe_init_params().
+ */
+ speeds = hw->phy.speeds_supported;
+ if (speeds == 0)
+ speeds = ixgbe->speeds_supported;
+
switch (pr_num) {
case MAC_PROP_DUPLEX:
case MAC_PROP_SPEED:
mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
break;
case MAC_PROP_ADV_100FDX_CAP:
+ mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
+ value = (speeds & IXGBE_LINK_SPEED_100_FULL) ? 1 : 0;
+ mac_prop_info_set_default_uint8(prh, value);
+ break;
+
case MAC_PROP_ADV_1000FDX_CAP:
+ mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
+ value = (speeds & IXGBE_LINK_SPEED_1GB_FULL) ? 1 : 0;
+ mac_prop_info_set_default_uint8(prh, value);
+ break;
+
+ case MAC_PROP_ADV_2500FDX_CAP:
+ mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
+ value = (speeds & IXGBE_LINK_SPEED_2_5GB_FULL) ? 1 : 0;
+ mac_prop_info_set_default_uint8(prh, value);
+ break;
+
+ case MAC_PROP_ADV_5000FDX_CAP:
+ mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
+ value = (speeds & IXGBE_LINK_SPEED_5GB_FULL) ? 1 : 0;
+ mac_prop_info_set_default_uint8(prh, value);
+ break;
+
case MAC_PROP_ADV_10GFDX_CAP:
mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
- mac_prop_info_set_default_uint8(prh, 1);
+ value = (speeds & IXGBE_LINK_SPEED_10GB_FULL) ? 1 : 0;
+ mac_prop_info_set_default_uint8(prh, value);
break;
+ /*
+ * We allow speed changes only on baseT PHYs. MAC_PROP_EN_* are marked
+ * read-only on non-baseT (SFP) PHYs.
+ */
case MAC_PROP_AUTONEG:
+ perm = (hw->phy.media_type == ixgbe_media_type_copper) ?
+ MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
+ mac_prop_info_set_perm(prh, perm);
+ mac_prop_info_set_default_uint8(prh, 1);
+ break;
+
case MAC_PROP_EN_10GFDX_CAP:
+ if (speeds & IXGBE_LINK_SPEED_10GB_FULL) {
+ perm = (hw->phy.media_type == ixgbe_media_type_copper) ?
+ MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
+ mac_prop_info_set_perm(prh, perm);
+ mac_prop_info_set_default_uint8(prh, 1);
+ }
+ break;
+
+ case MAC_PROP_EN_5000FDX_CAP:
+ if (speeds & IXGBE_LINK_SPEED_5GB_FULL) {
+ perm = (hw->phy.media_type == ixgbe_media_type_copper) ?
+ MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
+ mac_prop_info_set_perm(prh, perm);
+ mac_prop_info_set_default_uint8(prh, 1);
+ }
+ break;
+
+ case MAC_PROP_EN_2500FDX_CAP:
+ if (speeds & IXGBE_LINK_SPEED_2_5GB_FULL) {
+ perm = (hw->phy.media_type == ixgbe_media_type_copper) ?
+ MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
+ mac_prop_info_set_perm(prh, perm);
+ mac_prop_info_set_default_uint8(prh, 1);
+ }
+ break;
+
case MAC_PROP_EN_1000FDX_CAP:
+ if (speeds & IXGBE_LINK_SPEED_1GB_FULL) {
+ perm = (hw->phy.media_type == ixgbe_media_type_copper) ?
+ MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
+ mac_prop_info_set_perm(prh, perm);
+ mac_prop_info_set_default_uint8(prh, 1);
+ }
+ break;
+
case MAC_PROP_EN_100FDX_CAP:
- perm = (ixgbe->hw.phy.media_type == ixgbe_media_type_copper) ?
+ if (speeds & IXGBE_LINK_SPEED_100_FULL) {
+ perm = (hw->phy.media_type == ixgbe_media_type_copper) ?
MAC_PROP_PERM_RW : MAC_PROP_PERM_READ;
mac_prop_info_set_perm(prh, perm);
mac_prop_info_set_default_uint8(prh, 1);
+ }
break;
case MAC_PROP_FLOWCTRL:
mac_prop_info_set_default_link_flowctrl(prh,
LINK_FLOWCTRL_NONE);
@@ -593,10 +759,12 @@
* All en_* parameters are locked (read-only) while
* the device is in any sort of loopback mode ...
*/
switch (pr_num) {
case MAC_PROP_EN_10GFDX_CAP:
+ case MAC_PROP_EN_5000FDX_CAP:
+ case MAC_PROP_EN_2500FDX_CAP:
case MAC_PROP_EN_1000FDX_CAP:
case MAC_PROP_EN_100FDX_CAP:
case MAC_PROP_AUTONEG:
case MAC_PROP_FLOWCTRL:
return (B_TRUE);
@@ -710,16 +878,18 @@
err = EINVAL;
else {
ixgbe->intr_throttling[0] = (uint32_t)result;
/*
- * 82599 and X540 require the interrupt throttling
+ * 82599, X540 and X550 require the interrupt throttling
* rate is a multiple of 8. This is enforced by the
* register definiton.
*/
if (hw->mac.type == ixgbe_mac_82599EB ||
- hw->mac.type == ixgbe_mac_X540) {
+ hw->mac.type == ixgbe_mac_X540 ||
+ hw->mac.type == ixgbe_mac_X550 ||
+ hw->mac.type == ixgbe_mac_X550EM_x) {
ixgbe->intr_throttling[0] =
ixgbe->intr_throttling[0] & 0xFF8;
}
for (i = 0; i < MAX_INTR_VECTOR; i++)