cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

mac.c (23621B)


      1/* Copyright 2008-2015 Freescale Semiconductor, Inc.
      2 *
      3 * Redistribution and use in source and binary forms, with or without
      4 * modification, are permitted provided that the following conditions are met:
      5 *     * Redistributions of source code must retain the above copyright
      6 *	 notice, this list of conditions and the following disclaimer.
      7 *     * Redistributions in binary form must reproduce the above copyright
      8 *	 notice, this list of conditions and the following disclaimer in the
      9 *	 documentation and/or other materials provided with the distribution.
     10 *     * Neither the name of Freescale Semiconductor nor the
     11 *	 names of its contributors may be used to endorse or promote products
     12 *	 derived from this software without specific prior written permission.
     13 *
     14 *
     15 * ALTERNATIVELY, this software may be distributed under the terms of the
     16 * GNU General Public License ("GPL") as published by the Free Software
     17 * Foundation, either version 2 of that License or (at your option) any
     18 * later version.
     19 *
     20 * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
     21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     23 * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
     24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30 */
     31
     32#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
     33
     34#include <linux/init.h>
     35#include <linux/module.h>
     36#include <linux/of_address.h>
     37#include <linux/of_platform.h>
     38#include <linux/of_net.h>
     39#include <linux/of_mdio.h>
     40#include <linux/device.h>
     41#include <linux/phy.h>
     42#include <linux/netdevice.h>
     43#include <linux/phy_fixed.h>
     44#include <linux/etherdevice.h>
     45#include <linux/libfdt_env.h>
     46
     47#include "mac.h"
     48#include "fman_mac.h"
     49#include "fman_dtsec.h"
     50#include "fman_tgec.h"
     51#include "fman_memac.h"
     52
     53MODULE_LICENSE("Dual BSD/GPL");
     54MODULE_DESCRIPTION("FSL FMan MAC API based driver");
     55
     56struct mac_priv_s {
     57	struct device			*dev;
     58	void __iomem			*vaddr;
     59	u8				cell_index;
     60	struct fman			*fman;
     61	struct device_node		*internal_phy_node;
     62	/* List of multicast addresses */
     63	struct list_head		mc_addr_list;
     64	struct platform_device		*eth_dev;
     65	struct fixed_phy_status		*fixed_link;
     66	u16				speed;
     67	u16				max_speed;
     68
     69	int (*enable)(struct fman_mac *mac_dev, enum comm_mode mode);
     70	int (*disable)(struct fman_mac *mac_dev, enum comm_mode mode);
     71};
     72
     73struct mac_address {
     74	u8 addr[ETH_ALEN];
     75	struct list_head list;
     76};
     77
     78static void mac_exception(void *handle, enum fman_mac_exceptions ex)
     79{
     80	struct mac_device	*mac_dev;
     81	struct mac_priv_s	*priv;
     82
     83	mac_dev = handle;
     84	priv = mac_dev->priv;
     85
     86	if (ex == FM_MAC_EX_10G_RX_FIFO_OVFL) {
     87		/* don't flag RX FIFO after the first */
     88		mac_dev->set_exception(mac_dev->fman_mac,
     89				       FM_MAC_EX_10G_RX_FIFO_OVFL, false);
     90		dev_err(priv->dev, "10G MAC got RX FIFO Error = %x\n", ex);
     91	}
     92
     93	dev_dbg(priv->dev, "%s:%s() -> %d\n", KBUILD_BASENAME ".c",
     94		__func__, ex);
     95}
     96
     97static int set_fman_mac_params(struct mac_device *mac_dev,
     98			       struct fman_mac_params *params)
     99{
    100	struct mac_priv_s *priv = mac_dev->priv;
    101
    102	params->base_addr = (typeof(params->base_addr))
    103		devm_ioremap(priv->dev, mac_dev->res->start,
    104			     resource_size(mac_dev->res));
    105	if (!params->base_addr)
    106		return -ENOMEM;
    107
    108	memcpy(&params->addr, mac_dev->addr, sizeof(mac_dev->addr));
    109	params->max_speed	= priv->max_speed;
    110	params->phy_if		= mac_dev->phy_if;
    111	params->basex_if	= false;
    112	params->mac_id		= priv->cell_index;
    113	params->fm		= (void *)priv->fman;
    114	params->exception_cb	= mac_exception;
    115	params->event_cb	= mac_exception;
    116	params->dev_id		= mac_dev;
    117	params->internal_phy_node = priv->internal_phy_node;
    118
    119	return 0;
    120}
    121
    122static int tgec_initialization(struct mac_device *mac_dev)
    123{
    124	int err;
    125	struct mac_priv_s	*priv;
    126	struct fman_mac_params	params;
    127	u32			version;
    128
    129	priv = mac_dev->priv;
    130
    131	err = set_fman_mac_params(mac_dev, &params);
    132	if (err)
    133		goto _return;
    134
    135	mac_dev->fman_mac = tgec_config(&params);
    136	if (!mac_dev->fman_mac) {
    137		err = -EINVAL;
    138		goto _return;
    139	}
    140
    141	err = tgec_cfg_max_frame_len(mac_dev->fman_mac, fman_get_max_frm());
    142	if (err < 0)
    143		goto _return_fm_mac_free;
    144
    145	err = tgec_init(mac_dev->fman_mac);
    146	if (err < 0)
    147		goto _return_fm_mac_free;
    148
    149	/* For 10G MAC, disable Tx ECC exception */
    150	err = mac_dev->set_exception(mac_dev->fman_mac,
    151				     FM_MAC_EX_10G_TX_ECC_ER, false);
    152	if (err < 0)
    153		goto _return_fm_mac_free;
    154
    155	err = tgec_get_version(mac_dev->fman_mac, &version);
    156	if (err < 0)
    157		goto _return_fm_mac_free;
    158
    159	dev_info(priv->dev, "FMan XGEC version: 0x%08x\n", version);
    160
    161	goto _return;
    162
    163_return_fm_mac_free:
    164	tgec_free(mac_dev->fman_mac);
    165
    166_return:
    167	return err;
    168}
    169
    170static int dtsec_initialization(struct mac_device *mac_dev)
    171{
    172	int			err;
    173	struct mac_priv_s	*priv;
    174	struct fman_mac_params	params;
    175	u32			version;
    176
    177	priv = mac_dev->priv;
    178
    179	err = set_fman_mac_params(mac_dev, &params);
    180	if (err)
    181		goto _return;
    182
    183	mac_dev->fman_mac = dtsec_config(&params);
    184	if (!mac_dev->fman_mac) {
    185		err = -EINVAL;
    186		goto _return;
    187	}
    188
    189	err = dtsec_cfg_max_frame_len(mac_dev->fman_mac, fman_get_max_frm());
    190	if (err < 0)
    191		goto _return_fm_mac_free;
    192
    193	err = dtsec_cfg_pad_and_crc(mac_dev->fman_mac, true);
    194	if (err < 0)
    195		goto _return_fm_mac_free;
    196
    197	err = dtsec_init(mac_dev->fman_mac);
    198	if (err < 0)
    199		goto _return_fm_mac_free;
    200
    201	/* For 1G MAC, disable by default the MIB counters overflow interrupt */
    202	err = mac_dev->set_exception(mac_dev->fman_mac,
    203				     FM_MAC_EX_1G_RX_MIB_CNT_OVFL, false);
    204	if (err < 0)
    205		goto _return_fm_mac_free;
    206
    207	err = dtsec_get_version(mac_dev->fman_mac, &version);
    208	if (err < 0)
    209		goto _return_fm_mac_free;
    210
    211	dev_info(priv->dev, "FMan dTSEC version: 0x%08x\n", version);
    212
    213	goto _return;
    214
    215_return_fm_mac_free:
    216	dtsec_free(mac_dev->fman_mac);
    217
    218_return:
    219	return err;
    220}
    221
    222static int memac_initialization(struct mac_device *mac_dev)
    223{
    224	int			 err;
    225	struct mac_priv_s	*priv;
    226	struct fman_mac_params	 params;
    227
    228	priv = mac_dev->priv;
    229
    230	err = set_fman_mac_params(mac_dev, &params);
    231	if (err)
    232		goto _return;
    233
    234	if (priv->max_speed == SPEED_10000)
    235		params.phy_if = PHY_INTERFACE_MODE_XGMII;
    236
    237	mac_dev->fman_mac = memac_config(&params);
    238	if (!mac_dev->fman_mac) {
    239		err = -EINVAL;
    240		goto _return;
    241	}
    242
    243	err = memac_cfg_max_frame_len(mac_dev->fman_mac, fman_get_max_frm());
    244	if (err < 0)
    245		goto _return_fm_mac_free;
    246
    247	err = memac_cfg_reset_on_init(mac_dev->fman_mac, true);
    248	if (err < 0)
    249		goto _return_fm_mac_free;
    250
    251	err = memac_cfg_fixed_link(mac_dev->fman_mac, priv->fixed_link);
    252	if (err < 0)
    253		goto _return_fm_mac_free;
    254
    255	err = memac_init(mac_dev->fman_mac);
    256	if (err < 0)
    257		goto _return_fm_mac_free;
    258
    259	dev_info(priv->dev, "FMan MEMAC\n");
    260
    261	goto _return;
    262
    263_return_fm_mac_free:
    264	memac_free(mac_dev->fman_mac);
    265
    266_return:
    267	return err;
    268}
    269
    270static int start(struct mac_device *mac_dev)
    271{
    272	int	 err;
    273	struct phy_device *phy_dev = mac_dev->phy_dev;
    274	struct mac_priv_s *priv = mac_dev->priv;
    275
    276	err = priv->enable(mac_dev->fman_mac, COMM_MODE_RX_AND_TX);
    277	if (!err && phy_dev)
    278		phy_start(phy_dev);
    279
    280	return err;
    281}
    282
    283static int stop(struct mac_device *mac_dev)
    284{
    285	struct mac_priv_s *priv = mac_dev->priv;
    286
    287	if (mac_dev->phy_dev)
    288		phy_stop(mac_dev->phy_dev);
    289
    290	return priv->disable(mac_dev->fman_mac, COMM_MODE_RX_AND_TX);
    291}
    292
    293static int set_multi(struct net_device *net_dev, struct mac_device *mac_dev)
    294{
    295	struct mac_priv_s	*priv;
    296	struct mac_address	*old_addr, *tmp;
    297	struct netdev_hw_addr	*ha;
    298	int			err;
    299	enet_addr_t		*addr;
    300
    301	priv = mac_dev->priv;
    302
    303	/* Clear previous address list */
    304	list_for_each_entry_safe(old_addr, tmp, &priv->mc_addr_list, list) {
    305		addr = (enet_addr_t *)old_addr->addr;
    306		err = mac_dev->remove_hash_mac_addr(mac_dev->fman_mac, addr);
    307		if (err < 0)
    308			return err;
    309
    310		list_del(&old_addr->list);
    311		kfree(old_addr);
    312	}
    313
    314	/* Add all the addresses from the new list */
    315	netdev_for_each_mc_addr(ha, net_dev) {
    316		addr = (enet_addr_t *)ha->addr;
    317		err = mac_dev->add_hash_mac_addr(mac_dev->fman_mac, addr);
    318		if (err < 0)
    319			return err;
    320
    321		tmp = kmalloc(sizeof(*tmp), GFP_ATOMIC);
    322		if (!tmp)
    323			return -ENOMEM;
    324
    325		ether_addr_copy(tmp->addr, ha->addr);
    326		list_add(&tmp->list, &priv->mc_addr_list);
    327	}
    328	return 0;
    329}
    330
    331/**
    332 * fman_set_mac_active_pause
    333 * @mac_dev:	A pointer to the MAC device
    334 * @rx:		Pause frame setting for RX
    335 * @tx:		Pause frame setting for TX
    336 *
    337 * Set the MAC RX/TX PAUSE frames settings
    338 *
    339 * Avoid redundant calls to FMD, if the MAC driver already contains the desired
    340 * active PAUSE settings. Otherwise, the new active settings should be reflected
    341 * in FMan.
    342 *
    343 * Return: 0 on success; Error code otherwise.
    344 */
    345int fman_set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx)
    346{
    347	struct fman_mac *fman_mac = mac_dev->fman_mac;
    348	int err = 0;
    349
    350	if (rx != mac_dev->rx_pause_active) {
    351		err = mac_dev->set_rx_pause(fman_mac, rx);
    352		if (likely(err == 0))
    353			mac_dev->rx_pause_active = rx;
    354	}
    355
    356	if (tx != mac_dev->tx_pause_active) {
    357		u16 pause_time = (tx ? FSL_FM_PAUSE_TIME_ENABLE :
    358					 FSL_FM_PAUSE_TIME_DISABLE);
    359
    360		err = mac_dev->set_tx_pause(fman_mac, 0, pause_time, 0);
    361
    362		if (likely(err == 0))
    363			mac_dev->tx_pause_active = tx;
    364	}
    365
    366	return err;
    367}
    368EXPORT_SYMBOL(fman_set_mac_active_pause);
    369
    370/**
    371 * fman_get_pause_cfg
    372 * @mac_dev:	A pointer to the MAC device
    373 * @rx_pause:	Return value for RX setting
    374 * @tx_pause:	Return value for TX setting
    375 *
    376 * Determine the MAC RX/TX PAUSE frames settings based on PHY
    377 * autonegotiation or values set by eththool.
    378 *
    379 * Return: Pointer to FMan device.
    380 */
    381void fman_get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause,
    382			bool *tx_pause)
    383{
    384	struct phy_device *phy_dev = mac_dev->phy_dev;
    385	u16 lcl_adv, rmt_adv;
    386	u8 flowctrl;
    387
    388	*rx_pause = *tx_pause = false;
    389
    390	if (!phy_dev->duplex)
    391		return;
    392
    393	/* If PAUSE autonegotiation is disabled, the TX/RX PAUSE settings
    394	 * are those set by ethtool.
    395	 */
    396	if (!mac_dev->autoneg_pause) {
    397		*rx_pause = mac_dev->rx_pause_req;
    398		*tx_pause = mac_dev->tx_pause_req;
    399		return;
    400	}
    401
    402	/* Else if PAUSE autonegotiation is enabled, the TX/RX PAUSE
    403	 * settings depend on the result of the link negotiation.
    404	 */
    405
    406	/* get local capabilities */
    407	lcl_adv = linkmode_adv_to_lcl_adv_t(phy_dev->advertising);
    408
    409	/* get link partner capabilities */
    410	rmt_adv = 0;
    411	if (phy_dev->pause)
    412		rmt_adv |= LPA_PAUSE_CAP;
    413	if (phy_dev->asym_pause)
    414		rmt_adv |= LPA_PAUSE_ASYM;
    415
    416	/* Calculate TX/RX settings based on local and peer advertised
    417	 * symmetric/asymmetric PAUSE capabilities.
    418	 */
    419	flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
    420	if (flowctrl & FLOW_CTRL_RX)
    421		*rx_pause = true;
    422	if (flowctrl & FLOW_CTRL_TX)
    423		*tx_pause = true;
    424}
    425EXPORT_SYMBOL(fman_get_pause_cfg);
    426
    427static void adjust_link_void(struct mac_device *mac_dev)
    428{
    429}
    430
    431static void adjust_link_dtsec(struct mac_device *mac_dev)
    432{
    433	struct phy_device *phy_dev = mac_dev->phy_dev;
    434	struct fman_mac *fman_mac;
    435	bool rx_pause, tx_pause;
    436	int err;
    437
    438	fman_mac = mac_dev->fman_mac;
    439	if (!phy_dev->link) {
    440		dtsec_restart_autoneg(fman_mac);
    441
    442		return;
    443	}
    444
    445	dtsec_adjust_link(fman_mac, phy_dev->speed);
    446	fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
    447	err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
    448	if (err < 0)
    449		dev_err(mac_dev->priv->dev, "fman_set_mac_active_pause() = %d\n",
    450			err);
    451}
    452
    453static void adjust_link_memac(struct mac_device *mac_dev)
    454{
    455	struct phy_device *phy_dev = mac_dev->phy_dev;
    456	struct fman_mac *fman_mac;
    457	bool rx_pause, tx_pause;
    458	int err;
    459
    460	fman_mac = mac_dev->fman_mac;
    461	memac_adjust_link(fman_mac, phy_dev->speed);
    462
    463	fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
    464	err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
    465	if (err < 0)
    466		dev_err(mac_dev->priv->dev, "fman_set_mac_active_pause() = %d\n",
    467			err);
    468}
    469
    470static void setup_dtsec(struct mac_device *mac_dev)
    471{
    472	mac_dev->init			= dtsec_initialization;
    473	mac_dev->set_promisc		= dtsec_set_promiscuous;
    474	mac_dev->change_addr		= dtsec_modify_mac_address;
    475	mac_dev->add_hash_mac_addr	= dtsec_add_hash_mac_address;
    476	mac_dev->remove_hash_mac_addr	= dtsec_del_hash_mac_address;
    477	mac_dev->set_tx_pause		= dtsec_set_tx_pause_frames;
    478	mac_dev->set_rx_pause		= dtsec_accept_rx_pause_frames;
    479	mac_dev->set_exception		= dtsec_set_exception;
    480	mac_dev->set_allmulti		= dtsec_set_allmulti;
    481	mac_dev->set_tstamp		= dtsec_set_tstamp;
    482	mac_dev->set_multi		= set_multi;
    483	mac_dev->start			= start;
    484	mac_dev->stop			= stop;
    485	mac_dev->adjust_link            = adjust_link_dtsec;
    486	mac_dev->priv->enable		= dtsec_enable;
    487	mac_dev->priv->disable		= dtsec_disable;
    488}
    489
    490static void setup_tgec(struct mac_device *mac_dev)
    491{
    492	mac_dev->init			= tgec_initialization;
    493	mac_dev->set_promisc		= tgec_set_promiscuous;
    494	mac_dev->change_addr		= tgec_modify_mac_address;
    495	mac_dev->add_hash_mac_addr	= tgec_add_hash_mac_address;
    496	mac_dev->remove_hash_mac_addr	= tgec_del_hash_mac_address;
    497	mac_dev->set_tx_pause		= tgec_set_tx_pause_frames;
    498	mac_dev->set_rx_pause		= tgec_accept_rx_pause_frames;
    499	mac_dev->set_exception		= tgec_set_exception;
    500	mac_dev->set_allmulti		= tgec_set_allmulti;
    501	mac_dev->set_tstamp		= tgec_set_tstamp;
    502	mac_dev->set_multi		= set_multi;
    503	mac_dev->start			= start;
    504	mac_dev->stop			= stop;
    505	mac_dev->adjust_link            = adjust_link_void;
    506	mac_dev->priv->enable		= tgec_enable;
    507	mac_dev->priv->disable		= tgec_disable;
    508}
    509
    510static void setup_memac(struct mac_device *mac_dev)
    511{
    512	mac_dev->init			= memac_initialization;
    513	mac_dev->set_promisc		= memac_set_promiscuous;
    514	mac_dev->change_addr		= memac_modify_mac_address;
    515	mac_dev->add_hash_mac_addr	= memac_add_hash_mac_address;
    516	mac_dev->remove_hash_mac_addr	= memac_del_hash_mac_address;
    517	mac_dev->set_tx_pause		= memac_set_tx_pause_frames;
    518	mac_dev->set_rx_pause		= memac_accept_rx_pause_frames;
    519	mac_dev->set_exception		= memac_set_exception;
    520	mac_dev->set_allmulti		= memac_set_allmulti;
    521	mac_dev->set_tstamp		= memac_set_tstamp;
    522	mac_dev->set_multi		= set_multi;
    523	mac_dev->start			= start;
    524	mac_dev->stop			= stop;
    525	mac_dev->adjust_link            = adjust_link_memac;
    526	mac_dev->priv->enable		= memac_enable;
    527	mac_dev->priv->disable		= memac_disable;
    528}
    529
    530#define DTSEC_SUPPORTED \
    531	(SUPPORTED_10baseT_Half \
    532	| SUPPORTED_10baseT_Full \
    533	| SUPPORTED_100baseT_Half \
    534	| SUPPORTED_100baseT_Full \
    535	| SUPPORTED_Autoneg \
    536	| SUPPORTED_Pause \
    537	| SUPPORTED_Asym_Pause \
    538	| SUPPORTED_FIBRE \
    539	| SUPPORTED_MII)
    540
    541static DEFINE_MUTEX(eth_lock);
    542
    543static const u16 phy2speed[] = {
    544	[PHY_INTERFACE_MODE_MII]		= SPEED_100,
    545	[PHY_INTERFACE_MODE_GMII]		= SPEED_1000,
    546	[PHY_INTERFACE_MODE_SGMII]		= SPEED_1000,
    547	[PHY_INTERFACE_MODE_TBI]		= SPEED_1000,
    548	[PHY_INTERFACE_MODE_RMII]		= SPEED_100,
    549	[PHY_INTERFACE_MODE_RGMII]		= SPEED_1000,
    550	[PHY_INTERFACE_MODE_RGMII_ID]		= SPEED_1000,
    551	[PHY_INTERFACE_MODE_RGMII_RXID]	= SPEED_1000,
    552	[PHY_INTERFACE_MODE_RGMII_TXID]	= SPEED_1000,
    553	[PHY_INTERFACE_MODE_RTBI]		= SPEED_1000,
    554	[PHY_INTERFACE_MODE_QSGMII]		= SPEED_1000,
    555	[PHY_INTERFACE_MODE_XGMII]		= SPEED_10000
    556};
    557
    558static struct platform_device *dpaa_eth_add_device(int fman_id,
    559						   struct mac_device *mac_dev)
    560{
    561	struct platform_device *pdev;
    562	struct dpaa_eth_data data;
    563	struct mac_priv_s	*priv;
    564	static int dpaa_eth_dev_cnt;
    565	int ret;
    566
    567	priv = mac_dev->priv;
    568
    569	data.mac_dev = mac_dev;
    570	data.mac_hw_id = priv->cell_index;
    571	data.fman_hw_id = fman_id;
    572
    573	mutex_lock(&eth_lock);
    574	pdev = platform_device_alloc("dpaa-ethernet", dpaa_eth_dev_cnt);
    575	if (!pdev) {
    576		ret = -ENOMEM;
    577		goto no_mem;
    578	}
    579
    580	pdev->dev.parent = priv->dev;
    581
    582	ret = platform_device_add_data(pdev, &data, sizeof(data));
    583	if (ret)
    584		goto err;
    585
    586	ret = platform_device_add(pdev);
    587	if (ret)
    588		goto err;
    589
    590	dpaa_eth_dev_cnt++;
    591	mutex_unlock(&eth_lock);
    592
    593	return pdev;
    594
    595err:
    596	platform_device_put(pdev);
    597no_mem:
    598	mutex_unlock(&eth_lock);
    599
    600	return ERR_PTR(ret);
    601}
    602
    603static const struct of_device_id mac_match[] = {
    604	{ .compatible	= "fsl,fman-dtsec" },
    605	{ .compatible	= "fsl,fman-xgec" },
    606	{ .compatible	= "fsl,fman-memac" },
    607	{}
    608};
    609MODULE_DEVICE_TABLE(of, mac_match);
    610
    611static int mac_probe(struct platform_device *_of_dev)
    612{
    613	int			 err, i, nph;
    614	struct device		*dev;
    615	struct device_node	*mac_node, *dev_node;
    616	struct mac_device	*mac_dev;
    617	struct platform_device	*of_dev;
    618	struct resource		 res;
    619	struct mac_priv_s	*priv;
    620	u32			 val;
    621	u8			fman_id;
    622	phy_interface_t          phy_if;
    623
    624	dev = &_of_dev->dev;
    625	mac_node = dev->of_node;
    626
    627	mac_dev = devm_kzalloc(dev, sizeof(*mac_dev), GFP_KERNEL);
    628	if (!mac_dev) {
    629		err = -ENOMEM;
    630		goto _return;
    631	}
    632	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
    633	if (!priv) {
    634		err = -ENOMEM;
    635		goto _return;
    636	}
    637
    638	/* Save private information */
    639	mac_dev->priv = priv;
    640	priv->dev = dev;
    641
    642	if (of_device_is_compatible(mac_node, "fsl,fman-dtsec")) {
    643		setup_dtsec(mac_dev);
    644		priv->internal_phy_node = of_parse_phandle(mac_node,
    645							  "tbi-handle", 0);
    646	} else if (of_device_is_compatible(mac_node, "fsl,fman-xgec")) {
    647		setup_tgec(mac_dev);
    648	} else if (of_device_is_compatible(mac_node, "fsl,fman-memac")) {
    649		setup_memac(mac_dev);
    650		priv->internal_phy_node = of_parse_phandle(mac_node,
    651							  "pcsphy-handle", 0);
    652	} else {
    653		dev_err(dev, "MAC node (%pOF) contains unsupported MAC\n",
    654			mac_node);
    655		err = -EINVAL;
    656		goto _return;
    657	}
    658
    659	INIT_LIST_HEAD(&priv->mc_addr_list);
    660
    661	/* Get the FM node */
    662	dev_node = of_get_parent(mac_node);
    663	if (!dev_node) {
    664		dev_err(dev, "of_get_parent(%pOF) failed\n",
    665			mac_node);
    666		err = -EINVAL;
    667		goto _return_of_get_parent;
    668	}
    669
    670	of_dev = of_find_device_by_node(dev_node);
    671	if (!of_dev) {
    672		dev_err(dev, "of_find_device_by_node(%pOF) failed\n", dev_node);
    673		err = -EINVAL;
    674		goto _return_of_node_put;
    675	}
    676
    677	/* Get the FMan cell-index */
    678	err = of_property_read_u32(dev_node, "cell-index", &val);
    679	if (err) {
    680		dev_err(dev, "failed to read cell-index for %pOF\n", dev_node);
    681		err = -EINVAL;
    682		goto _return_of_node_put;
    683	}
    684	/* cell-index 0 => FMan id 1 */
    685	fman_id = (u8)(val + 1);
    686
    687	priv->fman = fman_bind(&of_dev->dev);
    688	if (!priv->fman) {
    689		dev_err(dev, "fman_bind(%pOF) failed\n", dev_node);
    690		err = -ENODEV;
    691		goto _return_of_node_put;
    692	}
    693
    694	of_node_put(dev_node);
    695
    696	/* Get the address of the memory mapped registers */
    697	err = of_address_to_resource(mac_node, 0, &res);
    698	if (err < 0) {
    699		dev_err(dev, "of_address_to_resource(%pOF) = %d\n",
    700			mac_node, err);
    701		goto _return_of_get_parent;
    702	}
    703
    704	mac_dev->res = __devm_request_region(dev,
    705					     fman_get_mem_region(priv->fman),
    706					     res.start, resource_size(&res),
    707					     "mac");
    708	if (!mac_dev->res) {
    709		dev_err(dev, "__devm_request_mem_region(mac) failed\n");
    710		err = -EBUSY;
    711		goto _return_of_get_parent;
    712	}
    713
    714	priv->vaddr = devm_ioremap(dev, mac_dev->res->start,
    715				   resource_size(mac_dev->res));
    716	if (!priv->vaddr) {
    717		dev_err(dev, "devm_ioremap() failed\n");
    718		err = -EIO;
    719		goto _return_of_get_parent;
    720	}
    721
    722	if (!of_device_is_available(mac_node)) {
    723		err = -ENODEV;
    724		goto _return_of_get_parent;
    725	}
    726
    727	/* Get the cell-index */
    728	err = of_property_read_u32(mac_node, "cell-index", &val);
    729	if (err) {
    730		dev_err(dev, "failed to read cell-index for %pOF\n", mac_node);
    731		err = -EINVAL;
    732		goto _return_of_get_parent;
    733	}
    734	priv->cell_index = (u8)val;
    735
    736	/* Get the MAC address */
    737	err = of_get_mac_address(mac_node, mac_dev->addr);
    738	if (err)
    739		dev_warn(dev, "of_get_mac_address(%pOF) failed\n", mac_node);
    740
    741	/* Get the port handles */
    742	nph = of_count_phandle_with_args(mac_node, "fsl,fman-ports", NULL);
    743	if (unlikely(nph < 0)) {
    744		dev_err(dev, "of_count_phandle_with_args(%pOF, fsl,fman-ports) failed\n",
    745			mac_node);
    746		err = nph;
    747		goto _return_of_get_parent;
    748	}
    749
    750	if (nph != ARRAY_SIZE(mac_dev->port)) {
    751		dev_err(dev, "Not supported number of fman-ports handles of mac node %pOF from device tree\n",
    752			mac_node);
    753		err = -EINVAL;
    754		goto _return_of_get_parent;
    755	}
    756
    757	for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) {
    758		/* Find the port node */
    759		dev_node = of_parse_phandle(mac_node, "fsl,fman-ports", i);
    760		if (!dev_node) {
    761			dev_err(dev, "of_parse_phandle(%pOF, fsl,fman-ports) failed\n",
    762				mac_node);
    763			err = -EINVAL;
    764			goto _return_of_node_put;
    765		}
    766
    767		of_dev = of_find_device_by_node(dev_node);
    768		if (!of_dev) {
    769			dev_err(dev, "of_find_device_by_node(%pOF) failed\n",
    770				dev_node);
    771			err = -EINVAL;
    772			goto _return_of_node_put;
    773		}
    774
    775		mac_dev->port[i] = fman_port_bind(&of_dev->dev);
    776		if (!mac_dev->port[i]) {
    777			dev_err(dev, "dev_get_drvdata(%pOF) failed\n",
    778				dev_node);
    779			err = -EINVAL;
    780			goto _return_of_node_put;
    781		}
    782		of_node_put(dev_node);
    783	}
    784
    785	/* Get the PHY connection type */
    786	err = of_get_phy_mode(mac_node, &phy_if);
    787	if (err) {
    788		dev_warn(dev,
    789			 "of_get_phy_mode() for %pOF failed. Defaulting to SGMII\n",
    790			 mac_node);
    791		phy_if = PHY_INTERFACE_MODE_SGMII;
    792	}
    793	mac_dev->phy_if = phy_if;
    794
    795	priv->speed		= phy2speed[mac_dev->phy_if];
    796	priv->max_speed		= priv->speed;
    797	mac_dev->if_support	= DTSEC_SUPPORTED;
    798	/* We don't support half-duplex in SGMII mode */
    799	if (mac_dev->phy_if == PHY_INTERFACE_MODE_SGMII)
    800		mac_dev->if_support &= ~(SUPPORTED_10baseT_Half |
    801					SUPPORTED_100baseT_Half);
    802
    803	/* Gigabit support (no half-duplex) */
    804	if (priv->max_speed == 1000)
    805		mac_dev->if_support |= SUPPORTED_1000baseT_Full;
    806
    807	/* The 10G interface only supports one mode */
    808	if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII)
    809		mac_dev->if_support = SUPPORTED_10000baseT_Full;
    810
    811	/* Get the rest of the PHY information */
    812	mac_dev->phy_node = of_parse_phandle(mac_node, "phy-handle", 0);
    813	if (!mac_dev->phy_node && of_phy_is_fixed_link(mac_node)) {
    814		struct phy_device *phy;
    815
    816		err = of_phy_register_fixed_link(mac_node);
    817		if (err)
    818			goto _return_of_get_parent;
    819
    820		priv->fixed_link = kzalloc(sizeof(*priv->fixed_link),
    821					   GFP_KERNEL);
    822		if (!priv->fixed_link) {
    823			err = -ENOMEM;
    824			goto _return_of_get_parent;
    825		}
    826
    827		mac_dev->phy_node = of_node_get(mac_node);
    828		phy = of_phy_find_device(mac_dev->phy_node);
    829		if (!phy) {
    830			err = -EINVAL;
    831			of_node_put(mac_dev->phy_node);
    832			goto _return_of_get_parent;
    833		}
    834
    835		priv->fixed_link->link = phy->link;
    836		priv->fixed_link->speed = phy->speed;
    837		priv->fixed_link->duplex = phy->duplex;
    838		priv->fixed_link->pause = phy->pause;
    839		priv->fixed_link->asym_pause = phy->asym_pause;
    840
    841		put_device(&phy->mdio.dev);
    842	}
    843
    844	err = mac_dev->init(mac_dev);
    845	if (err < 0) {
    846		dev_err(dev, "mac_dev->init() = %d\n", err);
    847		of_node_put(mac_dev->phy_node);
    848		goto _return_of_get_parent;
    849	}
    850
    851	/* pause frame autonegotiation enabled */
    852	mac_dev->autoneg_pause = true;
    853
    854	/* By intializing the values to false, force FMD to enable PAUSE frames
    855	 * on RX and TX
    856	 */
    857	mac_dev->rx_pause_req = true;
    858	mac_dev->tx_pause_req = true;
    859	mac_dev->rx_pause_active = false;
    860	mac_dev->tx_pause_active = false;
    861	err = fman_set_mac_active_pause(mac_dev, true, true);
    862	if (err < 0)
    863		dev_err(dev, "fman_set_mac_active_pause() = %d\n", err);
    864
    865	if (!is_zero_ether_addr(mac_dev->addr))
    866		dev_info(dev, "FMan MAC address: %pM\n", mac_dev->addr);
    867
    868	priv->eth_dev = dpaa_eth_add_device(fman_id, mac_dev);
    869	if (IS_ERR(priv->eth_dev)) {
    870		dev_err(dev, "failed to add Ethernet platform device for MAC %d\n",
    871			priv->cell_index);
    872		priv->eth_dev = NULL;
    873	}
    874
    875	goto _return;
    876
    877_return_of_node_put:
    878	of_node_put(dev_node);
    879_return_of_get_parent:
    880	kfree(priv->fixed_link);
    881_return:
    882	return err;
    883}
    884
    885static struct platform_driver mac_driver = {
    886	.driver = {
    887		.name		= KBUILD_MODNAME,
    888		.of_match_table	= mac_match,
    889	},
    890	.probe		= mac_probe,
    891};
    892
    893builtin_platform_driver(mac_driver);