Author: np
Date: Thu May 31 02:10:50 2018
New Revision: 334409
URL: https://svnweb.freebsd.org/changeset/base/334409

Log:
  cxgbe(4): Implement ifm_change callback.
  
  Sponsored by: Chelsio Communications

Modified:
  head/sys/dev/cxgbe/t4_main.c

Modified: head/sys/dev/cxgbe/t4_main.c
==============================================================================
--- head/sys/dev/cxgbe/t4_main.c        Thu May 31 01:01:35 2018        
(r334408)
+++ head/sys/dev/cxgbe/t4_main.c        Thu May 31 02:10:50 2018        
(r334409)
@@ -529,6 +529,7 @@ static int set_params__post_init(struct adapter *);
 static void t4_set_desc(struct adapter *);
 static void build_medialist(struct port_info *, struct ifmedia *);
 static void init_l1cfg(struct port_info *);
+static int apply_l1cfg(struct port_info *);
 static int cxgbe_init_synchronized(struct vi_info *);
 static int cxgbe_uninit_synchronized(struct vi_info *);
 static void quiesce_txq(struct adapter *, struct sge_txq *);
@@ -2077,14 +2078,42 @@ cxgbe_get_counter(struct ifnet *ifp, ift_counter c)
        }
 }
 
+/*
+ * The kernel picks a media from the list we had provided so we do not have to
+ * validate the request.
+ */
 static int
 cxgbe_media_change(struct ifnet *ifp)
 {
        struct vi_info *vi = ifp->if_softc;
+       struct port_info *pi = vi->pi;
+       struct ifmedia *ifm = &pi->media;
+       struct link_config *lc = &pi->link_cfg;
+       struct adapter *sc = pi->adapter;
+       int rc;
 
-       device_printf(vi->dev, "%s unimplemented.\n", __func__);
-
-       return (EOPNOTSUPP);
+       rc = begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4mec");
+       if (rc != 0)
+               return (rc);
+       PORT_LOCK(pi);
+       if (IFM_SUBTYPE(ifm->ifm_media) == IFM_AUTO) {
+               MPASS(lc->supported & FW_PORT_CAP_ANEG);
+               lc->requested_aneg = AUTONEG_ENABLE;
+       } else {
+               lc->requested_aneg = AUTONEG_DISABLE;
+               lc->requested_speed =
+                   ifmedia_baudrate(ifm->ifm_media) / 1000000;
+               lc->requested_fc = 0;
+               if (IFM_OPTIONS(ifm->ifm_media) & IFM_ETH_RXPAUSE)
+                       lc->requested_fc |= PAUSE_RX;
+               if (IFM_OPTIONS(ifm->ifm_media) & IFM_ETH_TXPAUSE)
+                       lc->requested_fc |= PAUSE_TX;
+       }
+       if (pi->up_vis > 0)
+               rc = apply_l1cfg(pi);
+       PORT_UNLOCK(pi);
+       end_synchronized_op(sc, 0);
+       return (rc);
 }
 
 /*
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to