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

Commit 244b124c authored by Hante Meuleman's avatar Hante Meuleman Committed by John W. Linville
Browse files

brcmfmac: Add wowl support for USB devices.



This patch adds wowl support for USB bus devices. This feature
requires FW which has support for wowl built in.

Reviewed-by: default avatarArend Van Spriel <arend@broadcom.com>
Reviewed-by: default avatarFranky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: default avatarPieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: default avatarDaniel (Deognyoun) Kim <dekim@broadcom.com>
Signed-off-by: default avatarHante Meuleman <meuleman@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent edad1873
Loading
Loading
Loading
Loading
+39 −10
Original line number Diff line number Diff line
@@ -93,6 +93,8 @@ struct brcmf_usbdev_info {
	u8 ifnum;

	struct urb *bulk_urb; /* used for FW download */

	bool wowl_enabled;
};

static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,
@@ -600,6 +602,16 @@ static int brcmf_usb_up(struct device *dev)
	return 0;
}

static void brcmf_cancel_all_urbs(struct brcmf_usbdev_info *devinfo)
{
	if (devinfo->ctl_urb)
		usb_kill_urb(devinfo->ctl_urb);
	if (devinfo->bulk_urb)
		usb_kill_urb(devinfo->bulk_urb);
	brcmf_usb_free_q(&devinfo->tx_postq, true);
	brcmf_usb_free_q(&devinfo->rx_postq, true);
}

static void brcmf_usb_down(struct device *dev)
{
	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
@@ -613,14 +625,7 @@ static void brcmf_usb_down(struct device *dev)

	brcmf_usb_state_change(devinfo, BRCMFMAC_USB_STATE_DOWN);

	if (devinfo->ctl_urb)
		usb_kill_urb(devinfo->ctl_urb);

	if (devinfo->bulk_urb)
		usb_kill_urb(devinfo->bulk_urb);
	brcmf_usb_free_q(&devinfo->tx_postq, true);

	brcmf_usb_free_q(&devinfo->rx_postq, true);
	brcmf_cancel_all_urbs(devinfo);
}

static void
@@ -1094,11 +1099,24 @@ struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo,
	return NULL;
}

static void brcmf_usb_wowl_config(struct device *dev, bool enabled)
{
	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);

	brcmf_dbg(USB, "Configuring WOWL, enabled=%d\n", enabled);
	devinfo->wowl_enabled = enabled;
	if (enabled)
		device_set_wakeup_enable(devinfo->dev, true);
	else
		device_set_wakeup_enable(devinfo->dev, false);
}

static struct brcmf_bus_ops brcmf_usb_bus_ops = {
	.txdata = brcmf_usb_tx,
	.stop = brcmf_usb_down,
	.txctl = brcmf_usb_tx_ctlpkt,
	.rxctl = brcmf_usb_rx_ctlpkt,
	.wowl_config = brcmf_usb_wowl_config,
};

static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo)
@@ -1186,6 +1204,9 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
	bus->ops = &brcmf_usb_bus_ops;
	bus->proto_type = BRCMF_PROTO_BCDC;
	bus->always_use_fws_queue = true;
#ifdef CONFIG_PM
	bus->wowl_supported = true;
#endif

	if (!brcmf_usb_dlneeded(devinfo)) {
		ret = brcmf_usb_bus_setup(devinfo);
@@ -1339,6 +1360,9 @@ static int brcmf_usb_suspend(struct usb_interface *intf, pm_message_t state)

	brcmf_dbg(USB, "Enter\n");
	devinfo->bus_pub.state = BRCMFMAC_USB_STATE_SLEEP;
	if (devinfo->wowl_enabled)
		brcmf_cancel_all_urbs(devinfo);
	else
		brcmf_detach(&usb->dev);
	return 0;
}
@@ -1352,7 +1376,12 @@ static int brcmf_usb_resume(struct usb_interface *intf)
	struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);

	brcmf_dbg(USB, "Enter\n");
	if (!devinfo->wowl_enabled)
		return brcmf_usb_bus_setup(devinfo);

	devinfo->bus_pub.state = BRCMFMAC_USB_STATE_UP;
	brcmf_usb_rx_fill_all(devinfo);
	return 0;
}

static int brcmf_usb_reset_resume(struct usb_interface *intf)