]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/net/sfc/mcdi_phy.c
include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[mv-sheeva.git] / drivers / net / sfc / mcdi_phy.c
index eb694af7a473503b176a23fb37cddce97e70b6cc..2f2354696663cc8f207af5bc8449b8f7d3d31e2a 100644 (file)
@@ -11,6 +11,7 @@
  * Driver for PHY related operations via MCDI.
  */
 
+#include <linux/slab.h>
 #include "efx.h"
 #include "phy.h"
 #include "mcdi.h"
@@ -381,6 +382,18 @@ static int efx_mcdi_phy_probe(struct efx_nic *efx)
         * but by convention we don't */
        efx->loopback_modes &= ~(1 << LOOPBACK_NONE);
 
+       /* Set the initial link mode */
+       efx_mcdi_phy_decode_link(
+               efx, &efx->link_state,
+               MCDI_DWORD(outbuf, GET_LINK_OUT_LINK_SPEED),
+               MCDI_DWORD(outbuf, GET_LINK_OUT_FLAGS),
+               MCDI_DWORD(outbuf, GET_LINK_OUT_FCNTL));
+
+       /* Default to Autonegotiated flow control if the PHY supports it */
+       efx->wanted_fc = EFX_FC_RX | EFX_FC_TX;
+       if (phy_data->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
+               efx->wanted_fc |= EFX_FC_AUTO;
+
        return 0;
 
 fail:
@@ -436,7 +449,7 @@ void efx_mcdi_phy_check_fcntl(struct efx_nic *efx, u32 lpa)
 
        /* The link partner capabilities are only relevent if the
         * link supports flow control autonegotiation */
-       if (~phy_cfg->supported_cap & (1 << MC_CMD_PHY_CAP_ASYM_LBN))
+       if (~phy_cfg->supported_cap & (1 << MC_CMD_PHY_CAP_AN_LBN))
                return;
 
        /* If flow control autoneg is supported and enabled, then fine */
@@ -560,6 +573,27 @@ static int efx_mcdi_phy_set_settings(struct efx_nic *efx, struct ethtool_cmd *ec
        return 0;
 }
 
+static int efx_mcdi_phy_test_alive(struct efx_nic *efx)
+{
+       u8 outbuf[MC_CMD_GET_PHY_STATE_OUT_LEN];
+       size_t outlen;
+       int rc;
+
+       BUILD_BUG_ON(MC_CMD_GET_PHY_STATE_IN_LEN != 0);
+
+       rc = efx_mcdi_rpc(efx, MC_CMD_GET_PHY_STATE, NULL, 0,
+                         outbuf, sizeof(outbuf), &outlen);
+       if (rc)
+               return rc;
+
+       if (outlen < MC_CMD_GET_PHY_STATE_OUT_LEN)
+               return -EMSGSIZE;
+       if (MCDI_DWORD(outbuf, GET_PHY_STATE_STATE) != MC_CMD_PHY_STATE_OK)
+               return -EINVAL;
+
+       return 0;
+}
+
 struct efx_phy_operations efx_mcdi_phy_ops = {
        .probe          = efx_mcdi_phy_probe,
        .init           = efx_port_dummy_op_int,
@@ -569,6 +603,7 @@ struct efx_phy_operations efx_mcdi_phy_ops = {
        .remove         = efx_mcdi_phy_remove,
        .get_settings   = efx_mcdi_phy_get_settings,
        .set_settings   = efx_mcdi_phy_set_settings,
+       .test_alive     = efx_mcdi_phy_test_alive,
        .run_tests      = NULL,
        .test_name      = NULL,
 };