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

Commit 788df732 authored by David S. Miller's avatar David S. Miller
Browse files
parents 6e50e8a2 0d5f0316
Loading
Loading
Loading
Loading
+36 −23
Original line number Diff line number Diff line
@@ -281,7 +281,9 @@ enum ath5k_radio {
	AR5K_RF5112	= 2,
	AR5K_RF2413	= 3,
	AR5K_RF5413	= 4,
	AR5K_RF2425	= 5,
	AR5K_RF2316	= 5,
	AR5K_RF2317	= 6,
	AR5K_RF2425	= 7,
};

/*
@@ -289,7 +291,7 @@ enum ath5k_radio {
 */

enum ath5k_srev_type {
	AR5K_VERSION_VER,
	AR5K_VERSION_MAC,
	AR5K_VERSION_RAD,
};

@@ -301,23 +303,24 @@ struct ath5k_srev_name {

#define AR5K_SREV_UNKNOWN	0xffff

#define AR5K_SREV_VER_AR5210	0x00
#define AR5K_SREV_VER_AR5311	0x10
#define AR5K_SREV_VER_AR5311A	0x20
#define AR5K_SREV_VER_AR5311B	0x30
#define AR5K_SREV_VER_AR5211	0x40
#define AR5K_SREV_VER_AR5212	0x50
#define AR5K_SREV_VER_AR5213	0x55
#define AR5K_SREV_VER_AR5213A	0x59
#define AR5K_SREV_VER_AR2413	0x78
#define AR5K_SREV_VER_AR2414	0x79
#define AR5K_SREV_VER_AR2424	0xa0 /* PCI-E */
#define AR5K_SREV_VER_AR5424	0xa3 /* PCI-E */
#define AR5K_SREV_VER_AR5413	0xa4
#define AR5K_SREV_VER_AR5414	0xa5
#define AR5K_SREV_VER_AR5416	0xc0 /* PCI-E */
#define AR5K_SREV_VER_AR5418	0xca /* PCI-E */
#define AR5K_SREV_VER_AR2425	0xe2 /* PCI-E */
#define AR5K_SREV_AR5210	0x00 /* Crete */
#define AR5K_SREV_AR5311	0x10 /* Maui 1 */
#define AR5K_SREV_AR5311A	0x20 /* Maui 2 */
#define AR5K_SREV_AR5311B	0x30 /* Spirit */
#define AR5K_SREV_AR5211	0x40 /* Oahu */
#define AR5K_SREV_AR5212	0x50 /* Venice */
#define AR5K_SREV_AR5213	0x55 /* ??? */
#define AR5K_SREV_AR5213A	0x59 /* Hainan */
#define AR5K_SREV_AR2413	0x78 /* Griffin lite */
#define AR5K_SREV_AR2414	0x70 /* Griffin */
#define AR5K_SREV_AR5424	0x90 /* Condor */
#define AR5K_SREV_AR5413	0xa4 /* Eagle lite */
#define AR5K_SREV_AR5414	0xa0 /* Eagle */
#define AR5K_SREV_AR2415	0xb0 /* Cobra */
#define AR5K_SREV_AR5416	0xc0 /* PCI-E */
#define AR5K_SREV_AR5418	0xca /* PCI-E */
#define AR5K_SREV_AR2425	0xe0 /* Swan */
#define AR5K_SREV_AR2417	0xf0 /* Nala */

#define AR5K_SREV_RAD_5110	0x00
#define AR5K_SREV_RAD_5111	0x10
@@ -329,10 +332,20 @@ struct ath5k_srev_name {
#define AR5K_SREV_RAD_2112	0x40
#define AR5K_SREV_RAD_2112A	0x45
#define	AR5K_SREV_RAD_2112B	0x46
#define AR5K_SREV_RAD_SC0	0x50	/* Found on 2413/2414 */
#define AR5K_SREV_RAD_SC1	0x60	/* Found on 5413/5414 */
#define AR5K_SREV_RAD_SC2	0xa0	/* Found on 2424-5/5424 */
#define AR5K_SREV_RAD_5133	0xc0	/* MIMO found on 5418 */
#define AR5K_SREV_RAD_2413	0x50
#define AR5K_SREV_RAD_5413	0x60
#define AR5K_SREV_RAD_2316	0x70
#define AR5K_SREV_RAD_2317	0x80
#define AR5K_SREV_RAD_5424	0xa0 /* Mostly same as 5413 */
#define AR5K_SREV_RAD_2425	0xa2
#define AR5K_SREV_RAD_5133	0xc0

#define AR5K_SREV_PHY_5211	0x30
#define AR5K_SREV_PHY_5212	0x41
#define AR5K_SREV_PHY_2112B	0x43
#define AR5K_SREV_PHY_2413	0x45
#define AR5K_SREV_PHY_5413	0x61
#define AR5K_SREV_PHY_2425	0x70

/* IEEE defs */
#define IEEE80211_MAX_LEN       2500
+114 −70
Original line number Diff line number Diff line
@@ -137,7 +137,7 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
	ah->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY;

	/*
	 * Set the mac revision based on the pci id
	 * Set the mac version based on the pci id
	 */
	ah->ah_version = mac_version;

@@ -160,87 +160,132 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
			0xffffffff;
	ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
			CHANNEL_5GHZ);
	ah->ah_phy = AR5K_PHY(0);

	if (ah->ah_version == AR5K_AR5210)
		ah->ah_radio_2ghz_revision = 0;
	else
	/* Try to identify radio chip based on it's srev */
	switch (ah->ah_radio_5ghz_revision & 0xf0) {
	case AR5K_SREV_RAD_5111:
		ah->ah_radio = AR5K_RF5111;
		ah->ah_single_chip = false;
		ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
							CHANNEL_2GHZ);

	/* Return on unsuported chips (unsupported eeprom etc) */
	if ((srev >= AR5K_SREV_VER_AR5416) &&
	(srev < AR5K_SREV_VER_AR2425)) {
		ATH5K_ERR(sc, "Device not yet supported.\n");
		ret = -ENODEV;
		goto err_free;
	} else if (srev == AR5K_SREV_VER_AR2425) {
		ATH5K_WARN(sc, "Support for RF2425 is under development.\n");
	}

	/* Identify single chip solutions */
	if (((srev <= AR5K_SREV_VER_AR5414) &&
	(srev >= AR5K_SREV_VER_AR2413)) ||
	(srev == AR5K_SREV_VER_AR2425)) {
		ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111;
		break;
	case AR5K_SREV_RAD_5112:
	case AR5K_SREV_RAD_2112:
		ah->ah_radio = AR5K_RF5112;
		ah->ah_single_chip = false;
		ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
							CHANNEL_2GHZ);
		ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
		break;
	case AR5K_SREV_RAD_2413:
		ah->ah_radio = AR5K_RF2413;
		ah->ah_single_chip = true;
		ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413;
		break;
	case AR5K_SREV_RAD_5413:
		ah->ah_radio = AR5K_RF5413;
		ah->ah_single_chip = true;
		ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
		break;
	case AR5K_SREV_RAD_2316:
		ah->ah_radio = AR5K_RF2316;
		ah->ah_single_chip = true;
		ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2316;
		break;
	case AR5K_SREV_RAD_2317:
		ah->ah_radio = AR5K_RF2317;
		ah->ah_single_chip = true;
		ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2317;
		break;
	case AR5K_SREV_RAD_5424:
		if (ah->ah_mac_version == AR5K_SREV_AR2425 ||
		ah->ah_mac_version == AR5K_SREV_AR2417){
			ah->ah_radio = AR5K_RF2425;
			ah->ah_single_chip = true;
			ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425;
		} else {
		ah->ah_single_chip = false;
			ah->ah_radio = AR5K_RF5413;
			ah->ah_single_chip = true;
			ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
		}

	/* Single chip radio */
	if (ah->ah_radio_2ghz_revision == ah->ah_radio_5ghz_revision)
		ah->ah_radio_2ghz_revision = 0;

	/* Identify the radio chip*/
		break;
	default:
		/* Identify radio based on mac/phy srev */
		if (ah->ah_version == AR5K_AR5210) {
			ah->ah_radio = AR5K_RF5110;
	/*
	 * Register returns 0x0/0x04 for radio revision
	 * so ath5k_hw_radio_revision doesn't parse the value
	 * correctly. For now we are based on mac's srev to
	 * identify RF2425 radio.
	 */
	} else if (srev == AR5K_SREV_VER_AR2425) {
			ah->ah_single_chip = false;
		} else if (ah->ah_version == AR5K_AR5211) {
			ah->ah_radio = AR5K_RF5111;
			ah->ah_single_chip = false;
			ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
								CHANNEL_2GHZ);
		} else if (ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4) ||
		ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4) ||
		ah->ah_phy_revision == AR5K_SREV_PHY_2425) {
			ah->ah_radio = AR5K_RF2425;
			ah->ah_single_chip = true;
			ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2425;
			ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425;
	} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) {
		ah->ah_radio = AR5K_RF5111;
		ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111;
	} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC0) {
		} else if (srev == AR5K_SREV_AR5213A &&
		ah->ah_phy_revision == AR5K_SREV_PHY_2112B) {
			ah->ah_radio = AR5K_RF5112;
		ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112;
	} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) {
		ah->ah_radio = AR5K_RF2413;
		ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413;
	} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC2) {
		ah->ah_radio = AR5K_RF5413;
		ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
	} else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133) {
		/* AR5424 */
		if (srev >= AR5K_SREV_VER_AR5424) {
			ah->ah_single_chip = false;
			ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2112B;
		} else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4)) {
			ah->ah_radio = AR5K_RF2316;
			ah->ah_single_chip = true;
			ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316;
			ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2316;
		} else if (ah->ah_mac_version == (AR5K_SREV_AR5414 >> 4) ||
		ah->ah_phy_revision == AR5K_SREV_PHY_5413) {
			ah->ah_radio = AR5K_RF5413;
			ah->ah_single_chip = true;
			ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5413;
			ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413;
		/* AR2424 */
		} else {
			ah->ah_radio = AR5K_RF2413; /* For testing */
		} else if (ah->ah_mac_version == (AR5K_SREV_AR2414 >> 4) ||
		ah->ah_phy_revision == AR5K_SREV_PHY_2413) {
			ah->ah_radio = AR5K_RF2413;
			ah->ah_single_chip = true;
			ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2413;
			ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413;
		} else {
			ATH5K_ERR(sc, "Couldn't identify radio revision.\n");
			ret = -ENODEV;
			goto err_free;
		}
	}
	ah->ah_phy = AR5K_PHY(0);


	/* Return on unsuported chips (unsupported eeprom etc) */
	if ((srev >= AR5K_SREV_AR5416) &&
	(srev < AR5K_SREV_AR2425)) {
		ATH5K_ERR(sc, "Device not yet supported.\n");
		ret = -ENODEV;
		goto err_free;
	}

	/*
	 * Write PCI-E power save settings
	 */
	if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) {
		ath5k_hw_reg_write(ah, 0x9248fc00, 0x4080);
		ath5k_hw_reg_write(ah, 0x24924924, 0x4080);
		ath5k_hw_reg_write(ah, 0x28000039, 0x4080);
		ath5k_hw_reg_write(ah, 0x53160824, 0x4080);
		ath5k_hw_reg_write(ah, 0xe5980579, 0x4080);
		ath5k_hw_reg_write(ah, 0x001defff, 0x4080);
		ath5k_hw_reg_write(ah, 0x1aaabe40, 0x4080);
		ath5k_hw_reg_write(ah, 0xbe105554, 0x4080);
		ath5k_hw_reg_write(ah, 0x000e3007, 0x4080);
		ath5k_hw_reg_write(ah, 0x00000000, 0x4084);
		ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES);
		ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES);
		/* Shut off RX when elecidle is asserted */
		ath5k_hw_reg_write(ah, 0x28000039, AR5K_PCIE_SERDES);
		ath5k_hw_reg_write(ah, 0x53160824, AR5K_PCIE_SERDES);
		/* TODO: EEPROM work */
		ath5k_hw_reg_write(ah, 0xe5980579, AR5K_PCIE_SERDES);
		/* Shut off PLL and CLKREQ active in L1 */
		ath5k_hw_reg_write(ah, 0x001defff, AR5K_PCIE_SERDES);
		/* Preserce other settings */
		ath5k_hw_reg_write(ah, 0x1aaabe40, AR5K_PCIE_SERDES);
		ath5k_hw_reg_write(ah, 0xbe105554, AR5K_PCIE_SERDES);
		ath5k_hw_reg_write(ah, 0x000e3007, AR5K_PCIE_SERDES);
		/* Reset SERDES to load new settings */
		ath5k_hw_reg_write(ah, 0x00000000, AR5K_PCIE_SERDES_RESET);
		mdelay(1);
	}

	/*
@@ -250,14 +295,13 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
	if (ret)
		goto err_free;

	/* Write AR5K_PCICFG_UNK on 2112B and later chips */
	if (ah->ah_radio_5ghz_revision > AR5K_SREV_RAD_2112B ||
	srev > AR5K_SREV_VER_AR2413) {
		ath5k_hw_reg_write(ah, AR5K_PCICFG_UNK, AR5K_PCICFG);
	}
	/* Enable pci core retry fix on Hainan (5213A) and later chips */
	if (srev >= AR5K_SREV_AR5213A)
		ath5k_hw_reg_write(ah, AR5K_PCICFG_RETRY_FIX, AR5K_PCICFG);

	/*
	 * Get card capabilities, values, ...
	 * Get card capabilities, calibration values etc
	 * TODO: EEPROM work
	 */
	ret = ath5k_eeprom_init(ah);
	if (ret) {
@@ -273,7 +317,7 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
		goto err_free;
	}

	/* Get MAC address */
	/* Set MAC address */
	ret = ath5k_eeprom_read_mac(ah, mac);
	if (ret) {
		ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n",
+36 −25
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ MODULE_AUTHOR("Nick Kossifidis");
MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards.");
MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_VERSION("0.5.0 (EXPERIMENTAL)");
MODULE_VERSION("0.6.0 (EXPERIMENTAL)");


/* Known PCI ids */
@@ -93,41 +93,48 @@ static struct pci_device_id ath5k_pci_id_table[] __devinitdata = {
	{ PCI_VDEVICE(ATHEROS, 0x0019), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
	{ PCI_VDEVICE(ATHEROS, 0x001a), .driver_data = AR5K_AR5212 }, /* 2413 Griffin-lite */
	{ PCI_VDEVICE(ATHEROS, 0x001b), .driver_data = AR5K_AR5212 }, /* 5413 Eagle */
	{ PCI_VDEVICE(ATHEROS, 0x001c), .driver_data = AR5K_AR5212 }, /* 5424 Condor (PCI-E)*/
	{ PCI_VDEVICE(ATHEROS, 0x001c), .driver_data = AR5K_AR5212 }, /* PCI-E cards */
	{ PCI_VDEVICE(ATHEROS, 0x001d), .driver_data = AR5K_AR5212 }, /* 2417 Nala */
	{ 0 }
};
MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table);

/* Known SREVs */
static struct ath5k_srev_name srev_names[] = {
	{ "5210",	AR5K_VERSION_VER,	AR5K_SREV_VER_AR5210 },
	{ "5311",	AR5K_VERSION_VER,	AR5K_SREV_VER_AR5311 },
	{ "5311A",	AR5K_VERSION_VER,	AR5K_SREV_VER_AR5311A },
	{ "5311B",	AR5K_VERSION_VER,	AR5K_SREV_VER_AR5311B },
	{ "5211",	AR5K_VERSION_VER,	AR5K_SREV_VER_AR5211 },
	{ "5212",	AR5K_VERSION_VER,	AR5K_SREV_VER_AR5212 },
	{ "5213",	AR5K_VERSION_VER,	AR5K_SREV_VER_AR5213 },
	{ "5213A",	AR5K_VERSION_VER,	AR5K_SREV_VER_AR5213A },
	{ "2413",	AR5K_VERSION_VER,	AR5K_SREV_VER_AR2413 },
	{ "2414",	AR5K_VERSION_VER,	AR5K_SREV_VER_AR2414 },
	{ "2424",	AR5K_VERSION_VER,	AR5K_SREV_VER_AR2424 },
	{ "5424",	AR5K_VERSION_VER,	AR5K_SREV_VER_AR5424 },
	{ "5413",	AR5K_VERSION_VER,	AR5K_SREV_VER_AR5413 },
	{ "5414",	AR5K_VERSION_VER,	AR5K_SREV_VER_AR5414 },
	{ "5416",	AR5K_VERSION_VER,	AR5K_SREV_VER_AR5416 },
	{ "5418",	AR5K_VERSION_VER,	AR5K_SREV_VER_AR5418 },
	{ "2425",	AR5K_VERSION_VER,	AR5K_SREV_VER_AR2425 },
	{ "xxxxx",	AR5K_VERSION_VER,	AR5K_SREV_UNKNOWN },
	{ "5210",	AR5K_VERSION_MAC,	AR5K_SREV_AR5210 },
	{ "5311",	AR5K_VERSION_MAC,	AR5K_SREV_AR5311 },
	{ "5311A",	AR5K_VERSION_MAC,	AR5K_SREV_AR5311A },
	{ "5311B",	AR5K_VERSION_MAC,	AR5K_SREV_AR5311B },
	{ "5211",	AR5K_VERSION_MAC,	AR5K_SREV_AR5211 },
	{ "5212",	AR5K_VERSION_MAC,	AR5K_SREV_AR5212 },
	{ "5213",	AR5K_VERSION_MAC,	AR5K_SREV_AR5213 },
	{ "5213A",	AR5K_VERSION_MAC,	AR5K_SREV_AR5213A },
	{ "2413",	AR5K_VERSION_MAC,	AR5K_SREV_AR2413 },
	{ "2414",	AR5K_VERSION_MAC,	AR5K_SREV_AR2414 },
	{ "5424",	AR5K_VERSION_MAC,	AR5K_SREV_AR5424 },
	{ "5413",	AR5K_VERSION_MAC,	AR5K_SREV_AR5413 },
	{ "5414",	AR5K_VERSION_MAC,	AR5K_SREV_AR5414 },
	{ "2415",	AR5K_VERSION_MAC,	AR5K_SREV_AR2415 },
	{ "5416",	AR5K_VERSION_MAC,	AR5K_SREV_AR5416 },
	{ "5418",	AR5K_VERSION_MAC,	AR5K_SREV_AR5418 },
	{ "2425",	AR5K_VERSION_MAC,	AR5K_SREV_AR2425 },
	{ "2417",	AR5K_VERSION_MAC,	AR5K_SREV_AR2417 },
	{ "xxxxx",	AR5K_VERSION_MAC,	AR5K_SREV_UNKNOWN },
	{ "5110",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_5110 },
	{ "5111",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_5111 },
	{ "5111A",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_5111A },
	{ "2111",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_2111 },
	{ "5112",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_5112 },
	{ "5112A",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_5112A },
	{ "5112B",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_5112B },
	{ "2112",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_2112 },
	{ "2112A",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_2112A },
	{ "SChip",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_SC0 },
	{ "SChip",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_SC1 },
	{ "SChip",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_SC2 },
	{ "2112B",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_2112B },
	{ "2413",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_2413 },
	{ "5413",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_5413 },
	{ "2316",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_2316 },
	{ "2317",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_2317 },
	{ "5424",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_5424 },
	{ "5133",	AR5K_VERSION_RAD,	AR5K_SREV_RAD_5133 },
	{ "xxxxx",	AR5K_VERSION_RAD,	AR5K_SREV_UNKNOWN },
};
@@ -390,7 +397,11 @@ ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val)
	for (i = 0; i < ARRAY_SIZE(srev_names); i++) {
		if (srev_names[i].sr_type != type)
			continue;
		if ((val & 0xff) < srev_names[i + 1].sr_val) {

		if ((val & 0xf0) == srev_names[i].sr_val)
			name = srev_names[i].sr_name;

		if ((val & 0xff) == srev_names[i].sr_val) {
			name = srev_names[i].sr_name;
			break;
		}
@@ -536,7 +547,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
		goto err_ah;

	ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n",
			ath5k_chip_name(AR5K_VERSION_VER,sc->ah->ah_mac_srev),
			ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev),
					sc->ah->ah_mac_srev,
					sc->ah->ah_phy_revision);

