Linux Audio

Check our new training course

Buildroot integration, development and maintenance

Need a Buildroot system for your embedded project?
Loading...
v6.8
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*******************************************************************************
  3  This contains the functions to handle the platform driver.
  4
  5  Copyright (C) 2007-2011  STMicroelectronics Ltd
  6
 
 
 
 
 
 
 
 
 
 
 
  7
  8  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
  9*******************************************************************************/
 10
 11#include <linux/device.h>
 12#include <linux/platform_device.h>
 13#include <linux/pm_runtime.h>
 14#include <linux/module.h>
 15#include <linux/io.h>
 16#include <linux/of.h>
 17#include <linux/of_net.h>
 
 18#include <linux/of_mdio.h>
 19
 20#include "stmmac.h"
 21#include "stmmac_platform.h"
 22
 23#ifdef CONFIG_OF
 24
 25/**
 26 * dwmac1000_validate_mcast_bins - validates the number of Multicast filter bins
 27 * @dev: struct device of the platform device
 28 * @mcast_bins: Multicast filtering bins
 29 * Description:
 30 * this function validates the number of Multicast filtering bins specified
 31 * by the configuration through the device tree. The Synopsys GMAC supports
 32 * 64 bins, 128 bins, or 256 bins. "bins" refer to the division of CRC
 33 * number space. 64 bins correspond to 6 bits of the CRC, 128 corresponds
 34 * to 7 bits, and 256 refers to 8 bits of the CRC. Any other setting is
 35 * invalid and will cause the filtering algorithm to use Multicast
 36 * promiscuous mode.
 37 */
 38static int dwmac1000_validate_mcast_bins(struct device *dev, int mcast_bins)
 39{
 40	int x = mcast_bins;
 41
 42	switch (x) {
 43	case HASH_TABLE_SIZE:
 44	case 128:
 45	case 256:
 46		break;
 47	default:
 48		x = 0;
 49		dev_info(dev, "Hash table entries set to unexpected value %d\n",
 50			 mcast_bins);
 51		break;
 52	}
 53	return x;
 54}
 55
 56/**
 57 * dwmac1000_validate_ucast_entries - validate the Unicast address entries
 58 * @dev: struct device of the platform device
 59 * @ucast_entries: number of Unicast address entries
 60 * Description:
 61 * This function validates the number of Unicast address entries supported
 62 * by a particular Synopsys 10/100/1000 controller. The Synopsys controller
 63 * supports 1..32, 64, or 128 Unicast filter entries for it's Unicast filter
 64 * logic. This function validates a valid, supported configuration is
 65 * selected, and defaults to 1 Unicast address if an unsupported
 66 * configuration is selected.
 67 */
 68static int dwmac1000_validate_ucast_entries(struct device *dev,
 69					    int ucast_entries)
 70{
 71	int x = ucast_entries;
 72
 73	switch (x) {
 74	case 1 ... 32:
 
 75	case 64:
 76	case 128:
 77		break;
 78	default:
 79		x = 1;
 80		dev_info(dev, "Unicast table entries set to unexpected value %d\n",
 81			 ucast_entries);
 82		break;
 83	}
 84	return x;
 85}
 86
 87/**
 88 * stmmac_axi_setup - parse DT parameters for programming the AXI register
 89 * @pdev: platform device
 
 90 * Description:
 91 * if required, from device-tree the AXI internal register can be tuned
 92 * by using platform parameters.
 93 */
 94static struct stmmac_axi *stmmac_axi_setup(struct platform_device *pdev)
 95{
 96	struct device_node *np;
 97	struct stmmac_axi *axi;
 98
 99	np = of_parse_phandle(pdev->dev.of_node, "snps,axi-config", 0);
100	if (!np)
101		return NULL;
102
103	axi = devm_kzalloc(&pdev->dev, sizeof(*axi), GFP_KERNEL);
104	if (!axi) {
105		of_node_put(np);
106		return ERR_PTR(-ENOMEM);
107	}
108
109	axi->axi_lpi_en = of_property_read_bool(np, "snps,lpi_en");
110	axi->axi_xit_frm = of_property_read_bool(np, "snps,xit_frm");
111	axi->axi_kbbe = of_property_read_bool(np, "snps,kbbe");
112	axi->axi_fb = of_property_read_bool(np, "snps,fb");
113	axi->axi_mb = of_property_read_bool(np, "snps,mb");
114	axi->axi_rb =  of_property_read_bool(np, "snps,rb");
115
116	if (of_property_read_u32(np, "snps,wr_osr_lmt", &axi->axi_wr_osr_lmt))
117		axi->axi_wr_osr_lmt = 1;
118	if (of_property_read_u32(np, "snps,rd_osr_lmt", &axi->axi_rd_osr_lmt))
119		axi->axi_rd_osr_lmt = 1;
120	of_property_read_u32_array(np, "snps,blen", axi->axi_blen, AXI_BLEN);
121	of_node_put(np);
122
123	return axi;
124}
125
126/**
127 * stmmac_mtl_setup - parse DT parameters for multiple queues configuration
128 * @pdev: platform device
129 * @plat: enet data
130 */
131static int stmmac_mtl_setup(struct platform_device *pdev,
132			    struct plat_stmmacenet_data *plat)
133{
134	struct device_node *q_node;
135	struct device_node *rx_node;
136	struct device_node *tx_node;
137	u8 queue = 0;
138	int ret = 0;
139
140	/* For backwards-compatibility with device trees that don't have any
141	 * snps,mtl-rx-config or snps,mtl-tx-config properties, we fall back
142	 * to one RX and TX queues each.
143	 */
144	plat->rx_queues_to_use = 1;
145	plat->tx_queues_to_use = 1;
146
147	/* First Queue must always be in DCB mode. As MTL_QUEUE_DCB = 1 we need
148	 * to always set this, otherwise Queue will be classified as AVB
149	 * (because MTL_QUEUE_AVB = 0).
150	 */
151	plat->rx_queues_cfg[0].mode_to_use = MTL_QUEUE_DCB;
152	plat->tx_queues_cfg[0].mode_to_use = MTL_QUEUE_DCB;
153
154	rx_node = of_parse_phandle(pdev->dev.of_node, "snps,mtl-rx-config", 0);
155	if (!rx_node)
156		return ret;
157
158	tx_node = of_parse_phandle(pdev->dev.of_node, "snps,mtl-tx-config", 0);
159	if (!tx_node) {
160		of_node_put(rx_node);
161		return ret;
162	}
163
164	/* Processing RX queues common config */
165	if (of_property_read_u32(rx_node, "snps,rx-queues-to-use",
166				 &plat->rx_queues_to_use))
167		plat->rx_queues_to_use = 1;
168
169	if (of_property_read_bool(rx_node, "snps,rx-sched-sp"))
170		plat->rx_sched_algorithm = MTL_RX_ALGORITHM_SP;
171	else if (of_property_read_bool(rx_node, "snps,rx-sched-wsp"))
172		plat->rx_sched_algorithm = MTL_RX_ALGORITHM_WSP;
173	else
174		plat->rx_sched_algorithm = MTL_RX_ALGORITHM_SP;
175
176	/* Processing individual RX queue config */
177	for_each_child_of_node(rx_node, q_node) {
178		if (queue >= plat->rx_queues_to_use)
179			break;
180
181		if (of_property_read_bool(q_node, "snps,dcb-algorithm"))
182			plat->rx_queues_cfg[queue].mode_to_use = MTL_QUEUE_DCB;
183		else if (of_property_read_bool(q_node, "snps,avb-algorithm"))
184			plat->rx_queues_cfg[queue].mode_to_use = MTL_QUEUE_AVB;
185		else
186			plat->rx_queues_cfg[queue].mode_to_use = MTL_QUEUE_DCB;
187
188		if (of_property_read_u32(q_node, "snps,map-to-dma-channel",
189					 &plat->rx_queues_cfg[queue].chan))
190			plat->rx_queues_cfg[queue].chan = queue;
191		/* TODO: Dynamic mapping to be included in the future */
192
193		if (of_property_read_u32(q_node, "snps,priority",
194					&plat->rx_queues_cfg[queue].prio)) {
195			plat->rx_queues_cfg[queue].prio = 0;
196			plat->rx_queues_cfg[queue].use_prio = false;
197		} else {
198			plat->rx_queues_cfg[queue].use_prio = true;
199		}
200
201		/* RX queue specific packet type routing */
202		if (of_property_read_bool(q_node, "snps,route-avcp"))
203			plat->rx_queues_cfg[queue].pkt_route = PACKET_AVCPQ;
204		else if (of_property_read_bool(q_node, "snps,route-ptp"))
205			plat->rx_queues_cfg[queue].pkt_route = PACKET_PTPQ;
206		else if (of_property_read_bool(q_node, "snps,route-dcbcp"))
207			plat->rx_queues_cfg[queue].pkt_route = PACKET_DCBCPQ;
208		else if (of_property_read_bool(q_node, "snps,route-up"))
209			plat->rx_queues_cfg[queue].pkt_route = PACKET_UPQ;
210		else if (of_property_read_bool(q_node, "snps,route-multi-broad"))
211			plat->rx_queues_cfg[queue].pkt_route = PACKET_MCBCQ;
212		else
213			plat->rx_queues_cfg[queue].pkt_route = 0x0;
214
215		queue++;
216	}
217	if (queue != plat->rx_queues_to_use) {
218		ret = -EINVAL;
219		dev_err(&pdev->dev, "Not all RX queues were configured\n");
220		goto out;
221	}
222
223	/* Processing TX queues common config */
224	if (of_property_read_u32(tx_node, "snps,tx-queues-to-use",
225				 &plat->tx_queues_to_use))
226		plat->tx_queues_to_use = 1;
227
228	if (of_property_read_bool(tx_node, "snps,tx-sched-wrr"))
229		plat->tx_sched_algorithm = MTL_TX_ALGORITHM_WRR;
230	else if (of_property_read_bool(tx_node, "snps,tx-sched-wfq"))
231		plat->tx_sched_algorithm = MTL_TX_ALGORITHM_WFQ;
232	else if (of_property_read_bool(tx_node, "snps,tx-sched-dwrr"))
233		plat->tx_sched_algorithm = MTL_TX_ALGORITHM_DWRR;
 
 
234	else
235		plat->tx_sched_algorithm = MTL_TX_ALGORITHM_SP;
236
237	queue = 0;
238
239	/* Processing individual TX queue config */
240	for_each_child_of_node(tx_node, q_node) {
241		if (queue >= plat->tx_queues_to_use)
242			break;
243
244		if (of_property_read_u32(q_node, "snps,weight",
245					 &plat->tx_queues_cfg[queue].weight))
246			plat->tx_queues_cfg[queue].weight = 0x10 + queue;
247
248		if (of_property_read_bool(q_node, "snps,dcb-algorithm")) {
249			plat->tx_queues_cfg[queue].mode_to_use = MTL_QUEUE_DCB;
250		} else if (of_property_read_bool(q_node,
251						 "snps,avb-algorithm")) {
252			plat->tx_queues_cfg[queue].mode_to_use = MTL_QUEUE_AVB;
253
254			/* Credit Base Shaper parameters used by AVB */
255			if (of_property_read_u32(q_node, "snps,send_slope",
256				&plat->tx_queues_cfg[queue].send_slope))
257				plat->tx_queues_cfg[queue].send_slope = 0x0;
258			if (of_property_read_u32(q_node, "snps,idle_slope",
259				&plat->tx_queues_cfg[queue].idle_slope))
260				plat->tx_queues_cfg[queue].idle_slope = 0x0;
261			if (of_property_read_u32(q_node, "snps,high_credit",
262				&plat->tx_queues_cfg[queue].high_credit))
263				plat->tx_queues_cfg[queue].high_credit = 0x0;
264			if (of_property_read_u32(q_node, "snps,low_credit",
265				&plat->tx_queues_cfg[queue].low_credit))
266				plat->tx_queues_cfg[queue].low_credit = 0x0;
267		} else {
268			plat->tx_queues_cfg[queue].mode_to_use = MTL_QUEUE_DCB;
269		}
270
271		if (of_property_read_u32(q_node, "snps,priority",
272					&plat->tx_queues_cfg[queue].prio)) {
273			plat->tx_queues_cfg[queue].prio = 0;
274			plat->tx_queues_cfg[queue].use_prio = false;
275		} else {
276			plat->tx_queues_cfg[queue].use_prio = true;
277		}
278
279		plat->tx_queues_cfg[queue].coe_unsupported =
280			of_property_read_bool(q_node, "snps,coe-unsupported");
281
282		queue++;
283	}
284	if (queue != plat->tx_queues_to_use) {
285		ret = -EINVAL;
286		dev_err(&pdev->dev, "Not all TX queues were configured\n");
287		goto out;
288	}
289
290out:
291	of_node_put(rx_node);
292	of_node_put(tx_node);
293	of_node_put(q_node);
294
295	return ret;
296}
297
298/**
299 * stmmac_of_get_mdio() - Gets the MDIO bus from the devicetree.
300 * @np: devicetree node
301 *
302 * The MDIO bus will be searched for in the following ways:
303 * 1. The compatible is "snps,dwc-qos-ethernet-4.10" && a "mdio" named
304 *    child node exists
305 * 2. A child node with the "snps,dwmac-mdio" compatible is present
 
 
 
 
 
 
 
 
 
 
 
 
 
 
306 *
307 * Return: The MDIO node if present otherwise NULL
308 */
309static struct device_node *stmmac_of_get_mdio(struct device_node *np)
 
