Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.17.
  1// SPDX-License-Identifier: GPL-2.0
  2
  3/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
  4 * Copyright (C) 2018-2022 Linaro Ltd.
  5 */
  6
  7#include <linux/errno.h>
  8#include <linux/if_arp.h>
  9#include <linux/netdevice.h>
 10#include <linux/skbuff.h>
 11#include <linux/if_rmnet.h>
 12#include <linux/etherdevice.h>
 13#include <net/pkt_sched.h>
 14#include <linux/pm_runtime.h>
 15#include <linux/remoteproc/qcom_rproc.h>
 16
 17#include "ipa.h"
 18#include "ipa_data.h"
 19#include "ipa_endpoint.h"
 20#include "ipa_table.h"
 21#include "ipa_mem.h"
 22#include "ipa_modem.h"
 23#include "ipa_smp2p.h"
 24#include "ipa_qmi.h"
 25#include "ipa_uc.h"
 26#include "ipa_power.h"
 27
 28#define IPA_NETDEV_NAME		"rmnet_ipa%d"
 29#define IPA_NETDEV_TAILROOM	0	/* for padding by mux layer */
 30#define IPA_NETDEV_TIMEOUT	10	/* seconds */
 31
 32enum ipa_modem_state {
 33	IPA_MODEM_STATE_STOPPED	= 0,
 34	IPA_MODEM_STATE_STARTING,
 35	IPA_MODEM_STATE_RUNNING,
 36	IPA_MODEM_STATE_STOPPING,
 37};
 38
 39/**
 40 * struct ipa_priv - IPA network device private data
 41 * @ipa:	IPA pointer
 42 * @work:	Work structure used to wake the modem netdev TX queue
 43 */
 44struct ipa_priv {
 45	struct ipa *ipa;
 46	struct work_struct work;
 47};
 48
 49/** ipa_open() - Opens the modem network interface */
 50static int ipa_open(struct net_device *netdev)
 51{
 52	struct ipa_priv *priv = netdev_priv(netdev);
 53	struct ipa *ipa = priv->ipa;
 54	struct device *dev;
 55	int ret;
 56
 57	dev = &ipa->pdev->dev;
 58	ret = pm_runtime_get_sync(dev);
 59	if (ret < 0)
 60		goto err_power_put;
 61
 62	ret = ipa_endpoint_enable_one(ipa->name_map[IPA_ENDPOINT_AP_MODEM_TX]);
 63	if (ret)
 64		goto err_power_put;
 65
 66	ret = ipa_endpoint_enable_one(ipa->name_map[IPA_ENDPOINT_AP_MODEM_RX]);
 67	if (ret)
 68		goto err_disable_tx;
 69
 70	netif_start_queue(netdev);
 71
 72	pm_runtime_mark_last_busy(dev);
 73	(void)pm_runtime_put_autosuspend(dev);
 74
 75	return 0;
 76
 77err_disable_tx:
 78	ipa_endpoint_disable_one(ipa->name_map[IPA_ENDPOINT_AP_MODEM_TX]);
 79err_power_put:
 80	pm_runtime_put_noidle(dev);
 81
 82	return ret;
 83}
 84
 85/** ipa_stop() - Stops the modem network interface. */
 86static int ipa_stop(struct net_device *netdev)
 87{
 88	struct ipa_priv *priv = netdev_priv(netdev);
 89	struct ipa *ipa = priv->ipa;
 90	struct device *dev;
 91	int ret;
 92
 93	dev = &ipa->pdev->dev;
 94	ret = pm_runtime_get_sync(dev);
 95	if (ret < 0)
 96		goto out_power_put;
 97
 98	netif_stop_queue(netdev);
 99
100	ipa_endpoint_disable_one(ipa->name_map[IPA_ENDPOINT_AP_MODEM_RX]);
101	ipa_endpoint_disable_one(ipa->name_map[IPA_ENDPOINT_AP_MODEM_TX]);
102out_power_put:
103	pm_runtime_mark_last_busy(dev);
104	(void)pm_runtime_put_autosuspend(dev);
105
106	return 0;
107}
108
109/** ipa_start_xmit() - Transmits an skb.
110 * @skb: skb to be transmitted
111 * @dev: network device
112 *
113 * Return codes:
114 * NETDEV_TX_OK: Success
115 * NETDEV_TX_BUSY: Error while transmitting the skb. Try again later
116 */
117static netdev_tx_t
118ipa_start_xmit(struct sk_buff *skb, struct net_device *netdev)
119{
120	struct net_device_stats *stats = &netdev->stats;
121	struct ipa_priv *priv = netdev_priv(netdev);
122	struct ipa_endpoint *endpoint;
123	struct ipa *ipa = priv->ipa;
124	u32 skb_len = skb->len;
125	struct device *dev;
126	int ret;
127
128	if (!skb_len)
129		goto err_drop_skb;
130
131	endpoint = ipa->name_map[IPA_ENDPOINT_AP_MODEM_TX];
132	if (endpoint->config.qmap && skb->protocol != htons(ETH_P_MAP))
133		goto err_drop_skb;
134
135	/* The hardware must be powered for us to transmit */
136	dev = &ipa->pdev->dev;
137	ret = pm_runtime_get(dev);
138	if (ret < 1) {
139		/* If a resume won't happen, just drop the packet */
140		if (ret < 0 && ret != -EINPROGRESS) {
141			ipa_power_modem_queue_active(ipa);
142			pm_runtime_put_noidle(dev);
143			goto err_drop_skb;
144		}
145
146		/* No power (yet).  Stop the network stack from transmitting
147		 * until we're resumed; ipa_modem_resume() arranges for the
148		 * TX queue to be started again.
149		 */
150		ipa_power_modem_queue_stop(ipa);
151
152		pm_runtime_put_noidle(dev);
153
154		return NETDEV_TX_BUSY;
155	}
156
157	ipa_power_modem_queue_active(ipa);
158
159	ret = ipa_endpoint_skb_tx(endpoint, skb);
160
161	pm_runtime_mark_last_busy(dev);
162	(void)pm_runtime_put_autosuspend(dev);
163
164	if (ret) {
165		if (ret != -E2BIG)
166			return NETDEV_TX_BUSY;
167		goto err_drop_skb;
168	}
169
170	stats->tx_packets++;
171	stats->tx_bytes += skb_len;
172
173	return NETDEV_TX_OK;
174
175err_drop_skb:
176	dev_kfree_skb_any(skb);
177	stats->tx_dropped++;
178
179	return NETDEV_TX_OK;
180}
181
182void ipa_modem_skb_rx(struct net_device *netdev, struct sk_buff *skb)
183{
184	struct net_device_stats *stats = &netdev->stats;
185
186	if (skb) {
187		skb->dev = netdev;
188		skb->protocol = htons(ETH_P_MAP);
189		stats->rx_packets++;
190		stats->rx_bytes += skb->len;
191
192		(void)netif_receive_skb(skb);
193	} else {
194		stats->rx_dropped++;
195	}
196}
197
198static const struct net_device_ops ipa_modem_ops = {
199	.ndo_open	= ipa_open,
200	.ndo_stop	= ipa_stop,
201	.ndo_start_xmit	= ipa_start_xmit,
202};
203
204/** ipa_modem_netdev_setup() - netdev setup function for the modem */
205static void ipa_modem_netdev_setup(struct net_device *netdev)
206{
207	netdev->netdev_ops = &ipa_modem_ops;
208
209	netdev->header_ops = NULL;
210	netdev->type = ARPHRD_RAWIP;
211	netdev->hard_header_len = 0;
212	netdev->min_header_len = ETH_HLEN;
213	netdev->min_mtu = ETH_MIN_MTU;
214	netdev->max_mtu = IPA_MTU;
215	netdev->mtu = netdev->max_mtu;
216	netdev->addr_len = 0;
217	netdev->tx_queue_len = DEFAULT_TX_QUEUE_LEN;
218	netdev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST);
219	netdev->priv_flags |= IFF_TX_SKB_SHARING;
220	eth_broadcast_addr(netdev->broadcast);
221
222	/* The endpoint is configured for QMAP */
223	netdev->needed_headroom = sizeof(struct rmnet_map_header);
224	netdev->needed_tailroom = IPA_NETDEV_TAILROOM;
225	netdev->watchdog_timeo = IPA_NETDEV_TIMEOUT * HZ;
226	netdev->hw_features = NETIF_F_SG;
227}
228
229/** ipa_modem_suspend() - suspend callback
230 * @netdev:	Network device
231 *
232 * Suspend the modem's endpoints.
233 */
234void ipa_modem_suspend(struct net_device *netdev)
235{
236	struct ipa_priv *priv = netdev_priv(netdev);
237	struct ipa *ipa = priv->ipa;
238
239	if (!(netdev->flags & IFF_UP))
240		return;
241
242	ipa_endpoint_suspend_one(ipa->name_map[IPA_ENDPOINT_AP_MODEM_RX]);
243	ipa_endpoint_suspend_one(ipa->name_map[IPA_ENDPOINT_AP_MODEM_TX]);
244}
245
246/**
247 * ipa_modem_wake_queue_work() - enable modem netdev queue
248 * @work:	Work structure
249 *
250 * Re-enable transmit on the modem network device.  This is called
251 * in (power management) work queue context, scheduled when resuming
252 * the modem.  We can't enable the queue directly in ipa_modem_resume()
253 * because transmits restart the instant the queue is awakened; but the
254 * device power state won't be ACTIVE until *after* ipa_modem_resume()
255 * returns.
256 */
257static void ipa_modem_wake_queue_work(struct work_struct *work)
258{
259	struct ipa_priv *priv = container_of(work, struct ipa_priv, work);
260
261	ipa_power_modem_queue_wake(priv->ipa);
262}
263
264/** ipa_modem_resume() - resume callback for runtime_pm
265 * @dev: pointer to device
266 *
267 * Resume the modem's endpoints.
268 */
269void ipa_modem_resume(struct net_device *netdev)
270{
271	struct ipa_priv *priv = netdev_priv(netdev);
272	struct ipa *ipa = priv->ipa;
273
274	if (!(netdev->flags & IFF_UP))
275		return;
276
277	ipa_endpoint_resume_one(ipa->name_map[IPA_ENDPOINT_AP_MODEM_TX]);
278	ipa_endpoint_resume_one(ipa->name_map[IPA_ENDPOINT_AP_MODEM_RX]);
279
280	/* Arrange for the TX queue to be restarted */
281	(void)queue_pm_work(&priv->work);
282}
283
284int ipa_modem_start(struct ipa *ipa)
285{
286	enum ipa_modem_state state;
287	struct net_device *netdev;
288	struct ipa_priv *priv;
289	int ret;
290
291	/* Only attempt to start the modem if it's stopped */
292	state = atomic_cmpxchg(&ipa->modem_state, IPA_MODEM_STATE_STOPPED,
293			       IPA_MODEM_STATE_STARTING);
294
295	/* Silently ignore attempts when running, or when changing state */
296	if (state != IPA_MODEM_STATE_STOPPED)
297		return 0;
298
299	netdev = alloc_netdev(sizeof(struct ipa_priv), IPA_NETDEV_NAME,
300			      NET_NAME_UNKNOWN, ipa_modem_netdev_setup);
301	if (!netdev) {
302		ret = -ENOMEM;
303		goto out_set_state;
304	}
305
306	SET_NETDEV_DEV(netdev, &ipa->pdev->dev);
307	priv = netdev_priv(netdev);
308	priv->ipa = ipa;
309	INIT_WORK(&priv->work, ipa_modem_wake_queue_work);
310	ipa->name_map[IPA_ENDPOINT_AP_MODEM_TX]->netdev = netdev;
311	ipa->name_map[IPA_ENDPOINT_AP_MODEM_RX]->netdev = netdev;
312	ipa->modem_netdev = netdev;
313
314	ret = register_netdev(netdev);
315	if (ret) {
316		ipa->modem_netdev = NULL;
317		ipa->name_map[IPA_ENDPOINT_AP_MODEM_RX]->netdev = NULL;
318		ipa->name_map[IPA_ENDPOINT_AP_MODEM_TX]->netdev = NULL;
319		free_netdev(netdev);
320	}
321
322out_set_state:
323	if (ret)
324		atomic_set(&ipa->modem_state, IPA_MODEM_STATE_STOPPED);
325	else
326		atomic_set(&ipa->modem_state, IPA_MODEM_STATE_RUNNING);
327	smp_mb__after_atomic();
328
329	return ret;
330}
331
332int ipa_modem_stop(struct ipa *ipa)
333{
334	struct net_device *netdev = ipa->modem_netdev;
335	enum ipa_modem_state state;
336
337	/* Only attempt to stop the modem if it's running */
338	state = atomic_cmpxchg(&ipa->modem_state, IPA_MODEM_STATE_RUNNING,
339			       IPA_MODEM_STATE_STOPPING);
340
341	/* Silently ignore attempts when already stopped */
342	if (state == IPA_MODEM_STATE_STOPPED)
343		return 0;
344
345	/* If we're somewhere between stopped and starting, we're busy */
346	if (state != IPA_MODEM_STATE_RUNNING)
347		return -EBUSY;
348
349	/* Clean up the netdev and endpoints if it was started */
350	if (netdev) {
351		struct ipa_priv *priv = netdev_priv(netdev);
352
353		cancel_work_sync(&priv->work);
354		/* If it was opened, stop it first */
355		if (netdev->flags & IFF_UP)
356			(void)ipa_stop(netdev);
357		unregister_netdev(netdev);
358		ipa->modem_netdev = NULL;
359		ipa->name_map[IPA_ENDPOINT_AP_MODEM_RX]->netdev = NULL;
360		ipa->name_map[IPA_ENDPOINT_AP_MODEM_TX]->netdev = NULL;
361		free_netdev(netdev);
362	}
363
364	atomic_set(&ipa->modem_state, IPA_MODEM_STATE_STOPPED);
365	smp_mb__after_atomic();
366
367	return 0;
368}
369
370/* Treat a "clean" modem stop the same as a crash */
371static void ipa_modem_crashed(struct ipa *ipa)
372{
373	struct device *dev = &ipa->pdev->dev;
374	int ret;
375
376	/* Prevent the modem from triggering a call to ipa_setup() */
377	ipa_smp2p_irq_disable_setup(ipa);
378
379	ret = pm_runtime_get_sync(dev);
380	if (ret < 0) {
381		dev_err(dev, "error %d getting power to handle crash\n", ret);
382		goto out_power_put;
383	}
384
385	ipa_endpoint_modem_pause_all(ipa, true);
386
387	ipa_endpoint_modem_hol_block_clear_all(ipa);
388
389	ipa_table_reset(ipa, true);
390
391	ret = ipa_table_hash_flush(ipa);
392	if (ret)
393		dev_err(dev, "error %d flushing hash caches\n", ret);
394
395	ret = ipa_endpoint_modem_exception_reset_all(ipa);
396	if (ret)
397		dev_err(dev, "error %d resetting exception endpoint\n", ret);
398
399	ipa_endpoint_modem_pause_all(ipa, false);
400
401	ret = ipa_modem_stop(ipa);
402	if (ret)
403		dev_err(dev, "error %d stopping modem\n", ret);
404
405	/* Now prepare for the next modem boot */
406	ret = ipa_mem_zero_modem(ipa);
407	if (ret)
408		dev_err(dev, "error %d zeroing modem memory regions\n", ret);
409
410out_power_put:
411	pm_runtime_mark_last_busy(dev);
412	(void)pm_runtime_put_autosuspend(dev);
413}
414
415static int ipa_modem_notify(struct notifier_block *nb, unsigned long action,
416			    void *data)
417{
418	struct ipa *ipa = container_of(nb, struct ipa, nb);
419	struct qcom_ssr_notify_data *notify_data = data;
420	struct device *dev = &ipa->pdev->dev;
421
422	switch (action) {
423	case QCOM_SSR_BEFORE_POWERUP:
424		dev_info(dev, "received modem starting event\n");
425		ipa_uc_power(ipa);
426		ipa_smp2p_notify_reset(ipa);
427		break;
428
429	case QCOM_SSR_AFTER_POWERUP:
430		dev_info(dev, "received modem running event\n");
431		break;
432
433	case QCOM_SSR_BEFORE_SHUTDOWN:
434		dev_info(dev, "received modem %s event\n",
435			 notify_data->crashed ? "crashed" : "stopping");
436		if (ipa->setup_complete)
437			ipa_modem_crashed(ipa);
438		break;
439
440	case QCOM_SSR_AFTER_SHUTDOWN:
441		dev_info(dev, "received modem offline event\n");
442		break;
443
444	default:
445		dev_err(dev, "received unrecognized event %lu\n", action);
446		break;
447	}
448
449	return NOTIFY_OK;
450}
451
452int ipa_modem_config(struct ipa *ipa)
453{
454	void *notifier;
455
456	ipa->nb.notifier_call = ipa_modem_notify;
457
458	notifier = qcom_register_ssr_notifier("mpss", &ipa->nb);
459	if (IS_ERR(notifier))
460		return PTR_ERR(notifier);
461
462	ipa->notifier = notifier;
463
464	return 0;
465}
466
467void ipa_modem_deconfig(struct ipa *ipa)
468{
469	struct device *dev = &ipa->pdev->dev;
470	int ret;
471
472	ret = qcom_unregister_ssr_notifier(ipa->notifier, &ipa->nb);
473	if (ret)
474		dev_err(dev, "error %d unregistering notifier", ret);
475
476	ipa->notifier = NULL;
477	memset(&ipa->nb, 0, sizeof(ipa->nb));
478}