+44 −5
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
	/*
	 * It may take some time to disable the DMA receive unit
	 */
	for (i = 2000; i > 0 &&
	for (i = 1000; i > 0 &&
			(ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0;
			i--)
		udelay(10);
@@ -182,11 +182,10 @@ int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue)
 * have any pending frames. Returns -EBUSY if we still have pending frames,
 * -EINVAL if queue number is out of range.
 *
 * TODO: Test queue drain code
 */
int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
{
	unsigned int i = 100;
	unsigned int i = 40;
	u32 tx_queue, pending;

	ATH5K_TRACE(ah->ah_sc);
@@ -233,13 +232,53 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
			udelay(100);
		} while (--i && pending);

		/* For 2413+ order PCU to drop packets using
		 * QUIET mechanism */
		if (ah->ah_mac_version >= (AR5K_SREV_AR2414 >> 4) &&
		pending){
			/* Set periodicity and duration */
			ath5k_hw_reg_write(ah,
				AR5K_REG_SM(100, AR5K_QUIET_CTL2_QT_PER)|
				AR5K_REG_SM(10, AR5K_QUIET_CTL2_QT_DUR),
				AR5K_QUIET_CTL2);

			/* Enable quiet period for current TSF */
			ath5k_hw_reg_write(ah,
				AR5K_QUIET_CTL1_QT_EN |
				AR5K_REG_SM(ath5k_hw_reg_read(ah,
						AR5K_TSF_L32_5211) >> 10,
						AR5K_QUIET_CTL1_NEXT_QT_TSF),
				AR5K_QUIET_CTL1);

			/* Force channel idle high */
			AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211,
					AR5K_DIAG_SW_CHANEL_IDLE_HIGH);

			/* Wait a while and disable mechanism */
			udelay(200);
			AR5K_REG_DISABLE_BITS(ah, AR5K_QUIET_CTL1,
						AR5K_QUIET_CTL1_QT_EN);

			/* Re-check for pending frames */
			i = 40;
			do {
				pending = ath5k_hw_reg_read(ah,
					AR5K_QUEUE_STATUS(queue)) &
					AR5K_QCU_STS_FRMPENDCNT;
				udelay(100);
			} while (--i && pending);

			AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211,
					AR5K_DIAG_SW_CHANEL_IDLE_HIGH);
		}

		/* Clear register */
		ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD);
		if (pending)
			return -EBUSY;
	}

	/* TODO: Check for success else return error */
	/* TODO: Check for success on 5210 else return error */
	return 0;
}

@@ -415,7 +454,7 @@ done:
bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah)
{
	ATH5K_TRACE(ah->ah_sc);
	return ath5k_hw_reg_read(ah, AR5K_INTPEND);
	return ath5k_hw_reg_read(ah, AR5K_INTPEND) == 1 ? 1 : 0;
}

/**
+13 −1
Original line number Diff line number Diff line
@@ -633,8 +633,20 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
 */
void ath5k_hw_reset_tsf(struct ath5k_hw *ah)
{
	u32 val;

	ATH5K_TRACE(ah->ah_sc);
	AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_RESET_TSF);

	val = ath5k_hw_reg_read(ah, AR5K_BEACON) | AR5K_BEACON_RESET_TSF;

	/*
	 * Each write to the RESET_TSF bit toggles a hardware internal
	 * signal to reset TSF, but if left high it will cause a TSF reset
	 * on the next chip reset as well.  Thus we always write the value
	 * twice to clear the signal.
	 */
	ath5k_hw_reg_write(ah, val, AR5K_BEACON);
	ath5k_hw_reg_write(ah, val, AR5K_BEACON);
}

/*
Loading