Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F151152064
D2540.id5426.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D2540.id5426.diff
View Options
Index: head/sys/dev/sfxge/sfxge_port.c
===================================================================
--- head/sys/dev/sfxge/sfxge_port.c
+++ head/sys/dev/sfxge/sfxge_port.c
@@ -39,6 +39,8 @@
#include "sfxge.h"
+static int sfxge_phy_cap_mask(struct sfxge_softc *, int, uint32_t *);
+
static int
sfxge_mac_stat_update(struct sfxge_softc *sc)
{
@@ -443,6 +445,7 @@
efx_nic_t *enp;
size_t pdu;
int rc;
+ uint32_t phy_cap_mask;
port = &sc->port;
enp = sc->enp;
@@ -483,10 +486,13 @@
if ((rc = efx_mac_drain(enp, B_FALSE)) != 0)
goto fail3;
- if ((rc = efx_phy_adv_cap_set(sc->enp, sc->media.ifm_cur->ifm_data))
- != 0)
+ if ((rc = sfxge_phy_cap_mask(sc, sc->media.ifm_cur->ifm_media,
+ &phy_cap_mask)) != 0)
goto fail4;
+ if ((rc = efx_phy_adv_cap_set(sc->enp, phy_cap_mask)) != 0)
+ goto fail5;
+
port->init_state = SFXGE_PORT_STARTED;
/* Single poll in case there were missing initial events */
@@ -495,6 +501,7 @@
return (0);
+fail5:
fail4:
(void)efx_mac_drain(enp, B_TRUE);
fail3:
@@ -738,12 +745,95 @@
SFXGE_ADAPTER_UNLOCK(sc);
}
+static efx_phy_cap_type_t
+sfxge_link_mode_to_phy_cap(efx_link_mode_t mode)
+{
+ switch (mode) {
+ case EFX_LINK_10HDX:
+ return (EFX_PHY_CAP_10HDX);
+ case EFX_LINK_10FDX:
+ return (EFX_PHY_CAP_10FDX);
+ case EFX_LINK_100HDX:
+ return (EFX_PHY_CAP_100HDX);
+ case EFX_LINK_100FDX:
+ return (EFX_PHY_CAP_100FDX);
+ case EFX_LINK_1000HDX:
+ return (EFX_PHY_CAP_1000HDX);
+ case EFX_LINK_1000FDX:
+ return (EFX_PHY_CAP_1000FDX);
+ case EFX_LINK_10000FDX:
+ return (EFX_PHY_CAP_10000FDX);
+ default:
+ EFSYS_ASSERT(B_FALSE);
+ return (EFX_PHY_CAP_INVALID);
+ }
+}
+
+static int
+sfxge_phy_cap_mask(struct sfxge_softc *sc, int ifmedia, uint32_t *phy_cap_mask)
+{
+ efx_phy_media_type_t medium_type;
+ boolean_t mode_found = B_FALSE;
+ uint32_t cap_mask, mode_cap_mask;
+ efx_link_mode_t mode;
+ efx_phy_cap_type_t phy_cap;
+
+ efx_phy_media_type_get(sc->enp, &medium_type);
+ if (medium_type >= nitems(sfxge_link_mode)) {
+ if_printf(sc->ifnet, "unexpected media type %d\n", medium_type);
+ return (EINVAL);
+ }
+
+ efx_phy_adv_cap_get(sc->enp, EFX_PHY_CAP_PERM, &cap_mask);
+
+ for (mode = EFX_LINK_10HDX; mode < EFX_LINK_NMODES; mode++) {
+ if (ifmedia == sfxge_link_mode[medium_type][mode]) {
+ mode_found = B_TRUE;
+ break;
+ }
+ }
+
+ if (!mode_found) {
+ /*
+ * If media is not in the table, it must be IFM_AUTO.
+ */
+ KASSERT((cap_mask & (1 << EFX_PHY_CAP_AN)) &&
+ ifmedia == (IFM_ETHER | IFM_AUTO),
+ ("%s: no mode for media %d", __func__, ifmedia));
+ *phy_cap_mask = (cap_mask & ~(1 << EFX_PHY_CAP_ASYM));
+ return (0);
+ }
+
+ phy_cap = sfxge_link_mode_to_phy_cap(mode);
+ if (phy_cap == EFX_PHY_CAP_INVALID) {
+ if_printf(sc->ifnet,
+ "cannot map link mode %d to phy capability\n",
+ mode);
+ return (EINVAL);
+ }
+
+ mode_cap_mask = (1 << phy_cap);
+ mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_AN);
+#ifdef SFXGE_HAVE_PAUSE_MEDIAOPTS
+ if (ifmedia & IFM_ETH_RXPAUSE)
+ mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_PAUSE);
+ if (!(ifmedia & IFM_ETH_TXPAUSE))
+ mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_ASYM);
+#else
+ mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_PAUSE);
+#endif
+
+ *phy_cap_mask = mode_cap_mask;
+ return (0);
+}
+
static int
sfxge_media_change(struct ifnet *ifp)
{
struct sfxge_softc *sc;
struct ifmedia_entry *ifm;
int rc;
+ uint32_t phy_cap_mask;
sc = ifp->if_softc;
ifm = sc->media.ifm_cur;
@@ -759,7 +849,10 @@
if (rc != 0)
goto out;
- rc = efx_phy_adv_cap_set(sc->enp, ifm->ifm_data);
+ if ((rc = sfxge_phy_cap_mask(sc, ifm->ifm_media, &phy_cap_mask)) != 0)
+ goto out;
+
+ rc = efx_phy_adv_cap_set(sc->enp, phy_cap_mask);
out:
SFXGE_ADAPTER_UNLOCK(sc);
@@ -771,6 +864,7 @@
efx_phy_media_type_t medium_type;
uint32_t cap_mask, mode_cap_mask;
efx_link_mode_t mode;
+ efx_phy_cap_type_t phy_cap;
int mode_ifm, best_mode_ifm = 0;
int rc;
@@ -801,41 +895,30 @@
efx_phy_media_type_get(sc->enp, &medium_type);
efx_phy_adv_cap_get(sc->enp, EFX_PHY_CAP_PERM, &cap_mask);
- EFX_STATIC_ASSERT(EFX_LINK_10HDX == EFX_PHY_CAP_10HDX + 1);
- EFX_STATIC_ASSERT(EFX_LINK_10FDX == EFX_PHY_CAP_10FDX + 1);
- EFX_STATIC_ASSERT(EFX_LINK_100HDX == EFX_PHY_CAP_100HDX + 1);
- EFX_STATIC_ASSERT(EFX_LINK_100FDX == EFX_PHY_CAP_100FDX + 1);
- EFX_STATIC_ASSERT(EFX_LINK_1000HDX == EFX_PHY_CAP_1000HDX + 1);
- EFX_STATIC_ASSERT(EFX_LINK_1000FDX == EFX_PHY_CAP_1000FDX + 1);
- EFX_STATIC_ASSERT(EFX_LINK_10000FDX == EFX_PHY_CAP_10000FDX + 1);
+ for (mode = EFX_LINK_10HDX; mode < EFX_LINK_NMODES; mode++) {
+ phy_cap = sfxge_link_mode_to_phy_cap(mode);
+ if (phy_cap == EFX_PHY_CAP_INVALID)
+ continue;
- for (mode = EFX_LINK_10HDX; mode <= EFX_LINK_10000FDX; mode++) {
- mode_cap_mask = 1 << (mode - 1);
+ mode_cap_mask = (1 << phy_cap);
mode_ifm = sfxge_link_mode[medium_type][mode];
if ((cap_mask & mode_cap_mask) && mode_ifm) {
- mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_AN);
-
-#ifdef SFXGE_HAVE_PAUSE_MEDIAOPTS
/* No flow-control */
- ifmedia_add(&sc->media, mode_ifm, mode_cap_mask, NULL);
+ ifmedia_add(&sc->media, mode_ifm, 0, NULL);
+#ifdef SFXGE_HAVE_PAUSE_MEDIAOPTS
/* Respond-only. If using AN, we implicitly
* offer symmetric as well, but that doesn't
* mean we *have* to generate pause frames.
*/
- mode_cap_mask |= cap_mask & ((1 << EFX_PHY_CAP_PAUSE) |
- (1 << EFX_PHY_CAP_ASYM));
mode_ifm |= IFM_ETH_RXPAUSE;
- ifmedia_add(&sc->media, mode_ifm, mode_cap_mask, NULL);
+ ifmedia_add(&sc->media, mode_ifm, 0, NULL);
/* Symmetric */
- mode_cap_mask &= ~(1 << EFX_PHY_CAP_ASYM);
mode_ifm |= IFM_ETH_TXPAUSE;
-#else /* !SFXGE_HAVE_PAUSE_MEDIAOPTS */
- mode_cap_mask |= cap_mask & (1 << EFX_PHY_CAP_PAUSE);
+ ifmedia_add(&sc->media, mode_ifm, 0, NULL);
#endif
- ifmedia_add(&sc->media, mode_ifm, mode_cap_mask, NULL);
/* Link modes are numbered in order of speed,
* so assume the last one available is the best.
@@ -847,8 +930,7 @@
if (cap_mask & (1 << EFX_PHY_CAP_AN)) {
/* Add autoselect mode. */
mode_ifm = IFM_ETHER | IFM_AUTO;
- ifmedia_add(&sc->media, mode_ifm,
- cap_mask & ~(1 << EFX_PHY_CAP_ASYM), NULL);
+ ifmedia_add(&sc->media, mode_ifm, 0, NULL);
best_mode_ifm = mode_ifm;
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Apr 7, 11:03 AM (2 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31027293
Default Alt Text
D2540.id5426.diff (6 KB)
Attached To
Mode
D2540: sfxge: avoid usage of ifm_data
Attached
Detach File
Event Timeline
Log In to Comment