310{
 
311	static const struct of_device_id need_mdio_ids[] = {
312		{ .compatible = "snps,dwc-qos-ethernet-4.10" },
313		{},
314	};
315	struct device_node *mdio_node = NULL;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
316
317	if (of_match_node(need_mdio_ids, np)) {
318		mdio_node = of_get_child_by_name(np, "mdio");
319	} else {
320		/**
321		 * If snps,dwmac-mdio is passed from DT, always register
322		 * the MDIO
323		 */
324		for_each_child_of_node(np, mdio_node) {
325			if (of_device_is_compatible(mdio_node,
326						    "snps,dwmac-mdio"))
327				break;
328		}
329	}
330
331	return mdio_node;
332}
333
334/**
335 * stmmac_mdio_setup() - Populate platform related MDIO structures.
336 * @plat: driver data platform structure
337 * @np: devicetree node
338 * @dev: device pointer
339 *
340 * This searches for MDIO information from the devicetree.
341 * If an MDIO node is found, it's assigned to plat->mdio_node and
342 * plat->mdio_bus_data is allocated.
343 * If no connection can be determined, just plat->mdio_bus_data is allocated
344 * to indicate a bus should be created and scanned for a phy.
345 * If it's determined there's no MDIO bus needed, both are left NULL.
346 *
347 * This expects that plat->phy_node has already been searched for.
348 *
349 * Return: 0 on success, errno otherwise.
350 */
351static int stmmac_mdio_setup(struct plat_stmmacenet_data *plat,
352			     struct device_node *np, struct device *dev)
353{
354	bool legacy_mdio;
355
356	plat->mdio_node = stmmac_of_get_mdio(np);
357	if (plat->mdio_node)
358		dev_dbg(dev, "Found MDIO subnode\n");
359
360	/* Legacy devicetrees allowed for no MDIO bus description and expect
361	 * the bus to be scanned for devices. If there's no phy or fixed-link
362	 * described assume this is the case since there must be something
363	 * connected to the MAC.
364	 */
365	legacy_mdio = !of_phy_is_fixed_link(np) && !plat->phy_node;
366	if (legacy_mdio)
367		dev_info(dev, "Deprecated MDIO bus assumption used\n");
368
369	if (plat->mdio_node || legacy_mdio) {
370		plat->mdio_bus_data = devm_kzalloc(dev,
371						   sizeof(*plat->mdio_bus_data),
372						   GFP_KERNEL);
373		if (!plat->mdio_bus_data)
374			return -ENOMEM;
375
376		plat->mdio_bus_data->needs_reset = true;
377	}
378
 
 
 
 
379	return 0;
380}
381
382/**
383 * stmmac_of_get_mac_mode - retrieves the interface of the MAC
384 * @np: - device-tree node
385 * Description:
386 * Similar to `of_get_phy_mode()`, this function will retrieve (from
387 * the device-tree) the interface mode on the MAC side. This assumes
388 * that there is mode converter in-between the MAC & PHY
389 * (e.g. GMII-to-RGMII).
390 */
391static int stmmac_of_get_mac_mode(struct device_node *np)
392{
393	const char *pm;
394	int err, i;
395
396	err = of_property_read_string(np, "mac-mode", &pm);
397	if (err < 0)
398		return err;
399
400	for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++) {
401		if (!strcasecmp(pm, phy_modes(i)))
402			return i;
403	}
404
405	return -ENODEV;
406}
407
408/**
409 * stmmac_remove_config_dt - undo the effects of stmmac_probe_config_dt()
410 * @pdev: platform_device structure
411 * @plat: driver data platform structure
412 *
413 * Release resources claimed by stmmac_probe_config_dt().
414 */
415static void stmmac_remove_config_dt(struct platform_device *pdev,
416				    struct plat_stmmacenet_data *plat)
417{
418	clk_disable_unprepare(plat->stmmac_clk);
419	clk_disable_unprepare(plat->pclk);
420	of_node_put(plat->phy_node);
421	of_node_put(plat->mdio_node);
422}
423
424/**
425 * stmmac_probe_config_dt - parse device-tree driver parameters
426 * @pdev: platform_device structure
427 * @mac: MAC address to use
428 * Description:
429 * this function is to read the driver parameters from device-tree and
430 * set some private fields that will be used by the main at runtime.
431 */
432static struct plat_stmmacenet_data *
433stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
434{
435	struct device_node *np = pdev->dev.of_node;
436	struct plat_stmmacenet_data *plat;
437	struct stmmac_dma_cfg *dma_cfg;
438	int phy_mode;
439	void *ret;
440	int rc;
441
442	plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL);
443	if (!plat)
444		return ERR_PTR(-ENOMEM);
445
446	rc = of_get_mac_address(np, mac);
447	if (rc) {
448		if (rc == -EPROBE_DEFER)
449			return ERR_PTR(rc);
450
451		eth_zero_addr(mac);
452	}
453
454	phy_mode = device_get_phy_mode(&pdev->dev);
455	if (phy_mode < 0)
456		return ERR_PTR(phy_mode);
457
458	plat->phy_interface = phy_mode;
459	rc = stmmac_of_get_mac_mode(np);
460	plat->mac_interface = rc < 0 ? plat->phy_interface : rc;
461
462	/* Some wrapper drivers still rely on phy_node. Let's save it while
463	 * they are not converted to phylink. */
464	plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
465
466	/* PHYLINK automatically parses the phy-handle property */
467	plat->port_node = of_fwnode_handle(np);
468
469	/* Get max speed of operation from device tree */
470	of_property_read_u32(np, "max-speed", &plat->max_speed);
 
