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

Commit e5c1a0aa authored by David S. Miller's avatar David S. Miller
Browse files
parents 1cd4efdd 31f66be4
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -5255,7 +5255,8 @@ static int set_wep_key(struct airo_info *ai, u16 index, const char *key,
	WepKeyRid wkr;
	int rc;

	WARN_ON(keylen == 0);
	if (WARN_ON(keylen == 0))
		return -1;

	memset(&wkr, 0, sizeof(wkr));
	wkr.len = cpu_to_le16(sizeof(wkr));
+1 −0
Original line number Diff line number Diff line
@@ -166,6 +166,7 @@ struct ar9170 {
	struct ath_common common;
	struct mutex mutex;
	enum ar9170_device_state state;
	bool registered;
	unsigned long bad_hw_nagger;

	int (*open)(struct ar9170 *);
+7 −3
Original line number Diff line number Diff line
@@ -2701,7 +2701,8 @@ int ar9170_register(struct ar9170 *ar, struct device *pdev)
	dev_info(pdev, "Atheros AR9170 is registered as '%s'\n",
		 wiphy_name(ar->hw->wiphy));

	return err;
	ar->registered = true;
	return 0;

err_unreg:
	ieee80211_unregister_hw(ar->hw);
@@ -2712,11 +2713,14 @@ err_out:

void ar9170_unregister(struct ar9170 *ar)
{
	if (ar->registered) {
#ifdef CONFIG_AR9170_LEDS
		ar9170_unregister_leds(ar);
#endif /* CONFIG_AR9170_LEDS */

	kfree_skb(ar->rx_failover);
	ieee80211_unregister_hw(ar->hw);
	}

	kfree_skb(ar->rx_failover);
	mutex_destroy(&ar->mutex);
}
+103 −67
Original line number Diff line number Diff line
@@ -582,43 +582,6 @@ static int ar9170_usb_upload(struct ar9170_usb *aru, const void *data,
	return 0;
}

static int ar9170_usb_request_firmware(struct ar9170_usb *aru)
{
	int err = 0;

	err = request_firmware(&aru->firmware, "ar9170.fw",
			       &aru->udev->dev);
	if (!err) {
		aru->init_values = NULL;
		return 0;
	}

	if (aru->req_one_stage_fw) {
		dev_err(&aru->udev->dev, "ar9170.fw firmware file "
			"not found and is required for this device\n");
		return -EINVAL;
	}

	dev_err(&aru->udev->dev, "ar9170.fw firmware file "
		"not found, trying old firmware...\n");

	err = request_firmware(&aru->init_values, "ar9170-1.fw",
			       &aru->udev->dev);
	if (err) {
		dev_err(&aru->udev->dev, "file with init values not found.\n");
		return err;
	}

	err = request_firmware(&aru->firmware, "ar9170-2.fw", &aru->udev->dev);
	if (err) {
		release_firmware(aru->init_values);
		dev_err(&aru->udev->dev, "firmware file not found.\n");
		return err;
	}

	return err;
}

static int ar9170_usb_reset(struct ar9170_usb *aru)
{
	int ret, lock = (aru->intf->condition != USB_INTERFACE_BINDING);
@@ -757,6 +720,103 @@ err_out:
	return err;
}

static void ar9170_usb_firmware_failed(struct ar9170_usb *aru)
{
	struct device *parent = aru->udev->dev.parent;

	/* unbind anything failed */
	if (parent)
		down(&parent->sem);
	device_release_driver(&aru->udev->dev);
	if (parent)
		up(&parent->sem);
}

static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context)
{
	struct ar9170_usb *aru = context;
	int err;

	aru->firmware = fw;

	if (!fw) {
		dev_err(&aru->udev->dev, "firmware file not found.\n");
		goto err_freefw;
	}

	err = ar9170_usb_init_device(aru);
	if (err)
		goto err_freefw;

	err = ar9170_usb_open(&aru->common);
	if (err)
		goto err_unrx;

	err = ar9170_register(&aru->common, &aru->udev->dev);

	ar9170_usb_stop(&aru->common);
	if (err)
		goto err_unrx;

	return;

 err_unrx:
	ar9170_usb_cancel_urbs(aru);

 err_freefw:
	ar9170_usb_firmware_failed(aru);
}

static void ar9170_usb_firmware_inits(const struct firmware *fw,
				      void *context)
{
	struct ar9170_usb *aru = context;
	int err;

	if (!fw) {
		dev_err(&aru->udev->dev, "file with init values not found.\n");
		ar9170_usb_firmware_failed(aru);
		return;
	}

	aru->init_values = fw;

	/* ok so we have the init values -- get code for two-stage */

	err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-2.fw",
				      &aru->udev->dev, GFP_KERNEL, aru,
				      ar9170_usb_firmware_finish);
	if (err)
		ar9170_usb_firmware_failed(aru);
}

