Lines Matching +full:modem +full:- +full:remoteproc
1 // SPDX-License-Identifier: GPL-2.0
3 /* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
4 * Copyright (C) 2018-2022 Linaro Ltd.
15 #include <linux/remoteproc/qcom_rproc.h>
40 * struct ipa_priv - IPA network device private data
42 * @work: Work structure used to wake the modem netdev TX queue
49 /** ipa_open() - Opens the modem network interface */
53 struct ipa *ipa = priv->ipa; in ipa_open()
57 dev = &ipa->pdev->dev; in ipa_open()
62 ret = ipa_endpoint_enable_one(ipa->name_map[IPA_ENDPOINT_AP_MODEM_TX]); in ipa_open()
66 ret = ipa_endpoint_enable_one(ipa->name_map[IPA_ENDPOINT_AP_MODEM_RX]); in ipa_open()
78 ipa_endpoint_disable_one(ipa->name_map[IPA_ENDPOINT_AP_MODEM_TX]); in ipa_open()
85 /** ipa_stop() - Stops the modem network interface. */
89 struct ipa *ipa = priv->ipa; in ipa_stop()
93 dev = &ipa->pdev->dev; in ipa_stop()
100 ipa_endpoint_disable_one(ipa->name_map[IPA_ENDPOINT_AP_MODEM_RX]); in ipa_stop()
101 ipa_endpoint_disable_one(ipa->name_map[IPA_ENDPOINT_AP_MODEM_TX]); in ipa_stop()
109 /** ipa_start_xmit() - Transmits an skb.
120 struct net_device_stats *stats = &netdev->stats; in ipa_start_xmit()
123 struct ipa *ipa = priv->ipa; in ipa_start_xmit()
124 u32 skb_len = skb->len; in ipa_start_xmit()
131 endpoint = ipa->name_map[IPA_ENDPOINT_AP_MODEM_TX]; in ipa_start_xmit()
132 if (endpoint->config.qmap && skb->protocol != htons(ETH_P_MAP)) in ipa_start_xmit()
136 dev = &ipa->pdev->dev; in ipa_start_xmit()
140 if (ret < 0 && ret != -EINPROGRESS) { in ipa_start_xmit()
165 if (ret != -E2BIG) in ipa_start_xmit()
170 stats->tx_packets++; in ipa_start_xmit()
171 stats->tx_bytes += skb_len; in ipa_start_xmit()
177 stats->tx_dropped++; in ipa_start_xmit()
184 struct net_device_stats *stats = &netdev->stats; in ipa_modem_skb_rx()
187 skb->dev = netdev; in ipa_modem_skb_rx()
188 skb->protocol = htons(ETH_P_MAP); in ipa_modem_skb_rx()
189 stats->rx_packets++; in ipa_modem_skb_rx()
190 stats->rx_bytes += skb->len; in ipa_modem_skb_rx()
194 stats->rx_dropped++; in ipa_modem_skb_rx()
204 /** ipa_modem_netdev_setup() - netdev setup function for the modem */
207 netdev->netdev_ops = &ipa_modem_ops; in ipa_modem_netdev_setup()
209 netdev->header_ops = NULL; in ipa_modem_netdev_setup()
210 netdev->type = ARPHRD_RAWIP; in ipa_modem_netdev_setup()
211 netdev->hard_header_len = 0; in ipa_modem_netdev_setup()
212 netdev->min_header_len = ETH_HLEN; in ipa_modem_netdev_setup()
213 netdev->min_mtu = ETH_MIN_MTU; in ipa_modem_netdev_setup()
214 netdev->max_mtu = IPA_MTU; in ipa_modem_netdev_setup()
215 netdev->mtu = netdev->max_mtu; in ipa_modem_netdev_setup()
216 netdev->addr_len = 0; in ipa_modem_netdev_setup()
217 netdev->tx_queue_len = DEFAULT_TX_QUEUE_LEN; in ipa_modem_netdev_setup()
218 netdev->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); in ipa_modem_netdev_setup()
219 netdev->priv_flags |= IFF_TX_SKB_SHARING; in ipa_modem_netdev_setup()
220 eth_broadcast_addr(netdev->broadcast); in ipa_modem_netdev_setup()
223 netdev->needed_headroom = sizeof(struct rmnet_map_header); in ipa_modem_netdev_setup()
224 netdev->needed_tailroom = IPA_NETDEV_TAILROOM; in ipa_modem_netdev_setup()
225 netdev->watchdog_timeo = IPA_NETDEV_TIMEOUT * HZ; in ipa_modem_netdev_setup()
226 netdev->hw_features = NETIF_F_SG; in ipa_modem_netdev_setup()
229 /** ipa_modem_suspend() - suspend callback
232 * Suspend the modem's endpoints.
237 struct ipa *ipa = priv->ipa; in ipa_modem_suspend()
239 if (!(netdev->flags & IFF_UP)) in ipa_modem_suspend()
242 ipa_endpoint_suspend_one(ipa->name_map[IPA_ENDPOINT_AP_MODEM_RX]); in ipa_modem_suspend()
243 ipa_endpoint_suspend_one(ipa->name_map[IPA_ENDPOINT_AP_MODEM_TX]); in ipa_modem_suspend()
247 * ipa_modem_wake_queue_work() - enable modem netdev queue
250 * Re-enable transmit on the modem network device. This is called
252 * the modem. We can't enable the queue directly in ipa_modem_resume()
261 ipa_power_modem_queue_wake(priv->ipa); in ipa_modem_wake_queue_work()
264 /** ipa_modem_resume() - resume callback for runtime_pm
267 * Resume the modem's endpoints.
272 struct ipa *ipa = priv->ipa; in ipa_modem_resume()
274 if (!(netdev->flags & IFF_UP)) in ipa_modem_resume()
277 ipa_endpoint_resume_one(ipa->name_map[IPA_ENDPOINT_AP_MODEM_TX]); in ipa_modem_resume()
278 ipa_endpoint_resume_one(ipa->name_map[IPA_ENDPOINT_AP_MODEM_RX]); in ipa_modem_resume()
281 (void)queue_pm_work(&priv->work); in ipa_modem_resume()
291 /* Only attempt to start the modem if it's stopped */ in ipa_modem_start()
292 state = atomic_cmpxchg(&ipa->modem_state, IPA_MODEM_STATE_STOPPED, in ipa_modem_start()
302 ret = -ENOMEM; in ipa_modem_start()
306 SET_NETDEV_DEV(netdev, &ipa->pdev->dev); in ipa_modem_start()
308 priv->ipa = ipa; in ipa_modem_start()
309 INIT_WORK(&priv->work, ipa_modem_wake_queue_work); in ipa_modem_start()
310 ipa->name_map[IPA_ENDPOINT_AP_MODEM_TX]->netdev = netdev; in ipa_modem_start()
311 ipa->name_map[IPA_ENDPOINT_AP_MODEM_RX]->netdev = netdev; in ipa_modem_start()
312 ipa->modem_netdev = netdev; in ipa_modem_start()
316 ipa->modem_netdev = NULL; in ipa_modem_start()
317 ipa->name_map[IPA_ENDPOINT_AP_MODEM_RX]->netdev = NULL; in ipa_modem_start()
318 ipa->name_map[IPA_ENDPOINT_AP_MODEM_TX]->netdev = NULL; in ipa_modem_start()
324 atomic_set(&ipa->modem_state, IPA_MODEM_STATE_STOPPED); in ipa_modem_start()
326 atomic_set(&ipa->modem_state, IPA_MODEM_STATE_RUNNING); in ipa_modem_start()
334 struct net_device *netdev = ipa->modem_netdev; in ipa_modem_stop()
337 /* Only attempt to stop the modem if it's running */ in ipa_modem_stop()
338 state = atomic_cmpxchg(&ipa->modem_state, IPA_MODEM_STATE_RUNNING, in ipa_modem_stop()
347 return -EBUSY; in ipa_modem_stop()
353 cancel_work_sync(&priv->work); in ipa_modem_stop()
355 if (netdev->flags & IFF_UP) in ipa_modem_stop()
358 ipa->modem_netdev = NULL; in ipa_modem_stop()
359 ipa->name_map[IPA_ENDPOINT_AP_MODEM_RX]->netdev = NULL; in ipa_modem_stop()
360 ipa->name_map[IPA_ENDPOINT_AP_MODEM_TX]->netdev = NULL; in ipa_modem_stop()
364 atomic_set(&ipa->modem_state, IPA_MODEM_STATE_STOPPED); in ipa_modem_stop()
370 /* Treat a "clean" modem stop the same as a crash */
373 struct device *dev = &ipa->pdev->dev; in ipa_modem_crashed()
376 /* Prevent the modem from triggering a call to ipa_setup() */ in ipa_modem_crashed()
403 dev_err(dev, "error %d stopping modem\n", ret); in ipa_modem_crashed()
405 /* Now prepare for the next modem boot */ in ipa_modem_crashed()
408 dev_err(dev, "error %d zeroing modem memory regions\n", ret); in ipa_modem_crashed()
420 struct device *dev = &ipa->pdev->dev; in ipa_modem_notify()
424 dev_info(dev, "received modem starting event\n"); in ipa_modem_notify()
430 dev_info(dev, "received modem running event\n"); in ipa_modem_notify()
434 dev_info(dev, "received modem %s event\n", in ipa_modem_notify()
435 notify_data->crashed ? "crashed" : "stopping"); in ipa_modem_notify()
436 if (ipa->setup_complete) in ipa_modem_notify()
441 dev_info(dev, "received modem offline event\n"); in ipa_modem_notify()
456 ipa->nb.notifier_call = ipa_modem_notify; in ipa_modem_config()
458 notifier = qcom_register_ssr_notifier("mpss", &ipa->nb); in ipa_modem_config()
462 ipa->notifier = notifier; in ipa_modem_config()
469 struct device *dev = &ipa->pdev->dev; in ipa_modem_deconfig()
472 ret = qcom_unregister_ssr_notifier(ipa->notifier, &ipa->nb); in ipa_modem_deconfig()
476 ipa->notifier = NULL; in ipa_modem_deconfig()
477 memset(&ipa->nb, 0, sizeof(ipa->nb)); in ipa_modem_deconfig()