471
472	plat->bus_id = of_alias_get_id(np, "ethernet");
473	if (plat->bus_id < 0)
474		plat->bus_id = 0;
475
476	/* Default to phy auto-detection */
477	plat->phy_addr = -1;
478
479	/* Default to get clk_csr from stmmac_clk_csr_set(),
480	 * or get clk_csr from device tree.
481	 */
482	plat->clk_csr = -1;
483	if (of_property_read_u32(np, "snps,clk-csr", &plat->clk_csr))
484		of_property_read_u32(np, "clk_csr", &plat->clk_csr);
485
486	/* "snps,phy-addr" is not a standard property. Mark it as deprecated
487	 * and warn of its use. Remove this when phy node support is added.
488	 */
489	if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0)
490		dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n");
491
492	rc = stmmac_mdio_setup(plat, np, &pdev->dev);
 
493	if (rc)
494		return ERR_PTR(rc);
495
496	of_property_read_u32(np, "tx-fifo-depth", &plat->tx_fifo_size);
497
498	of_property_read_u32(np, "rx-fifo-depth", &plat->rx_fifo_size);
499
500	plat->force_sf_dma_mode =
501		of_property_read_bool(np, "snps,force_sf_dma_mode");
502
503	if (of_property_read_bool(np, "snps,en-tx-lpi-clockgating"))
504		plat->flags |= STMMAC_FLAG_EN_TX_LPI_CLOCKGATING;
505
506	/* Set the maxmtu to a default of JUMBO_LEN in case the
507	 * parameter is not present in the device tree.
508	 */
509	plat->maxmtu = JUMBO_LEN;
510
511	/* Set default value for multicast hash bins */
512	plat->multicast_filter_bins = HASH_TABLE_SIZE;
513
514	/* Set default value for unicast filter entries */
515	plat->unicast_filter_entries = 1;
516
517	/*
518	 * Currently only the properties needed on SPEAr600
519	 * are provided. All other properties should be added
520	 * once needed on other platforms.
521	 */
522	if (of_device_is_compatible(np, "st,spear600-gmac") ||
523		of_device_is_compatible(np, "snps,dwmac-3.50a") ||
524		of_device_is_compatible(np, "snps,dwmac-3.70a") ||
525		of_device_is_compatible(np, "snps,dwmac")) {
526		/* Note that the max-frame-size parameter as defined in the
527		 * ePAPR v1.1 spec is defined as max-frame-size, it's
528		 * actually used as the IEEE definition of MAC Client
529		 * data, or MTU. The ePAPR specification is confusing as
530		 * the definition is max-frame-size, but usage examples
531		 * are clearly MTUs
532		 */
533		of_property_read_u32(np, "max-frame-size", &plat->maxmtu);
534		of_property_read_u32(np, "snps,multicast-filter-bins",
535				     &plat->multicast_filter_bins);
536		of_property_read_u32(np, "snps,perfect-filter-entries",
537				     &plat->unicast_filter_entries);
538		plat->unicast_filter_entries = dwmac1000_validate_ucast_entries(
539				&pdev->dev, plat->unicast_filter_entries);
540		plat->multicast_filter_bins = dwmac1000_validate_mcast_bins(
541				&pdev->dev, plat->multicast_filter_bins);
542		plat->has_gmac = 1;
543		plat->pmt = 1;
544	}
545
546	if (of_device_is_compatible(np, "snps,dwmac-3.40a")) {
547		plat->has_gmac = 1;
548		plat->enh_desc = 1;
549		plat->tx_coe = 1;
550		plat->bugged_jumbo = 1;
551		plat->pmt = 1;
552	}
553
554	if (of_device_is_compatible(np, "snps,dwmac-4.00") ||
555	    of_device_is_compatible(np, "snps,dwmac-4.10a") ||
556	    of_device_is_compatible(np, "snps,dwmac-4.20a") ||
557	    of_device_is_compatible(np, "snps,dwmac-5.10a") ||
558	    of_device_is_compatible(np, "snps,dwmac-5.20")) {
559		plat->has_gmac4 = 1;
560		plat->has_gmac = 0;
561		plat->pmt = 1;
562		if (of_property_read_bool(np, "snps,tso"))
563			plat->flags |= STMMAC_FLAG_TSO_EN;
564	}
565
566	if (of_device_is_compatible(np, "snps,dwmac-3.610") ||
567		of_device_is_compatible(np, "snps,dwmac-3.710")) {
568		plat->enh_desc = 1;
569		plat->bugged_jumbo = 1;
570		plat->force_sf_dma_mode = 1;
571	}
572
573	if (of_device_is_compatible(np, "snps,dwxgmac")) {
574		plat->has_xgmac = 1;
575		plat->pmt = 1;
576		if (of_property_read_bool(np, "snps,tso"))
577			plat->flags |= STMMAC_FLAG_TSO_EN;
578	}
579
580	dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
581			       GFP_KERNEL);
582	if (!dma_cfg) {
583		stmmac_remove_config_dt(pdev, plat);
584		return ERR_PTR(-ENOMEM);
585	}
586	plat->dma_cfg = dma_cfg;
587
588	of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
589	if (!dma_cfg->pbl)
590		dma_cfg->pbl = DEFAULT_DMA_PBL;
591	of_property_read_u32(np, "snps,txpbl", &dma_cfg->txpbl);
592	of_property_read_u32(np, "snps,rxpbl", &dma_cfg->rxpbl);
593	dma_cfg->pblx8 = !of_property_read_bool(np, "snps,no-pbl-x8");
594
595	dma_cfg->aal = of_property_read_bool(np, "snps,aal");
596	dma_cfg->fixed_burst = of_property_read_bool(np, "snps,fixed-burst");
597	dma_cfg->mixed_burst = of_property_read_bool(np, "snps,mixed-burst");
598
599	plat->force_thresh_dma_mode = of_property_read_bool(np, "snps,force_thresh_dma_mode");
600	if (plat->force_thresh_dma_mode && plat->force_sf_dma_mode) {
601		plat->force_sf_dma_mode = 0;
602		dev_warn(&pdev->dev,
603			 "force_sf_dma_mode is ignored if force_thresh_dma_mode is set.\n");
604	}
605
606	of_property_read_u32(np, "snps,ps-speed", &plat->mac_port_sel_speed);
607
608	plat->axi = stmmac_axi_setup(pdev);
609
610	rc = stmmac_mtl_setup(pdev, plat);
611	if (rc) {
612		stmmac_remove_config_dt(pdev, plat);
613		return ERR_PTR(rc);
614	}
615
616	/* clock setup */
617	if (!of_device_is_compatible(np, "snps,dwc-qos-ethernet-4.10")) {
618		plat->stmmac_clk = devm_clk_get(&pdev->dev,
619						STMMAC_RESOURCE_NAME);
620		if (IS_ERR(plat->stmmac_clk)) {
621			dev_warn(&pdev->dev, "Cannot get CSR clock\n");
622			plat->stmmac_clk = NULL;
623		}
624		clk_prepare_enable(plat->stmmac_clk);
625	}
 