static void ar9170_usb_firmware_step2(const struct firmware *fw, void *context)
{
	struct ar9170_usb *aru = context;
	int err;

	if (fw) {
		ar9170_usb_firmware_finish(fw, context);
		return;
	}

	if (aru->req_one_stage_fw) {
		dev_err(&aru->udev->dev, "ar9170.fw firmware file "
			"not found and is required for this device\n");
		ar9170_usb_firmware_failed(aru);
		return;
	}

	dev_err(&aru->udev->dev, "ar9170.fw firmware file "
		"not found, trying old firmware...\n");

	err = request_firmware_nowait(THIS_MODULE, 1, "ar9170-1.fw",
				      &aru->udev->dev, GFP_KERNEL, aru,
				      ar9170_usb_firmware_inits);
	if (err)
		ar9170_usb_firmware_failed(aru);
}

static bool ar9170_requires_one_stage(const struct usb_device_id *id)
{
	if (!id->driver_info)
@@ -814,33 +874,9 @@ static int ar9170_usb_probe(struct usb_interface *intf,
	if (err)
		goto err_freehw;

	err = ar9170_usb_request_firmware(aru);
	if (err)
		goto err_freehw;

	err = ar9170_usb_init_device(aru);
	if (err)
		goto err_freefw;

	err = ar9170_usb_open(ar);
	if (err)
		goto err_unrx;

	err = ar9170_register(ar, &udev->dev);

	ar9170_usb_stop(ar);
	if (err)
		goto err_unrx;

	return 0;

err_unrx:
	ar9170_usb_cancel_urbs(aru);

err_freefw:
	release_firmware(aru->init_values);
	release_firmware(aru->firmware);

	return request_firmware_nowait(THIS_MODULE, 1, "ar9170.fw",
				       &aru->udev->dev, GFP_KERNEL, aru,
				       ar9170_usb_firmware_step2);
err_freehw:
	usb_set_intfdata(intf, NULL);
	usb_put_dev(udev);
@@ -860,12 +896,12 @@ static void ar9170_usb_disconnect(struct usb_interface *intf)
	ar9170_unregister(&aru->common);
	ar9170_usb_cancel_urbs(aru);

	release_firmware(aru->init_values);
	release_firmware(aru->firmware);

	usb_put_dev(aru->udev);
	usb_set_intfdata(intf, NULL);
	ieee80211_free_hw(aru->common.hw);

	release_firmware(aru->init_values);
	release_firmware(aru->firmware);
}

#ifdef CONFIG_PM
+3 −3
Original line number Diff line number Diff line
@@ -1323,7 +1323,7 @@ static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,

static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
			    struct ieee80211_sta *sta, void *priv_sta,
			    u32 changed)
			    u32 changed, enum nl80211_channel_type oper_chan_type)
{
	struct ath_softc *sc = priv;
	struct ath_rate_priv *ath_rc_priv = priv_sta;
@@ -1340,8 +1340,8 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
		if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
			return;

		if (sc->hw->conf.channel_type == NL80211_CHAN_HT40MINUS ||
		    sc->hw->conf.channel_type == NL80211_CHAN_HT40PLUS)
		if (oper_chan_type == NL80211_CHAN_HT40MINUS ||
		    oper_chan_type == NL80211_CHAN_HT40PLUS)
			oper_cw40 = true;

		oper_sgi40 = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
Loading