pci.c 8.2 KB
Newer Older
1
/*
2
 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include <linux/nl80211.h>
#include <linux/pci.h>
S
Sujith 已提交
19
#include "ath9k.h"
20 21 22 23 24 25 26 27

static struct pci_device_id ath_pci_id_table[] __devinitdata = {
	{ PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI   */
	{ PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */
	{ PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI   */
	{ PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI   */
	{ PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
	{ PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
28 29
	{ PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI   */
	{ PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */
30 31 32 33
	{ 0 }
};

/* return bus cachesize in 4B word units */
34
static void ath_pci_read_cachesize(struct ath_common *common, int *csz)
35
{
36 37
	struct ath_hw *ah = (struct ath_hw *) common->ah;
	struct ath_softc *sc = ah->ah_sc;
38 39
	u8 u8tmp;

40
	pci_read_config_byte(to_pci_dev(sc->dev), PCI_CACHE_LINE_SIZE, &u8tmp);
41 42 43 44 45 46 47 48 49 50 51 52
	*csz = (int)u8tmp;

	/*
	 * This check was put in to avoid "unplesant" consequences if
	 * the bootrom has not fully initialized all PCI devices.
	 * Sometimes the cache line size register is not set
	 */

	if (*csz == 0)
		*csz = DEFAULT_CACHELINE >> 2;   /* Use the default size */
}

53
static void ath_pci_cleanup(struct ath_common *common)
54
{
55 56
	struct ath_hw *ah = (struct ath_hw *) common->ah;
	struct ath_softc *sc = ah->ah_sc;
57 58 59 60
	struct pci_dev *pdev = to_pci_dev(sc->dev);

	pci_iounmap(pdev, sc->mem);
	pci_disable_device(pdev);
S
Sujith 已提交
61
	pci_release_region(pdev, 0);
62 63
}

64
static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data)
65
{
66 67
	struct ath_hw *ah = (struct ath_hw *) common->ah;

68 69 70 71 72
	(void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));

	if (!ath9k_hw_wait(ah,
			   AR_EEPROM_STATUS_DATA,
			   AR_EEPROM_STATUS_DATA_BUSY |
S
Sujith 已提交
73 74
			   AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
			   AH_WAIT_TIMEOUT)) {
75 76 77 78 79 80 81 82 83
		return false;
	}

	*data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
		   AR_EEPROM_STATUS_DATA_VAL);

	return true;
}

84 85 86
/*
 * Bluetooth coexistance requires disabling ASPM.
 */
87
static void ath_pci_bt_coex_prep(struct ath_common *common)
88
{
89 90
	struct ath_hw *ah = (struct ath_hw *) common->ah;
	struct ath_softc *sc = ah->ah_sc;
91 92 93 94 95 96 97 98 99 100 101
	struct pci_dev *pdev = to_pci_dev(sc->dev);
	u8 aspm;

	if (!pdev->is_pcie)
		return;

	pci_read_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, &aspm);
	aspm &= ~(ATH_PCIE_CAP_LINK_L0S | ATH_PCIE_CAP_LINK_L1);
	pci_write_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, aspm);
}

102
const static struct ath_bus_ops ath_pci_bus_ops = {
103 104
	.read_cachesize = ath_pci_read_cachesize,
	.cleanup = ath_pci_cleanup,
105
	.eeprom_read = ath_pci_eeprom_read,
106
	.bt_coex_prep = ath_pci_bt_coex_prep,
107 108 109 110 111
};

static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
	void __iomem *mem;
112
	struct ath_wiphy *aphy;
113 114 115
	struct ath_softc *sc;
	struct ieee80211_hw *hw;
	u8 csz;
116
	u16 subsysid;
117
	u32 val;
118
	int ret = 0;
119
	struct ath_hw *ah;
120 121 122 123

	if (pci_enable_device(pdev))
		return -EIO;

124
	ret =  pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
125 126 127 128 129 130

	if (ret) {
		printk(KERN_ERR "ath9k: 32-bit DMA not available\n");
		goto bad;
	}

131
	ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163

	if (ret) {
		printk(KERN_ERR "ath9k: 32-bit DMA consistent "
			"DMA enable failed\n");
		goto bad;
	}

	/*
	 * Cache line size is used to size and align various
	 * structures used to communicate with the hardware.
	 */
	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
	if (csz == 0) {
		/*
		 * Linux 2.4.18 (at least) writes the cache line size
		 * register as a 16-bit wide register which is wrong.
		 * We must have this setup properly for rx buffer
		 * DMA to work so force a reasonable value here if it
		 * comes up zero.
		 */
		csz = L1_CACHE_BYTES / sizeof(u32);
		pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
	}
	/*
	 * The default setting of latency timer yields poor results,
	 * set it to the value used by other systems. It may be worth
	 * tweaking this setting more.
	 */
	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);

	pci_set_master(pdev);