626
627	plat->pclk = devm_clk_get_optional(&pdev->dev, "pclk");
628	if (IS_ERR(plat->pclk)) {
629		ret = plat->pclk;
630		goto error_pclk_get;
 
 
631	}
632	clk_prepare_enable(plat->pclk);
633
634	/* Fall-back to main clock in case of no PTP ref is passed */
635	plat->clk_ptp_ref = devm_clk_get(&pdev->dev, "ptp_ref");
636	if (IS_ERR(plat->clk_ptp_ref)) {
637		plat->clk_ptp_rate = clk_get_rate(plat->stmmac_clk);
638		plat->clk_ptp_ref = NULL;
639		dev_info(&pdev->dev, "PTP uses main clock\n");
640	} else {
641		plat->clk_ptp_rate = clk_get_rate(plat->clk_ptp_ref);
642		dev_dbg(&pdev->dev, "PTP rate %d\n", plat->clk_ptp_rate);
643	}
644
645	plat->stmmac_rst = devm_reset_control_get_optional(&pdev->dev,
646							   STMMAC_RESOURCE_NAME);
647	if (IS_ERR(plat->stmmac_rst)) {
648		ret = plat->stmmac_rst;
649		goto error_hw_init;
650	}
651
652	plat->stmmac_ahb_rst = devm_reset_control_get_optional_shared(
653							&pdev->dev, "ahb");
654	if (IS_ERR(plat->stmmac_ahb_rst)) {
655		ret = plat->stmmac_ahb_rst;
656		goto error_hw_init;
657	}
658
659	return plat;
660
661error_hw_init:
662	clk_disable_unprepare(plat->pclk);
663error_pclk_get:
664	clk_disable_unprepare(plat->stmmac_clk);
665
666	return ret;
667}
668
669static void devm_stmmac_remove_config_dt(void *data)
670{
671	struct plat_stmmacenet_data *plat = data;
672
673	/* Platform data argument is unused */
674	stmmac_remove_config_dt(NULL, plat);
675}
676
677/**
678 * devm_stmmac_probe_config_dt
679 * @pdev: platform_device structure
680 * @mac: MAC address to use
681 * Description: Devres variant of stmmac_probe_config_dt(). Does not require
682 * the user to call stmmac_remove_config_dt() at driver detach.
683 */
684struct plat_stmmacenet_data *
685devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
686{
687	struct plat_stmmacenet_data *plat;
688	int ret;
689
690	plat = stmmac_probe_config_dt(pdev, mac);
691	if (IS_ERR(plat))
692		return plat;
693
694	ret = devm_add_action_or_reset(&pdev->dev,
695				       devm_stmmac_remove_config_dt, plat);
696	if (ret)
697		return ERR_PTR(ret);
698
699	return plat;
 
 
 
700}
701#else
702struct plat_stmmacenet_data *
703devm_stmmac_probe_config_dt(struct platform_device *pdev, u8 *mac)
704{
705	return ERR_PTR(-EINVAL);
706}
 
 
 
 
 
707#endif /* CONFIG_OF */
708EXPORT_SYMBOL_GPL(devm_stmmac_probe_config_dt);
 
709
710int stmmac_get_platform_resources(struct platform_device *pdev,
711				  struct stmmac_resources *stmmac_res)
712{
 
 
713	memset(stmmac_res, 0, sizeof(*stmmac_res));
714
715	/* Get IRQ information early to have an ability to ask for deferred
716	 * probe if needed before we went too far with resource allocation.
717	 */
718	stmmac_res->irq = platform_get_irq_byname(pdev, "macirq");
719	if (stmmac_res->irq < 0)
 
 
 
 
720		return stmmac_res->irq;
 
721
722	/* On some platforms e.g. SPEAr the wake up irq differs from the mac irq
723	 * The external wake up irq can be passed through the platform code
724	 * named as "eth_wake_irq"
725	 *
726	 * In case the wake up interrupt is not passed from the platform
727	 * so the driver will continue to use the mac irq (ndev->irq)
728	 */
729	stmmac_res->wol_irq =
730		platform_get_irq_byname_optional(pdev, "eth_wake_irq");
731	if (stmmac_res->wol_irq < 0) {
732		if (stmmac_res->wol_irq == -EPROBE_DEFER)
733			return -EPROBE_DEFER;
734		dev_info(&pdev->dev, "IRQ eth_wake_irq not found\n");
735		stmmac_res->wol_irq = stmmac_res->irq;
736	}
737
738	stmmac_res->lpi_irq =
739		platform_get_irq_byname_optional(pdev, "eth_lpi");
740	if (stmmac_res->lpi_irq < 0) {
741		if (stmmac_res->lpi_irq == -EPROBE_DEFER)
742			return -EPROBE_DEFER;
743		dev_info(&pdev->dev, "IRQ eth_lpi not found\n");
744	}
745
746	stmmac_res->addr = devm_platform_ioremap_resource(pdev, 0);
 
747
748	return PTR_ERR_OR_ZERO(stmmac_res->addr);
749}
750EXPORT_SYMBOL_GPL(stmmac_get_platform_resources);
751
752/**
753 * stmmac_pltfr_init
754 * @pdev: pointer to the platform device
755 * @plat: driver data platform structure
756 * Description: Call the platform's init callback (if any) and propagate
757 * the return value.
758 */
759int stmmac_pltfr_init(struct platform_device *pdev,
760		      struct plat_stmmacenet_data *plat)
761{
762	int ret = 0;
763
764	if (plat->init)
765		ret = plat->init(pdev, plat->bsp_priv);
766
767	return ret;
768}
769EXPORT_SYMBOL_GPL(stmmac_pltfr_init);
770
771/**
772 * stmmac_pltfr_exit
773 * @pdev: pointer to the platform device
774 * @plat: driver data platform structure
775 * Description: Call the platform's exit callback (if any).
776 */
777void stmmac_pltfr_exit(struct platform_device *pdev,
778		       struct plat_stmmacenet_data *plat)
779{
780	if (plat->exit)
781		plat->exit(pdev, plat->bsp_priv);
782}
783EXPORT_SYMBOL_GPL(stmmac_pltfr_exit);
784
785/**
786 * stmmac_pltfr_probe
787 * @pdev: platform device pointer
788 * @plat: driver data platform structure
789 * @res: stmmac resources structure
790 * Description: This calls the platform's init() callback and probes the
791 * stmmac driver.
792 */
793int stmmac_pltfr_probe(struct platform_device *pdev,
794		       struct plat_stmmacenet_data *plat,
795		       struct stmmac_resources *res)
796{
797	int ret;
798
799	ret = stmmac_pltfr_init(pdev, plat);
800	if (ret)
801		return ret;
802
803	ret = stmmac_dvr_probe(&pdev->dev, plat, res);
804	if (ret) {
805		stmmac_pltfr_exit(pdev, plat);
806		return ret;
807	}
808
809	return ret;
810}
811EXPORT_SYMBOL_GPL(stmmac_pltfr_probe);
812
813static void devm_stmmac_pltfr_remove(void *data)
814{
815	struct platform_device *pdev = data;
816
817	stmmac_pltfr_remove(pdev);
818}
819
820/**
821 * devm_stmmac_pltfr_probe
822 * @pdev: pointer to the platform device
823 * @plat: driver data platform structure
824 * @res: stmmac resources
825 * Description: Devres variant of stmmac_pltfr_probe(). Allows users to skip
826 * calling stmmac_pltfr_remove() on driver detach.
827 */
828int devm_stmmac_pltfr_probe(struct platform_device *pdev,
829			    struct plat_stmmacenet_data *plat,
830			    struct stmmac_resources *res)
831{
832	int ret;
833
834	ret = stmmac_pltfr_probe(pdev, plat, res);
835	if (ret)
836		return ret;
837
838	return devm_add_action_or_reset(&pdev->dev, devm_stmmac_pltfr_remove,
839					pdev);
840}
841EXPORT_SYMBOL_GPL(devm_stmmac_pltfr_probe);
842
843/**
844 * stmmac_pltfr_remove
845 * @pdev: pointer to the platform device
846 * Description: This undoes the effects of stmmac_pltfr_probe() by removing the
847 * driver and calling the platform's exit() callback.
848 */
849void stmmac_pltfr_remove(struct platform_device *pdev)
850{
851	struct net_device *ndev = platform_get_drvdata(pdev);
852	struct stmmac_priv *priv = netdev_priv(ndev);
853	struct plat_stmmacenet_data *plat = priv->plat;
854
855	stmmac_dvr_remove(&pdev->dev);
856	stmmac_pltfr_exit(pdev, plat);
857}
858EXPORT_SYMBOL_GPL(stmmac_pltfr_remove);
859
 
