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