xref: /linux-6.15/drivers/net/can/dev/dev.c (revision d50c8376)
13e77f70eSMarc Kleine-Budde // SPDX-License-Identifier: GPL-2.0-only
23e77f70eSMarc Kleine-Budde /* Copyright (C) 2005 Marc Kleine-Budde, Pengutronix
33e77f70eSMarc Kleine-Budde  * Copyright (C) 2006 Andrey Volkov, Varma Electronics
43e77f70eSMarc Kleine-Budde  * Copyright (C) 2008-2009 Wolfgang Grandegger <[email protected]>
53e77f70eSMarc Kleine-Budde  */
63e77f70eSMarc Kleine-Budde 
73e77f70eSMarc Kleine-Budde #include <linux/kernel.h>
83e77f70eSMarc Kleine-Budde #include <linux/slab.h>
93e77f70eSMarc Kleine-Budde #include <linux/netdevice.h>
103e77f70eSMarc Kleine-Budde #include <linux/if_arp.h>
113e77f70eSMarc Kleine-Budde #include <linux/workqueue.h>
123e77f70eSMarc Kleine-Budde #include <linux/can.h>
133e77f70eSMarc Kleine-Budde #include <linux/can/can-ml.h>
143e77f70eSMarc Kleine-Budde #include <linux/can/dev.h>
153e77f70eSMarc Kleine-Budde #include <linux/can/skb.h>
166e86a154SOleksij Rempel #include <linux/gpio/consumer.h>
173e77f70eSMarc Kleine-Budde #include <linux/of.h>
183e77f70eSMarc Kleine-Budde 
can_update_state_error_stats(struct net_device * dev,enum can_state new_state)193e77f70eSMarc Kleine-Budde static void can_update_state_error_stats(struct net_device *dev,
203e77f70eSMarc Kleine-Budde 					 enum can_state new_state)
213e77f70eSMarc Kleine-Budde {
223e77f70eSMarc Kleine-Budde 	struct can_priv *priv = netdev_priv(dev);
233e77f70eSMarc Kleine-Budde 
243e77f70eSMarc Kleine-Budde 	if (new_state <= priv->state)
253e77f70eSMarc Kleine-Budde 		return;
263e77f70eSMarc Kleine-Budde 
273e77f70eSMarc Kleine-Budde 	switch (new_state) {
283e77f70eSMarc Kleine-Budde 	case CAN_STATE_ERROR_WARNING:
293e77f70eSMarc Kleine-Budde 		priv->can_stats.error_warning++;
303e77f70eSMarc Kleine-Budde 		break;
313e77f70eSMarc Kleine-Budde 	case CAN_STATE_ERROR_PASSIVE:
323e77f70eSMarc Kleine-Budde 		priv->can_stats.error_passive++;
333e77f70eSMarc Kleine-Budde 		break;
343e77f70eSMarc Kleine-Budde 	case CAN_STATE_BUS_OFF:
353e77f70eSMarc Kleine-Budde 		priv->can_stats.bus_off++;
363e77f70eSMarc Kleine-Budde 		break;
373e77f70eSMarc Kleine-Budde 	default:
383e77f70eSMarc Kleine-Budde 		break;
393e77f70eSMarc Kleine-Budde 	}
403e77f70eSMarc Kleine-Budde }
413e77f70eSMarc Kleine-Budde 
can_tx_state_to_frame(struct net_device * dev,enum can_state state)423e77f70eSMarc Kleine-Budde static int can_tx_state_to_frame(struct net_device *dev, enum can_state state)
433e77f70eSMarc Kleine-Budde {
443e77f70eSMarc Kleine-Budde 	switch (state) {
453e77f70eSMarc Kleine-Budde 	case CAN_STATE_ERROR_ACTIVE:
463e77f70eSMarc Kleine-Budde 		return CAN_ERR_CRTL_ACTIVE;
473e77f70eSMarc Kleine-Budde 	case CAN_STATE_ERROR_WARNING:
483e77f70eSMarc Kleine-Budde 		return CAN_ERR_CRTL_TX_WARNING;
493e77f70eSMarc Kleine-Budde 	case CAN_STATE_ERROR_PASSIVE:
503e77f70eSMarc Kleine-Budde 		return CAN_ERR_CRTL_TX_PASSIVE;
513e77f70eSMarc Kleine-Budde 	default:
523e77f70eSMarc Kleine-Budde 		return 0;
533e77f70eSMarc Kleine-Budde 	}
543e77f70eSMarc Kleine-Budde }
553e77f70eSMarc Kleine-Budde 
can_rx_state_to_frame(struct net_device * dev,enum can_state state)563e77f70eSMarc Kleine-Budde static int can_rx_state_to_frame(struct net_device *dev, enum can_state state)
573e77f70eSMarc Kleine-Budde {
583e77f70eSMarc Kleine-Budde 	switch (state) {
593e77f70eSMarc Kleine-Budde 	case CAN_STATE_ERROR_ACTIVE:
603e77f70eSMarc Kleine-Budde 		return CAN_ERR_CRTL_ACTIVE;
613e77f70eSMarc Kleine-Budde 	case CAN_STATE_ERROR_WARNING:
623e77f70eSMarc Kleine-Budde 		return CAN_ERR_CRTL_RX_WARNING;
633e77f70eSMarc Kleine-Budde 	case CAN_STATE_ERROR_PASSIVE:
643e77f70eSMarc Kleine-Budde 		return CAN_ERR_CRTL_RX_PASSIVE;
653e77f70eSMarc Kleine-Budde 	default:
663e77f70eSMarc Kleine-Budde 		return 0;
673e77f70eSMarc Kleine-Budde 	}
683e77f70eSMarc Kleine-Budde }
693e77f70eSMarc Kleine-Budde 
can_get_state_str(const enum can_state state)706fe27d68SVincent Mailhol const char *can_get_state_str(const enum can_state state)
713e77f70eSMarc Kleine-Budde {
723e77f70eSMarc Kleine-Budde 	switch (state) {
733e77f70eSMarc Kleine-Budde 	case CAN_STATE_ERROR_ACTIVE:
743e77f70eSMarc Kleine-Budde 		return "Error Active";
753e77f70eSMarc Kleine-Budde 	case CAN_STATE_ERROR_WARNING:
763e77f70eSMarc Kleine-Budde 		return "Error Warning";
773e77f70eSMarc Kleine-Budde 	case CAN_STATE_ERROR_PASSIVE:
783e77f70eSMarc Kleine-Budde 		return "Error Passive";
793e77f70eSMarc Kleine-Budde 	case CAN_STATE_BUS_OFF:
803e77f70eSMarc Kleine-Budde 		return "Bus Off";
813e77f70eSMarc Kleine-Budde 	case CAN_STATE_STOPPED:
823e77f70eSMarc Kleine-Budde 		return "Stopped";
833e77f70eSMarc Kleine-Budde 	case CAN_STATE_SLEEPING:
843e77f70eSMarc Kleine-Budde 		return "Sleeping";
853e77f70eSMarc Kleine-Budde 	default:
863e77f70eSMarc Kleine-Budde 		return "<unknown>";
873e77f70eSMarc Kleine-Budde 	}
883e77f70eSMarc Kleine-Budde }
896fe27d68SVincent Mailhol EXPORT_SYMBOL_GPL(can_get_state_str);
903e77f70eSMarc Kleine-Budde 
can_state_err_to_state(u16 err)919beebc2bSMarc Kleine-Budde static enum can_state can_state_err_to_state(u16 err)
929beebc2bSMarc Kleine-Budde {
939beebc2bSMarc Kleine-Budde 	if (err < CAN_ERROR_WARNING_THRESHOLD)
949beebc2bSMarc Kleine-Budde 		return CAN_STATE_ERROR_ACTIVE;
959beebc2bSMarc Kleine-Budde 	if (err < CAN_ERROR_PASSIVE_THRESHOLD)
969beebc2bSMarc Kleine-Budde 		return CAN_STATE_ERROR_WARNING;
979beebc2bSMarc Kleine-Budde 	if (err < CAN_BUS_OFF_THRESHOLD)
989beebc2bSMarc Kleine-Budde 		return CAN_STATE_ERROR_PASSIVE;
999beebc2bSMarc Kleine-Budde 
1009beebc2bSMarc Kleine-Budde 	return CAN_STATE_BUS_OFF;
1019beebc2bSMarc Kleine-Budde }
1029beebc2bSMarc Kleine-Budde 
can_state_get_by_berr_counter(const struct net_device * dev,const struct can_berr_counter * bec,enum can_state * tx_state,enum can_state * rx_state)1039beebc2bSMarc Kleine-Budde void can_state_get_by_berr_counter(const struct net_device *dev,
1049beebc2bSMarc Kleine-Budde 				   const struct can_berr_counter *bec,
1059beebc2bSMarc Kleine-Budde 				   enum can_state *tx_state,
1069beebc2bSMarc Kleine-Budde 				   enum can_state *rx_state)
1079beebc2bSMarc Kleine-Budde {
1089beebc2bSMarc Kleine-Budde 	*tx_state = can_state_err_to_state(bec->txerr);
1099beebc2bSMarc Kleine-Budde 	*rx_state = can_state_err_to_state(bec->rxerr);
1109beebc2bSMarc Kleine-Budde }
1119beebc2bSMarc Kleine-Budde EXPORT_SYMBOL_GPL(can_state_get_by_berr_counter);
1129beebc2bSMarc Kleine-Budde 
can_change_state(struct net_device * dev,struct can_frame * cf,enum can_state tx_state,enum can_state rx_state)1133e77f70eSMarc Kleine-Budde void can_change_state(struct net_device *dev, struct can_frame *cf,
1143e77f70eSMarc Kleine-Budde 		      enum can_state tx_state, enum can_state rx_state)
1153e77f70eSMarc Kleine-Budde {
1163e77f70eSMarc Kleine-Budde 	struct can_priv *priv = netdev_priv(dev);
1173e77f70eSMarc Kleine-Budde 	enum can_state new_state = max(tx_state, rx_state);
1183e77f70eSMarc Kleine-Budde 
1193e77f70eSMarc Kleine-Budde 	if (unlikely(new_state == priv->state)) {
1203e77f70eSMarc Kleine-Budde 		netdev_warn(dev, "%s: oops, state did not change", __func__);
1213e77f70eSMarc Kleine-Budde 		return;
1223e77f70eSMarc Kleine-Budde 	}
1233e77f70eSMarc Kleine-Budde 
1243e77f70eSMarc Kleine-Budde 	netdev_dbg(dev, "Controller changed from %s State (%d) into %s State (%d).\n",
1253e77f70eSMarc Kleine-Budde 		   can_get_state_str(priv->state), priv->state,
1263e77f70eSMarc Kleine-Budde 		   can_get_state_str(new_state), new_state);
1273e77f70eSMarc Kleine-Budde 
1283e77f70eSMarc Kleine-Budde 	can_update_state_error_stats(dev, new_state);
1293e77f70eSMarc Kleine-Budde 	priv->state = new_state;
1303e77f70eSMarc Kleine-Budde 
1313e77f70eSMarc Kleine-Budde 	if (!cf)
1323e77f70eSMarc Kleine-Budde 		return;
1333e77f70eSMarc Kleine-Budde 
1343e77f70eSMarc Kleine-Budde 	if (unlikely(new_state == CAN_STATE_BUS_OFF)) {
1353e77f70eSMarc Kleine-Budde 		cf->can_id |= CAN_ERR_BUSOFF;
1363e77f70eSMarc Kleine-Budde 		return;
1373e77f70eSMarc Kleine-Budde 	}
1383e77f70eSMarc Kleine-Budde 
1393e77f70eSMarc Kleine-Budde 	cf->can_id |= CAN_ERR_CRTL;
1403e77f70eSMarc Kleine-Budde 	cf->data[1] |= tx_state >= rx_state ?
1413e77f70eSMarc Kleine-Budde 		       can_tx_state_to_frame(dev, tx_state) : 0;
1423e77f70eSMarc Kleine-Budde 	cf->data[1] |= tx_state <= rx_state ?
1433e77f70eSMarc Kleine-Budde 		       can_rx_state_to_frame(dev, rx_state) : 0;
1443e77f70eSMarc Kleine-Budde }
1453e77f70eSMarc Kleine-Budde EXPORT_SYMBOL_GPL(can_change_state);
1463e77f70eSMarc Kleine-Budde 
1473e77f70eSMarc Kleine-Budde /* CAN device restart for bus-off recovery */
can_restart(struct net_device * dev)1483e77f70eSMarc Kleine-Budde static void can_restart(struct net_device *dev)
1493e77f70eSMarc Kleine-Budde {
1503e77f70eSMarc Kleine-Budde 	struct can_priv *priv = netdev_priv(dev);
1513e77f70eSMarc Kleine-Budde 	struct sk_buff *skb;
1523e77f70eSMarc Kleine-Budde 	struct can_frame *cf;
1533e77f70eSMarc Kleine-Budde 	int err;
1543e77f70eSMarc Kleine-Budde 
155fe5c9940SMarc Kleine-Budde 	if (netif_carrier_ok(dev))
156fe5c9940SMarc Kleine-Budde 		netdev_err(dev, "Attempt to restart for bus-off recovery, but carrier is OK?\n");
1573e77f70eSMarc Kleine-Budde 
1583e77f70eSMarc Kleine-Budde 	/* No synchronization needed because the device is bus-off and
1593e77f70eSMarc Kleine-Budde 	 * no messages can come in or go out.
1603e77f70eSMarc Kleine-Budde 	 */
1613e77f70eSMarc Kleine-Budde 	can_flush_echo_skb(dev);
1623e77f70eSMarc Kleine-Budde 
1633e77f70eSMarc Kleine-Budde 	/* send restart message upstream */
1643e77f70eSMarc Kleine-Budde 	skb = alloc_can_err_skb(dev, &cf);
1658f3ec204SMarc Kleine-Budde 	if (skb) {
1663e77f70eSMarc Kleine-Budde 		cf->can_id |= CAN_ERR_RESTARTED;
16700f4a0afSSebastian Andrzej Siewior 		netif_rx(skb);
1688f3ec204SMarc Kleine-Budde 	}
1690fe2f273SJakub Kicinski 
1703e77f70eSMarc Kleine-Budde 	/* Now restart the device */
1713e77f70eSMarc Kleine-Budde 	netif_carrier_on(dev);
1726841cab8SMarc Kleine-Budde 	err = priv->do_set_mode(dev, CAN_MODE_START);
1736841cab8SMarc Kleine-Budde 	if (err) {
174f0e0c809SMarc Kleine-Budde 		netdev_err(dev, "Restart failed, error %pe\n", ERR_PTR(err));
1756841cab8SMarc Kleine-Budde 		netif_carrier_off(dev);
176f0e0c809SMarc Kleine-Budde 	} else {
177f0e0c809SMarc Kleine-Budde 		netdev_dbg(dev, "Restarted\n");
178f0e0c809SMarc Kleine-Budde 		priv->can_stats.restarts++;
1796841cab8SMarc Kleine-Budde 	}
1803e77f70eSMarc Kleine-Budde }
1813e77f70eSMarc Kleine-Budde 
can_restart_work(struct work_struct * work)1823e77f70eSMarc Kleine-Budde static void can_restart_work(struct work_struct *work)
1833e77f70eSMarc Kleine-Budde {
1843e77f70eSMarc Kleine-Budde 	struct delayed_work *dwork = to_delayed_work(work);
1853e77f70eSMarc Kleine-Budde 	struct can_priv *priv = container_of(dwork, struct can_priv,
1863e77f70eSMarc Kleine-Budde 					     restart_work);
1873e77f70eSMarc Kleine-Budde 
1883e77f70eSMarc Kleine-Budde 	can_restart(priv->dev);
1893e77f70eSMarc Kleine-Budde }
1903e77f70eSMarc Kleine-Budde 
can_restart_now(struct net_device * dev)1913e77f70eSMarc Kleine-Budde int can_restart_now(struct net_device *dev)
1923e77f70eSMarc Kleine-Budde {
1933e77f70eSMarc Kleine-Budde 	struct can_priv *priv = netdev_priv(dev);
1943e77f70eSMarc Kleine-Budde 
1953e77f70eSMarc Kleine-Budde 	/* A manual restart is only permitted if automatic restart is
1963e77f70eSMarc Kleine-Budde 	 * disabled and the device is in the bus-off state
1973e77f70eSMarc Kleine-Budde 	 */
1983e77f70eSMarc Kleine-Budde 	if (priv->restart_ms)
1993e77f70eSMarc Kleine-Budde 		return -EINVAL;
2003e77f70eSMarc Kleine-Budde 	if (priv->state != CAN_STATE_BUS_OFF)
2013e77f70eSMarc Kleine-Budde 		return -EBUSY;
2023e77f70eSMarc Kleine-Budde 
2033e77f70eSMarc Kleine-Budde 	cancel_delayed_work_sync(&priv->restart_work);
2043e77f70eSMarc Kleine-Budde 	can_restart(dev);
2053e77f70eSMarc Kleine-Budde 
2063e77f70eSMarc Kleine-Budde 	return 0;
2073e77f70eSMarc Kleine-Budde }
2083e77f70eSMarc Kleine-Budde 
2093e77f70eSMarc Kleine-Budde /* CAN bus-off
2103e77f70eSMarc Kleine-Budde  *
2113e77f70eSMarc Kleine-Budde  * This functions should be called when the device goes bus-off to
2123e77f70eSMarc Kleine-Budde  * tell the netif layer that no more packets can be sent or received.
2133e77f70eSMarc Kleine-Budde  * If enabled, a timer is started to trigger bus-off recovery.
2143e77f70eSMarc Kleine-Budde  */
can_bus_off(struct net_device * dev)2153e77f70eSMarc Kleine-Budde void can_bus_off(struct net_device *dev)
2163e77f70eSMarc Kleine-Budde {
2173e77f70eSMarc Kleine-Budde 	struct can_priv *priv = netdev_priv(dev);
2183e77f70eSMarc Kleine-Budde 
2193e77f70eSMarc Kleine-Budde 	if (priv->restart_ms)
2203e77f70eSMarc Kleine-Budde 		netdev_info(dev, "bus-off, scheduling restart in %d ms\n",
2213e77f70eSMarc Kleine-Budde 			    priv->restart_ms);
2223e77f70eSMarc Kleine-Budde 	else
2233e77f70eSMarc Kleine-Budde 		netdev_info(dev, "bus-off\n");
2243e77f70eSMarc Kleine-Budde 
2253e77f70eSMarc Kleine-Budde 	netif_carrier_off(dev);
2263e77f70eSMarc Kleine-Budde 
2273e77f70eSMarc Kleine-Budde 	if (priv->restart_ms)
2283e77f70eSMarc Kleine-Budde 		schedule_delayed_work(&priv->restart_work,
2293e77f70eSMarc Kleine-Budde 				      msecs_to_jiffies(priv->restart_ms));
2303e77f70eSMarc Kleine-Budde }
2313e77f70eSMarc Kleine-Budde EXPORT_SYMBOL_GPL(can_bus_off);
2323e77f70eSMarc Kleine-Budde 
can_setup(struct net_device * dev)2330a042c6eSMarc Kleine-Budde void can_setup(struct net_device *dev)
2343e77f70eSMarc Kleine-Budde {
2353e77f70eSMarc Kleine-Budde 	dev->type = ARPHRD_CAN;
2363e77f70eSMarc Kleine-Budde 	dev->mtu = CAN_MTU;
2373e77f70eSMarc Kleine-Budde 	dev->hard_header_len = 0;
2383e77f70eSMarc Kleine-Budde 	dev->addr_len = 0;
2393e77f70eSMarc Kleine-Budde 	dev->tx_queue_len = 10;
2403e77f70eSMarc Kleine-Budde 
2413e77f70eSMarc Kleine-Budde 	/* New-style flags. */
2423e77f70eSMarc Kleine-Budde 	dev->flags = IFF_NOARP;
2433e77f70eSMarc Kleine-Budde 	dev->features = NETIF_F_HW_CSUM;
2443e77f70eSMarc Kleine-Budde }
2453e77f70eSMarc Kleine-Budde 
2463e77f70eSMarc Kleine-Budde /* Allocate and setup space for the CAN network device */
alloc_candev_mqs(int sizeof_priv,unsigned int echo_skb_max,unsigned int txqs,unsigned int rxqs)2473e77f70eSMarc Kleine-Budde struct net_device *alloc_candev_mqs(int sizeof_priv, unsigned int echo_skb_max,
2483e77f70eSMarc Kleine-Budde 				    unsigned int txqs, unsigned int rxqs)
2493e77f70eSMarc Kleine-Budde {
2504e096a18SOleksij Rempel 	struct can_ml_priv *can_ml;
2513e77f70eSMarc Kleine-Budde 	struct net_device *dev;
2523e77f70eSMarc Kleine-Budde 	struct can_priv *priv;
2533e77f70eSMarc Kleine-Budde 	int size;
2543e77f70eSMarc Kleine-Budde 
2553e77f70eSMarc Kleine-Budde 	/* We put the driver's priv, the CAN mid layer priv and the
2563e77f70eSMarc Kleine-Budde 	 * echo skb into the netdevice's priv. The memory layout for
2573e77f70eSMarc Kleine-Budde 	 * the netdev_priv is like this:
2583e77f70eSMarc Kleine-Budde 	 *
2593e77f70eSMarc Kleine-Budde 	 * +-------------------------+
2603e77f70eSMarc Kleine-Budde 	 * | driver's priv           |
2613e77f70eSMarc Kleine-Budde 	 * +-------------------------+
2623e77f70eSMarc Kleine-Budde 	 * | struct can_ml_priv      |
2633e77f70eSMarc Kleine-Budde 	 * +-------------------------+
2643e77f70eSMarc Kleine-Budde 	 * | array of struct sk_buff |
2653e77f70eSMarc Kleine-Budde 	 * +-------------------------+
2663e77f70eSMarc Kleine-Budde 	 */
2673e77f70eSMarc Kleine-Budde 
2683e77f70eSMarc Kleine-Budde 	size = ALIGN(sizeof_priv, NETDEV_ALIGN) + sizeof(struct can_ml_priv);
2693e77f70eSMarc Kleine-Budde 
2703e77f70eSMarc Kleine-Budde 	if (echo_skb_max)
2713e77f70eSMarc Kleine-Budde 		size = ALIGN(size, sizeof(struct sk_buff *)) +
2723e77f70eSMarc Kleine-Budde 			echo_skb_max * sizeof(struct sk_buff *);
2733e77f70eSMarc Kleine-Budde 
2743e77f70eSMarc Kleine-Budde 	dev = alloc_netdev_mqs(size, "can%d", NET_NAME_UNKNOWN, can_setup,
2753e77f70eSMarc Kleine-Budde 			       txqs, rxqs);
2763e77f70eSMarc Kleine-Budde 	if (!dev)
2773e77f70eSMarc Kleine-Budde 		return NULL;
2783e77f70eSMarc Kleine-Budde 
2793e77f70eSMarc Kleine-Budde 	priv = netdev_priv(dev);
2803e77f70eSMarc Kleine-Budde 	priv->dev = dev;
2813e77f70eSMarc Kleine-Budde 
2824e096a18SOleksij Rempel 	can_ml = (void *)priv + ALIGN(sizeof_priv, NETDEV_ALIGN);
2834e096a18SOleksij Rempel 	can_set_ml_priv(dev, can_ml);
2843e77f70eSMarc Kleine-Budde 
2853e77f70eSMarc Kleine-Budde 	if (echo_skb_max) {
2863e77f70eSMarc Kleine-Budde 		priv->echo_skb_max = echo_skb_max;
2873e77f70eSMarc Kleine-Budde 		priv->echo_skb = (void *)priv +
2883e77f70eSMarc Kleine-Budde 			(size - echo_skb_max * sizeof(struct sk_buff *));
2893e77f70eSMarc Kleine-Budde 	}
2903e77f70eSMarc Kleine-Budde 
2913e77f70eSMarc Kleine-Budde 	priv->state = CAN_STATE_STOPPED;
2923e77f70eSMarc Kleine-Budde 
2933e77f70eSMarc Kleine-Budde 	INIT_DELAYED_WORK(&priv->restart_work, can_restart_work);
2943e77f70eSMarc Kleine-Budde 
2953e77f70eSMarc Kleine-Budde 	return dev;
2963e77f70eSMarc Kleine-Budde }
2973e77f70eSMarc Kleine-Budde EXPORT_SYMBOL_GPL(alloc_candev_mqs);
2983e77f70eSMarc Kleine-Budde 
2993e77f70eSMarc Kleine-Budde /* Free space of the CAN network device */
free_candev(struct net_device * dev)3003e77f70eSMarc Kleine-Budde void free_candev(struct net_device *dev)
3013e77f70eSMarc Kleine-Budde {
3023e77f70eSMarc Kleine-Budde 	free_netdev(dev);
3033e77f70eSMarc Kleine-Budde }
3043e77f70eSMarc Kleine-Budde EXPORT_SYMBOL_GPL(free_candev);
3053e77f70eSMarc Kleine-Budde 
3063e77f70eSMarc Kleine-Budde /* changing MTU and control mode for CAN/CANFD devices */
can_change_mtu(struct net_device * dev,int new_mtu)3073e77f70eSMarc Kleine-Budde int can_change_mtu(struct net_device *dev, int new_mtu)
3083e77f70eSMarc Kleine-Budde {
3093e77f70eSMarc Kleine-Budde 	struct can_priv *priv = netdev_priv(dev);
310c9e1d8edSVincent Mailhol 	u32 ctrlmode_static = can_get_static_ctrlmode(priv);
3113e77f70eSMarc Kleine-Budde 
3123e77f70eSMarc Kleine-Budde 	/* Do not allow changing the MTU while running */
3133e77f70eSMarc Kleine-Budde 	if (dev->flags & IFF_UP)
3143e77f70eSMarc Kleine-Budde 		return -EBUSY;
3153e77f70eSMarc Kleine-Budde 
3163e77f70eSMarc Kleine-Budde 	/* allow change of MTU according to the CANFD ability of the device */
3173e77f70eSMarc Kleine-Budde 	switch (new_mtu) {
3183e77f70eSMarc Kleine-Budde 	case CAN_MTU:
3193e77f70eSMarc Kleine-Budde 		/* 'CANFD-only' controllers can not switch to CAN_MTU */
320c9e1d8edSVincent Mailhol 		if (ctrlmode_static & CAN_CTRLMODE_FD)
3213e77f70eSMarc Kleine-Budde 			return -EINVAL;
3223e77f70eSMarc Kleine-Budde 
3233e77f70eSMarc Kleine-Budde 		priv->ctrlmode &= ~CAN_CTRLMODE_FD;
3243e77f70eSMarc Kleine-Budde 		break;
3253e77f70eSMarc Kleine-Budde 
3263e77f70eSMarc Kleine-Budde 	case CANFD_MTU:
3273e77f70eSMarc Kleine-Budde 		/* check for potential CANFD ability */
3283e77f70eSMarc Kleine-Budde 		if (!(priv->ctrlmode_supported & CAN_CTRLMODE_FD) &&
329c9e1d8edSVincent Mailhol 		    !(ctrlmode_static & CAN_CTRLMODE_FD))
3303e77f70eSMarc Kleine-Budde 			return -EINVAL;
3313e77f70eSMarc Kleine-Budde 
3323e77f70eSMarc Kleine-Budde 		priv->ctrlmode |= CAN_CTRLMODE_FD;
3333e77f70eSMarc Kleine-Budde 		break;
3343e77f70eSMarc Kleine-Budde 
3353e77f70eSMarc Kleine-Budde 	default:
3363e77f70eSMarc Kleine-Budde 		return -EINVAL;
3373e77f70eSMarc Kleine-Budde 	}
3383e77f70eSMarc Kleine-Budde 
3391eb2cdedSEric Dumazet 	WRITE_ONCE(dev->mtu, new_mtu);
3403e77f70eSMarc Kleine-Budde 	return 0;
3413e77f70eSMarc Kleine-Budde }
3423e77f70eSMarc Kleine-Budde EXPORT_SYMBOL_GPL(can_change_mtu);
3433e77f70eSMarc Kleine-Budde 
34490f942c5SVincent Mailhol /* generic implementation of netdev_ops::ndo_eth_ioctl for CAN devices
34590f942c5SVincent Mailhol  * supporting hardware timestamps
34690f942c5SVincent Mailhol  */
can_eth_ioctl_hwts(struct net_device * netdev,struct ifreq * ifr,int cmd)34790f942c5SVincent Mailhol int can_eth_ioctl_hwts(struct net_device *netdev, struct ifreq *ifr, int cmd)
34890f942c5SVincent Mailhol {
34990f942c5SVincent Mailhol 	struct hwtstamp_config hwts_cfg = { 0 };
35090f942c5SVincent Mailhol 
35190f942c5SVincent Mailhol 	switch (cmd) {
35290f942c5SVincent Mailhol 	case SIOCSHWTSTAMP: /* set */
35390f942c5SVincent Mailhol 		if (copy_from_user(&hwts_cfg, ifr->ifr_data, sizeof(hwts_cfg)))
35490f942c5SVincent Mailhol 			return -EFAULT;
35590f942c5SVincent Mailhol 		if (hwts_cfg.tx_type == HWTSTAMP_TX_ON &&
35690f942c5SVincent Mailhol 		    hwts_cfg.rx_filter == HWTSTAMP_FILTER_ALL)
35790f942c5SVincent Mailhol 			return 0;
35890f942c5SVincent Mailhol 		return -ERANGE;
35990f942c5SVincent Mailhol 
36090f942c5SVincent Mailhol 	case SIOCGHWTSTAMP: /* get */
36190f942c5SVincent Mailhol 		hwts_cfg.tx_type = HWTSTAMP_TX_ON;
36290f942c5SVincent Mailhol 		hwts_cfg.rx_filter = HWTSTAMP_FILTER_ALL;
36390f942c5SVincent Mailhol 		if (copy_to_user(ifr->ifr_data, &hwts_cfg, sizeof(hwts_cfg)))
36490f942c5SVincent Mailhol 			return -EFAULT;
36590f942c5SVincent Mailhol 		return 0;
36690f942c5SVincent Mailhol 
36790f942c5SVincent Mailhol 	default:
36890f942c5SVincent Mailhol 		return -EOPNOTSUPP;
36990f942c5SVincent Mailhol 	}
37090f942c5SVincent Mailhol }
37190f942c5SVincent Mailhol EXPORT_SYMBOL(can_eth_ioctl_hwts);
37290f942c5SVincent Mailhol 
3737fb48d25SVincent Mailhol /* generic implementation of ethtool_ops::get_ts_info for CAN devices
3747fb48d25SVincent Mailhol  * supporting hardware timestamps
3757fb48d25SVincent Mailhol  */
can_ethtool_op_get_ts_info_hwts(struct net_device * dev,struct kernel_ethtool_ts_info * info)3767fb48d25SVincent Mailhol int can_ethtool_op_get_ts_info_hwts(struct net_device *dev,
377*2111375bSKory Maincent 				    struct kernel_ethtool_ts_info *info)
3787fb48d25SVincent Mailhol {
3797fb48d25SVincent Mailhol 	info->so_timestamping =
3807fb48d25SVincent Mailhol 		SOF_TIMESTAMPING_TX_SOFTWARE |
3817fb48d25SVincent Mailhol 		SOF_TIMESTAMPING_TX_HARDWARE |
3827fb48d25SVincent Mailhol 		SOF_TIMESTAMPING_RX_HARDWARE |
3837fb48d25SVincent Mailhol 		SOF_TIMESTAMPING_RAW_HARDWARE;
3847fb48d25SVincent Mailhol 	info->tx_types = BIT(HWTSTAMP_TX_ON);
3857fb48d25SVincent Mailhol 	info->rx_filters = BIT(HWTSTAMP_FILTER_ALL);
3867fb48d25SVincent Mailhol 
3877fb48d25SVincent Mailhol 	return 0;
3887fb48d25SVincent Mailhol }
3897fb48d25SVincent Mailhol EXPORT_SYMBOL(can_ethtool_op_get_ts_info_hwts);
3907fb48d25SVincent Mailhol 
3913e77f70eSMarc Kleine-Budde /* Common open function when the device gets opened.
3923e77f70eSMarc Kleine-Budde  *
3933e77f70eSMarc Kleine-Budde  * This function should be called in the open function of the device
3943e77f70eSMarc Kleine-Budde  * driver.
3953e77f70eSMarc Kleine-Budde  */
open_candev(struct net_device * dev)3963e77f70eSMarc Kleine-Budde int open_candev(struct net_device *dev)
3973e77f70eSMarc Kleine-Budde {
3983e77f70eSMarc Kleine-Budde 	struct can_priv *priv = netdev_priv(dev);
3993e77f70eSMarc Kleine-Budde 
4003e77f70eSMarc Kleine-Budde 	if (!priv->bittiming.bitrate) {
4013e77f70eSMarc Kleine-Budde 		netdev_err(dev, "bit-timing not yet defined\n");
4023e77f70eSMarc Kleine-Budde 		return -EINVAL;
4033e77f70eSMarc Kleine-Budde 	}
4043e77f70eSMarc Kleine-Budde 
4053e77f70eSMarc Kleine-Budde 	/* For CAN FD the data bitrate has to be >= the arbitration bitrate */
4063e77f70eSMarc Kleine-Budde 	if ((priv->ctrlmode & CAN_CTRLMODE_FD) &&
4073e77f70eSMarc Kleine-Budde 	    (!priv->data_bittiming.bitrate ||
4083e77f70eSMarc Kleine-Budde 	     priv->data_bittiming.bitrate < priv->bittiming.bitrate)) {
4093e77f70eSMarc Kleine-Budde 		netdev_err(dev, "incorrect/missing data bit-timing\n");
4103e77f70eSMarc Kleine-Budde 		return -EINVAL;
4113e77f70eSMarc Kleine-Budde 	}
4123e77f70eSMarc Kleine-Budde 
4133e77f70eSMarc Kleine-Budde 	/* Switch carrier on if device was stopped while in bus-off state */
4143e77f70eSMarc Kleine-Budde 	if (!netif_carrier_ok(dev))
4153e77f70eSMarc Kleine-Budde 		netif_carrier_on(dev);
4163e77f70eSMarc Kleine-Budde 
4173e77f70eSMarc Kleine-Budde 	return 0;
4183e77f70eSMarc Kleine-Budde }
4193e77f70eSMarc Kleine-Budde EXPORT_SYMBOL_GPL(open_candev);
4203e77f70eSMarc Kleine-Budde 
4213e77f70eSMarc Kleine-Budde #ifdef CONFIG_OF
4223e77f70eSMarc Kleine-Budde /* Common function that can be used to understand the limitation of
4233e77f70eSMarc Kleine-Budde  * a transceiver when it provides no means to determine these limitations
4243e77f70eSMarc Kleine-Budde  * at runtime.
4253e77f70eSMarc Kleine-Budde  */
of_can_transceiver(struct net_device * dev)4263e77f70eSMarc Kleine-Budde void of_can_transceiver(struct net_device *dev)
4273e77f70eSMarc Kleine-Budde {
4283e77f70eSMarc Kleine-Budde 	struct device_node *dn;
4293e77f70eSMarc Kleine-Budde 	struct can_priv *priv = netdev_priv(dev);
4303e77f70eSMarc Kleine-Budde 	struct device_node *np = dev->dev.parent->of_node;
4313e77f70eSMarc Kleine-Budde 	int ret;
4323e77f70eSMarc Kleine-Budde 
4333e77f70eSMarc Kleine-Budde 	dn = of_get_child_by_name(np, "can-transceiver");
4343e77f70eSMarc Kleine-Budde 	if (!dn)
4353e77f70eSMarc Kleine-Budde 		return;
4363e77f70eSMarc Kleine-Budde 
4373e77f70eSMarc Kleine-Budde 	ret = of_property_read_u32(dn, "max-bitrate", &priv->bitrate_max);
4383e77f70eSMarc Kleine-Budde 	of_node_put(dn);
4393e77f70eSMarc Kleine-Budde 	if ((ret && ret != -EINVAL) || (!ret && !priv->bitrate_max))
4403e77f70eSMarc Kleine-Budde 		netdev_warn(dev, "Invalid value for transceiver max bitrate. Ignoring bitrate limit.\n");
4413e77f70eSMarc Kleine-Budde }
4423e77f70eSMarc Kleine-Budde EXPORT_SYMBOL_GPL(of_can_transceiver);
4433e77f70eSMarc Kleine-Budde #endif
4443e77f70eSMarc Kleine-Budde 
4453e77f70eSMarc Kleine-Budde /* Common close function for cleanup before the device gets closed.
4463e77f70eSMarc Kleine-Budde  *
4473e77f70eSMarc Kleine-Budde  * This function should be called in the close function of the device
4483e77f70eSMarc Kleine-Budde  * driver.
4493e77f70eSMarc Kleine-Budde  */
close_candev(struct net_device * dev)4503e77f70eSMarc Kleine-Budde void close_candev(struct net_device *dev)
4513e77f70eSMarc Kleine-Budde {
4523e77f70eSMarc Kleine-Budde 	struct can_priv *priv = netdev_priv(dev);
4533e77f70eSMarc Kleine-Budde 
4543e77f70eSMarc Kleine-Budde 	cancel_delayed_work_sync(&priv->restart_work);
4553e77f70eSMarc Kleine-Budde 	can_flush_echo_skb(dev);
4563e77f70eSMarc Kleine-Budde }
4573e77f70eSMarc Kleine-Budde EXPORT_SYMBOL_GPL(close_candev);
4583e77f70eSMarc Kleine-Budde 
can_set_termination(struct net_device * ndev,u16 term)4596e86a154SOleksij Rempel static int can_set_termination(struct net_device *ndev, u16 term)
4606e86a154SOleksij Rempel {
4616e86a154SOleksij Rempel 	struct can_priv *priv = netdev_priv(ndev);
4626e86a154SOleksij Rempel 	int set;
4636e86a154SOleksij Rempel 
4646e86a154SOleksij Rempel 	if (term == priv->termination_gpio_ohms[CAN_TERMINATION_GPIO_ENABLED])
4656e86a154SOleksij Rempel 		set = 1;
4666e86a154SOleksij Rempel 	else
4676e86a154SOleksij Rempel 		set = 0;
4686e86a154SOleksij Rempel 
4696e86a154SOleksij Rempel 	gpiod_set_value_cansleep(priv->termination_gpio, set);
4706e86a154SOleksij Rempel 
4716e86a154SOleksij Rempel 	return 0;
4726e86a154SOleksij Rempel }
4736e86a154SOleksij Rempel 
can_get_termination(struct net_device * ndev)4746e86a154SOleksij Rempel static int can_get_termination(struct net_device *ndev)
4756e86a154SOleksij Rempel {
4766e86a154SOleksij Rempel 	struct can_priv *priv = netdev_priv(ndev);
4776e86a154SOleksij Rempel 	struct device *dev = ndev->dev.parent;
4786e86a154SOleksij Rempel 	struct gpio_desc *gpio;
4796e86a154SOleksij Rempel 	u32 term;
4806e86a154SOleksij Rempel 	int ret;
4816e86a154SOleksij Rempel 
4826e86a154SOleksij Rempel 	/* Disabling termination by default is the safe choice: Else if many
4836e86a154SOleksij Rempel 	 * bus participants enable it, no communication is possible at all.
4846e86a154SOleksij Rempel 	 */
4856e86a154SOleksij Rempel 	gpio = devm_gpiod_get_optional(dev, "termination", GPIOD_OUT_LOW);
4866e86a154SOleksij Rempel 	if (IS_ERR(gpio))
4876e86a154SOleksij Rempel 		return dev_err_probe(dev, PTR_ERR(gpio),
4886e86a154SOleksij Rempel 				     "Cannot get termination-gpios\n");
4896e86a154SOleksij Rempel 
4906e86a154SOleksij Rempel 	if (!gpio)
4916e86a154SOleksij Rempel 		return 0;
4926e86a154SOleksij Rempel 
4936e86a154SOleksij Rempel 	ret = device_property_read_u32(dev, "termination-ohms", &term);
4946e86a154SOleksij Rempel 	if (ret) {
4956e86a154SOleksij Rempel 		netdev_err(ndev, "Cannot get termination-ohms: %pe\n",
4966e86a154SOleksij Rempel 			   ERR_PTR(ret));
4976e86a154SOleksij Rempel 		return ret;
4986e86a154SOleksij Rempel 	}
4996e86a154SOleksij Rempel 
5006e86a154SOleksij Rempel 	if (term > U16_MAX) {
5016e86a154SOleksij Rempel 		netdev_err(ndev, "Invalid termination-ohms value (%u > %u)\n",
5026e86a154SOleksij Rempel 			   term, U16_MAX);
5036e86a154SOleksij Rempel 		return -EINVAL;
5046e86a154SOleksij Rempel 	}
5056e86a154SOleksij Rempel 
5066e86a154SOleksij Rempel 	priv->termination_const_cnt = ARRAY_SIZE(priv->termination_gpio_ohms);
5076e86a154SOleksij Rempel 	priv->termination_const = priv->termination_gpio_ohms;
5086e86a154SOleksij Rempel 	priv->termination_gpio = gpio;
5096e86a154SOleksij Rempel 	priv->termination_gpio_ohms[CAN_TERMINATION_GPIO_DISABLED] =
5106e86a154SOleksij Rempel 		CAN_TERMINATION_DISABLED;
5116e86a154SOleksij Rempel 	priv->termination_gpio_ohms[CAN_TERMINATION_GPIO_ENABLED] = term;
5126e86a154SOleksij Rempel 	priv->do_set_termination = can_set_termination;
5136e86a154SOleksij Rempel 
5146e86a154SOleksij Rempel 	return 0;
5156e86a154SOleksij Rempel }
5166e86a154SOleksij Rempel 
517d58ac89dSMarc Kleine-Budde static bool
can_bittiming_const_valid(const struct can_bittiming_const * btc)518d58ac89dSMarc Kleine-Budde can_bittiming_const_valid(const struct can_bittiming_const *btc)
519d58ac89dSMarc Kleine-Budde {
520d58ac89dSMarc Kleine-Budde 	if (!btc)
521d58ac89dSMarc Kleine-Budde 		return true;
522d58ac89dSMarc Kleine-Budde 
523d58ac89dSMarc Kleine-Budde 	if (!btc->sjw_max)
524d58ac89dSMarc Kleine-Budde 		return false;
525d58ac89dSMarc Kleine-Budde 
526d58ac89dSMarc Kleine-Budde 	return true;
527d58ac89dSMarc Kleine-Budde }
528d58ac89dSMarc Kleine-Budde 
5293e77f70eSMarc Kleine-Budde /* Register the CAN network device */
register_candev(struct net_device * dev)5303e77f70eSMarc Kleine-Budde int register_candev(struct net_device *dev)
5313e77f70eSMarc Kleine-Budde {
5323e77f70eSMarc Kleine-Budde 	struct can_priv *priv = netdev_priv(dev);
5336e86a154SOleksij Rempel 	int err;
5343e77f70eSMarc Kleine-Budde 
5353e77f70eSMarc Kleine-Budde 	/* Ensure termination_const, termination_const_cnt and
5363e77f70eSMarc Kleine-Budde 	 * do_set_termination consistency. All must be either set or
5373e77f70eSMarc Kleine-Budde 	 * unset.
5383e77f70eSMarc Kleine-Budde 	 */
5393e77f70eSMarc Kleine-Budde 	if ((!priv->termination_const != !priv->termination_const_cnt) ||
5403e77f70eSMarc Kleine-Budde 	    (!priv->termination_const != !priv->do_set_termination))
5413e77f70eSMarc Kleine-Budde 		return -EINVAL;
5423e77f70eSMarc Kleine-Budde 
5433e77f70eSMarc Kleine-Budde 	if (!priv->bitrate_const != !priv->bitrate_const_cnt)
5443e77f70eSMarc Kleine-Budde 		return -EINVAL;
5453e77f70eSMarc Kleine-Budde 
5463e77f70eSMarc Kleine-Budde 	if (!priv->data_bitrate_const != !priv->data_bitrate_const_cnt)
5473e77f70eSMarc Kleine-Budde 		return -EINVAL;
5483e77f70eSMarc Kleine-Budde 
549a3db5424SMarc Kleine-Budde 	/* We only support either fixed bit rates or bit timing const. */
550a3db5424SMarc Kleine-Budde 	if ((priv->bitrate_const || priv->data_bitrate_const) &&
551a3db5424SMarc Kleine-Budde 	    (priv->bittiming_const || priv->data_bittiming_const))
552a3db5424SMarc Kleine-Budde 		return -EINVAL;
553a3db5424SMarc Kleine-Budde 
554d58ac89dSMarc Kleine-Budde 	if (!can_bittiming_const_valid(priv->bittiming_const) ||
555d58ac89dSMarc Kleine-Budde 	    !can_bittiming_const_valid(priv->data_bittiming_const))
556d58ac89dSMarc Kleine-Budde 		return -EINVAL;
557d58ac89dSMarc Kleine-Budde 
5586e86a154SOleksij Rempel 	if (!priv->termination_const) {
5596e86a154SOleksij Rempel 		err = can_get_termination(dev);
5606e86a154SOleksij Rempel 		if (err)
5616e86a154SOleksij Rempel 			return err;
5626e86a154SOleksij Rempel 	}
5636e86a154SOleksij Rempel 
5643e77f70eSMarc Kleine-Budde 	dev->rtnl_link_ops = &can_link_ops;
5653e77f70eSMarc Kleine-Budde 	netif_carrier_off(dev);
5663e77f70eSMarc Kleine-Budde 
5673e77f70eSMarc Kleine-Budde 	return register_netdev(dev);
5683e77f70eSMarc Kleine-Budde }
5693e77f70eSMarc Kleine-Budde EXPORT_SYMBOL_GPL(register_candev);
5703e77f70eSMarc Kleine-Budde 
5713e77f70eSMarc Kleine-Budde /* Unregister the CAN network device */
unregister_candev(struct net_device * dev)5723e77f70eSMarc Kleine-Budde void unregister_candev(struct net_device *dev)
5733e77f70eSMarc Kleine-Budde {
5743e77f70eSMarc Kleine-Budde 	unregister_netdev(dev);
5753e77f70eSMarc Kleine-Budde }
5763e77f70eSMarc Kleine-Budde EXPORT_SYMBOL_GPL(unregister_candev);
5773e77f70eSMarc Kleine-Budde 
5783e77f70eSMarc Kleine-Budde /* Test if a network device is a candev based device
5793e77f70eSMarc Kleine-Budde  * and return the can_priv* if so.
5803e77f70eSMarc Kleine-Budde  */
safe_candev_priv(struct net_device * dev)5813e77f70eSMarc Kleine-Budde struct can_priv *safe_candev_priv(struct net_device *dev)
5823e77f70eSMarc Kleine-Budde {
5833e77f70eSMarc Kleine-Budde 	if (dev->type != ARPHRD_CAN || dev->rtnl_link_ops != &can_link_ops)
5843e77f70eSMarc Kleine-Budde 		return NULL;
5853e77f70eSMarc Kleine-Budde 
5863e77f70eSMarc Kleine-Budde 	return netdev_priv(dev);
5873e77f70eSMarc Kleine-Budde }
5883e77f70eSMarc Kleine-Budde EXPORT_SYMBOL_GPL(safe_candev_priv);
5893e77f70eSMarc Kleine-Budde 
can_dev_init(void)5903e77f70eSMarc Kleine-Budde static __init int can_dev_init(void)
5913e77f70eSMarc Kleine-Budde {
5923e77f70eSMarc Kleine-Budde 	int err;
5933e77f70eSMarc Kleine-Budde 
5940a042c6eSMarc Kleine-Budde 	err = can_netlink_register();
5953e77f70eSMarc Kleine-Budde 	if (!err)
5966a528644SVincent Mailhol 		pr_info("CAN device driver interface\n");
5973e77f70eSMarc Kleine-Budde 
5983e77f70eSMarc Kleine-Budde 	return err;
5993e77f70eSMarc Kleine-Budde }
6003e77f70eSMarc Kleine-Budde module_init(can_dev_init);
6013e77f70eSMarc Kleine-Budde 
can_dev_exit(void)6023e77f70eSMarc Kleine-Budde static __exit void can_dev_exit(void)
6033e77f70eSMarc Kleine-Budde {
6040a042c6eSMarc Kleine-Budde 	can_netlink_unregister();
6053e77f70eSMarc Kleine-Budde }
6063e77f70eSMarc Kleine-Budde module_exit(can_dev_exit);
6073e77f70eSMarc Kleine-Budde 
6083e77f70eSMarc Kleine-Budde MODULE_ALIAS_RTNL_LINK("can");
609