860/**
861 * stmmac_pltfr_suspend
862 * @dev: device pointer
863 * Description: this function is invoked when suspend the driver and it direcly
864 * call the main suspend function and then, if required, on some platform, it
865 * can call an exit helper.
866 */
867static int __maybe_unused stmmac_pltfr_suspend(struct device *dev)
868{
869	int ret;
870	struct net_device *ndev = dev_get_drvdata(dev);
871	struct stmmac_priv *priv = netdev_priv(ndev);
872	struct platform_device *pdev = to_platform_device(dev);
873
874	ret = stmmac_suspend(dev);
875	stmmac_pltfr_exit(pdev, priv->plat);
 
876
877	return ret;
878}
879
880/**
881 * stmmac_pltfr_resume
882 * @dev: device pointer
883 * Description: this function is invoked when resume the driver before calling
884 * the main resume function, on some platforms, it can call own init helper
885 * if required.
886 */
887static int __maybe_unused stmmac_pltfr_resume(struct device *dev)
888{
889	struct net_device *ndev = dev_get_drvdata(dev);
890	struct stmmac_priv *priv = netdev_priv(ndev);
891	struct platform_device *pdev = to_platform_device(dev);
892	int ret;
893
894	ret = stmmac_pltfr_init(pdev, priv->plat);
895	if (ret)
896		return ret;
897
898	return stmmac_resume(dev);
899}
 
