common/sfc_efx/base: fix PHY config failure on Riverhead
[dpdk.git] / drivers / common / sfc_efx / base / efx_nic.c
index 267d010..a78c4c3 100644 (file)
@@ -85,10 +85,66 @@ efx_family(
                }
        }
 
+       if (venid == EFX_PCI_VENID_XILINX) {
+               switch (devid) {
+#if EFSYS_OPT_RIVERHEAD
+               case EFX_PCI_DEVID_RIVERHEAD:
+               case EFX_PCI_DEVID_RIVERHEAD_VF:
+                       *efp = EFX_FAMILY_RIVERHEAD;
+                       *membarp = EFX_MEM_BAR_RIVERHEAD;
+                       return (0);
+#endif /* EFSYS_OPT_RIVERHEAD */
+               default:
+                       break;
+               }
+       }
+
        *efp = EFX_FAMILY_INVALID;
        return (ENOTSUP);
 }
 
+#if EFSYS_OPT_PCI
+
+       __checkReturn   efx_rc_t
+efx_family_probe_bar(
+       __in            uint16_t venid,
+       __in            uint16_t devid,
+       __in            efsys_pci_config_t *espcp,
+       __in            const efx_pci_ops_t *epop,
+       __out           efx_family_t *efp,
+       __out           efx_bar_region_t *ebrp)
+{
+       efx_rc_t rc;
+       unsigned int membar;
+
+       if (venid == EFX_PCI_VENID_XILINX) {
+               switch (devid) {
+#if EFSYS_OPT_RIVERHEAD
+               case EFX_PCI_DEVID_RIVERHEAD:
+               case EFX_PCI_DEVID_RIVERHEAD_VF:
+                       rc = rhead_pci_nic_membar_lookup(espcp, epop, ebrp);
+                       if (rc == 0)
+                               *efp = EFX_FAMILY_RIVERHEAD;
+
+                       return (rc);
+#endif /* EFSYS_OPT_RIVERHEAD */
+               default:
+                       break;
+               }
+       }
+
+       rc = efx_family(venid, devid, efp, &membar);
+       if (rc == 0) {
+               ebrp->ebr_type = EFX_BAR_TYPE_MEM;
+               ebrp->ebr_index = membar;
+               ebrp->ebr_offset = 0;
+               ebrp->ebr_length = 0;
+       }
+
+       return (rc);
+}
+
+#endif /* EFSYS_OPT_PCI */
 
 #if EFSYS_OPT_SIENA
 
@@ -174,12 +230,34 @@ static const efx_nic_ops_t        __efx_nic_medford2_ops = {
 
 #endif /* EFSYS_OPT_MEDFORD2 */
 
+#if EFSYS_OPT_RIVERHEAD
+
+static const efx_nic_ops_t     __efx_nic_riverhead_ops = {
+       rhead_nic_probe,                /* eno_probe */
+       rhead_board_cfg,                /* eno_board_cfg */
+       rhead_nic_set_drv_limits,       /* eno_set_drv_limits */
+       rhead_nic_reset,                /* eno_reset */
+       rhead_nic_init,                 /* eno_init */
+       rhead_nic_get_vi_pool,          /* eno_get_vi_pool */
+       rhead_nic_get_bar_region,       /* eno_get_bar_region */
+       rhead_nic_hw_unavailable,       /* eno_hw_unavailable */
+       rhead_nic_set_hw_unavailable,   /* eno_set_hw_unavailable */
+#if EFSYS_OPT_DIAG
+       rhead_nic_register_test,        /* eno_register_test */
+#endif /* EFSYS_OPT_DIAG */
+       rhead_nic_fini,                 /* eno_fini */
+       rhead_nic_unprobe,              /* eno_unprobe */
+};
+
+#endif /* EFSYS_OPT_RIVERHEAD */
+
 
        __checkReturn   efx_rc_t
 efx_nic_create(
        __in            efx_family_t family,
        __in            efsys_identifier_t *esip,
        __in            efsys_bar_t *esbp,
+       __in            uint32_t fcw_offset,
        __in            efsys_lock_t *eslp,
        __deref_out     efx_nic_t **enpp)
 {
@@ -271,11 +349,30 @@ efx_nic_create(
                break;
 #endif /* EFSYS_OPT_MEDFORD2 */
 
+#if EFSYS_OPT_RIVERHEAD
+       case EFX_FAMILY_RIVERHEAD:
+               enp->en_enop = &__efx_nic_riverhead_ops;
+               enp->en_features =
+                   EFX_FEATURE_IPV6 |
+                   EFX_FEATURE_LINK_EVENTS |
+                   EFX_FEATURE_PERIODIC_MAC_STATS |
+                   EFX_FEATURE_MCDI |
+                   EFX_FEATURE_MAC_HEADER_FILTERS |
+                   EFX_FEATURE_MCDI_DMA;
+               enp->en_arch.ef10.ena_fcw_base = fcw_offset;
+               break;
+#endif /* EFSYS_OPT_RIVERHEAD */
+
        default:
                rc = ENOTSUP;
                goto fail2;
        }
 
+       if ((family != EFX_FAMILY_RIVERHEAD) && (fcw_offset != 0)) {
+               rc = EINVAL;
+               goto fail3;
+       }
+
        enp->en_family = family;
        enp->en_esip = esip;
        enp->en_esbp = esbp;
@@ -285,6 +382,8 @@ efx_nic_create(
 
        return (0);
 
+fail3:
+       EFSYS_PROBE(fail3);
 fail2:
        EFSYS_PROBE(fail2);
 
@@ -304,6 +403,7 @@ efx_nic_probe(
        __in            efx_nic_t *enp,
        __in            efx_fw_variant_t efv)
 {
+       efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
        const efx_nic_ops_t *enop;
        efx_rc_t rc;
 
@@ -337,6 +437,8 @@ efx_nic_probe(
        if ((rc = enop->eno_probe(enp)) != 0)
                goto fail1;
 
+       encp->enc_features = enp->en_features;
+
        if ((rc = efx_phy_probe(enp)) != 0)
                goto fail2;