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

Commit dcc51417 authored by David S. Miller's avatar David S. Miller
Browse files
parents bd28bdb1 4cc683c9
Loading
Loading
Loading
Loading
+19 −8
Original line number Original line Diff line number Diff line
@@ -340,9 +340,9 @@ static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
}
}


/* Interrupt handling */
/* Interrupt handling */
static int 	ath5k_init(struct ath5k_softc *sc);
static int 	ath5k_init(struct ath5k_softc *sc, bool is_resume);
static int 	ath5k_stop_locked(struct ath5k_softc *sc);
static int 	ath5k_stop_locked(struct ath5k_softc *sc);
static int 	ath5k_stop_hw(struct ath5k_softc *sc);
static int 	ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend);
static irqreturn_t ath5k_intr(int irq, void *dev_id);
static irqreturn_t ath5k_intr(int irq, void *dev_id);
static void 	ath5k_tasklet_reset(unsigned long data);
static void 	ath5k_tasklet_reset(unsigned long data);


@@ -646,7 +646,7 @@ ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)


	ath5k_led_off(sc);
	ath5k_led_off(sc);


	ath5k_stop_hw(sc);
	ath5k_stop_hw(sc, true);


	free_irq(pdev->irq, sc);
	free_irq(pdev->irq, sc);
	pci_save_state(pdev);
	pci_save_state(pdev);
@@ -683,7 +683,7 @@ ath5k_pci_resume(struct pci_dev *pdev)
		goto err_no_irq;
		goto err_no_irq;
	}
	}


	err = ath5k_init(sc);
	err = ath5k_init(sc, true);
	if (err)
	if (err)
		goto err_irq;
		goto err_irq;
	ath5k_led_enable(sc);
	ath5k_led_enable(sc);
@@ -2200,12 +2200,17 @@ ath5k_beacon_config(struct ath5k_softc *sc)
\********************/
\********************/


static int
static int
ath5k_init(struct ath5k_softc *sc)
ath5k_init(struct ath5k_softc *sc, bool is_resume)
{
{
	int ret;
	int ret;


	mutex_lock(&sc->lock);
	mutex_lock(&sc->lock);


	if (is_resume && !test_bit(ATH_STAT_STARTED, sc->status))
		goto out_ok;

	__clear_bit(ATH_STAT_STARTED, sc->status);

	ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);
	ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);


	/*
	/*
@@ -2230,12 +2235,15 @@ ath5k_init(struct ath5k_softc *sc)
	if (ret)
	if (ret)
		goto done;
		goto done;


	__set_bit(ATH_STAT_STARTED, sc->status);

	/* Set ack to be sent at low bit-rates */
	/* Set ack to be sent at low bit-rates */
	ath5k_hw_set_ack_bitrate_high(sc->ah, false);
	ath5k_hw_set_ack_bitrate_high(sc->ah, false);


	mod_timer(&sc->calib_tim, round_jiffies(jiffies +
	mod_timer(&sc->calib_tim, round_jiffies(jiffies +
			msecs_to_jiffies(ath5k_calinterval * 1000)));
			msecs_to_jiffies(ath5k_calinterval * 1000)));


out_ok:
	ret = 0;
	ret = 0;
done:
done:
	mmiowb();
	mmiowb();
@@ -2290,7 +2298,7 @@ ath5k_stop_locked(struct ath5k_softc *sc)
 * stop is preempted).
 * stop is preempted).
 */
 */
static int
static int
ath5k_stop_hw(struct ath5k_softc *sc)
ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend)
{
{
	int ret;
	int ret;


@@ -2321,6 +2329,9 @@ ath5k_stop_hw(struct ath5k_softc *sc)
		}
		}
	}
	}
	ath5k_txbuf_free(sc, sc->bbuf);
	ath5k_txbuf_free(sc, sc->bbuf);
	if (!is_suspend)
		__clear_bit(ATH_STAT_STARTED, sc->status);

	mmiowb();
	mmiowb();
	mutex_unlock(&sc->lock);
	mutex_unlock(&sc->lock);


@@ -2718,12 +2729,12 @@ ath5k_reset_wake(struct ath5k_softc *sc)


static int ath5k_start(struct ieee80211_hw *hw)
static int ath5k_start(struct ieee80211_hw *hw)
{
{
	return ath5k_init(hw->priv);
	return ath5k_init(hw->priv, false);
}
}


static void ath5k_stop(struct ieee80211_hw *hw)
static void ath5k_stop(struct ieee80211_hw *hw)
{
{
	ath5k_stop_hw(hw->priv);
	ath5k_stop_hw(hw->priv, false);
}
}


