From fb8977c5be93f8e967df224fe0a44721d60e34dc Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Fri, 13 Sep 2019 19:21:16 -0500 Subject: net: Always build the string_to_enetaddr() helper Part of the env cleanup moved this out of the environment code and into the net code. However, this helper is sometimes needed even when the net stack isn't included. Move the helper to lib/net_utils.c like it's similarly-purposed string_to_ip(). Also rename the moved function to similar naming. Signed-off-by: Joe Hershberger Reported-by: Ondrej Jirman --- include/net.h | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) (limited to 'include') diff --git a/include/net.h b/include/net.h index 11eca1bc6c3..22c83bc2137 100644 --- a/include/net.h +++ b/include/net.h @@ -826,6 +826,19 @@ static inline void net_random_ethaddr(uchar *addr) addr[0] |= 0x02; /* set local assignment bit (IEEE802) */ } +/** + * string_to_enetaddr() - Parse a MAC address + * + * Convert a string MAC address + * + * Implemented in lib/net_utils.c (built unconditionally) + * + * @addr: MAC address in aa:bb:cc:dd:ee:ff format, where each part is a 2-digit + * hex value + * @enetaddr: Place to put MAC address (6 bytes) + */ +void string_to_enetaddr(const char *addr, uint8_t *enetaddr); + /* Convert an IP address to a string */ void ip_to_string(struct in_addr x, char *s); @@ -880,19 +893,6 @@ unsigned int random_port(void); */ int update_tftp(ulong addr, char *interface, char *devstring); -/**********************************************************************/ - -/** - * eth_parse_enetaddr() - Parse a MAC address - * - * Convert a string MAC address - * - * @addr: MAC address in aa:bb:cc:dd:ee:ff format, where each part is a 2-digit - * hex value - * @enetaddr: Place to put MAC address (6 bytes) - */ -void eth_parse_enetaddr(const char *addr, uint8_t *enetaddr); - /** * env_get_ip() - Convert an environment value to to an ip address * @@ -905,5 +905,4 @@ static inline struct in_addr env_get_ip(char *var) { return string_to_ip(env_get(var)); } - #endif /* __NET_H__ */ -- cgit v1.3.1 From d724321f99bbaf024a5ec4bacf1520de3bc1ac87 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Fri, 13 Sep 2019 19:29:41 -0500 Subject: net: Improve documentation for string_to_ip() Signed-off-by: Joe Hershberger --- include/net.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/net.h b/include/net.h index 22c83bc2137..834f2449826 100644 --- a/include/net.h +++ b/include/net.h @@ -845,9 +845,10 @@ void ip_to_string(struct in_addr x, char *s); /** * string_to_ip() - Convert a string to ip address * - * @s: String to conver, in the format format a.b.c.d, where each value is a - * decimal number from 0 to 255 - * @return IP address, or 0 if invalid + * Implemented in lib/net_utils.c (built unconditionally) + * + * @s: Input string to parse + * @return: in_addr struct containing the parsed IP address */ struct in_addr string_to_ip(const char *s); -- cgit v1.3.1 From fb6038390ebe8717a66dd3a4e37bffb96e50c07a Mon Sep 17 00:00:00 2001 From: Grygorii Strashko Date: Mon, 18 Nov 2019 23:04:42 +0200 Subject: dt-bindings: phy: dp83867: Add documentation for disabling clock output Based on commit 980066e6d964 ("dt-bindings: phy: dp83867: Add documentation for disabling clock output") of mainline linux kernel. The clock output is generally only used for testing and development and not used to daisy-chain PHYs. It's just a source of RF noise afterward. Add a mux value for "off". I've added it as another enumeration to the output property. In the actual PHY, the mux and the output enable are independently controllable. However, it doesn't seem useful to be able to describe the mux setting when the output is disabled. Document that PHY's default setting will be left as is if the property is omitted. Signed-off-by: Grygorii Strashko Acked-by: Joe Hershberger --- doc/device-tree-bindings/net/ti,dp83867.txt | 6 ++++-- include/dt-bindings/net/ti-dp83867.h | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/doc/device-tree-bindings/net/ti,dp83867.txt b/doc/device-tree-bindings/net/ti,dp83867.txt index 034146f5f80..268220964aa 100644 --- a/doc/device-tree-bindings/net/ti,dp83867.txt +++ b/doc/device-tree-bindings/net/ti,dp83867.txt @@ -12,8 +12,10 @@ Required properties: compensate for the board being designed with the lanes swapped. - enet-phy-no-lane-swap - Indicates that PHY will disable swap of the TX/RX lanes. - - ti,clk-output-sel - Clock output select - see dt-bindings/net/ti-dp83867.h - for applicable values + - ti,clk-output-sel - Muxing option for CLK_OUT pin. See dt-bindings/net/ti-dp83867.h + for applicable values. The CLK_OUT pin can also + be disabled by this property. When omitted, the + PHY's default will be left as is. Default child nodes are standard Ethernet PHY device nodes as described in doc/devicetree/bindings/net/ethernet.txt diff --git a/include/dt-bindings/net/ti-dp83867.h b/include/dt-bindings/net/ti-dp83867.h index 85d08f69746..cde5aa7e27d 100644 --- a/include/dt-bindings/net/ti-dp83867.h +++ b/include/dt-bindings/net/ti-dp83867.h @@ -45,5 +45,6 @@ #define DP83867_CLK_O_SEL_CHN_C_TCLK 0xA #define DP83867_CLK_O_SEL_CHN_D_TCLK 0xB #define DP83867_CLK_O_SEL_REF_CLK 0xC - +/* Special flag to indicate clock should be off */ +#define DP83867_CLK_O_SEL_OFF 0xFFFFFFFF #endif -- cgit v1.3.1 From 17285fc2833e0db04a2bd3d411cdf1a3e387de83 Mon Sep 17 00:00:00 2001 From: Alex Marginean Date: Thu, 14 Nov 2019 18:28:28 +0200 Subject: include: phy: define XFI and USXGMII interface types Drivers currently use XGMII for XFI and USXGMII and, where needed, use other information to identify the actual protocol on the board. With these two defined drivers can now rely on DT phy-mode property. Signed-off-by: Alex Marginean Acked-by: Joe Hershberger --- include/phy_interface.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include') diff --git a/include/phy_interface.h b/include/phy_interface.h index c6823189f84..73f3a3679ce 100644 --- a/include/phy_interface.h +++ b/include/phy_interface.h @@ -31,6 +31,8 @@ typedef enum { PHY_INTERFACE_MODE_XLAUI, PHY_INTERFACE_MODE_CAUI2, PHY_INTERFACE_MODE_CAUI4, + PHY_INTERFACE_MODE_XFI, + PHY_INTERFACE_MODE_USXGMII, PHY_INTERFACE_MODE_NONE, /* Must be last */ PHY_INTERFACE_MODE_COUNT, @@ -58,6 +60,8 @@ static const char * const phy_interface_strings[] = { [PHY_INTERFACE_MODE_XLAUI] = "xlaui4", [PHY_INTERFACE_MODE_CAUI2] = "caui2", [PHY_INTERFACE_MODE_CAUI4] = "caui4", + [PHY_INTERFACE_MODE_XFI] = "xfi", + [PHY_INTERFACE_MODE_USXGMII] = "usxgmii", [PHY_INTERFACE_MODE_NONE] = "", }; -- cgit v1.3.1 From d718b697a1794876511d6a30a047acfce0b69312 Mon Sep 17 00:00:00 2001 From: Alex Marginean Date: Thu, 14 Nov 2019 18:28:29 +0200 Subject: include: phy: add data field for private driver data This is useful to carry custom information between the driver structure associated with a specific HW and the driver code. Signed-off-by: Alex Marginean Acked-by: Joe Hershberger --- include/phy.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include') diff --git a/include/phy.h b/include/phy.h index e50f56b6eb1..6ace9b3a0c4 100644 --- a/include/phy.h +++ b/include/phy.h @@ -115,6 +115,9 @@ struct phy_driver { u16 val); struct list_head list; + + /* driver private data */ + ulong data; }; struct phy_device { -- cgit v1.3.1 From a5d32c37d9eec2f819273536a5600a0fbde09acb Mon Sep 17 00:00:00 2001 From: Alex Marginean Date: Mon, 25 Nov 2019 17:15:11 +0200 Subject: net: mdio-uclass: rename arguments of dm_mdio_phy_connect for clarity Renamed dm_mdio_phy_connect arguments dev to mdiodev and addr to phyaddr for a bit more clarity and consistency with the following patches. Also use NULL instead of 0 on error return path. Signed-off-by: Alex Marginean Acked-by: Joe Hershberger --- include/miiphy.h | 6 +++--- net/mdio-uclass.c | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/include/miiphy.h b/include/miiphy.h index 9b97d09f186..94bf0da24a0 100644 --- a/include/miiphy.h +++ b/include/miiphy.h @@ -154,14 +154,14 @@ void dm_mdio_probe_devices(void); /** * dm_mdio_phy_connect - Wrapper over phy_connect for DM MDIO * - * @dev: mdio dev - * @addr: PHY address on MDIO bus + * @mdiodev: mdio device the PHY is accesible on + * @phyaddr: PHY address on MDIO bus * @ethdev: ethernet device to connect to the PHY * @interface: MAC-PHY protocol * * @return pointer to phy_device, or 0 on error */ -struct phy_device *dm_mdio_phy_connect(struct udevice *dev, int addr, +struct phy_device *dm_mdio_phy_connect(struct udevice *mdiodev, int phyaddr, struct udevice *ethdev, phy_interface_t interface); diff --git a/net/mdio-uclass.c b/net/mdio-uclass.c index 6f922e80b6f..7a5f1d6dcc8 100644 --- a/net/mdio-uclass.c +++ b/net/mdio-uclass.c @@ -104,16 +104,16 @@ static int dm_mdio_pre_remove(struct udevice *dev) return 0; } -struct phy_device *dm_mdio_phy_connect(struct udevice *dev, int addr, +struct phy_device *dm_mdio_phy_connect(struct udevice *mdiodev, int phyaddr, struct udevice *ethdev, phy_interface_t interface) { - struct mdio_perdev_priv *pdata = dev_get_uclass_priv(dev); + struct mdio_perdev_priv *pdata = dev_get_uclass_priv(mdiodev); - if (device_probe(dev)) - return 0; + if (device_probe(mdiodev)) + return NULL; - return phy_connect(pdata->mii_bus, addr, ethdev, interface); + return phy_connect(pdata->mii_bus, phyaddr, ethdev, interface); } UCLASS_DRIVER(mdio) = { -- cgit v1.3.1 From 2f6245594e1f11db00efcaa5ac122918f019e0b4 Mon Sep 17 00:00:00 2001 From: Alex Marginean Date: Mon, 25 Nov 2019 17:15:12 +0200 Subject: net: mdio-uclass: add dm_eth_phy_connect helper function The function connects an ethernet device to a PHY using DT information. This API is only available for eth devices with an associated device tree node. Signed-off-by: Alex Marginean Acked-by: Joe Hershberger --- include/miiphy.h | 12 ++++++++ net/mdio-uclass.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) (limited to 'include') diff --git a/include/miiphy.h b/include/miiphy.h index 94bf0da24a0..61c136b114c 100644 --- a/include/miiphy.h +++ b/include/miiphy.h @@ -165,6 +165,18 @@ struct phy_device *dm_mdio_phy_connect(struct udevice *mdiodev, int phyaddr, struct udevice *ethdev, phy_interface_t interface); +/** + * dm_eth_phy_connect - Connect an Eth device to a PHY based on device tree + * + * Picks up the DT phy-handle and phy-mode from ethernet device node and + * connects the ethernet device to the linked PHY. + * + * @ethdev: ethernet device + * + * @return pointer to phy_device, or 0 on error + */ +struct phy_device *dm_eth_phy_connect(struct udevice *ethdev); + #endif #ifdef CONFIG_DM_MDIO_MUX diff --git a/net/mdio-uclass.c b/net/mdio-uclass.c index 7a5f1d6dcc8..f75e4df626b 100644 --- a/net/mdio-uclass.c +++ b/net/mdio-uclass.c @@ -10,6 +10,16 @@ #include #include +/* DT node properties for MAC-PHY interface */ +#define PHY_MODE_STR_CNT 2 +static const char *phy_mode_str[PHY_MODE_STR_CNT] = { "phy-mode", + "phy-connection-type" }; +/* DT node properties that reference a PHY node */ +#define PHY_HANDLE_STR_CNT 3 +const char *phy_handle_str[PHY_HANDLE_STR_CNT] = { "phy-handle", + "phy", + "phy-device" }; + void dm_mdio_probe_devices(void) { struct udevice *it; @@ -116,6 +126,86 @@ struct phy_device *dm_mdio_phy_connect(struct udevice *mdiodev, int phyaddr, return phy_connect(pdata->mii_bus, phyaddr, ethdev, interface); } +static struct phy_device *dm_eth_connect_phy_handle(struct udevice *ethdev, + phy_interface_t interface) +{ + u32 phy_addr; + struct udevice *mdiodev; + struct phy_device *phy; + struct ofnode_phandle_args phandle = {.node = ofnode_null()}; + int i; + + for (i = 0; i < PHY_HANDLE_STR_CNT; i++) + if (!dev_read_phandle_with_args(ethdev, phy_handle_str[i], NULL, + 0, 0, &phandle)) + break; + + if (!ofnode_valid(phandle.node)) { + dev_dbg(dev, "can't find PHY node\n"); + return NULL; + } + + /* + * reading 'reg' directly should be fine. This is a PHY node, the + * address is always size 1 and requires no translation + */ + if (ofnode_read_u32(phandle.node, "reg", &phy_addr)) { + dev_dbg(ethdev, "missing reg property in phy node\n"); + return NULL; + } + + if (uclass_get_device_by_ofnode(UCLASS_MDIO, + ofnode_get_parent(phandle.node), + &mdiodev)) { + dev_dbg(dev, "can't find MDIO bus for node %s\n", + ofnode_get_name(ofnode_get_parent(phandle.node))); + return NULL; + } + + phy = dm_mdio_phy_connect(mdiodev, phy_addr, ethdev, interface); + + if (phy) + phy->node = phandle.node; + + return phy; +} + +/* Connect to a PHY linked in eth DT node */ +struct phy_device *dm_eth_phy_connect(struct udevice *ethdev) +{ + const char *if_str; + phy_interface_t interface; + struct phy_device *phy; + int i; + + if (!ofnode_valid(ethdev->node)) { + debug("%s: supplied eth dev has no DT node!\n", ethdev->name); + return NULL; + } + + interface = PHY_INTERFACE_MODE_NONE; + for (i = 0; i < PHY_MODE_STR_CNT; i++) { + if_str = ofnode_read_string(ethdev->node, phy_mode_str[i]); + if (if_str) { + interface = phy_get_interface_by_name(if_str); + break; + } + } + if (interface < 0) + interface = PHY_INTERFACE_MODE_NONE; + if (interface == PHY_INTERFACE_MODE_NONE) + dev_dbg(ethdev, "can't find interface mode, default to NONE\n"); + + phy = dm_eth_connect_phy_handle(ethdev, interface); + + if (!phy) + return NULL; + + phy->interface = interface; + + return phy; +} + UCLASS_DRIVER(mdio) = { .id = UCLASS_MDIO, .name = "mdio", -- cgit v1.3.1 From b8a4dd28f3b719d176fed5dc8d23a898463b072c Mon Sep 17 00:00:00 2001 From: Vignesh Raghavendra Date: Wed, 4 Dec 2019 22:17:20 +0530 Subject: dma: Introduce dma_get_cfg() interface Sometimes, there would be a need to exchange data between DMA provider and DMA client which are very specific to DMA driver of the SoC/platform and are not generic enough to be put into struct dma. Therefore, introduce dma_get_cfg() interface to get DMA provider specific data from client device. Clients can use unique configuration ID flags to get different configuration data from DMA driver. Signed-off-by: Vignesh Raghavendra Acked-by: Joe Hershberger Reviewed-by: Grygorii Strashko --- drivers/dma/dma-uclass.c | 12 ++++++++++++ include/dma-uclass.h | 11 +++++++++++ include/dma.h | 12 ++++++++++++ 3 files changed, 35 insertions(+) (limited to 'include') diff --git a/drivers/dma/dma-uclass.c b/drivers/dma/dma-uclass.c index 0ff56f7e88c..5598bca21c5 100644 --- a/drivers/dma/dma-uclass.c +++ b/drivers/dma/dma-uclass.c @@ -187,6 +187,18 @@ int dma_send(struct dma *dma, void *src, size_t len, void *metadata) return ops->send(dma, src, len, metadata); } + +int dma_get_cfg(struct dma *dma, u32 cfg_id, void **cfg_data) +{ + struct dma_ops *ops = dma_dev_ops(dma->dev); + + debug("%s(dma=%p)\n", __func__, dma); + + if (!ops->get_cfg) + return -ENOSYS; + + return ops->get_cfg(dma, cfg_id, cfg_data); +} #endif /* CONFIG_DMA_CHANNELS */ int dma_get_device(u32 transfer_type, struct udevice **devp) diff --git a/include/dma-uclass.h b/include/dma-uclass.h index 31b43fb4b98..a1d9d26ac56 100644 --- a/include/dma-uclass.h +++ b/include/dma-uclass.h @@ -108,6 +108,17 @@ struct dma_ops { * @return zero on success, or -ve error code. */ int (*send)(struct dma *dma, void *src, size_t len, void *metadata); + /** + * get_cfg() - Get DMA channel configuration for client's use + * + * @dma: The DMA Channel to manipulate + * @cfg_id: DMA provider specific ID to identify what + * configuration data client needs + * @data: Pointer to store pointer to DMA driver specific + * configuration data for the given cfg_id (output param) + * @return zero on success, or -ve error code. + */ + int (*get_cfg)(struct dma *dma, u32 cfg_id, void **data); #endif /* CONFIG_DMA_CHANNELS */ /** * transfer() - Issue a DMA transfer. The implementation must diff --git a/include/dma.h b/include/dma.h index d1c3d0df7d9..6c55aa3a004 100644 --- a/include/dma.h +++ b/include/dma.h @@ -290,6 +290,18 @@ int dma_receive(struct dma *dma, void **dst, void *metadata); * @return zero on success, or -ve error code. */ int dma_send(struct dma *dma, void *src, size_t len, void *metadata); + +/** + * dma_get_cfg() - Get DMA channel configuration for client's use + * + * @dma: The DMA Channel to manipulate + * @cfg_id: DMA provider specific ID to identify what + * configuration data client needs + * @cfg_data: Pointer to store pointer to DMA driver specific + * configuration data for the given cfg_id (output param) + * @return zero on success, or -ve error code. + */ +int dma_get_cfg(struct dma *dma, u32 cfg_id, void **cfg_data); #endif /* CONFIG_DMA_CHANNELS */ /* -- cgit v1.3.1 From 5e6d9ccde9cf700e19e0d783f1f671a1eb4a60fb Mon Sep 17 00:00:00 2001 From: Vignesh Raghavendra Date: Wed, 4 Dec 2019 22:17:21 +0530 Subject: dma: ti: k3-udma: Implement dma_get_cfg() interface Implement dma_get_cfg() interface to pass flow id information for DMA clients to use. This is needed because on K3 SoCs, CPSW (ethernet) and UDMA (DMA provider) support "flows" within a given RX DMA channel. This allows different network packets to be segregated while using same RX DMA channel. In order for basic ethernet to work, CPSW slave must be aware of the flow ID allocated for the RX channel by the DMA driver. This interface allows CPSW to query flow ID from DMA provider and configure it in CPSW HW. Signed-off-by: Vignesh Raghavendra Acked-by: Joe Hershberger Reviewed-by: Grygorii Strashko --- drivers/dma/ti/k3-udma.c | 28 ++++++++++++++++++++++++++++ include/linux/soc/ti/ti-udma.h | 19 +++++++++++++++++++ 2 files changed, 47 insertions(+) (limited to 'include') diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c index 2e64d338caa..f90ca53e906 100644 --- a/drivers/dma/ti/k3-udma.c +++ b/drivers/dma/ti/k3-udma.c @@ -104,6 +104,8 @@ struct udma_chan { struct udma_rchan *rchan; struct udma_rflow *rflow; + struct ti_udma_drv_chan_cfg_data cfg_data; + u32 bcnt; /* number of bytes completed since the start of the channel */ bool pkt_mode; /* TR or packet */ @@ -1407,6 +1409,11 @@ static int udma_request(struct dma *dma) uc->desc_rx_cur = 0; uc->num_rx_bufs = 0; + if (uc->dir == DMA_DEV_TO_MEM) { + uc->cfg_data.flow_id_base = uc->rflow->id; + uc->cfg_data.flow_id_cnt = 1; + } + return 0; } @@ -1689,6 +1696,26 @@ int udma_prepare_rcv_buf(struct dma *dma, void *dst, size_t size) return 0; } +static int udma_get_cfg(struct dma *dma, u32 id, void **data) +{ + struct udma_dev *ud = dev_get_priv(dma->dev); + struct udma_chan *uc; + + if (dma->id >= (ud->rchan_cnt + ud->tchan_cnt)) { + dev_err(dma->dev, "invalid dma ch_id %lu\n", dma->id); + return -EINVAL; + } + + switch (id) { + case TI_UDMA_CHAN_PRIV_INFO: + uc = &ud->channels[dma->id]; + *data = &uc->cfg_data; + return 0; + } + + return -EINVAL; +} + static const struct dma_ops udma_ops = { .transfer = udma_transfer, .of_xlate = udma_of_xlate, @@ -1699,6 +1726,7 @@ static const struct dma_ops udma_ops = { .send = udma_send, .receive = udma_receive, .prepare_rcv_buf = udma_prepare_rcv_buf, + .get_cfg = udma_get_cfg, }; static const struct udevice_id udma_ids[] = { diff --git a/include/linux/soc/ti/ti-udma.h b/include/linux/soc/ti/ti-udma.h index e9d4226c48d..04e354fb2d6 100644 --- a/include/linux/soc/ti/ti-udma.h +++ b/include/linux/soc/ti/ti-udma.h @@ -21,4 +21,23 @@ struct ti_udma_drv_packet_data { u32 dest_tag; }; +/** + * struct ti_udma_drv_chan_cfg_data - TI UDMA per channel specific + * configuration data + * + * @flow_id_base: Start index of flow ID allocated to this channel + * @flow_id_cnt: Number of flows allocated for this channel starting at + * flow_id_base + * + * TI UDMA channel specific data returned as part of dma_get_cfg() call + * from the DMA client driver. + */ +struct ti_udma_drv_chan_cfg_data { + u32 flow_id_base; + u32 flow_id_cnt; +}; + +/* TI UDMA specific flag IDs for dma_get_cfg() call */ +#define TI_UDMA_CHAN_PRIV_INFO 0 + #endif /* __TI_UDMA_H */ -- cgit v1.3.1