900
901static int __maybe_unused stmmac_runtime_suspend(struct device *dev)
902{
903	struct net_device *ndev = dev_get_drvdata(dev);
904	struct stmmac_priv *priv = netdev_priv(ndev);
905
906	stmmac_bus_clks_config(priv, false);
907
908	return 0;
909}
910
911static int __maybe_unused stmmac_runtime_resume(struct device *dev)
912{
913	struct net_device *ndev = dev_get_drvdata(dev);
914	struct stmmac_priv *priv = netdev_priv(ndev);
915
916	return stmmac_bus_clks_config(priv, true);
917}
918
919static int __maybe_unused stmmac_pltfr_noirq_suspend(struct device *dev)
920{
921	struct net_device *ndev = dev_get_drvdata(dev);
922	struct stmmac_priv *priv = netdev_priv(ndev);
923	int ret;
924
925	if (!netif_running(ndev))
926		return 0;
927
928	if (!device_may_wakeup(priv->device) || !priv->plat->pmt) {
929		/* Disable clock in case of PWM is off */
930		clk_disable_unprepare(priv->plat->clk_ptp_ref);
931
932		ret = pm_runtime_force_suspend(dev);
933		if (ret)
934			return ret;
935	}
936
937	return 0;
938}
939
940static int __maybe_unused stmmac_pltfr_noirq_resume(struct device *dev)
941{
942	struct net_device *ndev = dev_get_drvdata(dev);
943	struct stmmac_priv *priv = netdev_priv(ndev);
944	int ret;
945
946	if (!netif_running(ndev))
947		return 0;
948
949	if (!device_may_wakeup(priv->device) || !priv->plat->pmt) {
950		/* enable the clk previously disabled */
951		ret = pm_runtime_force_resume(dev);
952		if (ret)
953			return ret;
954
955		ret = clk_prepare_enable(priv->plat->clk_ptp_ref);
956		if (ret < 0) {
957			netdev_warn(priv->dev,
958				    "failed to enable PTP reference clock: %pe\n",
959				    ERR_PTR(ret));
960			return ret;
961		}
962	}
963
964	return 0;
965}
966
967const struct dev_pm_ops stmmac_pltfr_pm_ops = {
968	SET_SYSTEM_SLEEP_PM_OPS(stmmac_pltfr_suspend, stmmac_pltfr_resume)
969	SET_RUNTIME_PM_OPS(stmmac_runtime_suspend, stmmac_runtime_resume, NULL)
970	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(stmmac_pltfr_noirq_suspend, stmmac_pltfr_noirq_resume)
971};
972EXPORT_SYMBOL_GPL(stmmac_pltfr_pm_ops);
973
974MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet platform support");
975MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
976MODULE_LICENSE("GPL");
v4.17
 
  1/*******************************************************************************
  2  This contains the functions to handle the platform driver.
  3
  4  Copyright (C) 2007-2011  STMicroelectronics Ltd
  5
  6  This program is free software; you can redistribute it and/or modify it
  7  under the terms and conditions of the GNU General Public License,
  8  version 2, as published by the Free Software Foundation.
  9
 10  This program is distributed in the hope it will be useful, but WITHOUT
 11  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 12  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 13  more details.
 14
 15  The full GNU General Public License is included in this distribution in
 16  the file called "COPYING".
 17
 18  Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
 19*******************************************************************************/
 20
 
 21#include <linux/platform_device.h>
 
 22#include <linux/module.h>
 23#include <linux/io.h>
 24#include <linux/of.h>
 25#include <linux/of_net.h>
 26#include <linux/of_device.h>
 27#include <linux/of_mdio.h>
 28
 29#include "stmmac.h"
 30#include "stmmac_platform.h"
 31
 32#ifdef CONFIG_OF
 33
 34/**
 35 * dwmac1000_validate_mcast_bins - validates the number of Multicast filter bins
 
 36 * @mcast_bins: Multicast filtering bins
 37 * Description:
 38 * this function validates the number of Multicast filtering bins specified
 39 * by the configuration through the device tree. The Synopsys GMAC supports
 40 * 64 bins, 128 bins, or 256 bins. "bins" refer to the division of CRC
 41 * number space. 64 bins correspond to 6 bits of the CRC, 128 corresponds
 42 * to 7 bits, and 256 refers to 8 bits of the CRC. Any other setting is
 43 * invalid and will cause the filtering algorithm to use Multicast
 44 * promiscuous mode.
 45 */
 46static int dwmac1000_validate_mcast_bins(int mcast_bins)
 47{
 48	int x = mcast_bins;
 49
 50	switch (x) {
 51	case HASH_TABLE_SIZE:
 52	case 128:
 53	case 256:
 54		break;
 55	default:
 56		x = 0;
 57		pr_info("Hash table entries set to unexpected value %d",
 58			mcast_bins);
 59		break;
 60	}
 61	return x;
 62}
 63
 64/**
 65 * dwmac1000_validate_ucast_entries - validate the Unicast address entries
 
 66 * @ucast_entries: number of Unicast address entries
 67 * Description:
 68 * This function validates the number of Unicast address entries supported
 69 * by a particular Synopsys 10/100/1000 controller. The Synopsys controller
 70 * supports 1, 32, 64, or 128 Unicast filter entries for it's Unicast filter
 71 * logic. This function validates a valid, supported configuration is
 72 * selected, and defaults to 1 Unicast address if an unsupported
 73 * configuration is selected.
 74 */
 75static int dwmac1000_validate_ucast_entries(int ucast_entries)
 
 76{
 77	int x = ucast_entries;
 78
 79	switch (x) {
 80	case 1:
 81	case 32:
 82	case 64:
 83	case 128:
 84		break;
 85	default:
 86		x = 1;
 87		pr_info("Unicast table entries set to unexpected value %d\n",
 88			ucast_entries);
 89		break;
 90	}
 91	return x;
 92}
 93
 94/**
 95 * stmmac_axi_setup - parse DT parameters for programming the AXI register
 96 * @pdev: platform device
 97 * @priv: driver private struct.
 98 * Description:
 99 * if required, from device-tree the AXI internal register can be tuned
100 * by using platform parameters.
101 */
102static struct stmmac_axi *stmmac_axi_setup(struct platform_device *pdev)
103{
104	struct device_node *np;
105	struct stmmac_axi *axi;
106
107	np = of_parse_phandle(pdev->dev.of_node, "snps,axi-config", 0);
108	if (!np)
109		return NULL;
110
111	axi = devm_kzalloc(&pdev->dev, sizeof(*axi), GFP_KERNEL);
112	if (!axi) {
113		of_node_put(np);
114		return ERR_PTR(-ENOMEM);
115	}
116
117	axi->axi_lpi_en = of_property_read_bool(np, "snps,lpi_en");
118	axi->axi_xit_frm = of_property_read_bool(np, "snps,xit_frm");
119	axi->axi_kbbe = of_property_read_bool(np, "snps,axi_kbbe");
120	axi->axi_fb = of_property_read_bool(np, "snps,axi_fb");
121	axi->axi_mb = of_property_read_bool(np, "snps,axi_mb");
122	axi->axi_rb =  of_property_read_bool(np, "snps,axi_rb");
123
124	if (of_property_read_u32(np, "snps,wr_osr_lmt", &axi->axi_wr_osr_lmt))
125		axi->axi_wr_osr_lmt = 1;
126	if (of_property_read_u32(np, "snps,rd_osr_lmt", &axi->axi_rd_osr_lmt))
127		axi->axi_rd_osr_lmt = 1;
128	of_property_read_u32_array(np, "snps,blen", axi->axi_blen, AXI_BLEN);
129	of_node_put(np);
130
131	return axi;
132}
133
134/**
135 * stmmac_mtl_setup - parse DT parameters for multiple queues configuration
136 * @pdev: platform device
 
137 */
138static int stmmac_mtl_setup(struct platform_device *pdev,
139			    struct plat_stmmacenet_data *plat)
140{
141	struct device_node *q_node;
142	struct device_node *rx_node;
143	struct device_node *tx_node;
144	u8 queue = 0;
145	int ret = 0;
146
147	/* For backwards-compatibility with device trees that don't have any
148	 * snps,mtl-rx-config or snps,mtl-tx-config properties, we fall back
149	 * to one RX and TX queues each.
150	 */
151	plat->rx_queues_to_use = 1;
152	plat->tx_queues_to_use = 1;
153
154	/* First Queue must always be in DCB mode. As MTL_QUEUE_DCB = 1 we need
155	 * to always set this, otherwise Queue will be classified as AVB
156	 * (because MTL_QUEUE_AVB = 0).
157	 */
158	plat->rx_queues_cfg[0].mode_to_use = MTL_QUEUE_DCB;
159	plat->tx_queues_cfg[0].mode_to_use = MTL_QUEUE_DCB;
160
161	rx_node = of_parse_phandle(pdev->dev.of_node, "snps,mtl-rx-config", 0);
162	if (!rx_node)
163		return ret;
164
165	tx_node = of_parse_phandle(pdev->dev.of_node, "snps,mtl-tx-config", 0);
166	if (!tx_node) {
167		of_node_put(rx_node);
168		return ret;
169	}
170
171	/* Processing RX queues common config */
172	if (of_property_read_u32(rx_node, "snps,rx-queues-to-use",
173				 &plat->rx_queues_to_use))
174		plat->rx_queues_to_use = 1;
175
176	if (of_property_read_bool(rx_node, "snps,rx-sched-sp"))
177		plat->rx_sched_algorithm = MTL_RX_ALGORITHM_SP;
178	else if (of_property_read_bool(rx_node, "snps,rx-sched-wsp"))
179		plat->rx_sched_algorithm = MTL_RX_ALGORITHM_WSP;
180	else
181		plat->rx_sched_algorithm = MTL_RX_ALGORITHM_SP;
182
183	/* Processing individual RX queue config */
184	for_each_child_of_node(rx_node, q_node) {
185		if (queue >= plat->rx_queues_to_use)
186			break;
187
188		if (of_property_read_bool(q_node, "snps,dcb-algorithm"))
189			plat->rx_queues_cfg[queue].mode_to_use = MTL_QUEUE_DCB;
190		else if (of_property_read_bool(q_node, "snps,avb-algorithm"))
191			plat->rx_queues_cfg[queue].mode_to_use = MTL_QUEUE_AVB;
192		else
193			plat->rx_queues_cfg[queue].mode_to_use = MTL_QUEUE_DCB;
194
195		if (of_property_read_u32(q_node, "snps,map-to-dma-channel",
196					 &plat->rx_queues_cfg[queue].chan))
197			plat->rx_queues_cfg[queue].chan = queue;
198		/* TODO: Dynamic mapping to be included in the future */
199
200		if (of_property_read_u32(q_node, "snps,priority",
201					&plat->rx_queues_cfg[queue].prio)) {
202			plat->rx_queues_cfg[queue].prio = 0;
203			plat->rx_queues_cfg[queue].use_prio = false;
204		} else {
205			plat->rx_queues_cfg[queue].use_prio = true;
206		}
207
208		/* RX queue specific packet type routing */
209		if (of_property_read_bool(q_node, "snps,route-avcp"))
210			plat->rx_queues_cfg[queue].pkt_route = PACKET_AVCPQ;
211		else if (of_property_read_bool(q_node, "snps,route-ptp"))
212			plat->rx_queues_cfg[queue].pkt_route = PACKET_PTPQ;
213		else if (of_property_read_bool(q_node, "snps,route-dcbcp"))
214			plat->rx_queues_cfg[queue].pkt_route = PACKET_DCBCPQ;
215		else if (of_property_read_bool(q_node, "snps,route-up"))
216			plat->rx_queues_cfg[queue].pkt_route = PACKET_UPQ;
217		else if (of_property_read_bool(q_node, "snps,route-multi-broad"))
218			plat->rx_queues_cfg[queue].pkt_route = PACKET_MCBCQ;
219		else
220			plat->rx_queues_cfg[queue].pkt_route = 0x0;
221
222		queue++;
223	}
224	if (queue != plat->rx_queues_to_use) {
225		ret = -EINVAL;
226		dev_err(&pdev->dev, "Not all RX queues were configured\n");
227		goto out;
228	}
229
230	/* Processing TX queues common config */
231	if (of_property_read_u32(tx_node, "snps,tx-queues-to-use",
232				 &plat->tx_queues_to_use))
233		plat->tx_queues_to_use = 1;
234
235	if (of_property_read_bool(tx_node, "snps,tx-sched-wrr"))
236		plat->tx_sched_algorithm = MTL_TX_ALGORITHM_WRR;
237	else if (of_property_read_bool(tx_node, "snps,tx-sched-wfq"))
238		plat->tx_sched_algorithm = MTL_TX_ALGORITHM_WFQ;
239	else if (of_property_read_bool(tx_node, "snps,tx-sched-dwrr"))
240		plat->tx_sched_algorithm = MTL_TX_ALGORITHM_DWRR;
241	else if (of_property_read_bool(tx_node, "snps,tx-sched-sp"))
242		plat->tx_sched_algorithm = MTL_TX_ALGORITHM_SP;
243	else
244		plat->tx_sched_algorithm = MTL_TX_ALGORITHM_SP;
245
246	queue = 0;
247
248	/* Processing individual TX queue config */
249	for_each_child_of_node(tx_node, q_node) {
250		if (queue >= plat->tx_queues_to_use)
251			break;
252
253		if (of_property_read_u32(q_node, "snps,weight",
254					 &plat->tx_queues_cfg[queue].weight))
255			plat->tx_queues_cfg[queue].weight = 0x10 + queue;
256
257		if (of_property_read_bool(q_node, "snps,dcb-algorithm")) {
258			plat->tx_queues_cfg[queue].mode_to_use = MTL_QUEUE_DCB;
259		} else if (of_property_read_bool(q_node,
260						 "snps,avb-algorithm")) {
261			plat->tx_queues_cfg[queue].mode_to_use = MTL_QUEUE_AVB;
262
263			/* Credit Base Shaper parameters used by AVB */
264			if (of_property_read_u32(q_node, "snps,send_slope",
265				&plat->tx_queues_cfg[queue].send_slope))
266				plat->tx_queues_cfg[queue].send_slope = 0x0;
267			if (of_property_read_u32(q_node, "snps,idle_slope",
268				&plat->tx_queues_cfg[queue].idle_slope))
269				plat->tx_queues_cfg[queue].idle_slope = 0x0;
270			if (of_property_read_u32(q_node, "snps,high_credit",
271				&plat->tx_queues_cfg[queue].high_credit))
272				plat->tx_queues_cfg[queue].high_credit = 0x0;
273			if (of_property_read_u32(q_node, "snps,low_credit",
274				&plat->tx_queues_cfg[queue].low_credit))
275				plat->tx_queues_cfg[queue].low_credit = 0x0;
276		} else {
277			plat->tx_queues_cfg[queue].mode_to_use = MTL_QUEUE_DCB;
278		}
279
280		if (of_property_read_u32(q_node, "snps,priority",
281					&plat->tx_queues_cfg[queue].prio)) {
282			plat->tx_queues_cfg[queue].prio = 0;
283			plat->tx_queues_cfg[queue].use_prio = false;
284		} else {
285			plat->tx_queues_cfg[queue].use_prio = true;
286		}
287
 
 
 
288		queue++;
289	}
290	if (queue != plat->tx_queues_to_use) {
291		ret = -EINVAL;
292		dev_err(&pdev->dev, "Not all TX queues were configured\n");
293		goto out;
294	}
295
296out:
297	of_node_put(rx_node);
298	of_node_put(tx_node);
299	of_node_put(q_node);
300
301	return ret;
302}
303
304/**
305 * stmmac_dt_phy - parse device-tree driver parameters to allocate PHY resources
306 * @plat: driver data platform structure
307 * @np: device tree node
308 * @dev: device pointer
309 * Description:
310 * The mdio bus will be allocated in case of a phy transceiver is on board;
311 * it will be NULL if the fixed-link is configured.
312 * If there is the "snps,dwmac-mdio" sub-node the mdio will be allocated
313 * in any case (for DSA, mdio must be registered even if fixed-link).
314 * The table below sums the supported configurations:
315 *	-------------------------------
316 *	snps,phy-addr	|     Y
317 *	-------------------------------
318 *	phy-handle	|     Y
319 *	-------------------------------
320 *	fixed-link	|     N
321 *	-------------------------------
322 *	snps,dwmac-mdio	|
323 *	  even if	|     Y
324 *	fixed-link	|
325 *	-------------------------------
326 *
327 * It returns 0 in case of success otherwise -ENODEV.
328 */
329static int stmmac_dt_phy(struct plat_stmmacenet_data *plat,
330			 struct device_node *np, struct device *dev)
331{
332	bool mdio = true;
333	static const struct of_device_id need_mdio_ids[] = {
334		{ .compatible = "snps,dwc-qos-ethernet-4.10" },
335		{},
336	};
337
338	/* If phy-handle property is passed from DT, use it as the PHY */
339	plat->phy_node = of_parse_phandle(np, "phy-handle", 0);
340	if (plat->phy_node)
341		dev_dbg(dev, "Found phy-handle subnode\n");
342
343	/* If phy-handle is not specified, check if we have a fixed-phy */
344	if (!plat->phy_node && of_phy_is_fixed_link(np)) {
345		if ((of_phy_register_fixed_link(np) < 0))
346			return -ENODEV;
347
348		dev_dbg(dev, "Found fixed-link subnode\n");
349		plat->phy_node = of_node_get(np);
350		mdio = false;
351	}
352
353	if (of_match_node(need_mdio_ids, np)) {
354		plat->mdio_node = of_get_child_by_name(np, "mdio");
355	} else {
356		/**
357		 * If snps,dwmac-mdio is passed from DT, always register
358		 * the MDIO
359		 */
360		for_each_child_of_node(np, plat->mdio_node) {
361			if (of_device_is_compatible(plat->mdio_node,
362						    "snps,dwmac-mdio"))
363				break;
364		}
365	}
366
367	if (plat->mdio_node) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
368		dev_dbg(dev, "Found MDIO subnode\n");
369		mdio = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
370	}
371
372	if (mdio)
373		plat->mdio_bus_data =
374			devm_kzalloc(dev, sizeof(struct stmmac_mdio_bus_data),
375				     GFP_KERNEL);
376	return 0;
377}
378
379/**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
380 * stmmac_probe_config_dt - parse device-tree driver parameters
381 * @pdev: platform_device structure
382 * @mac: MAC address to use
383 * Description:
384 * this function is to read the driver parameters from device-tree and
385 * set some private fields that will be used by the main at runtime.
386 */
387struct plat_stmmacenet_data *
388stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
389{
390	struct device_node *np = pdev->dev.of_node;
391	struct plat_stmmacenet_data *plat;
392	struct stmmac_dma_cfg *dma_cfg;
 
 
393	int rc;
394
395	plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL);
396	if (!plat)
397		return ERR_PTR(-ENOMEM);
398
399	*mac = of_get_mac_address(np);
400	plat->interface = of_get_phy_mode(np);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
401
402	/* Get max speed of operation from device tree */
403	if (of_property_read_u32(np, "max-speed", &plat->max_speed))
404		plat->max_speed = -1;
405
406	plat->bus_id = of_alias_get_id(np, "ethernet");
407	if (plat->bus_id < 0)
408		plat->bus_id = 0;
409
410	/* Default to phy auto-detection */
411	plat->phy_addr = -1;
412
 
 
 
 
 
 
 