static int ath5k_add_interface(struct ieee80211_hw *hw,
static int ath5k_add_interface(struct ieee80211_hw *hw,
+2 −1
Original line number Original line Diff line number Diff line
@@ -128,11 +128,12 @@ struct ath5k_softc {
	size_t			desc_len;	/* size of TX/RX descriptors */
	size_t			desc_len;	/* size of TX/RX descriptors */
	u16			cachelsz;	/* cache line size */
	u16			cachelsz;	/* cache line size */


	DECLARE_BITMAP(status, 4);
	DECLARE_BITMAP(status, 5);
#define ATH_STAT_INVALID	0		/* disable hardware accesses */
#define ATH_STAT_INVALID	0		/* disable hardware accesses */
#define ATH_STAT_MRRETRY	1		/* multi-rate retry support */
#define ATH_STAT_MRRETRY	1		/* multi-rate retry support */
#define ATH_STAT_PROMISC	2
#define ATH_STAT_PROMISC	2
#define ATH_STAT_LEDSOFT	3		/* enable LED gpio status */
#define ATH_STAT_LEDSOFT	3		/* enable LED gpio status */
#define ATH_STAT_STARTED	4		/* opened & irqs enabled */


	unsigned int		filter_flags;	/* HW flags, AR5K_RX_FILTER_* */
	unsigned int		filter_flags;	/* HW flags, AR5K_RX_FILTER_* */
	unsigned int		curmode;	/* current phy mode */
	unsigned int		curmode;	/* current phy mode */
+29 −13
Original line number Original line Diff line number Diff line
@@ -433,7 +433,7 @@ struct fw_info {
const static struct fw_info orinoco_fw[] = {
const static struct fw_info orinoco_fw[] = {
	{ "", "agere_sta_fw.bin", "agere_ap_fw.bin", 0x00390000, 1000 },
	{ "", "agere_sta_fw.bin", "agere_ap_fw.bin", 0x00390000, 1000 },
	{ "", "prism_sta_fw.bin", "prism_ap_fw.bin", 0, 1024 },
	{ "", "prism_sta_fw.bin", "prism_ap_fw.bin", 0, 1024 },
	{ "symbol_sp24t_prim_fw", "symbol_sp24t_sec_fw", "", 0x00003100, 0x100 }
	{ "symbol_sp24t_prim_fw", "symbol_sp24t_sec_fw", "", 0x00003100, 512 }
};
};


/* Structure used to access fields in FW
/* Structure used to access fields in FW
@@ -458,7 +458,7 @@ orinoco_dl_firmware(struct orinoco_private *priv,
		    int ap)
		    int ap)
{
{
	/* Plug Data Area (PDA) */
	/* Plug Data Area (PDA) */
	__le16 pda[512] = { 0 };
	__le16 *pda;


	hermes_t *hw = &priv->hw;
	hermes_t *hw = &priv->hw;
	const struct firmware *fw_entry;
	const struct firmware *fw_entry;
@@ -467,7 +467,11 @@ orinoco_dl_firmware(struct orinoco_private *priv,
	const unsigned char *end;
	const unsigned char *end;
	const char *firmware;
	const char *firmware;
	struct net_device *dev = priv->ndev;
	struct net_device *dev = priv->ndev;
	int err;
	int err = 0;

	pda = kzalloc(fw->pda_size, GFP_KERNEL);
	if (!pda)
		return -ENOMEM;


	if (ap)
	if (ap)
		firmware = fw->ap_fw;
		firmware = fw->ap_fw;
@@ -478,17 +482,17 @@ orinoco_dl_firmware(struct orinoco_private *priv,
	       dev->name, firmware);
	       dev->name, firmware);


	/* Read current plug data */
	/* Read current plug data */
	err = hermes_read_pda(hw, pda, fw->pda_addr,
	err = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 0);
			      min_t(u16, fw->pda_size, sizeof(pda)), 0);
	printk(KERN_DEBUG "%s: Read PDA returned %d\n", dev->name, err);
	printk(KERN_DEBUG "%s: Read PDA returned %d\n", dev->name, err);
	if (err)
	if (err)
		return err;
		goto free;


	err = request_firmware(&fw_entry, firmware, priv->dev);
	err = request_firmware(&fw_entry, firmware, priv->dev);
	if (err) {
	if (err) {
		printk(KERN_ERR "%s: Cannot find firmware %s\n",
		printk(KERN_ERR "%s: Cannot find firmware %s\n",
		       dev->name, firmware);
		       dev->name, firmware);
		return -ENOENT;
		err = -ENOENT;
		goto free;
	}
	}


	hdr = (const struct orinoco_fw_header *) fw_entry->data;
	hdr = (const struct orinoco_fw_header *) fw_entry->data;
@@ -532,6 +536,9 @@ orinoco_dl_firmware(struct orinoco_private *priv,


abort:
abort:
	release_firmware(fw_entry);
	release_firmware(fw_entry);

free:
	kfree(pda);
	return err;
	return err;
}
}


@@ -549,12 +556,12 @@ symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw,
		int secondary)
		int secondary)
{
{
	hermes_t *hw = &priv->hw;
	hermes_t *hw = &priv->hw;
	int ret;
	int ret = 0;
	const unsigned char *ptr;
	const unsigned char *ptr;
	const unsigned char *first_block;
	const unsigned char *first_block;


	/* Plug Data Area (PDA) */
	/* Plug Data Area (PDA) */
	__le16 pda[256];
	__le16 *pda = NULL;


	/* Binary block begins after the 0x1A marker */
	/* Binary block begins after the 0x1A marker */
	ptr = image;
	ptr = image;
@@ -563,28 +570,33 @@ symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw,


	/* Read the PDA from EEPROM */
	/* Read the PDA from EEPROM */
	if (secondary) {
	if (secondary) {
		ret = hermes_read_pda(hw, pda, fw->pda_addr, sizeof(pda), 1);
		pda = kzalloc(fw->pda_size, GFP_KERNEL);
		if (!pda)
			return -ENOMEM;

		ret = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 1);
		if (ret)
		if (ret)
			return ret;
			goto free;
	}
	}


	/* Stop the firmware, so that it can be safely rewritten */
	/* Stop the firmware, so that it can be safely rewritten */
	if (priv->stop_fw) {
	if (priv->stop_fw) {
		ret = priv->stop_fw(priv, 1);
		ret = priv->stop_fw(priv, 1);
		if (ret)
		if (ret)
			return ret;
			goto free;
	}
	}


	/* Program the adapter with new firmware */
	/* Program the adapter with new firmware */
	ret = hermes_program(hw, first_block, end);
	ret = hermes_program(hw, first_block, end);
	if (ret)
	if (ret)
		return ret;
		goto free;


	/* Write the PDA to the adapter */
	/* Write the PDA to the adapter */
	if (secondary) {
	if (secondary) {
		size_t len = hermes_blocks_length(first_block);
		size_t len = hermes_blocks_length(first_block);
		ptr = first_block + len;
		ptr = first_block + len;
		ret = hermes_apply_pda(hw, ptr, pda);
		ret = hermes_apply_pda(hw, ptr, pda);
		kfree(pda);
		if (ret)
		if (ret)
			return ret;
			return ret;
	}
	}
@@ -608,6 +620,10 @@ symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw,
		return -ENODEV;
		return -ENODEV;


	return 0;
	return 0;

free:
	kfree(pda);
	return ret;
}
}




