Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 180d3780 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "net: usbnet: Do not wait for ipa_ready_callback"

parents aa87696b d8a7e3a7
Loading
Loading
Loading
Loading
+38 −44
Original line number Diff line number Diff line
@@ -2008,14 +2008,42 @@ static void usbnet_ipa_send_routine(struct work_struct *work)
	spin_unlock(&dev->ipa_pendq.lock);
}

static void usbnet_odu_bridge_init(struct work_struct *work)
{
	struct usbnet *dev = container_of(work, struct usbnet, odu_bridge_init);
	struct odu_bridge_params params;
	int status;

	/* Initialize the ODU bridge driver */
	params.netdev_name      = dev->net->name;
	params.priv             = dev;
	params.tx_dp_notify     = usbnet_ipa_tx_dp_cb;
	params.send_dl_skb      = (void *)&usbnet_ipa_tx_dl;
	params.ipa_desc_size    = (dev->ipa_high_watermark + 1) *
					sizeof(struct sps_iovec);
	memcpy(params.device_ethaddr, dev->net->dev_addr, 6);

	status = odu_bridge_init(&params);
	if (status) {
		pr_err("Couldnt initialize ODU_Bridge Driver\n");
		return;
	}

	status = odu_bridge_connect();
	if (!status) {
		usbnet_ipa_set_perf_level(dev);
	} else {
		pr_err("Could not connect to ODU bridge %d\n", status);
		return;
	}
}

static void usbnet_ipa_ready_callback(void *user_data)
{
	struct usbnet *dev = user_data;

	pr_info("%s: ipa is ready\n", __func__);
	dev->ipa_ready = true;

	wake_up_interruptible(&dev->wait_for_ipa_ready);
	queue_work(usbnet_wq, &dev->odu_bridge_init);
}

int
@@ -2030,9 +2058,6 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
	const char			*name;
	struct usb_driver 	*driver = to_usb_driver(udev->dev.driver);
	struct usbnet_ipa_ctx *usbnet_ipa = NULL;
	struct odu_bridge_params *params_ptr, params;

	params_ptr = &params;

	/* usbnet already took usb runtime pm, so have to enable the feature
	 * for usb interface, otherwise usb_autopm_get_interface may return
@@ -2070,7 +2095,6 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
	dev->msg_enable = netif_msg_init (msg_level, NETIF_MSG_DRV
				| NETIF_MSG_PROBE | NETIF_MSG_LINK);
	init_waitqueue_head(&dev->wait);
	init_waitqueue_head(&dev->wait_for_ipa_ready);
	skb_queue_head_init (&dev->rxq);
	skb_queue_head_init (&dev->txq);
	skb_queue_head_init (&dev->done);
@@ -2200,6 +2224,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
		/* Initialize flow control variables */
		skb_queue_head_init(&dev->ipa_pendq);
		INIT_WORK(&dev->ipa_send_task, usbnet_ipa_send_routine);
		INIT_WORK(&dev->odu_bridge_init, usbnet_odu_bridge_init);

		status = usbnet_ipa_setup_rm(dev);
		if (status) {
@@ -2211,34 +2236,16 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
		if (status)
			pr_err("USBNET: Debugfs Init Failed\n");

		/* Initialize the ODU bridge driver now: odu_bridge_init()*/
		params_ptr->netdev_name = net->name;
		params_ptr->priv = dev;
		params.tx_dp_notify = usbnet_ipa_tx_dp_cb;
		params_ptr->send_dl_skb = (void *)&usbnet_ipa_tx_dl;
		memcpy(params_ptr->device_ethaddr, net->dev_addr, 6);
		params_ptr->ipa_desc_size = (dev->ipa_high_watermark + 1) *
					sizeof(struct sps_iovec);

		status = odu_bridge_init(params_ptr);
		if (status) {
			pr_err("Couldnt initialize ODU_Bridge Driver\n");
			goto ipa_cleanup;
		}

		status = ipa_register_ipa_ready_cb(usbnet_ipa_ready_callback,
						   dev);
		if (!status) {
			pr_info("%s: ipa is not ready\n", __func__);
			status = wait_event_interruptible_timeout(
					dev->wait_for_ipa_ready, dev->ipa_ready,
					msecs_to_jiffies
						(USBNET_IPA_READY_TIMEOUT));
			if (!status) {
				pr_err("%s: ipa ready timeout\n", __func__);
				status = -ETIMEDOUT;
				goto ipa_cleanup;
			}
		} else if (status == -EEXIST) {
			pr_debug("USBNET: IPA is ready\n");
			usbnet_odu_bridge_init(&dev->odu_bridge_init);
		} else {
			pr_err("USBNET: error in ipa register cb\n");
			goto free_ipa;
		}
	}

@@ -2250,21 +2257,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
	if (dev->driver_info->flags & FLAG_LINK_INTR)
		usbnet_link_change(dev, 0, 0);

	if (enable_ipa_bridge) {
		status = odu_bridge_connect();
		if (status) {
			pr_err("Could not connect to ODU bridge %d\n",
			       status);
			goto ipa_cleanup;
		} else {
			usbnet_ipa_set_perf_level(dev);
		}
	}

	return 0;

ipa_cleanup:
	usbnet_ipa_cleanup_rm(dev);
free_ipa:
	kfree(usbnet_ipa);
unreg_netdev:
+2 −3
Original line number Diff line number Diff line
@@ -27,7 +27,6 @@
#define USBNET_IPA_SYS_PIPE_MAX_PKTS_DESC 200
#define USBNET_IPA_SYS_PIPE_MIN_PKTS_DESC 5
#define USBNET_IPA_SYS_PIPE_DNE_PKTS (USBNET_IPA_SYS_PIPE_MAX_PKTS_DESC*2)
#define USBNET_IPA_READY_TIMEOUT 5000

struct usbnet_ipa_stats {
	/* RX Side */
@@ -119,8 +118,8 @@ struct usbnet {
	struct sk_buff_head	ipa_pendq;
	/* work to send pending packets to ipa */
	struct work_struct ipa_send_task;
	bool	ipa_ready;
	wait_queue_head_t wait_for_ipa_ready;
	/* work for odu bridge initialization */
	struct work_struct odu_bridge_init;
};

static inline struct usb_driver *driver_of(struct usb_interface *intf)