413	/* "snps,phy-addr" is not a standard property. Mark it as deprecated
414	 * and warn of its use. Remove this when phy node support is added.
415	 */
416	if (of_property_read_u32(np, "snps,phy-addr", &plat->phy_addr) == 0)
417		dev_warn(&pdev->dev, "snps,phy-addr property is deprecated\n");
418
419	/* To Configure PHY by using all device-tree supported properties */
420	rc = stmmac_dt_phy(plat, np, &pdev->dev);
421	if (rc)
422		return ERR_PTR(rc);
423
424	of_property_read_u32(np, "tx-fifo-depth", &plat->tx_fifo_size);
425
426	of_property_read_u32(np, "rx-fifo-depth", &plat->rx_fifo_size);
427
428	plat->force_sf_dma_mode =
429		of_property_read_bool(np, "snps,force_sf_dma_mode");
430
431	plat->en_tx_lpi_clockgating =
432		of_property_read_bool(np, "snps,en-tx-lpi-clockgating");
433
434	/* Set the maxmtu to a default of JUMBO_LEN in case the
435	 * parameter is not present in the device tree.
436	 */
437	plat->maxmtu = JUMBO_LEN;
438
439	/* Set default value for multicast hash bins */
440	plat->multicast_filter_bins = HASH_TABLE_SIZE;
441
442	/* Set default value for unicast filter entries */
443	plat->unicast_filter_entries = 1;
444
445	/*
446	 * Currently only the properties needed on SPEAr600
447	 * are provided. All other properties should be added
448	 * once needed on other platforms.
449	 */
450	if (of_device_is_compatible(np, "st,spear600-gmac") ||
451		of_device_is_compatible(np, "snps,dwmac-3.50a") ||
452		of_device_is_compatible(np, "snps,dwmac-3.70a") ||
453		of_device_is_compatible(np, "snps,dwmac")) {
454		/* Note that the max-frame-size parameter as defined in the
455		 * ePAPR v1.1 spec is defined as max-frame-size, it's
456		 * actually used as the IEEE definition of MAC Client
457		 * data, or MTU. The ePAPR specification is confusing as
458		 * the definition is max-frame-size, but usage examples
459		 * are clearly MTUs
460		 */
461		of_property_read_u32(np, "max-frame-size", &plat->maxmtu);
462		of_property_read_u32(np, "snps,multicast-filter-bins",
463				     &plat->multicast_filter_bins);
464		of_property_read_u32(np, "snps,perfect-filter-entries",
465				     &plat->unicast_filter_entries);
466		plat->unicast_filter_entries = dwmac1000_validate_ucast_entries(
467					       plat->unicast_filter_entries);
468		plat->multicast_filter_bins = dwmac1000_validate_mcast_bins(
469					      plat->multicast_filter_bins);
 
 
 
 
 
470		plat->has_gmac = 1;
 
 
 
471		plat->pmt = 1;
472	}
473
474	if (of_device_is_compatible(np, "snps,dwmac-4.00") ||
475	    of_device_is_compatible(np, "snps,dwmac-4.10a")) {
 
 
 
476		plat->has_gmac4 = 1;
477		plat->has_gmac = 0;
478		plat->pmt = 1;
479		plat->tso_en = of_property_read_bool(np, "snps,tso");
 
480	}
481
482	if (of_device_is_compatible(np, "snps,dwmac-3.610") ||
483		of_device_is_compatible(np, "snps,dwmac-3.710")) {
484		plat->enh_desc = 1;
485		plat->bugged_jumbo = 1;
486		plat->force_sf_dma_mode = 1;
487	}
488
 
 
 
 
 
 
 