+10 −18
Original line number Original line Diff line number Diff line
@@ -306,8 +306,8 @@ static int p54_convert_rev1(struct ieee80211_hw *dev,
	return 0;
	return 0;
}
}


static const char *p54_rf_chips[] = { "NULL", "Indigo?", "Duette",
static const char *p54_rf_chips[] = { "NULL", "Duette3", "Duette2",
                              "Frisbee", "Xbow", "Longbow" };
                              "Frisbee", "Xbow", "Longbow", "NULL", "NULL" };
static int p54_init_xbow_synth(struct ieee80211_hw *dev);
static int p54_init_xbow_synth(struct ieee80211_hw *dev);


static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
@@ -319,6 +319,7 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
	void *tmp;
	void *tmp;
	int err;
	int err;
	u8 *end = (u8 *)eeprom + len;
	u8 *end = (u8 *)eeprom + len;
	u16 synth;
	DECLARE_MAC_BUF(mac);
	DECLARE_MAC_BUF(mac);


	wrap = (struct eeprom_pda_wrap *) eeprom;
	wrap = (struct eeprom_pda_wrap *) eeprom;
@@ -400,8 +401,8 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
			tmp = entry->data;
			tmp = entry->data;
			while ((u8 *)tmp < entry->data + data_len) {
			while ((u8 *)tmp < entry->data + data_len) {
				struct bootrec_exp_if *exp_if = tmp;
				struct bootrec_exp_if *exp_if = tmp;
				if (le16_to_cpu(exp_if->if_id) == 0xF)
				if (le16_to_cpu(exp_if->if_id) == 0xf)
					priv->rxhw = le16_to_cpu(exp_if->variant) & 0x07;
					synth = le16_to_cpu(exp_if->variant);
				tmp += sizeof(struct bootrec_exp_if);
				tmp += sizeof(struct bootrec_exp_if);
			}
			}
			break;
			break;
@@ -427,22 +428,13 @@ static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
		goto err;
		goto err;
	}
	}


	switch (priv->rxhw) {
	priv->rxhw = synth & 0x07;
	case 4: /* XBow */
	if (priv->rxhw == 4)
		p54_init_xbow_synth(dev);
		p54_init_xbow_synth(dev);
	case 1: /* Indigo? */
	if (!(synth & 0x40))
	case 2: /* Duette */
		dev->wiphy->bands[IEEE80211_BAND_5GHZ] = &band_5GHz;
	case 3: /* Frisbee */
	case 5: /* Longbow */
		dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz;
		dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz;
		break;
	if (!(synth & 0x80))
	default:
		dev->wiphy->bands[IEEE80211_BAND_5GHZ] = &band_5GHz;
		printk(KERN_ERR "%s: unsupported RF-Chip\n",
			wiphy_name(dev->wiphy));
		err = -EINVAL;
		goto err;
	}


	if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
	if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
		u8 perm_addr[ETH_ALEN];
		u8 perm_addr[ETH_ALEN];