164 165 166 167 168 169 170 171
	/*
	 * Disable the RETRY_TIMEOUT register (0x41) to keep
	 * PCI Tx retries from interfering with C3 CPU state.
	 */
	pci_read_config_dword(pdev, 0x40, &val);
	if ((val & 0x0000ff00) != 0)
		pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);

172 173 174 175 176 177 178 179 180 181 182 183 184 185
	ret = pci_request_region(pdev, 0, "ath9k");
	if (ret) {
		dev_err(&pdev->dev, "PCI memory region reserve error\n");
		ret = -ENODEV;
		goto bad;
	}

	mem = pci_iomap(pdev, 0, 0);
	if (!mem) {
		printk(KERN_ERR "PCI memory map error\n") ;
		ret = -EIO;
		goto bad1;
	}

186 187
	hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) +
				sizeof(struct ath_softc), &ath9k_ops);
188 189 190
	if (!hw) {
		dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
		ret = -ENOMEM;
191 192 193 194 195 196
		goto bad2;
	}

	SET_IEEE80211_DEV(hw, &pdev->dev);
	pci_set_drvdata(pdev, hw);

197 198 199 200 201
	aphy = hw->priv;
	sc = (struct ath_softc *) (aphy + 1);
	aphy->sc = sc;
	aphy->hw = hw;
	sc->pri_wiphy = aphy;
202 203 204 205
	sc->hw = hw;
	sc->dev = &pdev->dev;
	sc->mem = mem;

206
	pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsysid);
207
	ret = ath_init_device(id->device, sc, subsysid, &ath_pci_bus_ops);
208 209
	if (ret) {
		dev_err(&pdev->dev, "failed to initialize device\n");
210 211 212 213 214
		goto bad3;
	}

	/* setup interrupt service routine */

215
	ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc);
216 217
	if (ret) {
		dev_err(&pdev->dev, "request_irq failed\n");
218 219 220 221 222 223 224 225 226 227
		goto bad4;
	}

	sc->irq = pdev->irq;

	ah = sc->sc_ah;
	printk(KERN_INFO
	       "%s: Atheros AR%s MAC/BB Rev:%x "
	       "AR%s RF Rev:%x: mem=0x%lx, irq=%d\n",
	       wiphy_name(hw->wiphy),
228 229 230 231
	       ath_mac_bb_name(ah->hw_version.macVersion),
	       ah->hw_version.macRev,
	       ath_rf_name((ah->hw_version.analog5GhzRev & AR_RADIO_SREV_MAJOR)),
	       ah->hw_version.phyRev,
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
	       (unsigned long)mem, pdev->irq);

	return 0;
bad4:
	ath_detach(sc);
bad3:
	ieee80211_free_hw(hw);
bad2:
	pci_iounmap(pdev, mem);
bad1:
	pci_release_region(pdev, 0);
bad:
	pci_disable_device(pdev);
	return ret;
}

static void ath_pci_remove(struct pci_dev *pdev)
{
	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
251 252
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
253 254 255 256 257 258 259 260 261

	ath_cleanup(sc);
}

#ifdef CONFIG_PM

static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
{
	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
262 263
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
264

265
	ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
266 267 268 269 270 271 272 273 274 275 276

	pci_save_state(pdev);
	pci_disable_device(pdev);
	pci_set_power_state(pdev, PCI_D3hot);

	return 0;
}

static int ath_pci_resume(struct pci_dev *pdev)
{
	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
277 278
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;
279
	u32 val;
280 281
	int err;

S
Sujith 已提交
282 283
	pci_restore_state(pdev);

284 285 286
	err = pci_enable_device(pdev);
	if (err)
		return err;
S
Sujith 已提交
287

288 289 290 291 292 293 294 295
	/*
	 * Suspend/Resume resets the PCI configuration space, so we have to
	 * re-disable the RETRY_TIMEOUT register (0x41) to keep
	 * PCI Tx retries from interfering with C3 CPU state
	 */
	pci_read_config_dword(pdev, 0x40, &val);
	if ((val & 0x0000ff00) != 0)
		pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
296 297

	/* Enable LED */
298
	ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin,
299
			    AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
300
	ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319

	return 0;
}

#endif /* CONFIG_PM */

MODULE_DEVICE_TABLE(pci, ath_pci_id_table);

static struct pci_driver ath_pci_driver = {
	.name       = "ath9k",
	.id_table   = ath_pci_id_table,
	.probe      = ath_pci_probe,
	.remove     = ath_pci_remove,
#ifdef CONFIG_PM
	.suspend    = ath_pci_suspend,
	.resume     = ath_pci_resume,
#endif /* CONFIG_PM */
};

S
Sujith 已提交
320
int ath_pci_init(void)
321 322 323 324 325 326 327 328
{
	return pci_register_driver(&ath_pci_driver);
}

void ath_pci_exit(void)
{
	pci_unregister_driver(&ath_pci_driver);
}