| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451 |
- From 38e50fc3d43882a43115b4f1ca3eb88255163c5b Mon Sep 17 00:00:00 2001
- From: Sean Anderson <[email protected]>
- Date: Mon, 17 Oct 2022 16:22:38 -0400
- Subject: [PATCH 03/21] net: dpaa: Convert to phylink
- This converts DPAA to phylink. All macs are converted. This should work
- with no device tree modifications (including those made in this series),
- except for QSGMII (as noted previously).
- The mEMAC configuration is one of the tricker areas. I have tried to
- capture all the restrictions across the various models. Most of the time,
- we assume that if the serdes supports a mode or the phy-interface-mode
- specifies it, then we support it. The only place we can't do this is
- (RG)MII, since there's no serdes. In that case, we rely on a (new)
- devicetree property. There are also several cases where half-duplex is
- broken. Unfortunately, only a single compatible is used for the MAC, so we
- have to use the board compatible instead.
- The 10GEC conversion is very straightforward, since it only supports XAUI.
- There is generally nothing to configure.
- The dTSEC conversion is broadly similar to mEMAC, but is simpler because we
- don't support configuring the SerDes (though this can be easily added) and
- we don't have multiple PCSs. From what I can tell, there's nothing
- different in the driver or documentation between SGMII and 1000BASE-X
- except for the advertising. Similarly, I couldn't find anything about
- 2500BASE-X. In both cases, I treat them like SGMII. These modes aren't used
- by any in-tree boards. Similarly, despite being mentioned in the driver, I
- couldn't find any documented SoCs which supported QSGMII. I have left it
- unimplemented for now.
- Signed-off-by: Sean Anderson <[email protected]>
- Signed-off-by: David S. Miller <[email protected]>
- ---
- drivers/net/ethernet/freescale/dpaa/Kconfig | 4 +-
- .../net/ethernet/freescale/dpaa/dpaa_eth.c | 89 +--
- .../ethernet/freescale/dpaa/dpaa_ethtool.c | 90 +--
- drivers/net/ethernet/freescale/fman/Kconfig | 1 -
- .../net/ethernet/freescale/fman/fman_dtsec.c | 458 +++++++--------
- .../net/ethernet/freescale/fman/fman_mac.h | 10 -
- .../net/ethernet/freescale/fman/fman_memac.c | 547 +++++++++---------
- .../net/ethernet/freescale/fman/fman_tgec.c | 131 ++---
- drivers/net/ethernet/freescale/fman/mac.c | 168 +-----
- drivers/net/ethernet/freescale/fman/mac.h | 23 +-
- 10 files changed, 612 insertions(+), 909 deletions(-)
- --- a/drivers/net/ethernet/freescale/dpaa/Kconfig
- +++ b/drivers/net/ethernet/freescale/dpaa/Kconfig
- @@ -2,8 +2,8 @@
- menuconfig FSL_DPAA_ETH
- tristate "DPAA Ethernet"
- depends on FSL_DPAA && FSL_FMAN
- - select PHYLIB
- - select FIXED_PHY
- + select PHYLINK
- + select PCS_LYNX
- help
- Data Path Acceleration Architecture Ethernet driver,
- supporting the Freescale QorIQ chips.
- --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
- +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
- @@ -264,8 +264,19 @@ static int dpaa_netdev_init(struct net_d
- net_dev->needed_headroom = priv->tx_headroom;
- net_dev->watchdog_timeo = msecs_to_jiffies(tx_timeout);
-
- - mac_dev->net_dev = net_dev;
- + /* The rest of the config is filled in by the mac device already */
- + mac_dev->phylink_config.dev = &net_dev->dev;
- + mac_dev->phylink_config.type = PHYLINK_NETDEV;
- mac_dev->update_speed = dpaa_eth_cgr_set_speed;
- + mac_dev->phylink = phylink_create(&mac_dev->phylink_config,
- + dev_fwnode(mac_dev->dev),
- + mac_dev->phy_if,
- + mac_dev->phylink_ops);
- + if (IS_ERR(mac_dev->phylink)) {
- + err = PTR_ERR(mac_dev->phylink);
- + dev_err_probe(dev, err, "Could not create phylink\n");
- + return err;
- + }
-
- /* start without the RUNNING flag, phylib controls it later */
- netif_carrier_off(net_dev);
- @@ -273,6 +284,7 @@ static int dpaa_netdev_init(struct net_d
- err = register_netdev(net_dev);
- if (err < 0) {
- dev_err(dev, "register_netdev() = %d\n", err);
- + phylink_destroy(mac_dev->phylink);
- return err;
- }
-
- @@ -295,8 +307,7 @@ static int dpaa_stop(struct net_device *
- */
- msleep(200);
-
- - if (mac_dev->phy_dev)
- - phy_stop(mac_dev->phy_dev);
- + phylink_stop(mac_dev->phylink);
- mac_dev->disable(mac_dev->fman_mac);
-
- for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) {
- @@ -305,8 +316,7 @@ static int dpaa_stop(struct net_device *
- err = error;
- }
-
- - if (net_dev->phydev)
- - phy_disconnect(net_dev->phydev);
- + phylink_disconnect_phy(mac_dev->phylink);
- net_dev->phydev = NULL;
-
- msleep(200);
- @@ -834,10 +844,10 @@ static int dpaa_eth_cgr_init(struct dpaa
-
- /* Set different thresholds based on the configured MAC speed.
- * This may turn suboptimal if the MAC is reconfigured at another
- - * speed, so MACs must call dpaa_eth_cgr_set_speed in their adjust_link
- + * speed, so MACs must call dpaa_eth_cgr_set_speed in their link_up
- * callback.
- */
- - if (priv->mac_dev->if_support & SUPPORTED_10000baseT_Full)
- + if (priv->mac_dev->phylink_config.mac_capabilities & MAC_10000FD)
- cs_th = DPAA_CS_THRESHOLD_10G;
- else
- cs_th = DPAA_CS_THRESHOLD_1G;
- @@ -866,7 +876,7 @@ out_error:
-
- static void dpaa_eth_cgr_set_speed(struct mac_device *mac_dev, int speed)
- {
- - struct net_device *net_dev = mac_dev->net_dev;
- + struct net_device *net_dev = to_net_dev(mac_dev->phylink_config.dev);
- struct dpaa_priv *priv = netdev_priv(net_dev);
- struct qm_mcc_initcgr opts = { };
- u32 cs_th;
- @@ -2905,58 +2915,6 @@ static void dpaa_eth_napi_disable(struct
- }
- }
-
- -static void dpaa_adjust_link(struct net_device *net_dev)
- -{
- - struct mac_device *mac_dev;
- - struct dpaa_priv *priv;
- -
- - priv = netdev_priv(net_dev);
- - mac_dev = priv->mac_dev;
- - mac_dev->adjust_link(mac_dev);
- -}
- -
- -/* The Aquantia PHYs are capable of performing rate adaptation */
- -#define PHY_VEND_AQUANTIA 0x03a1b400
- -#define PHY_VEND_AQUANTIA2 0x31c31c00
- -
- -static int dpaa_phy_init(struct net_device *net_dev)
- -{
- - __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
- - struct mac_device *mac_dev;
- - struct phy_device *phy_dev;
- - struct dpaa_priv *priv;
- - u32 phy_vendor;
- -
- - priv = netdev_priv(net_dev);
- - mac_dev = priv->mac_dev;
- -
- - phy_dev = of_phy_connect(net_dev, mac_dev->phy_node,
- - &dpaa_adjust_link, 0,
- - mac_dev->phy_if);
- - if (!phy_dev) {
- - netif_err(priv, ifup, net_dev, "init_phy() failed\n");
- - return -ENODEV;
- - }
- -
- - phy_vendor = phy_dev->drv->phy_id & GENMASK(31, 10);
- - /* Unless the PHY is capable of rate adaptation */
- - if (mac_dev->phy_if != PHY_INTERFACE_MODE_XGMII ||
- - (phy_vendor != PHY_VEND_AQUANTIA &&
- - phy_vendor != PHY_VEND_AQUANTIA2)) {
- - /* remove any features not supported by the controller */
- - ethtool_convert_legacy_u32_to_link_mode(mask,
- - mac_dev->if_support);
- - linkmode_and(phy_dev->supported, phy_dev->supported, mask);
- - }
- -
- - phy_support_asym_pause(phy_dev);
- -
- - mac_dev->phy_dev = phy_dev;
- - net_dev->phydev = phy_dev;
- -
- - return 0;
- -}
- -
- static int dpaa_open(struct net_device *net_dev)
- {
- struct mac_device *mac_dev;
- @@ -2967,7 +2925,8 @@ static int dpaa_open(struct net_device *
- mac_dev = priv->mac_dev;
- dpaa_eth_napi_enable(priv);
-
- - err = dpaa_phy_init(net_dev);
- + err = phylink_of_phy_connect(mac_dev->phylink,
- + mac_dev->dev->of_node, 0);
- if (err)
- goto phy_init_failed;
-
- @@ -2982,7 +2941,7 @@ static int dpaa_open(struct net_device *
- netif_err(priv, ifup, net_dev, "mac_dev->enable() = %d\n", err);
- goto mac_start_failed;
- }
- - phy_start(priv->mac_dev->phy_dev);
- + phylink_start(mac_dev->phylink);
-
- netif_tx_start_all_queues(net_dev);
-
- @@ -2991,6 +2950,7 @@ static int dpaa_open(struct net_device *
- mac_start_failed:
- for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++)
- fman_port_disable(mac_dev->port[i]);
- + phylink_disconnect_phy(mac_dev->phylink);
-
- phy_init_failed:
- dpaa_eth_napi_disable(priv);
- @@ -3146,10 +3106,12 @@ static int dpaa_ts_ioctl(struct net_devi
- static int dpaa_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd)
- {
- int ret = -EINVAL;
- + struct dpaa_priv *priv = netdev_priv(net_dev);
-
- if (cmd == SIOCGMIIREG) {
- if (net_dev->phydev)
- - return phy_mii_ioctl(net_dev->phydev, rq, cmd);
- + return phylink_mii_ioctl(priv->mac_dev->phylink, rq,
- + cmd);
- }
-
- if (cmd == SIOCSHWTSTAMP)
- @@ -3552,6 +3514,7 @@ static int dpaa_remove(struct platform_d
-
- dev_set_drvdata(dev, NULL);
- unregister_netdev(net_dev);
- + phylink_destroy(priv->mac_dev->phylink);
-
- err = dpaa_fq_free(dev, &priv->dpaa_fq_list);
-
- --- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
- +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
- @@ -54,27 +54,19 @@ static char dpaa_stats_global[][ETH_GSTR
- static int dpaa_get_link_ksettings(struct net_device *net_dev,
- struct ethtool_link_ksettings *cmd)
- {
- - if (!net_dev->phydev)
- - return 0;
- + struct dpaa_priv *priv = netdev_priv(net_dev);
- + struct mac_device *mac_dev = priv->mac_dev;
-
- - phy_ethtool_ksettings_get(net_dev->phydev, cmd);
- -
- - return 0;
- + return phylink_ethtool_ksettings_get(mac_dev->phylink, cmd);
- }
-
- static int dpaa_set_link_ksettings(struct net_device *net_dev,
- const struct ethtool_link_ksettings *cmd)
- {
- - int err;
- -
- - if (!net_dev->phydev)
- - return -ENODEV;
- + struct dpaa_priv *priv = netdev_priv(net_dev);
- + struct mac_device *mac_dev = priv->mac_dev;
-
- - err = phy_ethtool_ksettings_set(net_dev->phydev, cmd);
- - if (err < 0)
- - netdev_err(net_dev, "phy_ethtool_ksettings_set() = %d\n", err);
- -
- - return err;
- + return phylink_ethtool_ksettings_set(mac_dev->phylink, cmd);
- }
-
- static void dpaa_get_drvinfo(struct net_device *net_dev,
- @@ -99,80 +91,28 @@ static void dpaa_set_msglevel(struct net
-
- static int dpaa_nway_reset(struct net_device *net_dev)
- {
- - int err;
- -
- - if (!net_dev->phydev)
- - return -ENODEV;
- + struct dpaa_priv *priv = netdev_priv(net_dev);
- + struct mac_device *mac_dev = priv->mac_dev;
-
- - err = 0;
- - if (net_dev->phydev->autoneg) {
- - err = phy_start_aneg(net_dev->phydev);
- - if (err < 0)
- - netdev_err(net_dev, "phy_start_aneg() = %d\n",
- - err);
- - }
- -
- - return err;
- + return phylink_ethtool_nway_reset(mac_dev->phylink);
- }
-
- static void dpaa_get_pauseparam(struct net_device *net_dev,
- struct ethtool_pauseparam *epause)
- {
- - struct mac_device *mac_dev;
- - struct dpaa_priv *priv;
- -
- - priv = netdev_priv(net_dev);
- - mac_dev = priv->mac_dev;
- -
- - if (!net_dev->phydev)
- - return;
- + struct dpaa_priv *priv = netdev_priv(net_dev);
- + struct mac_device *mac_dev = priv->mac_dev;
-
- - epause->autoneg = mac_dev->autoneg_pause;
- - epause->rx_pause = mac_dev->rx_pause_active;
- - epause->tx_pause = mac_dev->tx_pause_active;
- + phylink_ethtool_get_pauseparam(mac_dev->phylink, epause);
- }
-
- static int dpaa_set_pauseparam(struct net_device *net_dev,
- struct ethtool_pauseparam *epause)
- {
- - struct mac_device *mac_dev;
- - struct phy_device *phydev;
- - bool rx_pause, tx_pause;
- - struct dpaa_priv *priv;
- - int err;
- -
- - priv = netdev_priv(net_dev);
- - mac_dev = priv->mac_dev;
- -
- - phydev = net_dev->phydev;
- - if (!phydev) {
- - netdev_err(net_dev, "phy device not initialized\n");
- - return -ENODEV;
- - }
- -
- - if (!phy_validate_pause(phydev, epause))
- - return -EINVAL;
- -
- - /* The MAC should know how to handle PAUSE frame autonegotiation before
- - * adjust_link is triggered by a forced renegotiation of sym/asym PAUSE
- - * settings.
- - */
- - mac_dev->autoneg_pause = !!epause->autoneg;
- - mac_dev->rx_pause_req = !!epause->rx_pause;
- - mac_dev->tx_pause_req = !!epause->tx_pause;
- -
- - /* Determine the sym/asym advertised PAUSE capabilities from the desired
- - * rx/tx pause settings.
- - */
- -
- - phy_set_asym_pause(phydev, epause->rx_pause, epause->tx_pause);
- -
- - fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
- - err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
- - if (err < 0)
- - netdev_err(net_dev, "set_mac_active_pause() = %d\n", err);
- + struct dpaa_priv *priv = netdev_priv(net_dev);
- + struct mac_device *mac_dev = priv->mac_dev;
-
- - return err;
- + return phylink_ethtool_set_pauseparam(mac_dev->phylink, epause);
- }
-
- static int dpaa_get_sset_count(struct net_device *net_dev, int type)
- --- a/drivers/net/ethernet/freescale/fman/Kconfig
- +++ b/drivers/net/ethernet/freescale/fman/Kconfig
- @@ -3,7 +3,6 @@ config FSL_FMAN
- tristate "FMan support"
- depends on FSL_SOC || ARCH_LAYERSCAPE || COMPILE_TEST
- select GENERIC_ALLOCATOR
- - select PHYLIB
- select PHYLINK
- select PCS
- select PCS_LYNX
- --- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c
- +++ b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
- @@ -17,6 +17,7 @@
- #include <linux/crc32.h>
- #include <linux/of_mdio.h>
- #include <linux/mii.h>
- +#include <linux/netdevice.h>
-
- /* TBI register addresses */
- #define MII_TBICON 0x11
- @@ -29,9 +30,6 @@
- #define TBICON_CLK_SELECT 0x0020 /* Clock select */
- #define TBICON_MI_MODE 0x0010 /* GMII mode (TBI if not set) */
-
- -#define TBIANA_SGMII 0x4001
- -#define TBIANA_1000X 0x01a0
- -
- /* Interrupt Mask Register (IMASK) */
- #define DTSEC_IMASK_BREN 0x80000000
- #define DTSEC_IMASK_RXCEN 0x40000000
- @@ -92,9 +90,10 @@
-
- #define DTSEC_ECNTRL_GMIIM 0x00000040
- #define DTSEC_ECNTRL_TBIM 0x00000020
- -#define DTSEC_ECNTRL_SGMIIM 0x00000002
- #define DTSEC_ECNTRL_RPM 0x00000010
- #define DTSEC_ECNTRL_R100M 0x00000008
- +#define DTSEC_ECNTRL_RMM 0x00000004
- +#define DTSEC_ECNTRL_SGMIIM 0x00000002
- #define DTSEC_ECNTRL_QSGMIIM 0x00000001
-
- #define TCTRL_TTSE 0x00000040
- @@ -318,7 +317,8 @@ struct fman_mac {
- void *fm;
- struct fman_rev_info fm_rev_info;
- bool basex_if;
- - struct phy_device *tbiphy;
- + struct mdio_device *tbidev;
- + struct phylink_pcs pcs;
- };
-
- static void set_dflts(struct dtsec_cfg *cfg)
- @@ -356,56 +356,14 @@ static int init(struct dtsec_regs __iome
- phy_interface_t iface, u16 iface_speed, u64 addr,
- u32 exception_mask, u8 tbi_addr)
- {
- - bool is_rgmii, is_sgmii, is_qsgmii;
- enet_addr_t eth_addr;
- - u32 tmp;
- + u32 tmp = 0;
- int i;
-
- /* Soft reset */
- iowrite32be(MACCFG1_SOFT_RESET, ®s->maccfg1);
- iowrite32be(0, ®s->maccfg1);
-
- - /* dtsec_id2 */
- - tmp = ioread32be(®s->tsec_id2);
- -
- - /* check RGMII support */
- - if (iface == PHY_INTERFACE_MODE_RGMII ||
- - iface == PHY_INTERFACE_MODE_RGMII_ID ||
- - iface == PHY_INTERFACE_MODE_RGMII_RXID ||
- - iface == PHY_INTERFACE_MODE_RGMII_TXID ||
- - iface == PHY_INTERFACE_MODE_RMII)
- - if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
- - return -EINVAL;
- -
- - if (iface == PHY_INTERFACE_MODE_SGMII ||
- - iface == PHY_INTERFACE_MODE_MII)
- - if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
- - return -EINVAL;
- -
- - is_rgmii = iface == PHY_INTERFACE_MODE_RGMII ||
- - iface == PHY_INTERFACE_MODE_RGMII_ID ||
- - iface == PHY_INTERFACE_MODE_RGMII_RXID ||
- - iface == PHY_INTERFACE_MODE_RGMII_TXID;
- - is_sgmii = iface == PHY_INTERFACE_MODE_SGMII;
- - is_qsgmii = iface == PHY_INTERFACE_MODE_QSGMII;
- -
- - tmp = 0;
- - if (is_rgmii || iface == PHY_INTERFACE_MODE_GMII)
- - tmp |= DTSEC_ECNTRL_GMIIM;
- - if (is_sgmii)
- - tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM);
- - if (is_qsgmii)
- - tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM |
- - DTSEC_ECNTRL_QSGMIIM);
- - if (is_rgmii)
- - tmp |= DTSEC_ECNTRL_RPM;
- - if (iface_speed == SPEED_100)
- - tmp |= DTSEC_ECNTRL_R100M;
- -
- - iowrite32be(tmp, ®s->ecntrl);
- -
- - tmp = 0;
- -
- if (cfg->tx_pause_time)
- tmp |= cfg->tx_pause_time;
- if (cfg->tx_pause_time_extd)
- @@ -446,17 +404,10 @@ static int init(struct dtsec_regs __iome
-
- tmp = 0;
-
- - if (iface_speed < SPEED_1000)
- - tmp |= MACCFG2_NIBBLE_MODE;
- - else if (iface_speed == SPEED_1000)
- - tmp |= MACCFG2_BYTE_MODE;
- -
- tmp |= (cfg->preamble_len << MACCFG2_PREAMBLE_LENGTH_SHIFT) &
- MACCFG2_PREAMBLE_LENGTH_MASK;
- if (cfg->tx_pad_crc)
- tmp |= MACCFG2_PAD_CRC_EN;
- - /* Full Duplex */
- - tmp |= MACCFG2_FULL_DUPLEX;
- iowrite32be(tmp, ®s->maccfg2);
-
- tmp = (((cfg->non_back_to_back_ipg1 <<
- @@ -525,10 +476,6 @@ static void set_bucket(struct dtsec_regs
-
- static int check_init_parameters(struct fman_mac *dtsec)
- {
- - if (dtsec->max_speed >= SPEED_10000) {
- - pr_err("1G MAC driver supports 1G or lower speeds\n");
- - return -EINVAL;
- - }
- if ((dtsec->dtsec_drv_param)->rx_prepend >
- MAX_PACKET_ALIGNMENT) {
- pr_err("packetAlignmentPadding can't be > than %d\n",
- @@ -630,22 +577,10 @@ static int get_exception_flag(enum fman_
- return bit_mask;
- }
-
- -static bool is_init_done(struct dtsec_cfg *dtsec_drv_params)
- -{
- - /* Checks if dTSEC driver parameters were initialized */
- - if (!dtsec_drv_params)
- - return true;
- -
- - return false;
- -}
- -
- static u16 dtsec_get_max_frame_length(struct fman_mac *dtsec)
- {
- struct dtsec_regs __iomem *regs = dtsec->regs;
-
- - if (is_init_done(dtsec->dtsec_drv_param))
- - return 0;
- -
- return (u16)ioread32be(®s->maxfrm);
- }
-
- @@ -682,6 +617,7 @@ static void dtsec_isr(void *handle)
- dtsec->exception_cb(dtsec->dev_id, FM_MAC_EX_1G_COL_RET_LMT);
- if (event & DTSEC_IMASK_XFUNEN) {
- /* FM_TX_LOCKUP_ERRATA_DTSEC6 Errata workaround */
- + /* FIXME: This races with the rest of the driver! */
- if (dtsec->fm_rev_info.major == 2) {
- u32 tpkt1, tmp_reg1, tpkt2, tmp_reg2, i;
- /* a. Write 0x00E0_0C00 to DTSEC_ID
- @@ -814,6 +750,43 @@ static void free_init_resources(struct f
- dtsec->unicast_addr_hash = NULL;
- }
-
- +static struct fman_mac *pcs_to_dtsec(struct phylink_pcs *pcs)
- +{
- + return container_of(pcs, struct fman_mac, pcs);
- +}
- +
- +static void dtsec_pcs_get_state(struct phylink_pcs *pcs,
- + struct phylink_link_state *state)
- +{
- + struct fman_mac *dtsec = pcs_to_dtsec(pcs);
- +
- + phylink_mii_c22_pcs_get_state(dtsec->tbidev, state);
- +}
- +
- +static int dtsec_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
- + phy_interface_t interface,
- + const unsigned long *advertising,
- + bool permit_pause_to_mac)
- +{
- + struct fman_mac *dtsec = pcs_to_dtsec(pcs);
- +
- + return phylink_mii_c22_pcs_config(dtsec->tbidev, mode, interface,
- + advertising);
- +}
- +
- +static void dtsec_pcs_an_restart(struct phylink_pcs *pcs)
- +{
- + struct fman_mac *dtsec = pcs_to_dtsec(pcs);
- +
- + phylink_mii_c22_pcs_an_restart(dtsec->tbidev);
- +}
- +
- +static const struct phylink_pcs_ops dtsec_pcs_ops = {
- + .pcs_get_state = dtsec_pcs_get_state,
- + .pcs_config = dtsec_pcs_config,
- + .pcs_an_restart = dtsec_pcs_an_restart,
- +};
- +
- static void graceful_start(struct fman_mac *dtsec)
- {
- struct dtsec_regs __iomem *regs = dtsec->regs;
- @@ -854,36 +827,11 @@ static void graceful_stop(struct fman_ma
-
- static int dtsec_enable(struct fman_mac *dtsec)
- {
- - struct dtsec_regs __iomem *regs = dtsec->regs;
- - u32 tmp;
- -
- - if (!is_init_done(dtsec->dtsec_drv_param))
- - return -EINVAL;
- -
- - /* Enable */
- - tmp = ioread32be(®s->maccfg1);
- - tmp |= MACCFG1_RX_EN | MACCFG1_TX_EN;
- - iowrite32be(tmp, ®s->maccfg1);
- -
- - /* Graceful start - clear the graceful Rx/Tx stop bit */
- - graceful_start(dtsec);
- -
- return 0;
- }
-
- static void dtsec_disable(struct fman_mac *dtsec)
- {
- - struct dtsec_regs __iomem *regs = dtsec->regs;
- - u32 tmp;
- -
- - WARN_ON_ONCE(!is_init_done(dtsec->dtsec_drv_param));
- -
- - /* Graceful stop - Assert the graceful Rx/Tx stop bit */
- - graceful_stop(dtsec);
- -
- - tmp = ioread32be(®s->maccfg1);
- - tmp &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN);
- - iowrite32be(tmp, ®s->maccfg1);
- }
-
- static int dtsec_set_tx_pause_frames(struct fman_mac *dtsec,
- @@ -894,11 +842,6 @@ static int dtsec_set_tx_pause_frames(str
- struct dtsec_regs __iomem *regs = dtsec->regs;
- u32 ptv = 0;
-
- - if (!is_init_done(dtsec->dtsec_drv_param))
- - return -EINVAL;
- -
- - graceful_stop(dtsec);
- -
- if (pause_time) {
- /* FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003 Errata workaround */
- if (dtsec->fm_rev_info.major == 2 && pause_time <= 320) {
- @@ -919,8 +862,6 @@ static int dtsec_set_tx_pause_frames(str
- iowrite32be(ioread32be(®s->maccfg1) & ~MACCFG1_TX_FLOW,
- ®s->maccfg1);
-
- - graceful_start(dtsec);
- -
- return 0;
- }
-
- @@ -929,11 +870,6 @@ static int dtsec_accept_rx_pause_frames(
- struct dtsec_regs __iomem *regs = dtsec->regs;
- u32 tmp;
-
- - if (!is_init_done(dtsec->dtsec_drv_param))
- - return -EINVAL;
- -
- - graceful_stop(dtsec);
- -
- tmp = ioread32be(®s->maccfg1);
- if (en)
- tmp |= MACCFG1_RX_FLOW;
- @@ -941,17 +877,125 @@ static int dtsec_accept_rx_pause_frames(
- tmp &= ~MACCFG1_RX_FLOW;
- iowrite32be(tmp, ®s->maccfg1);
-
- + return 0;
- +}
- +
- +static struct phylink_pcs *dtsec_select_pcs(struct phylink_config *config,
- + phy_interface_t iface)
- +{
- + struct fman_mac *dtsec = fman_config_to_mac(config)->fman_mac;
- +
- + switch (iface) {
- + case PHY_INTERFACE_MODE_SGMII:
- + case PHY_INTERFACE_MODE_1000BASEX:
- + case PHY_INTERFACE_MODE_2500BASEX:
- + return &dtsec->pcs;
- + default:
- + return NULL;
- + }
- +}
- +
- +static void dtsec_mac_config(struct phylink_config *config, unsigned int mode,
- + const struct phylink_link_state *state)
- +{
- + struct mac_device *mac_dev = fman_config_to_mac(config);
- + struct dtsec_regs __iomem *regs = mac_dev->fman_mac->regs;
- + u32 tmp;
- +
- + switch (state->interface) {
- + case PHY_INTERFACE_MODE_RMII:
- + tmp = DTSEC_ECNTRL_RMM;
- + break;
- + case PHY_INTERFACE_MODE_RGMII:
- + case PHY_INTERFACE_MODE_RGMII_ID:
- + case PHY_INTERFACE_MODE_RGMII_RXID:
- + case PHY_INTERFACE_MODE_RGMII_TXID:
- + tmp = DTSEC_ECNTRL_GMIIM | DTSEC_ECNTRL_RPM;
- + break;
- + case PHY_INTERFACE_MODE_SGMII:
- + case PHY_INTERFACE_MODE_1000BASEX:
- + case PHY_INTERFACE_MODE_2500BASEX:
- + tmp = DTSEC_ECNTRL_TBIM | DTSEC_ECNTRL_SGMIIM;
- + break;
- + default:
- + dev_warn(mac_dev->dev, "cannot configure dTSEC for %s\n",
- + phy_modes(state->interface));
- + return;
- + }
- +
- + iowrite32be(tmp, ®s->ecntrl);
- +}
- +
- +static void dtsec_link_up(struct phylink_config *config, struct phy_device *phy,
- + unsigned int mode, phy_interface_t interface,
- + int speed, int duplex, bool tx_pause, bool rx_pause)
- +{
- + struct mac_device *mac_dev = fman_config_to_mac(config);
- + struct fman_mac *dtsec = mac_dev->fman_mac;
- + struct dtsec_regs __iomem *regs = dtsec->regs;
- + u16 pause_time = tx_pause ? FSL_FM_PAUSE_TIME_ENABLE :
- + FSL_FM_PAUSE_TIME_DISABLE;
- + u32 tmp;
- +
- + dtsec_set_tx_pause_frames(dtsec, 0, pause_time, 0);
- + dtsec_accept_rx_pause_frames(dtsec, rx_pause);
- +
- + tmp = ioread32be(®s->ecntrl);
- + if (speed == SPEED_100)
- + tmp |= DTSEC_ECNTRL_R100M;
- + else
- + tmp &= ~DTSEC_ECNTRL_R100M;
- + iowrite32be(tmp, ®s->ecntrl);
- +
- + tmp = ioread32be(®s->maccfg2);
- + tmp &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE | MACCFG2_FULL_DUPLEX);
- + if (speed >= SPEED_1000)
- + tmp |= MACCFG2_BYTE_MODE;
- + else
- + tmp |= MACCFG2_NIBBLE_MODE;
- +
- + if (duplex == DUPLEX_FULL)
- + tmp |= MACCFG2_FULL_DUPLEX;
- +
- + iowrite32be(tmp, ®s->maccfg2);
- +
- + mac_dev->update_speed(mac_dev, speed);
- +
- + /* Enable */
- + tmp = ioread32be(®s->maccfg1);
- + tmp |= MACCFG1_RX_EN | MACCFG1_TX_EN;
- + iowrite32be(tmp, ®s->maccfg1);
- +
- + /* Graceful start - clear the graceful Rx/Tx stop bit */
- graceful_start(dtsec);
- +}
-
- - return 0;
- +static void dtsec_link_down(struct phylink_config *config, unsigned int mode,
- + phy_interface_t interface)
- +{
- + struct fman_mac *dtsec = fman_config_to_mac(config)->fman_mac;
- + struct dtsec_regs __iomem *regs = dtsec->regs;
- + u32 tmp;
- +
- + /* Graceful stop - Assert the graceful Rx/Tx stop bit */
- + graceful_stop(dtsec);
- +
- + tmp = ioread32be(®s->maccfg1);
- + tmp &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN);
- + iowrite32be(tmp, ®s->maccfg1);
- }
-
- +static const struct phylink_mac_ops dtsec_mac_ops = {
- + .validate = phylink_generic_validate,
- + .mac_select_pcs = dtsec_select_pcs,
- + .mac_config = dtsec_mac_config,
- + .mac_link_up = dtsec_link_up,
- + .mac_link_down = dtsec_link_down,
- +};
- +
- static int dtsec_modify_mac_address(struct fman_mac *dtsec,
- const enet_addr_t *enet_addr)
- {
- - if (!is_init_done(dtsec->dtsec_drv_param))
- - return -EINVAL;
- -
- graceful_stop(dtsec);
-
- /* Initialize MAC Station Address registers (1 & 2)
- @@ -975,9 +1019,6 @@ static int dtsec_add_hash_mac_address(st
- u32 crc = 0xFFFFFFFF;
- bool mcast, ghtx;
-
- - if (!is_init_done(dtsec->dtsec_drv_param))
- - return -EINVAL;
- -
- addr = ENET_ADDR_TO_UINT64(*eth_addr);
-
- ghtx = (bool)((ioread32be(®s->rctrl) & RCTRL_GHTX) ? true : false);
- @@ -1037,9 +1078,6 @@ static int dtsec_set_allmulti(struct fma
- u32 tmp;
- struct dtsec_regs __iomem *regs = dtsec->regs;
-
- - if (!is_init_done(dtsec->dtsec_drv_param))
- - return -EINVAL;
- -
- tmp = ioread32be(®s->rctrl);
- if (enable)
- tmp |= RCTRL_MPROM;
- @@ -1056,9 +1094,6 @@ static int dtsec_set_tstamp(struct fman_
- struct dtsec_regs __iomem *regs = dtsec->regs;
- u32 rctrl, tctrl;
-
- - if (!is_init_done(dtsec->dtsec_drv_param))
- - return -EINVAL;
- -
- rctrl = ioread32be(®s->rctrl);
- tctrl = ioread32be(®s->tctrl);
-
- @@ -1087,9 +1122,6 @@ static int dtsec_del_hash_mac_address(st
- u32 crc = 0xFFFFFFFF;
- bool mcast, ghtx;
-
- - if (!is_init_done(dtsec->dtsec_drv_param))
- - return -EINVAL;
- -
- addr = ENET_ADDR_TO_UINT64(*eth_addr);
-
- ghtx = (bool)((ioread32be(®s->rctrl) & RCTRL_GHTX) ? true : false);
- @@ -1153,9 +1185,6 @@ static int dtsec_set_promiscuous(struct
- struct dtsec_regs __iomem *regs = dtsec->regs;
- u32 tmp;
-
- - if (!is_init_done(dtsec->dtsec_drv_param))
- - return -EINVAL;
- -
- /* Set unicast promiscuous */
- tmp = ioread32be(®s->rctrl);
- if (new_val)
- @@ -1177,90 +1206,12 @@ static int dtsec_set_promiscuous(struct
- return 0;
- }
-
- -static int dtsec_adjust_link(struct fman_mac *dtsec, u16 speed)
- -{
- - struct dtsec_regs __iomem *regs = dtsec->regs;
- - u32 tmp;
- -
- - if (!is_init_done(dtsec->dtsec_drv_param))
- - return -EINVAL;
- -
- - graceful_stop(dtsec);
- -
- - tmp = ioread32be(®s->maccfg2);
- -
- - /* Full Duplex */
- - tmp |= MACCFG2_FULL_DUPLEX;
- -
- - tmp &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE);
- - if (speed < SPEED_1000)
- - tmp |= MACCFG2_NIBBLE_MODE;
- - else if (speed == SPEED_1000)
- - tmp |= MACCFG2_BYTE_MODE;
- - iowrite32be(tmp, ®s->maccfg2);
- -
- - tmp = ioread32be(®s->ecntrl);
- - if (speed == SPEED_100)
- - tmp |= DTSEC_ECNTRL_R100M;
- - else
- - tmp &= ~DTSEC_ECNTRL_R100M;
- - iowrite32be(tmp, ®s->ecntrl);
- -
- - graceful_start(dtsec);
- -
- - return 0;
- -}
- -
- -static int dtsec_restart_autoneg(struct fman_mac *dtsec)
- -{
- - u16 tmp_reg16;
- -
- - if (!is_init_done(dtsec->dtsec_drv_param))
- - return -EINVAL;
- -
- - tmp_reg16 = phy_read(dtsec->tbiphy, MII_BMCR);
- -
- - tmp_reg16 &= ~(BMCR_SPEED100 | BMCR_SPEED1000);
- - tmp_reg16 |= (BMCR_ANENABLE | BMCR_ANRESTART |
- - BMCR_FULLDPLX | BMCR_SPEED1000);
- -
- - phy_write(dtsec->tbiphy, MII_BMCR, tmp_reg16);
- -
- - return 0;
- -}
- -
- -static void adjust_link_dtsec(struct mac_device *mac_dev)
- -{
- - struct phy_device *phy_dev = mac_dev->phy_dev;
- - struct fman_mac *fman_mac;
- - bool rx_pause, tx_pause;
- - int err;
- -
- - fman_mac = mac_dev->fman_mac;
- - if (!phy_dev->link) {
- - dtsec_restart_autoneg(fman_mac);
- -
- - return;
- - }
- -
- - dtsec_adjust_link(fman_mac, phy_dev->speed);
- - mac_dev->update_speed(mac_dev, phy_dev->speed);
- - fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
- - err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
- - if (err < 0)
- - dev_err(mac_dev->dev, "fman_set_mac_active_pause() = %d\n",
- - err);
- -}
- -
- static int dtsec_set_exception(struct fman_mac *dtsec,
- enum fman_mac_exceptions exception, bool enable)
- {
- struct dtsec_regs __iomem *regs = dtsec->regs;
- u32 bit_mask = 0;
-
- - if (!is_init_done(dtsec->dtsec_drv_param))
- - return -EINVAL;
- -
- if (exception != FM_MAC_EX_1G_1588_TS_RX_ERR) {
- bit_mask = get_exception_flag(exception);
- if (bit_mask) {
- @@ -1310,12 +1261,9 @@ static int dtsec_init(struct fman_mac *d
- {
- struct dtsec_regs __iomem *regs = dtsec->regs;
- struct dtsec_cfg *dtsec_drv_param;
- - u16 max_frm_ln;
- + u16 max_frm_ln, tbicon;
- int err;
-
- - if (is_init_done(dtsec->dtsec_drv_param))
- - return -EINVAL;
- -
- if (DEFAULT_RESET_ON_INIT &&
- (fman_reset_mac(dtsec->fm, dtsec->mac_id) != 0)) {
- pr_err("Can't reset MAC!\n");
- @@ -1330,38 +1278,19 @@ static int dtsec_init(struct fman_mac *d
-
- err = init(dtsec->regs, dtsec_drv_param, dtsec->phy_if,
- dtsec->max_speed, dtsec->addr, dtsec->exceptions,
- - dtsec->tbiphy->mdio.addr);
- + dtsec->tbidev->addr);
- if (err) {
- free_init_resources(dtsec);
- pr_err("DTSEC version doesn't support this i/f mode\n");
- return err;
- }
-
- - if (dtsec->phy_if == PHY_INTERFACE_MODE_SGMII) {
- - u16 tmp_reg16;
- -
- - /* Configure the TBI PHY Control Register */
- - tmp_reg16 = TBICON_CLK_SELECT | TBICON_SOFT_RESET;
- - phy_write(dtsec->tbiphy, MII_TBICON, tmp_reg16);
- -
- - tmp_reg16 = TBICON_CLK_SELECT;
- - phy_write(dtsec->tbiphy, MII_TBICON, tmp_reg16);
- -
- - tmp_reg16 = (BMCR_RESET | BMCR_ANENABLE |
- - BMCR_FULLDPLX | BMCR_SPEED1000);
- - phy_write(dtsec->tbiphy, MII_BMCR, tmp_reg16);
- -
- - if (dtsec->basex_if)
- - tmp_reg16 = TBIANA_1000X;
- - else
- - tmp_reg16 = TBIANA_SGMII;
- - phy_write(dtsec->tbiphy, MII_ADVERTISE, tmp_reg16);
- + /* Configure the TBI PHY Control Register */
- + tbicon = TBICON_CLK_SELECT | TBICON_SOFT_RESET;
- + mdiodev_write(dtsec->tbidev, MII_TBICON, tbicon);
-
- - tmp_reg16 = (BMCR_ANENABLE | BMCR_ANRESTART |
- - BMCR_FULLDPLX | BMCR_SPEED1000);
- -
- - phy_write(dtsec->tbiphy, MII_BMCR, tmp_reg16);
- - }
- + tbicon = TBICON_CLK_SELECT;
- + mdiodev_write(dtsec->tbidev, MII_TBICON, tbicon);
-
- /* Max Frame Length */
- max_frm_ln = (u16)ioread32be(®s->maxfrm);
- @@ -1406,6 +1335,8 @@ static int dtsec_free(struct fman_mac *d
-
- kfree(dtsec->dtsec_drv_param);
- dtsec->dtsec_drv_param = NULL;
- + if (!IS_ERR_OR_NULL(dtsec->tbidev))
- + put_device(&dtsec->tbidev->dev);
- kfree(dtsec);
-
- return 0;
- @@ -1434,7 +1365,6 @@ static struct fman_mac *dtsec_config(str
-
- dtsec->regs = mac_dev->vaddr;
- dtsec->addr = ENET_ADDR_TO_UINT64(mac_dev->addr);
- - dtsec->max_speed = params->max_speed;
- dtsec->phy_if = mac_dev->phy_if;
- dtsec->mac_id = params->mac_id;
- dtsec->exceptions = (DTSEC_IMASK_BREN |
- @@ -1457,7 +1387,6 @@ static struct fman_mac *dtsec_config(str
- dtsec->en_tsu_err_exception = dtsec->dtsec_drv_param->ptp_exception_en;
-
- dtsec->fm = params->fm;
- - dtsec->basex_if = params->basex_if;
-
- /* Save FMan revision */
- fman_get_revision(dtsec->fm, &dtsec->fm_rev_info);
- @@ -1476,18 +1405,18 @@ int dtsec_initialization(struct mac_devi
- int err;
- struct fman_mac *dtsec;
- struct device_node *phy_node;
- + unsigned long capabilities;
- + unsigned long *supported;
-
- + mac_dev->phylink_ops = &dtsec_mac_ops;
- mac_dev->set_promisc = dtsec_set_promiscuous;
- mac_dev->change_addr = dtsec_modify_mac_address;
- mac_dev->add_hash_mac_addr = dtsec_add_hash_mac_address;
- mac_dev->remove_hash_mac_addr = dtsec_del_hash_mac_address;
- - mac_dev->set_tx_pause = dtsec_set_tx_pause_frames;
- - mac_dev->set_rx_pause = dtsec_accept_rx_pause_frames;
- mac_dev->set_exception = dtsec_set_exception;
- mac_dev->set_allmulti = dtsec_set_allmulti;
- mac_dev->set_tstamp = dtsec_set_tstamp;
- mac_dev->set_multi = fman_set_multi;
- - mac_dev->adjust_link = adjust_link_dtsec;
- mac_dev->enable = dtsec_enable;
- mac_dev->disable = dtsec_disable;
-
- @@ -1502,19 +1431,56 @@ int dtsec_initialization(struct mac_devi
- dtsec->dtsec_drv_param->tx_pad_crc = true;
-
- phy_node = of_parse_phandle(mac_node, "tbi-handle", 0);
- - if (!phy_node) {
- - pr_err("TBI PHY node is not available\n");
- + if (!phy_node || of_device_is_available(phy_node)) {
- + of_node_put(phy_node);
- err = -EINVAL;
- + dev_err_probe(mac_dev->dev, err,
- + "TBI PCS node is not available\n");
- goto _return_fm_mac_free;
- }
-
- - dtsec->tbiphy = of_phy_find_device(phy_node);
- - if (!dtsec->tbiphy) {
- - pr_err("of_phy_find_device (TBI PHY) failed\n");
- - err = -EINVAL;
- + dtsec->tbidev = of_mdio_find_device(phy_node);
- + of_node_put(phy_node);
- + if (!dtsec->tbidev) {
- + err = -EPROBE_DEFER;
- + dev_err_probe(mac_dev->dev, err,
- + "could not find mdiodev for PCS\n");
- goto _return_fm_mac_free;
- }
- - put_device(&dtsec->tbiphy->mdio.dev);
- + dtsec->pcs.ops = &dtsec_pcs_ops;
- + dtsec->pcs.poll = true;
- +
- + supported = mac_dev->phylink_config.supported_interfaces;
- +
- + /* FIXME: Can we use DTSEC_ID2_INT_FULL_OFF to determine if these are
- + * supported? If not, we can determine support via the phy if SerDes
- + * support is added.
- + */
- + if (mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII ||
- + mac_dev->phy_if == PHY_INTERFACE_MODE_1000BASEX) {
- + __set_bit(PHY_INTERFACE_MODE_SGMII, supported);
- + __set_bit(PHY_INTERFACE_MODE_1000BASEX, supported);
- + } else if (mac_dev->phy_if == PHY_INTERFACE_MODE_2500BASEX) {
- + __set_bit(PHY_INTERFACE_MODE_2500BASEX, supported);
- + }
- +
- + if (!(ioread32be(&dtsec->regs->tsec_id2) & DTSEC_ID2_INT_REDUCED_OFF)) {
- + phy_interface_set_rgmii(supported);
- +
- + /* DTSEC_ID2_INT_REDUCED_OFF indicates that the dTSEC supports
- + * RMII and RGMII. However, the only SoCs which support RMII
- + * are the P1017 and P1023. Avoid advertising this mode on
- + * other SoCs. This is a bit of a moot point, since there's no
- + * in-tree support for ethernet on these platforms...
- + */
- + if (of_machine_is_compatible("fsl,P1023") ||
- + of_machine_is_compatible("fsl,P1023RDB"))
- + __set_bit(PHY_INTERFACE_MODE_RMII, supported);
- + }
- +
- + capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE;
- + capabilities |= MAC_10 | MAC_100 | MAC_1000FD | MAC_2500FD;
- + mac_dev->phylink_config.mac_capabilities = capabilities;
-
- err = dtsec_init(dtsec);
- if (err < 0)
- --- a/drivers/net/ethernet/freescale/fman/fman_mac.h
- +++ b/drivers/net/ethernet/freescale/fman/fman_mac.h
- @@ -170,20 +170,10 @@ struct fman_mac_params {
- * 0 - FM_MAX_NUM_OF_10G_MACS
- */
- u8 mac_id;
- - /* Note that the speed should indicate the maximum rate that
- - * this MAC should support rather than the actual speed;
- - */
- - u16 max_speed;
- /* A handle to the FM object this port related to */
- void *fm;
- fman_mac_exception_cb *event_cb; /* MDIO Events Callback Routine */
- fman_mac_exception_cb *exception_cb;/* Exception Callback Routine */
- - /* SGMII/QSGII interface with 1000BaseX auto-negotiation between MAC
- - * and phy or backplane; Note: 1000BaseX auto-negotiation relates only
- - * to interface between MAC and phy/backplane, SGMII phy can still
- - * synchronize with far-end phy at 10Mbps, 100Mbps or 1000Mbps
- - */
- - bool basex_if;
- };
-
- struct eth_hash_t {
- --- a/drivers/net/ethernet/freescale/fman/fman_memac.c
- +++ b/drivers/net/ethernet/freescale/fman/fman_memac.c
- @@ -278,9 +278,6 @@ struct fman_mac {
- struct memac_regs __iomem *regs;
- /* MAC address of device */
- u64 addr;
- - /* Ethernet physical interface */
- - phy_interface_t phy_if;
- - u16 max_speed;
- struct mac_device *dev_id; /* device cookie used by the exception cbs */
- fman_mac_exception_cb *exception_cb;
- fman_mac_exception_cb *event_cb;
- @@ -293,12 +290,12 @@ struct fman_mac {
- struct memac_cfg *memac_drv_param;
- void *fm;
- struct fman_rev_info fm_rev_info;
- - bool basex_if;
- struct phy *serdes;
- struct phylink_pcs *sgmii_pcs;
- struct phylink_pcs *qsgmii_pcs;
- struct phylink_pcs *xfi_pcs;
- bool allmulti_enabled;
- + bool rgmii_no_half_duplex;
- };
-
- static void add_addr_in_paddr(struct memac_regs __iomem *regs, const u8 *adr,
- @@ -356,7 +353,6 @@ static void set_exception(struct memac_r
- }
-
- static int init(struct memac_regs __iomem *regs, struct memac_cfg *cfg,
- - phy_interface_t phy_if, u16 speed, bool slow_10g_if,
- u32 exceptions)
- {
- u32 tmp;
- @@ -384,41 +380,6 @@ static int init(struct memac_regs __iome
- iowrite32be((u32)cfg->pause_quanta, ®s->pause_quanta[0]);
- iowrite32be((u32)0, ®s->pause_thresh[0]);
-
- - /* IF_MODE */
- - tmp = 0;
- - switch (phy_if) {
- - case PHY_INTERFACE_MODE_XGMII:
- - tmp |= IF_MODE_10G;
- - break;
- - case PHY_INTERFACE_MODE_MII:
- - tmp |= IF_MODE_MII;
- - break;
- - default:
- - tmp |= IF_MODE_GMII;
- - if (phy_if == PHY_INTERFACE_MODE_RGMII ||
- - phy_if == PHY_INTERFACE_MODE_RGMII_ID ||
- - phy_if == PHY_INTERFACE_MODE_RGMII_RXID ||
- - phy_if == PHY_INTERFACE_MODE_RGMII_TXID)
- - tmp |= IF_MODE_RGMII | IF_MODE_RGMII_AUTO;
- - }
- - iowrite32be(tmp, ®s->if_mode);
- -
- - /* TX_FIFO_SECTIONS */
- - tmp = 0;
- - if (phy_if == PHY_INTERFACE_MODE_XGMII) {
- - if (slow_10g_if) {
- - tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G |
- - TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
- - } else {
- - tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_10G |
- - TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
- - }
- - } else {
- - tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_1G |
- - TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G);
- - }
- - iowrite32be(tmp, ®s->tx_fifo_sections);
- -
- /* clear all pending events and set-up interrupts */
- iowrite32be(0xffffffff, ®s->ievent);
- set_exception(regs, exceptions, true);
- @@ -458,24 +419,6 @@ static u32 get_mac_addr_hash_code(u64 et
- return xor_val;
- }
-
- -static void setup_sgmii_internal(struct fman_mac *memac,
- - struct phylink_pcs *pcs,
- - struct fixed_phy_status *fixed_link)
- -{
- - __ETHTOOL_DECLARE_LINK_MODE_MASK(advertising);
- - phy_interface_t iface = memac->basex_if ? PHY_INTERFACE_MODE_1000BASEX :
- - PHY_INTERFACE_MODE_SGMII;
- - unsigned int mode = fixed_link ? MLO_AN_FIXED : MLO_AN_INBAND;
- -
- - linkmode_set_pause(advertising, true, true);
- - pcs->ops->pcs_config(pcs, mode, iface, advertising, true);
- - if (fixed_link)
- - pcs->ops->pcs_link_up(pcs, mode, iface, fixed_link->speed,
- - fixed_link->duplex);
- - else
- - pcs->ops->pcs_an_restart(pcs);
- -}
- -
- static int check_init_parameters(struct fman_mac *memac)
- {
- if (!memac->exception_cb) {
- @@ -581,41 +524,31 @@ static void free_init_resources(struct f
- memac->unicast_addr_hash = NULL;
- }
-
- -static bool is_init_done(struct memac_cfg *memac_drv_params)
- -{
- - /* Checks if mEMAC driver parameters were initialized */
- - if (!memac_drv_params)
- - return true;
- -
- - return false;
- -}
- -
- static int memac_enable(struct fman_mac *memac)
- {
- - struct memac_regs __iomem *regs = memac->regs;
- - u32 tmp;
- + int ret;
-
- - if (!is_init_done(memac->memac_drv_param))
- - return -EINVAL;
- + ret = phy_init(memac->serdes);
- + if (ret) {
- + dev_err(memac->dev_id->dev,
- + "could not initialize serdes: %pe\n", ERR_PTR(ret));
- + return ret;
- + }
-
- - tmp = ioread32be(®s->command_config);
- - tmp |= CMD_CFG_RX_EN | CMD_CFG_TX_EN;
- - iowrite32be(tmp, ®s->command_config);
- + ret = phy_power_on(memac->serdes);
- + if (ret) {
- + dev_err(memac->dev_id->dev,
- + "could not power on serdes: %pe\n", ERR_PTR(ret));
- + phy_exit(memac->serdes);
- + }
-
- - return 0;
- + return ret;
- }
-
- static void memac_disable(struct fman_mac *memac)
- -
- {
- - struct memac_regs __iomem *regs = memac->regs;
- - u32 tmp;
- -
- - WARN_ON_ONCE(!is_init_done(memac->memac_drv_param));
- -
- - tmp = ioread32be(®s->command_config);
- - tmp &= ~(CMD_CFG_RX_EN | CMD_CFG_TX_EN);
- - iowrite32be(tmp, ®s->command_config);
- + phy_power_off(memac->serdes);
- + phy_exit(memac->serdes);
- }
-
- static int memac_set_promiscuous(struct fman_mac *memac, bool new_val)
- @@ -623,9 +556,6 @@ static int memac_set_promiscuous(struct
- struct memac_regs __iomem *regs = memac->regs;
- u32 tmp;
-
- - if (!is_init_done(memac->memac_drv_param))
- - return -EINVAL;
- -
- tmp = ioread32be(®s->command_config);
- if (new_val)
- tmp |= CMD_CFG_PROMIS_EN;
- @@ -637,73 +567,12 @@ static int memac_set_promiscuous(struct
- return 0;
- }
-
- -static int memac_adjust_link(struct fman_mac *memac, u16 speed)
- -{
- - struct memac_regs __iomem *regs = memac->regs;
- - u32 tmp;
- -
- - if (!is_init_done(memac->memac_drv_param))
- - return -EINVAL;
- -
- - tmp = ioread32be(®s->if_mode);
- -
- - /* Set full duplex */
- - tmp &= ~IF_MODE_HD;
- -
- - if (phy_interface_mode_is_rgmii(memac->phy_if)) {
- - /* Configure RGMII in manual mode */
- - tmp &= ~IF_MODE_RGMII_AUTO;
- - tmp &= ~IF_MODE_RGMII_SP_MASK;
- - /* Full duplex */
- - tmp |= IF_MODE_RGMII_FD;
- -
- - switch (speed) {
- - case SPEED_1000:
- - tmp |= IF_MODE_RGMII_1000;
- - break;
- - case SPEED_100:
- - tmp |= IF_MODE_RGMII_100;
- - break;
- - case SPEED_10:
- - tmp |= IF_MODE_RGMII_10;
- - break;
- - default:
- - break;
- - }
- - }
- -
- - iowrite32be(tmp, ®s->if_mode);
- -
- - return 0;
- -}
- -
- -static void adjust_link_memac(struct mac_device *mac_dev)
- -{
- - struct phy_device *phy_dev = mac_dev->phy_dev;
- - struct fman_mac *fman_mac;
- - bool rx_pause, tx_pause;
- - int err;
- -
- - fman_mac = mac_dev->fman_mac;
- - memac_adjust_link(fman_mac, phy_dev->speed);
- - mac_dev->update_speed(mac_dev, phy_dev->speed);
- -
- - fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
- - err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
- - if (err < 0)
- - dev_err(mac_dev->dev, "fman_set_mac_active_pause() = %d\n",
- - err);
- -}
- -
- static int memac_set_tx_pause_frames(struct fman_mac *memac, u8 priority,
- u16 pause_time, u16 thresh_time)
- {
- struct memac_regs __iomem *regs = memac->regs;
- u32 tmp;
-
- - if (!is_init_done(memac->memac_drv_param))
- - return -EINVAL;
- -
- tmp = ioread32be(®s->tx_fifo_sections);
-
- GET_TX_EMPTY_DEFAULT_VALUE(tmp);
- @@ -738,9 +607,6 @@ static int memac_accept_rx_pause_frames(
- struct memac_regs __iomem *regs = memac->regs;
- u32 tmp;
-
- - if (!is_init_done(memac->memac_drv_param))
- - return -EINVAL;
- -
- tmp = ioread32be(®s->command_config);
- if (en)
- tmp &= ~CMD_CFG_PAUSE_IGNORE;
- @@ -752,12 +618,175 @@ static int memac_accept_rx_pause_frames(
- return 0;
- }
-
- +static void memac_validate(struct phylink_config *config,
- + unsigned long *supported,
- + struct phylink_link_state *state)
- +{
- + struct fman_mac *memac = fman_config_to_mac(config)->fman_mac;
- + unsigned long caps = config->mac_capabilities;
- +
- + if (phy_interface_mode_is_rgmii(state->interface) &&
- + memac->rgmii_no_half_duplex)
- + caps &= ~(MAC_10HD | MAC_100HD);
- +
- + phylink_validate_mask_caps(supported, state, caps);
- +}
- +
- +/**
- + * memac_if_mode() - Convert an interface mode into an IF_MODE config
- + * @interface: A phy interface mode
- + *
- + * Return: A configuration word, suitable for programming into the lower bits
- + * of %IF_MODE.
- + */
- +static u32 memac_if_mode(phy_interface_t interface)
- +{
- + switch (interface) {
- + case PHY_INTERFACE_MODE_MII:
- + return IF_MODE_MII;
- + case PHY_INTERFACE_MODE_RGMII:
- + case PHY_INTERFACE_MODE_RGMII_ID:
- + case PHY_INTERFACE_MODE_RGMII_RXID:
- + case PHY_INTERFACE_MODE_RGMII_TXID:
- + return IF_MODE_GMII | IF_MODE_RGMII;
- + case PHY_INTERFACE_MODE_SGMII:
- + case PHY_INTERFACE_MODE_1000BASEX:
- + case PHY_INTERFACE_MODE_QSGMII:
- + return IF_MODE_GMII;
- + case PHY_INTERFACE_MODE_10GBASER:
- + return IF_MODE_10G;
- + default:
- + WARN_ON_ONCE(1);
- + return 0;
- + }
- +}
- +
- +static struct phylink_pcs *memac_select_pcs(struct phylink_config *config,
- + phy_interface_t iface)
- +{
- + struct fman_mac *memac = fman_config_to_mac(config)->fman_mac;
- +
- + switch (iface) {
- + case PHY_INTERFACE_MODE_SGMII:
- + case PHY_INTERFACE_MODE_1000BASEX:
- + return memac->sgmii_pcs;
- + case PHY_INTERFACE_MODE_QSGMII:
- + return memac->qsgmii_pcs;
- + case PHY_INTERFACE_MODE_10GBASER:
- + return memac->xfi_pcs;
- + default:
- + return NULL;
- + }
- +}
- +
- +static int memac_prepare(struct phylink_config *config, unsigned int mode,
- + phy_interface_t iface)
- +{
- + struct fman_mac *memac = fman_config_to_mac(config)->fman_mac;
- +
- + switch (iface) {
- + case PHY_INTERFACE_MODE_SGMII:
- + case PHY_INTERFACE_MODE_1000BASEX:
- + case PHY_INTERFACE_MODE_QSGMII:
- + case PHY_INTERFACE_MODE_10GBASER:
- + return phy_set_mode_ext(memac->serdes, PHY_MODE_ETHERNET,
- + iface);
- + default:
- + return 0;
- + }
- +}
- +
- +static void memac_mac_config(struct phylink_config *config, unsigned int mode,
- + const struct phylink_link_state *state)
- +{
- + struct mac_device *mac_dev = fman_config_to_mac(config);
- + struct memac_regs __iomem *regs = mac_dev->fman_mac->regs;
- + u32 tmp = ioread32be(®s->if_mode);
- +
- + tmp &= ~(IF_MODE_MASK | IF_MODE_RGMII);
- + tmp |= memac_if_mode(state->interface);
- + if (phylink_autoneg_inband(mode))
- + tmp |= IF_MODE_RGMII_AUTO;
- + iowrite32be(tmp, ®s->if_mode);
- +}
- +
- +static void memac_link_up(struct phylink_config *config, struct phy_device *phy,
- + unsigned int mode, phy_interface_t interface,
- + int speed, int duplex, bool tx_pause, bool rx_pause)
- +{
- + struct mac_device *mac_dev = fman_config_to_mac(config);
- + struct fman_mac *memac = mac_dev->fman_mac;
- + struct memac_regs __iomem *regs = memac->regs;
- + u32 tmp = memac_if_mode(interface);
- + u16 pause_time = tx_pause ? FSL_FM_PAUSE_TIME_ENABLE :
- + FSL_FM_PAUSE_TIME_DISABLE;
- +
- + memac_set_tx_pause_frames(memac, 0, pause_time, 0);
- + memac_accept_rx_pause_frames(memac, rx_pause);
- +
- + if (duplex == DUPLEX_HALF)
- + tmp |= IF_MODE_HD;
- +
- + switch (speed) {
- + case SPEED_1000:
- + tmp |= IF_MODE_RGMII_1000;
- + break;
- + case SPEED_100:
- + tmp |= IF_MODE_RGMII_100;
- + break;
- + case SPEED_10:
- + tmp |= IF_MODE_RGMII_10;
- + break;
- + }
- + iowrite32be(tmp, ®s->if_mode);
- +
- + /* TODO: EEE? */
- +
- + if (speed == SPEED_10000) {
- + if (memac->fm_rev_info.major == 6 &&
- + memac->fm_rev_info.minor == 4)
- + tmp = TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G;
- + else
- + tmp = TX_FIFO_SECTIONS_TX_AVAIL_10G;
- + tmp |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G;
- + } else {
- + tmp = TX_FIFO_SECTIONS_TX_AVAIL_1G |
- + TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G;
- + }
- + iowrite32be(tmp, ®s->tx_fifo_sections);
- +
- + mac_dev->update_speed(mac_dev, speed);
- +
- + tmp = ioread32be(®s->command_config);
- + tmp |= CMD_CFG_RX_EN | CMD_CFG_TX_EN;
- + iowrite32be(tmp, ®s->command_config);
- +}
- +
- +static void memac_link_down(struct phylink_config *config, unsigned int mode,
- + phy_interface_t interface)
- +{
- + struct fman_mac *memac = fman_config_to_mac(config)->fman_mac;
- + struct memac_regs __iomem *regs = memac->regs;
- + u32 tmp;
- +
- + /* TODO: graceful */
- + tmp = ioread32be(®s->command_config);
- + tmp &= ~(CMD_CFG_RX_EN | CMD_CFG_TX_EN);
- + iowrite32be(tmp, ®s->command_config);
- +}
- +
- +static const struct phylink_mac_ops memac_mac_ops = {
- + .validate = memac_validate,
- + .mac_select_pcs = memac_select_pcs,
- + .mac_prepare = memac_prepare,
- + .mac_config = memac_mac_config,
- + .mac_link_up = memac_link_up,
- + .mac_link_down = memac_link_down,
- +};
- +
- static int memac_modify_mac_address(struct fman_mac *memac,
- const enet_addr_t *enet_addr)
- {
- - if (!is_init_done(memac->memac_drv_param))
- - return -EINVAL;
- -
- add_addr_in_paddr(memac->regs, (const u8 *)(*enet_addr), 0);
-
- return 0;
- @@ -771,9 +800,6 @@ static int memac_add_hash_mac_address(st
- u32 hash;
- u64 addr;
-
- - if (!is_init_done(memac->memac_drv_param))
- - return -EINVAL;
- -
- addr = ENET_ADDR_TO_UINT64(*eth_addr);
-
- if (!(addr & GROUP_ADDRESS)) {
- @@ -802,9 +828,6 @@ static int memac_set_allmulti(struct fma
- u32 entry;
- struct memac_regs __iomem *regs = memac->regs;
-
- - if (!is_init_done(memac->memac_drv_param))
- - return -EINVAL;
- -
- if (enable) {
- for (entry = 0; entry < HASH_TABLE_SIZE; entry++)
- iowrite32be(entry | HASH_CTRL_MCAST_EN,
- @@ -834,9 +857,6 @@ static int memac_del_hash_mac_address(st
- u32 hash;
- u64 addr;
-
- - if (!is_init_done(memac->memac_drv_param))
- - return -EINVAL;
- -
- addr = ENET_ADDR_TO_UINT64(*eth_addr);
-
- hash = get_mac_addr_hash_code(addr) & HASH_CTRL_ADDR_MASK;
- @@ -864,9 +884,6 @@ static int memac_set_exception(struct fm
- {
- u32 bit_mask = 0;
-
- - if (!is_init_done(memac->memac_drv_param))
- - return -EINVAL;
- -
- bit_mask = get_exception_flag(exception);
- if (bit_mask) {
- if (enable)
- @@ -886,23 +903,15 @@ static int memac_init(struct fman_mac *m
- {
- struct memac_cfg *memac_drv_param;
- enet_addr_t eth_addr;
- - bool slow_10g_if = false;
- - struct fixed_phy_status *fixed_link = NULL;
- int err;
- u32 reg32 = 0;
-
- - if (is_init_done(memac->memac_drv_param))
- - return -EINVAL;
- -
- err = check_init_parameters(memac);
- if (err)
- return err;
-
- memac_drv_param = memac->memac_drv_param;
-
- - if (memac->fm_rev_info.major == 6 && memac->fm_rev_info.minor == 4)
- - slow_10g_if = true;
- -
- /* First, reset the MAC if desired. */
- if (memac_drv_param->reset_on_init) {
- err = reset(memac->regs);
- @@ -918,10 +927,7 @@ static int memac_init(struct fman_mac *m
- add_addr_in_paddr(memac->regs, (const u8 *)eth_addr, 0);
- }
-
- - fixed_link = memac_drv_param->fixed_link;
- -
- - init(memac->regs, memac->memac_drv_param, memac->phy_if,
- - memac->max_speed, slow_10g_if, memac->exceptions);
- + init(memac->regs, memac->memac_drv_param, memac->exceptions);
-
- /* FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320 errata workaround
- * Exists only in FMan 6.0 and 6.3.
- @@ -937,11 +943,6 @@ static int memac_init(struct fman_mac *m
- iowrite32be(reg32, &memac->regs->command_config);
- }
-
- - if (memac->phy_if == PHY_INTERFACE_MODE_SGMII)
- - setup_sgmii_internal(memac, memac->sgmii_pcs, fixed_link);
- - else if (memac->phy_if == PHY_INTERFACE_MODE_QSGMII)
- - setup_sgmii_internal(memac, memac->qsgmii_pcs, fixed_link);
- -
- /* Max Frame Length */
- err = fman_set_mac_max_frame(memac->fm, memac->mac_id,
- memac_drv_param->max_frame_length);
- @@ -970,9 +971,6 @@ static int memac_init(struct fman_mac *m
- fman_register_intr(memac->fm, FMAN_MOD_MAC, memac->mac_id,
- FMAN_INTR_TYPE_NORMAL, memac_exception, memac);
-
- - kfree(memac_drv_param);
- - memac->memac_drv_param = NULL;
- -
- return 0;
- }
-
- @@ -995,7 +993,6 @@ static int memac_free(struct fman_mac *m
- pcs_put(memac->sgmii_pcs);
- pcs_put(memac->qsgmii_pcs);
- pcs_put(memac->xfi_pcs);
- -
- kfree(memac->memac_drv_param);
- kfree(memac);
-
- @@ -1028,8 +1025,6 @@ static struct fman_mac *memac_config(str
- memac->addr = ENET_ADDR_TO_UINT64(mac_dev->addr);
-
- memac->regs = mac_dev->vaddr;
- - memac->max_speed = params->max_speed;
- - memac->phy_if = mac_dev->phy_if;
- memac->mac_id = params->mac_id;
- memac->exceptions = (MEMAC_IMASK_TSECC_ER | MEMAC_IMASK_TECC_ER |
- MEMAC_IMASK_RECC_ER | MEMAC_IMASK_MGI);
- @@ -1037,7 +1032,6 @@ static struct fman_mac *memac_config(str
- memac->event_cb = params->event_cb;
- memac->dev_id = mac_dev;
- memac->fm = params->fm;
- - memac->basex_if = params->basex_if;
-
- /* Save FMan revision */
- fman_get_revision(memac->fm, &memac->fm_rev_info);
- @@ -1064,37 +1058,44 @@ static struct phylink_pcs *memac_pcs_cre
- return pcs;
- }
-
- +static bool memac_supports(struct mac_device *mac_dev, phy_interface_t iface)
- +{
- + /* If there's no serdes device, assume that it's been configured for
- + * whatever the default interface mode is.
- + */
- + if (!mac_dev->fman_mac->serdes)
- + return mac_dev->phy_if == iface;
- + /* Otherwise, ask the serdes */
- + return !phy_validate(mac_dev->fman_mac->serdes, PHY_MODE_ETHERNET,
- + iface, NULL);
- +}
- +
- int memac_initialization(struct mac_device *mac_dev,
- struct device_node *mac_node,
- struct fman_mac_params *params)
- {
- int err;
- + struct device_node *fixed;
- struct phylink_pcs *pcs;
- - struct fixed_phy_status *fixed_link;
- struct fman_mac *memac;
- + unsigned long capabilities;
- + unsigned long *supported;
-
- + mac_dev->phylink_ops = &memac_mac_ops;
- mac_dev->set_promisc = memac_set_promiscuous;
- mac_dev->change_addr = memac_modify_mac_address;
- mac_dev->add_hash_mac_addr = memac_add_hash_mac_address;
- mac_dev->remove_hash_mac_addr = memac_del_hash_mac_address;
- - mac_dev->set_tx_pause = memac_set_tx_pause_frames;
- - mac_dev->set_rx_pause = memac_accept_rx_pause_frames;
- mac_dev->set_exception = memac_set_exception;
- mac_dev->set_allmulti = memac_set_allmulti;
- mac_dev->set_tstamp = memac_set_tstamp;
- mac_dev->set_multi = fman_set_multi;
- - mac_dev->adjust_link = adjust_link_memac;
- mac_dev->enable = memac_enable;
- mac_dev->disable = memac_disable;
-
- - if (params->max_speed == SPEED_10000)
- - mac_dev->phy_if = PHY_INTERFACE_MODE_XGMII;
- -
- mac_dev->fman_mac = memac_config(mac_dev, params);
- - if (!mac_dev->fman_mac) {
- - err = -EINVAL;
- - goto _return;
- - }
- + if (!mac_dev->fman_mac)
- + return -EINVAL;
-
- memac = mac_dev->fman_mac;
- memac->memac_drv_param->max_frame_length = fman_get_max_frm();
- @@ -1136,9 +1137,9 @@ int memac_initialization(struct mac_devi
- else
- pcs = memac_pcs_create(mac_node, err);
-
- - if (!pcs) {
- - dev_err(mac_dev->dev, "missing pcs\n");
- - err = -ENOENT;
- + if (IS_ERR(pcs)) {
- + err = PTR_ERR(pcs);
- + dev_err_probe(mac_dev->dev, err, "missing pcs\n");
- goto _return_fm_mac_free;
- }
-
- @@ -1159,84 +1160,100 @@ int memac_initialization(struct mac_devi
- } else if (IS_ERR(memac->serdes)) {
- dev_err_probe(mac_dev->dev, err, "could not get serdes\n");
- goto _return_fm_mac_free;
- - } else {
- - err = phy_init(memac->serdes);
- - if (err) {
- - dev_err_probe(mac_dev->dev, err,
- - "could not initialize serdes\n");
- - goto _return_fm_mac_free;
- - }
- -
- - err = phy_power_on(memac->serdes);
- - if (err) {
- - dev_err_probe(mac_dev->dev, err,
- - "could not power on serdes\n");
- - goto _return_phy_exit;
- - }
- -
- - if (memac->phy_if == PHY_INTERFACE_MODE_SGMII ||
- - memac->phy_if == PHY_INTERFACE_MODE_1000BASEX ||
- - memac->phy_if == PHY_INTERFACE_MODE_2500BASEX ||
- - memac->phy_if == PHY_INTERFACE_MODE_QSGMII ||
- - memac->phy_if == PHY_INTERFACE_MODE_XGMII) {
- - err = phy_set_mode_ext(memac->serdes, PHY_MODE_ETHERNET,
- - memac->phy_if);
- - if (err) {
- - dev_err_probe(mac_dev->dev, err,
- - "could not set serdes mode to %s\n",
- - phy_modes(memac->phy_if));
- - goto _return_phy_power_off;
- - }
- - }
- }
-
- - if (!mac_dev->phy_node && of_phy_is_fixed_link(mac_node)) {
- - struct phy_device *phy;
- -
- - err = of_phy_register_fixed_link(mac_node);
- - if (err)
- - goto _return_phy_power_off;
- -
- - fixed_link = kzalloc(sizeof(*fixed_link), GFP_KERNEL);
- - if (!fixed_link) {
- - err = -ENOMEM;
- - goto _return_phy_power_off;
- - }
- + /* The internal connection to the serdes is XGMII, but this isn't
- + * really correct for the phy mode (which is the external connection).
- + * However, this is how all older device trees say that they want
- + * 10GBASE-R (aka XFI), so just convert it for them.
- + */
- + if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
- + mac_dev->phy_if = PHY_INTERFACE_MODE_10GBASER;
-
- - mac_dev->phy_node = of_node_get(mac_node);
- - phy = of_phy_find_device(mac_dev->phy_node);
- - if (!phy) {
- - err = -EINVAL;
- - of_node_put(mac_dev->phy_node);
- - goto _return_fixed_link_free;
- - }
- + /* TODO: The following interface modes are supported by (some) hardware
- + * but not by this driver:
- + * - 1000BASE-KX
- + * - 10GBASE-KR
- + * - XAUI/HiGig
- + */
- + supported = mac_dev->phylink_config.supported_interfaces;
-
- - fixed_link->link = phy->link;
- - fixed_link->speed = phy->speed;
- - fixed_link->duplex = phy->duplex;
- - fixed_link->pause = phy->pause;
- - fixed_link->asym_pause = phy->asym_pause;
- + /* Note that half duplex is only supported on 10/100M interfaces. */
-
- - put_device(&phy->mdio.dev);
- - memac->memac_drv_param->fixed_link = fixed_link;
- + if (memac->sgmii_pcs &&
- + (memac_supports(mac_dev, PHY_INTERFACE_MODE_SGMII) ||
- + memac_supports(mac_dev, PHY_INTERFACE_MODE_1000BASEX))) {
- + __set_bit(PHY_INTERFACE_MODE_SGMII, supported);
- + __set_bit(PHY_INTERFACE_MODE_1000BASEX, supported);
- + }
- +
- + if (memac->sgmii_pcs &&
- + memac_supports(mac_dev, PHY_INTERFACE_MODE_2500BASEX))
- + __set_bit(PHY_INTERFACE_MODE_2500BASEX, supported);
- +
- + if (memac->qsgmii_pcs &&
- + memac_supports(mac_dev, PHY_INTERFACE_MODE_QSGMII))
- + __set_bit(PHY_INTERFACE_MODE_QSGMII, supported);
- + else if (mac_dev->phy_if == PHY_INTERFACE_MODE_QSGMII)
- + dev_warn(mac_dev->dev, "no QSGMII pcs specified\n");
- +
- + if (memac->xfi_pcs &&
- + memac_supports(mac_dev, PHY_INTERFACE_MODE_10GBASER)) {
- + __set_bit(PHY_INTERFACE_MODE_10GBASER, supported);
- + } else {
- + /* From what I can tell, no 10g macs support RGMII. */
- + phy_interface_set_rgmii(supported);
- + __set_bit(PHY_INTERFACE_MODE_MII, supported);
- }
-
- + capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE | MAC_10 | MAC_100;
- + capabilities |= MAC_1000FD | MAC_2500FD | MAC_10000FD;
- +
- + /* These SoCs don't support half duplex at all; there's no different
- + * FMan version or compatible, so we just have to check the machine
- + * compatible instead
- + */
- + if (of_machine_is_compatible("fsl,ls1043a") ||
- + of_machine_is_compatible("fsl,ls1046a") ||
- + of_machine_is_compatible("fsl,B4QDS"))
- + capabilities &= ~(MAC_10HD | MAC_100HD);
- +
- + mac_dev->phylink_config.mac_capabilities = capabilities;
- +
- + /* The T2080 and T4240 don't support half duplex RGMII. There is no
- + * other way to identify these SoCs, so just use the machine
- + * compatible.
- + */
- + if (of_machine_is_compatible("fsl,T2080QDS") ||
- + of_machine_is_compatible("fsl,T2080RDB") ||
- + of_machine_is_compatible("fsl,T2081QDS") ||
- + of_machine_is_compatible("fsl,T4240QDS") ||
- + of_machine_is_compatible("fsl,T4240RDB"))
- + memac->rgmii_no_half_duplex = true;
- +
- + /* Most boards should use MLO_AN_INBAND, but existing boards don't have
- + * a managed property. Default to MLO_AN_INBAND if nothing else is
- + * specified. We need to be careful and not enable this if we have a
- + * fixed link or if we are using MII or RGMII, since those
- + * configurations modes don't use in-band autonegotiation.
- + */
- + fixed = of_get_child_by_name(mac_node, "fixed-link");
- + if (!fixed && !of_property_read_bool(mac_node, "fixed-link") &&
- + !of_property_read_bool(mac_node, "managed") &&
- + mac_dev->phy_if != PHY_INTERFACE_MODE_MII &&
- + !phy_interface_mode_is_rgmii(mac_dev->phy_if))
- + mac_dev->phylink_config.ovr_an_inband = true;
- + of_node_put(fixed);
- +
- err = memac_init(mac_dev->fman_mac);
- if (err < 0)
- - goto _return_fixed_link_free;
- + goto _return_fm_mac_free;
-
- dev_info(mac_dev->dev, "FMan MEMAC\n");
-
- - goto _return;
- + return 0;
-
- -_return_phy_power_off:
- - phy_power_off(memac->serdes);
- -_return_phy_exit:
- - phy_exit(memac->serdes);
- -_return_fixed_link_free:
- - kfree(fixed_link);
- _return_fm_mac_free:
- memac_free(mac_dev->fman_mac);
- -_return:
- return err;
- }
- --- a/drivers/net/ethernet/freescale/fman/fman_tgec.c
- +++ b/drivers/net/ethernet/freescale/fman/fman_tgec.c
- @@ -13,6 +13,7 @@
- #include <linux/bitrev.h>
- #include <linux/io.h>
- #include <linux/crc32.h>
- +#include <linux/netdevice.h>
-
- /* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */
- #define TGEC_TX_IPG_LENGTH_MASK 0x000003ff
- @@ -243,10 +244,6 @@ static int init(struct tgec_regs __iomem
-
- static int check_init_parameters(struct fman_mac *tgec)
- {
- - if (tgec->max_speed < SPEED_10000) {
- - pr_err("10G MAC driver only support 10G speed\n");
- - return -EINVAL;
- - }
- if (!tgec->exception_cb) {
- pr_err("uninitialized exception_cb\n");
- return -EINVAL;
- @@ -384,40 +381,13 @@ static void free_init_resources(struct f
- tgec->unicast_addr_hash = NULL;
- }
-
- -static bool is_init_done(struct tgec_cfg *cfg)
- -{
- - /* Checks if tGEC driver parameters were initialized */
- - if (!cfg)
- - return true;
- -
- - return false;
- -}
- -
- static int tgec_enable(struct fman_mac *tgec)
- {
- - struct tgec_regs __iomem *regs = tgec->regs;
- - u32 tmp;
- -
- - if (!is_init_done(tgec->cfg))
- - return -EINVAL;
- -
- - tmp = ioread32be(®s->command_config);
- - tmp |= CMD_CFG_RX_EN | CMD_CFG_TX_EN;
- - iowrite32be(tmp, ®s->command_config);
- -
- return 0;
- }
-
- static void tgec_disable(struct fman_mac *tgec)
- {
- - struct tgec_regs __iomem *regs = tgec->regs;
- - u32 tmp;
- -
- - WARN_ON_ONCE(!is_init_done(tgec->cfg));
- -
- - tmp = ioread32be(®s->command_config);
- - tmp &= ~(CMD_CFG_RX_EN | CMD_CFG_TX_EN);
- - iowrite32be(tmp, ®s->command_config);
- }
-
- static int tgec_set_promiscuous(struct fman_mac *tgec, bool new_val)
- @@ -425,9 +395,6 @@ static int tgec_set_promiscuous(struct f
- struct tgec_regs __iomem *regs = tgec->regs;
- u32 tmp;
-
- - if (!is_init_done(tgec->cfg))
- - return -EINVAL;
- -
- tmp = ioread32be(®s->command_config);
- if (new_val)
- tmp |= CMD_CFG_PROMIS_EN;
- @@ -444,9 +411,6 @@ static int tgec_set_tx_pause_frames(stru
- {
- struct tgec_regs __iomem *regs = tgec->regs;
-
- - if (!is_init_done(tgec->cfg))
- - return -EINVAL;
- -
- iowrite32be((u32)pause_time, ®s->pause_quant);
-
- return 0;
- @@ -457,9 +421,6 @@ static int tgec_accept_rx_pause_frames(s
- struct tgec_regs __iomem *regs = tgec->regs;
- u32 tmp;
-
- - if (!is_init_done(tgec->cfg))
- - return -EINVAL;
- -
- tmp = ioread32be(®s->command_config);
- if (!en)
- tmp |= CMD_CFG_PAUSE_IGNORE;
- @@ -470,12 +431,53 @@ static int tgec_accept_rx_pause_frames(s
- return 0;
- }
-
- +static void tgec_mac_config(struct phylink_config *config, unsigned int mode,
- + const struct phylink_link_state *state)
- +{
- +}
- +
- +static void tgec_link_up(struct phylink_config *config, struct phy_device *phy,
- + unsigned int mode, phy_interface_t interface,
- + int speed, int duplex, bool tx_pause, bool rx_pause)
- +{
- + struct mac_device *mac_dev = fman_config_to_mac(config);
- + struct fman_mac *tgec = mac_dev->fman_mac;
- + struct tgec_regs __iomem *regs = tgec->regs;
- + u16 pause_time = tx_pause ? FSL_FM_PAUSE_TIME_ENABLE :
- + FSL_FM_PAUSE_TIME_DISABLE;
- + u32 tmp;
- +
- + tgec_set_tx_pause_frames(tgec, 0, pause_time, 0);
- + tgec_accept_rx_pause_frames(tgec, rx_pause);
- + mac_dev->update_speed(mac_dev, speed);
- +
- + tmp = ioread32be(®s->command_config);
- + tmp |= CMD_CFG_RX_EN | CMD_CFG_TX_EN;
- + iowrite32be(tmp, ®s->command_config);
- +}
- +
- +static void tgec_link_down(struct phylink_config *config, unsigned int mode,
- + phy_interface_t interface)
- +{
- + struct fman_mac *tgec = fman_config_to_mac(config)->fman_mac;
- + struct tgec_regs __iomem *regs = tgec->regs;
- + u32 tmp;
- +
- + tmp = ioread32be(®s->command_config);
- + tmp &= ~(CMD_CFG_RX_EN | CMD_CFG_TX_EN);
- + iowrite32be(tmp, ®s->command_config);
- +}
- +
- +static const struct phylink_mac_ops tgec_mac_ops = {
- + .validate = phylink_generic_validate,
- + .mac_config = tgec_mac_config,
- + .mac_link_up = tgec_link_up,
- + .mac_link_down = tgec_link_down,
- +};
- +
- static int tgec_modify_mac_address(struct fman_mac *tgec,
- const enet_addr_t *p_enet_addr)
- {
- - if (!is_init_done(tgec->cfg))
- - return -EINVAL;
- -
- tgec->addr = ENET_ADDR_TO_UINT64(*p_enet_addr);
- set_mac_address(tgec->regs, (const u8 *)(*p_enet_addr));
-
- @@ -490,9 +492,6 @@ static int tgec_add_hash_mac_address(str
- u32 crc = 0xFFFFFFFF, hash;
- u64 addr;
-
- - if (!is_init_done(tgec->cfg))
- - return -EINVAL;
- -
- addr = ENET_ADDR_TO_UINT64(*eth_addr);
-
- if (!(addr & GROUP_ADDRESS)) {
- @@ -525,9 +524,6 @@ static int tgec_set_allmulti(struct fman
- u32 entry;
- struct tgec_regs __iomem *regs = tgec->regs;
-
- - if (!is_init_done(tgec->cfg))
- - return -EINVAL;
- -
- if (enable) {
- for (entry = 0; entry < TGEC_HASH_TABLE_SIZE; entry++)
- iowrite32be(entry | TGEC_HASH_MCAST_EN,
- @@ -548,9 +544,6 @@ static int tgec_set_tstamp(struct fman_m
- struct tgec_regs __iomem *regs = tgec->regs;
- u32 tmp;
-
- - if (!is_init_done(tgec->cfg))
- - return -EINVAL;
- -
- tmp = ioread32be(®s->command_config);
-
- if (enable)
- @@ -572,9 +565,6 @@ static int tgec_del_hash_mac_address(str
- u32 crc = 0xFFFFFFFF, hash;
- u64 addr;
-
- - if (!is_init_done(tgec->cfg))
- - return -EINVAL;
- -
- addr = ((*(u64 *)eth_addr) >> 16);
-
- /* CRC calculation */
- @@ -601,22 +591,12 @@ static int tgec_del_hash_mac_address(str
- return 0;
- }
-
- -static void tgec_adjust_link(struct mac_device *mac_dev)
- -{
- - struct phy_device *phy_dev = mac_dev->phy_dev;
- -
- - mac_dev->update_speed(mac_dev, phy_dev->speed);
- -}
- -
- static int tgec_set_exception(struct fman_mac *tgec,
- enum fman_mac_exceptions exception, bool enable)
- {
- struct tgec_regs __iomem *regs = tgec->regs;
- u32 bit_mask = 0;
-
- - if (!is_init_done(tgec->cfg))
- - return -EINVAL;
- -
- bit_mask = get_exception_flag(exception);
- if (bit_mask) {
- if (enable)
- @@ -641,9 +621,6 @@ static int tgec_init(struct fman_mac *tg
- enet_addr_t eth_addr;
- int err;
-
- - if (is_init_done(tgec->cfg))
- - return -EINVAL;
- -
- if (DEFAULT_RESET_ON_INIT &&
- (fman_reset_mac(tgec->fm, tgec->mac_id) != 0)) {
- pr_err("Can't reset MAC!\n");
- @@ -753,7 +730,6 @@ static struct fman_mac *tgec_config(stru
-
- tgec->regs = mac_dev->vaddr;
- tgec->addr = ENET_ADDR_TO_UINT64(mac_dev->addr);
- - tgec->max_speed = params->max_speed;
- tgec->mac_id = params->mac_id;
- tgec->exceptions = (TGEC_IMASK_MDIO_SCAN_EVENT |
- TGEC_IMASK_REM_FAULT |
- @@ -788,17 +764,15 @@ int tgec_initialization(struct mac_devic
- int err;
- struct fman_mac *tgec;
-
- + mac_dev->phylink_ops = &tgec_mac_ops;
- mac_dev->set_promisc = tgec_set_promiscuous;
- mac_dev->change_addr = tgec_modify_mac_address;
- mac_dev->add_hash_mac_addr = tgec_add_hash_mac_address;
- mac_dev->remove_hash_mac_addr = tgec_del_hash_mac_address;
- - mac_dev->set_tx_pause = tgec_set_tx_pause_frames;
- - mac_dev->set_rx_pause = tgec_accept_rx_pause_frames;
- mac_dev->set_exception = tgec_set_exception;
- mac_dev->set_allmulti = tgec_set_allmulti;
- mac_dev->set_tstamp = tgec_set_tstamp;
- mac_dev->set_multi = fman_set_multi;
- - mac_dev->adjust_link = tgec_adjust_link;
- mac_dev->enable = tgec_enable;
- mac_dev->disable = tgec_disable;
-
- @@ -808,6 +782,19 @@ int tgec_initialization(struct mac_devic
- goto _return;
- }
-
- + /* The internal connection to the serdes is XGMII, but this isn't
- + * really correct for the phy mode (which is the external connection).
- + * However, this is how all older device trees say that they want
- + * XAUI, so just convert it for them.
- + */
- + if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
- + mac_dev->phy_if = PHY_INTERFACE_MODE_XAUI;
- +
- + __set_bit(PHY_INTERFACE_MODE_XAUI,
- + mac_dev->phylink_config.supported_interfaces);
- + mac_dev->phylink_config.mac_capabilities =
- + MAC_SYM_PAUSE | MAC_ASYM_PAUSE | MAC_10000FD;
- +
- tgec = mac_dev->fman_mac;
- tgec->cfg->max_frame_length = fman_get_max_frm();
- err = tgec_init(tgec);
- --- a/drivers/net/ethernet/freescale/fman/mac.c
- +++ b/drivers/net/ethernet/freescale/fman/mac.c
- @@ -15,6 +15,7 @@
- #include <linux/phy.h>
- #include <linux/netdevice.h>
- #include <linux/phy_fixed.h>
- +#include <linux/phylink.h>
- #include <linux/etherdevice.h>
- #include <linux/libfdt_env.h>
-
- @@ -93,130 +94,8 @@ int fman_set_multi(struct net_device *ne
- return 0;
- }
-
- -/**
- - * fman_set_mac_active_pause
- - * @mac_dev: A pointer to the MAC device
- - * @rx: Pause frame setting for RX
- - * @tx: Pause frame setting for TX
- - *
- - * Set the MAC RX/TX PAUSE frames settings
- - *
- - * Avoid redundant calls to FMD, if the MAC driver already contains the desired
- - * active PAUSE settings. Otherwise, the new active settings should be reflected
- - * in FMan.
- - *
- - * Return: 0 on success; Error code otherwise.
- - */
- -int fman_set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx)
- -{
- - struct fman_mac *fman_mac = mac_dev->fman_mac;
- - int err = 0;
- -
- - if (rx != mac_dev->rx_pause_active) {
- - err = mac_dev->set_rx_pause(fman_mac, rx);
- - if (likely(err == 0))
- - mac_dev->rx_pause_active = rx;
- - }
- -
- - if (tx != mac_dev->tx_pause_active) {
- - u16 pause_time = (tx ? FSL_FM_PAUSE_TIME_ENABLE :
- - FSL_FM_PAUSE_TIME_DISABLE);
- -
- - err = mac_dev->set_tx_pause(fman_mac, 0, pause_time, 0);
- -
- - if (likely(err == 0))
- - mac_dev->tx_pause_active = tx;
- - }
- -
- - return err;
- -}
- -EXPORT_SYMBOL(fman_set_mac_active_pause);
- -
- -/**
- - * fman_get_pause_cfg
- - * @mac_dev: A pointer to the MAC device
- - * @rx_pause: Return value for RX setting
- - * @tx_pause: Return value for TX setting
- - *
- - * Determine the MAC RX/TX PAUSE frames settings based on PHY
- - * autonegotiation or values set by eththool.
- - *
- - * Return: Pointer to FMan device.
- - */
- -void fman_get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause,
- - bool *tx_pause)
- -{
- - struct phy_device *phy_dev = mac_dev->phy_dev;
- - u16 lcl_adv, rmt_adv;
- - u8 flowctrl;
- -
- - *rx_pause = *tx_pause = false;
- -
- - if (!phy_dev->duplex)
- - return;
- -
- - /* If PAUSE autonegotiation is disabled, the TX/RX PAUSE settings
- - * are those set by ethtool.
- - */
- - if (!mac_dev->autoneg_pause) {
- - *rx_pause = mac_dev->rx_pause_req;
- - *tx_pause = mac_dev->tx_pause_req;
- - return;
- - }
- -
- - /* Else if PAUSE autonegotiation is enabled, the TX/RX PAUSE
- - * settings depend on the result of the link negotiation.
- - */
- -
- - /* get local capabilities */
- - lcl_adv = linkmode_adv_to_lcl_adv_t(phy_dev->advertising);
- -
- - /* get link partner capabilities */
- - rmt_adv = 0;
- - if (phy_dev->pause)
- - rmt_adv |= LPA_PAUSE_CAP;
- - if (phy_dev->asym_pause)
- - rmt_adv |= LPA_PAUSE_ASYM;
- -
- - /* Calculate TX/RX settings based on local and peer advertised
- - * symmetric/asymmetric PAUSE capabilities.
- - */
- - flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
- - if (flowctrl & FLOW_CTRL_RX)
- - *rx_pause = true;
- - if (flowctrl & FLOW_CTRL_TX)
- - *tx_pause = true;
- -}
- -EXPORT_SYMBOL(fman_get_pause_cfg);
- -
- -#define DTSEC_SUPPORTED \
- - (SUPPORTED_10baseT_Half \
- - | SUPPORTED_10baseT_Full \
- - | SUPPORTED_100baseT_Half \
- - | SUPPORTED_100baseT_Full \
- - | SUPPORTED_Autoneg \
- - | SUPPORTED_Pause \
- - | SUPPORTED_Asym_Pause \
- - | SUPPORTED_FIBRE \
- - | SUPPORTED_MII)
- -
- static DEFINE_MUTEX(eth_lock);
-
- -static const u16 phy2speed[] = {
- - [PHY_INTERFACE_MODE_MII] = SPEED_100,
- - [PHY_INTERFACE_MODE_GMII] = SPEED_1000,
- - [PHY_INTERFACE_MODE_SGMII] = SPEED_1000,
- - [PHY_INTERFACE_MODE_TBI] = SPEED_1000,
- - [PHY_INTERFACE_MODE_RMII] = SPEED_100,
- - [PHY_INTERFACE_MODE_RGMII] = SPEED_1000,
- - [PHY_INTERFACE_MODE_RGMII_ID] = SPEED_1000,
- - [PHY_INTERFACE_MODE_RGMII_RXID] = SPEED_1000,
- - [PHY_INTERFACE_MODE_RGMII_TXID] = SPEED_1000,
- - [PHY_INTERFACE_MODE_RTBI] = SPEED_1000,
- - [PHY_INTERFACE_MODE_QSGMII] = SPEED_1000,
- - [PHY_INTERFACE_MODE_XGMII] = SPEED_10000
- -};
- -
- static struct platform_device *dpaa_eth_add_device(int fman_id,
- struct mac_device *mac_dev)
- {
- @@ -263,8 +142,8 @@ no_mem:
- }
-
- static const struct of_device_id mac_match[] = {
- - { .compatible = "fsl,fman-dtsec", .data = dtsec_initialization },
- - { .compatible = "fsl,fman-xgec", .data = tgec_initialization },
- + { .compatible = "fsl,fman-dtsec", .data = dtsec_initialization },
- + { .compatible = "fsl,fman-xgec", .data = tgec_initialization },
- { .compatible = "fsl,fman-memac", .data = memac_initialization },
- {}
- };
- @@ -295,6 +174,7 @@ static int mac_probe(struct platform_dev
- priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
- if (!priv)
- return -ENOMEM;
- + platform_set_drvdata(_of_dev, mac_dev);
-
- /* Save private information */
- mac_dev->priv = priv;
- @@ -424,57 +304,21 @@ static int mac_probe(struct platform_dev
- }
- mac_dev->phy_if = phy_if;
-
- - priv->speed = phy2speed[mac_dev->phy_if];
- - params.max_speed = priv->speed;
- - mac_dev->if_support = DTSEC_SUPPORTED;
- - /* We don't support half-duplex in SGMII mode */
- - if (mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII)
- - mac_dev->if_support &= ~(SUPPORTED_10baseT_Half |
- - SUPPORTED_100baseT_Half);
- -
- - /* Gigabit support (no half-duplex) */
- - if (params.max_speed == 1000)
- - mac_dev->if_support |= SUPPORTED_1000baseT_Full;
- -
- - /* The 10G interface only supports one mode */
- - if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
- - mac_dev->if_support = SUPPORTED_10000baseT_Full;
- -
- - /* Get the rest of the PHY information */
- - mac_dev->phy_node = of_parse_phandle(mac_node, "phy-handle", 0);
- -
- - params.basex_if = false;
- params.mac_id = priv->cell_index;
- params.fm = (void *)priv->fman;
- params.exception_cb = mac_exception;
- params.event_cb = mac_exception;
-
- err = init(mac_dev, mac_node, ¶ms);
- - if (err < 0) {
- - dev_err(dev, "mac_dev->init() = %d\n", err);
- - of_node_put(mac_dev->phy_node);
- - return err;
- - }
- -
- - /* pause frame autonegotiation enabled */
- - mac_dev->autoneg_pause = true;
- -
- - /* By intializing the values to false, force FMD to enable PAUSE frames
- - * on RX and TX
- - */
- - mac_dev->rx_pause_req = true;
- - mac_dev->tx_pause_req = true;
- - mac_dev->rx_pause_active = false;
- - mac_dev->tx_pause_active = false;
- - err = fman_set_mac_active_pause(mac_dev, true, true);
- if (err < 0)
- - dev_err(dev, "fman_set_mac_active_pause() = %d\n", err);
- + return err;
-
- if (!is_zero_ether_addr(mac_dev->addr))
- dev_info(dev, "FMan MAC address: %pM\n", mac_dev->addr);
-
- priv->eth_dev = dpaa_eth_add_device(fman_id, mac_dev);
- if (IS_ERR(priv->eth_dev)) {
- + err = PTR_ERR(priv->eth_dev);
- dev_err(dev, "failed to add Ethernet platform device for MAC %d\n",
- priv->cell_index);
- priv->eth_dev = NULL;
- --- a/drivers/net/ethernet/freescale/fman/mac.h
- +++ b/drivers/net/ethernet/freescale/fman/mac.h
- @@ -9,6 +9,7 @@
- #include <linux/device.h>
- #include <linux/if_ether.h>
- #include <linux/phy.h>
- +#include <linux/phylink.h>
- #include <linux/list.h>
-
- #include "fman_port.h"
- @@ -24,32 +25,22 @@ struct mac_device {
- struct resource *res;
- u8 addr[ETH_ALEN];
- struct fman_port *port[2];
- - u32 if_support;
- - struct phy_device *phy_dev;
- + struct phylink *phylink;
- + struct phylink_config phylink_config;
- phy_interface_t phy_if;
- - struct device_node *phy_node;
- - struct net_device *net_dev;
-
- - bool autoneg_pause;
- - bool rx_pause_req;
- - bool tx_pause_req;
- - bool rx_pause_active;
- - bool tx_pause_active;
- bool promisc;
- bool allmulti;
-
- + const struct phylink_mac_ops *phylink_ops;
- int (*enable)(struct fman_mac *mac_dev);
- void (*disable)(struct fman_mac *mac_dev);
- - void (*adjust_link)(struct mac_device *mac_dev);
- int (*set_promisc)(struct fman_mac *mac_dev, bool enable);
- int (*change_addr)(struct fman_mac *mac_dev, const enet_addr_t *enet_addr);
- int (*set_allmulti)(struct fman_mac *mac_dev, bool enable);
- int (*set_tstamp)(struct fman_mac *mac_dev, bool enable);
- int (*set_multi)(struct net_device *net_dev,
- struct mac_device *mac_dev);
- - int (*set_rx_pause)(struct fman_mac *mac_dev, bool en);
- - int (*set_tx_pause)(struct fman_mac *mac_dev, u8 priority,
- - u16 pause_time, u16 thresh_time);
- int (*set_exception)(struct fman_mac *mac_dev,
- enum fman_mac_exceptions exception, bool enable);
- int (*add_hash_mac_addr)(struct fman_mac *mac_dev,
- @@ -63,6 +54,12 @@ struct mac_device {
- struct mac_priv_s *priv;
- };
-
- +static inline struct mac_device
- +*fman_config_to_mac(struct phylink_config *config)
- +{
- + return container_of(config, struct mac_device, phylink_config);
- +}
- +
- struct dpaa_eth_data {
- struct mac_device *mac_dev;
- int mac_hw_id;
|