489	dma_cfg = devm_kzalloc(&pdev->dev, sizeof(*dma_cfg),
490			       GFP_KERNEL);
491	if (!dma_cfg) {
492		stmmac_remove_config_dt(pdev, plat);
493		return ERR_PTR(-ENOMEM);
494	}
495	plat->dma_cfg = dma_cfg;
496
497	of_property_read_u32(np, "snps,pbl", &dma_cfg->pbl);
498	if (!dma_cfg->pbl)
499		dma_cfg->pbl = DEFAULT_DMA_PBL;
500	of_property_read_u32(np, "snps,txpbl", &dma_cfg->txpbl);
501	of_property_read_u32(np, "snps,rxpbl", &dma_cfg->rxpbl);
502	dma_cfg->pblx8 = !of_property_read_bool(np, "snps,no-pbl-x8");
503
504	dma_cfg->aal = of_property_read_bool(np, "snps,aal");
505	dma_cfg->fixed_burst = of_property_read_bool(np, "snps,fixed-burst");
506	dma_cfg->mixed_burst = of_property_read_bool(np, "snps,mixed-burst");
507
508	plat->force_thresh_dma_mode = of_property_read_bool(np, "snps,force_thresh_dma_mode");
509	if (plat->force_thresh_dma_mode) {
510		plat->force_sf_dma_mode = 0;
511		pr_warn("force_sf_dma_mode is ignored if force_thresh_dma_mode is set.");
 
512	}
513
514	of_property_read_u32(np, "snps,ps-speed", &plat->mac_port_sel_speed);
515
516	plat->axi = stmmac_axi_setup(pdev);
517
518	rc = stmmac_mtl_setup(pdev, plat);
519	if (rc) {
520		stmmac_remove_config_dt(pdev, plat);
521		return ERR_PTR(rc);
522	}
523
524	/* clock setup */
525	plat->stmmac_clk = devm_clk_get(&pdev->dev,
526					STMMAC_RESOURCE_NAME);
527	if (IS_ERR(plat->stmmac_clk)) {
528		dev_warn(&pdev->dev, "Cannot get CSR clock\n");
529		plat->stmmac_clk = NULL;
 
 
 
530	}
531	clk_prepare_enable(plat->stmmac_clk);
532
533	plat->pclk = devm_clk_get(&pdev->dev, "pclk");
534	if (IS_ERR(plat->pclk)) {
535		if (PTR_ERR(plat->pclk) == -EPROBE_DEFER)
536			goto error_pclk_get;
537
538		plat->pclk = NULL;
539	}
540	clk_prepare_enable(plat->pclk);
541
542	/* Fall-back to main clock in case of no PTP ref is passed */
543	plat->clk_ptp_ref = devm_clk_get(&pdev->dev, "ptp_ref");
544	if (IS_ERR(plat->clk_ptp_ref)) {
545		plat->clk_ptp_rate = clk_get_rate(plat->stmmac_clk);
546		plat->clk_ptp_ref = NULL;
547		dev_warn(&pdev->dev, "PTP uses main clock\n");
548	} else {
549		plat->clk_ptp_rate = clk_get_rate(plat->clk_ptp_ref);
550		dev_dbg(&pdev->dev, "PTP rate %d\n", plat->clk_ptp_rate);
551	}
552
553	plat->stmmac_rst = devm_reset_control_get(&pdev->dev,
554						  STMMAC_RESOURCE_NAME);
555	if (IS_ERR(plat->stmmac_rst)) {
556		if (PTR_ERR(plat->stmmac_rst) == -EPROBE_DEFER)
557			goto error_hw_init;
 
558
559		dev_info(&pdev->dev, "no reset control found\n");
560		plat->stmmac_rst = NULL;
 
 
 
561	}
562
563	return plat;
564
565error_hw_init:
566	clk_disable_unprepare(plat->pclk);
567error_pclk_get:
568	clk_disable_unprepare(plat->stmmac_clk);
569
570	return ERR_PTR(-EPROBE_DEFER);
 
 
 
 
 
 
 
 
571}
572
573/**
574 * stmmac_remove_config_dt - undo the effects of stmmac_probe_config_dt()
575 * @pdev: platform_device structure
576 * @plat: driver data platform structure
577 *
578 * Release resources claimed by stmmac_probe_config_dt().
579 */
580void stmmac_remove_config_dt(struct platform_device *pdev,
581			     struct plat_stmmacenet_data *plat)
582{
583	struct device_node *np = pdev->dev.of_node;
 
 
 
 
 
 
 
 
 
 
584
585	if (of_phy_is_fixed_link(np))
586		of_phy_deregister_fixed_link(np);
587	of_node_put(plat->phy_node);
588	of_node_put(plat->mdio_node);
589}
590#else
591struct plat_stmmacenet_data *
592stmmac_probe_config_dt(struct platform_device *pdev, const char **mac)
593{
594	return ERR_PTR(-EINVAL);
595}
596
597void stmmac_remove_config_dt(struct platform_device *pdev,
598			     struct plat_stmmacenet_data *plat)
599{
600}
601#endif /* CONFIG_OF */
602EXPORT_SYMBOL_GPL(stmmac_probe_config_dt);
603EXPORT_SYMBOL_GPL(stmmac_remove_config_dt);
604
605int stmmac_get_platform_resources(struct platform_device *pdev,
606				  struct stmmac_resources *stmmac_res)
607{
608	struct resource *res;
609
610	memset(stmmac_res, 0, sizeof(*stmmac_res));
611
612	/* Get IRQ information early to have an ability to ask for deferred
613	 * probe if needed before we went too far with resource allocation.
614	 */
615	stmmac_res->irq = platform_get_irq_byname(pdev, "macirq");
616	if (stmmac_res->irq < 0) {
617		if (stmmac_res->irq != -EPROBE_DEFER) {
618			dev_err(&pdev->dev,
619				"MAC IRQ configuration information not found\n");
620		}
621		return stmmac_res->irq;
622	}
623
624	/* On some platforms e.g. SPEAr the wake up irq differs from the mac irq
625	 * The external wake up irq can be passed through the platform code
626	 * named as "eth_wake_irq"
627	 *
628	 * In case the wake up interrupt is not passed from the platform
629	 * so the driver will continue to use the mac irq (ndev->irq)
630	 */
631	stmmac_res->wol_irq = platform_get_irq_byname(pdev, "eth_wake_irq");
 
632	if (stmmac_res->wol_irq < 0) {
633		if (stmmac_res->wol_irq == -EPROBE_DEFER)
634			return -EPROBE_DEFER;
 
635		stmmac_res->wol_irq = stmmac_res->irq;
636	}
637
638	stmmac_res->lpi_irq = platform_get_irq_byname(pdev, "eth_lpi");
639	if (stmmac_res->lpi_irq == -EPROBE_DEFER)
640		return -EPROBE_DEFER;
 
 
 
 
641
642	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
643	stmmac_res->addr = devm_ioremap_resource(&pdev->dev, res);
644
645	return PTR_ERR_OR_ZERO(stmmac_res->addr);
646}
647EXPORT_SYMBOL_GPL(stmmac_get_platform_resources);
648
649/**
650 * stmmac_pltfr_remove
651 * @pdev: platform device pointer
652 * Description: this function calls the main to free the net resources
653 * and calls the platforms hook and release the resources (e.g. mem).
 
654 */
655int stmmac_pltfr_remove(struct platform_device *pdev)
 
656{
657	struct net_device *ndev = platform_get_drvdata(pdev);
658	struct stmmac_priv *priv = netdev_priv(ndev);
659	struct plat_stmmacenet_data *plat = priv->plat;
660	int ret = stmmac_dvr_remove(&pdev->dev);
 
 
 
 
661
 
 
 
 
 
 
 
 
 
662	if (plat->exit)
663		plat->exit(pdev, plat->bsp_priv);
 
 
664
665	stmmac_remove_config_dt(pdev, plat);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
666
667	return ret;
668}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
669EXPORT_SYMBOL_GPL(stmmac_pltfr_remove);
670
671#ifdef CONFIG_PM_SLEEP
672/**
673 * stmmac_pltfr_suspend
674 * @dev: device pointer
675 * Description: this function is invoked when suspend the driver and it direcly
676 * call the main suspend function and then, if required, on some platform, it
677 * can call an exit helper.
678 */
679static int stmmac_pltfr_suspend(struct device *dev)
680{
681	int ret;
682	struct net_device *ndev = dev_get_drvdata(dev);
683	struct stmmac_priv *priv = netdev_priv(ndev);
684	struct platform_device *pdev = to_platform_device(dev);
685
686	ret = stmmac_suspend(dev);
687	if (priv->plat->exit)
688		priv->plat->exit(pdev, priv->plat->bsp_priv);
689
690	return ret;
691}
692
693/**
694 * stmmac_pltfr_resume
695 * @dev: device pointer
696 * Description: this function is invoked when resume the driver before calling
697 * the main resume function, on some platforms, it can call own init helper
698 * if required.
699 */
700static int stmmac_pltfr_resume(struct device *dev)
701{
702	struct net_device *ndev = dev_get_drvdata(dev);
703	struct stmmac_priv *priv = netdev_priv(ndev);
704	struct platform_device *pdev = to_platform_device(dev);
 
705
706	if (priv->plat->init)
707		priv->plat->init(pdev, priv->plat->bsp_priv);
 
708
709	return stmmac_resume(dev);
710}
711#endif /* CONFIG_PM_SLEEP */
712
713SIMPLE_DEV_PM_OPS(stmmac_pltfr_pm_ops, stmmac_pltfr_suspend,
714				       stmmac_pltfr_resume);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
715EXPORT_SYMBOL_GPL(stmmac_pltfr_pm_ops);
716
717MODULE_DESCRIPTION("STMMAC 10/100/1000 Ethernet platform support");
718MODULE_AUTHOR("Giuseppe Cavallaro <peppe.cavallaro@st.com>");
719MODULE_LICENSE("GPL");