^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Linux device driver for ADMtek ADM8211 (IEEE 802.11b MAC/BBP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (c) 2003, Jouni Malinen <j@w1.fi>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) 2004-2007, Michael Wu <flamingice@sourmilk.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Some parts copyright (c) 2003 by David Young <dyoung@pobox.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * and used with permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Much thanks to Infineon-ADMtek for their support of this driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/if.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/crc32.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/eeprom_93cx6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <net/mac80211.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "adm8211.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) MODULE_AUTHOR("Jouni Malinen <j@w1.fi>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) MODULE_DESCRIPTION("Driver for IEEE 802.11b wireless cards based on ADMtek ADM8211");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) MODULE_SUPPORTED_DEVICE("ADM8211");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static unsigned int tx_ring_size __read_mostly = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) static unsigned int rx_ring_size __read_mostly = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) module_param(tx_ring_size, uint, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) module_param(rx_ring_size, uint, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static const struct pci_device_id adm8211_pci_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* ADMtek ADM8211 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) { PCI_DEVICE(0x10B7, 0x6000) }, /* 3Com 3CRSHPW796 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) { PCI_DEVICE(0x1200, 0x8201) }, /* ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) { PCI_DEVICE(0x1317, 0x8201) }, /* ADM8211A */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) { PCI_DEVICE(0x1317, 0x8211) }, /* ADM8211B/C */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) { 0 }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static struct ieee80211_rate adm8211_rates[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) { .bitrate = 10, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) { .bitrate = 220, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, /* XX ?? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) static const struct ieee80211_channel adm8211_channels[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) { .center_freq = 2412},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) { .center_freq = 2417},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) { .center_freq = 2422},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) { .center_freq = 2427},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) { .center_freq = 2432},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) { .center_freq = 2437},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) { .center_freq = 2442},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) { .center_freq = 2447},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) { .center_freq = 2452},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) { .center_freq = 2457},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) { .center_freq = 2462},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) { .center_freq = 2467},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) { .center_freq = 2472},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) { .center_freq = 2484},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static void adm8211_eeprom_register_read(struct eeprom_93cx6 *eeprom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct adm8211_priv *priv = eeprom->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) u32 reg = ADM8211_CSR_READ(SPR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) eeprom->reg_data_in = reg & ADM8211_SPR_SDI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) eeprom->reg_data_out = reg & ADM8211_SPR_SDO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) eeprom->reg_data_clock = reg & ADM8211_SPR_SCLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) eeprom->reg_chip_select = reg & ADM8211_SPR_SCS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static void adm8211_eeprom_register_write(struct eeprom_93cx6 *eeprom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct adm8211_priv *priv = eeprom->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) u32 reg = 0x4000 | ADM8211_SPR_SRS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) if (eeprom->reg_data_in)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) reg |= ADM8211_SPR_SDI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (eeprom->reg_data_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) reg |= ADM8211_SPR_SDO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (eeprom->reg_data_clock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) reg |= ADM8211_SPR_SCLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (eeprom->reg_chip_select)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) reg |= ADM8211_SPR_SCS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) ADM8211_CSR_WRITE(SPR, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) ADM8211_CSR_READ(SPR); /* eeprom_delay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) static int adm8211_read_eeprom(struct ieee80211_hw *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) unsigned int words, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct ieee80211_chan_range chan_range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) u16 cr49;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct eeprom_93cx6 eeprom = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) .data = priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) .register_read = adm8211_eeprom_register_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) .register_write = adm8211_eeprom_register_write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (ADM8211_CSR_READ(CSR_TEST0) & ADM8211_CSR_TEST0_EPTYP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) /* 256 * 16-bit = 512 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) eeprom.width = PCI_EEPROM_WIDTH_93C66;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) words = 256;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /* 64 * 16-bit = 128 bytes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) eeprom.width = PCI_EEPROM_WIDTH_93C46;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) words = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) priv->eeprom_len = words * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) priv->eeprom = kmalloc(priv->eeprom_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (!priv->eeprom)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) eeprom_93cx6_multiread(&eeprom, 0, (__le16 *)priv->eeprom, words);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) cr49 = le16_to_cpu(priv->eeprom->cr49);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) priv->rf_type = (cr49 >> 3) & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) switch (priv->rf_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) case ADM8211_TYPE_INTERSIL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) case ADM8211_TYPE_RFMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) case ADM8211_TYPE_MARVEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) case ADM8211_TYPE_AIROHA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) case ADM8211_TYPE_ADMTEK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (priv->pdev->revision < ADM8211_REV_CA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) priv->rf_type = ADM8211_TYPE_RFMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) priv->rf_type = ADM8211_TYPE_AIROHA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) printk(KERN_WARNING "%s (adm8211): Unknown RFtype %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) pci_name(priv->pdev), (cr49 >> 3) & 0x7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) priv->bbp_type = cr49 & 0x7;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) switch (priv->bbp_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) case ADM8211_TYPE_INTERSIL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) case ADM8211_TYPE_RFMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) case ADM8211_TYPE_MARVEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) case ADM8211_TYPE_AIROHA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) case ADM8211_TYPE_ADMTEK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (priv->pdev->revision < ADM8211_REV_CA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) priv->bbp_type = ADM8211_TYPE_RFMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) priv->bbp_type = ADM8211_TYPE_ADMTEK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) printk(KERN_WARNING "%s (adm8211): Unknown BBPtype: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) pci_name(priv->pdev), cr49 >> 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) if (priv->eeprom->country_code >= ARRAY_SIZE(cranges)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) printk(KERN_WARNING "%s (adm8211): Invalid country code (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) pci_name(priv->pdev), priv->eeprom->country_code);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) chan_range = cranges[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) chan_range = cranges[priv->eeprom->country_code];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) printk(KERN_DEBUG "%s (adm8211): Channel range: %d - %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) pci_name(priv->pdev), (int)chan_range.min, (int)chan_range.max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) BUILD_BUG_ON(sizeof(priv->channels) != sizeof(adm8211_channels));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) memcpy(priv->channels, adm8211_channels, sizeof(priv->channels));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) priv->band.channels = priv->channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) priv->band.n_channels = ARRAY_SIZE(adm8211_channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) priv->band.bitrates = adm8211_rates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) priv->band.n_bitrates = ARRAY_SIZE(adm8211_rates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) for (i = 1; i <= ARRAY_SIZE(adm8211_channels); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (i < chan_range.min || i > chan_range.max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) priv->channels[i - 1].flags |= IEEE80211_CHAN_DISABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) switch (priv->eeprom->specific_bbptype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) case ADM8211_BBP_RFMD3000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) case ADM8211_BBP_RFMD3002:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) case ADM8211_BBP_ADM8011:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) priv->specific_bbptype = priv->eeprom->specific_bbptype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (priv->pdev->revision < ADM8211_REV_CA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) priv->specific_bbptype = ADM8211_BBP_RFMD3000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) priv->specific_bbptype = ADM8211_BBP_ADM8011;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) printk(KERN_WARNING "%s (adm8211): Unknown specific BBP: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) pci_name(priv->pdev), priv->eeprom->specific_bbptype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) switch (priv->eeprom->specific_rftype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) case ADM8211_RFMD2948:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) case ADM8211_RFMD2958:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) case ADM8211_RFMD2958_RF3000_CONTROL_POWER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) case ADM8211_MAX2820:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) case ADM8211_AL2210L:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) priv->transceiver_type = priv->eeprom->specific_rftype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (priv->pdev->revision == ADM8211_REV_BA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) priv->transceiver_type = ADM8211_RFMD2958_RF3000_CONTROL_POWER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) else if (priv->pdev->revision == ADM8211_REV_CA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) priv->transceiver_type = ADM8211_AL2210L;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) else if (priv->pdev->revision == ADM8211_REV_AB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) priv->transceiver_type = ADM8211_RFMD2948;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) printk(KERN_WARNING "%s (adm8211): Unknown transceiver: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) pci_name(priv->pdev), priv->eeprom->specific_rftype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) printk(KERN_DEBUG "%s (adm8211): RFtype=%d BBPtype=%d Specific BBP=%d "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) "Transceiver=%d\n", pci_name(priv->pdev), priv->rf_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) priv->bbp_type, priv->specific_bbptype, priv->transceiver_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static inline void adm8211_write_sram(struct ieee80211_hw *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) u32 addr, u32 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) ADM8211_CSR_WRITE(WEPCTL, addr | ADM8211_WEPCTL_TABLE_WR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) (priv->pdev->revision < ADM8211_REV_BA ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 0 : ADM8211_WEPCTL_SEL_WEPTABLE ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) ADM8211_CSR_READ(WEPCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) ADM8211_CSR_WRITE(WESK, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) ADM8211_CSR_READ(WESK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) static void adm8211_write_sram_bytes(struct ieee80211_hw *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) unsigned int addr, u8 *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) u32 reg = ADM8211_CSR_READ(WEPCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (priv->pdev->revision < ADM8211_REV_BA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) for (i = 0; i < len; i += 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) u16 val = buf[i] | (buf[i + 1] << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) adm8211_write_sram(dev, addr + i / 2, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) for (i = 0; i < len; i += 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) u32 val = (buf[i + 0] << 0 ) | (buf[i + 1] << 8 ) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) (buf[i + 2] << 16) | (buf[i + 3] << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) adm8211_write_sram(dev, addr + i / 4, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) ADM8211_CSR_WRITE(WEPCTL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static void adm8211_clear_sram(struct ieee80211_hw *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) u32 reg = ADM8211_CSR_READ(WEPCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) unsigned int addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) for (addr = 0; addr < ADM8211_SRAM_SIZE; addr++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) adm8211_write_sram(dev, addr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) ADM8211_CSR_WRITE(WEPCTL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static int adm8211_get_stats(struct ieee80211_hw *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct ieee80211_low_level_stats *stats)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) memcpy(stats, &priv->stats, sizeof(*stats));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) static void adm8211_interrupt_tci(struct ieee80211_hw *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) unsigned int dirty_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) spin_lock(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) for (dirty_tx = priv->dirty_tx; priv->cur_tx - dirty_tx; dirty_tx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) unsigned int entry = dirty_tx % priv->tx_ring_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) u32 status = le32_to_cpu(priv->tx_ring[entry].status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) struct ieee80211_tx_info *txi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) struct adm8211_tx_ring_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (status & TDES0_CONTROL_OWN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) !(status & TDES0_CONTROL_DONE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) info = &priv->tx_buffers[entry];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) skb = info->skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) txi = IEEE80211_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) /* TODO: check TDES0_STATUS_TUF and TDES0_STATUS_TRO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) dma_unmap_single(&priv->pdev->dev, info->mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) info->skb->len, DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) ieee80211_tx_info_clear_status(txi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) skb_pull(skb, sizeof(struct adm8211_tx_hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) memcpy(skb_push(skb, info->hdrlen), skb->cb, info->hdrlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) !(status & TDES0_STATUS_ES))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) txi->flags |= IEEE80211_TX_STAT_ACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) ieee80211_tx_status_irqsafe(dev, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) info->skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (priv->cur_tx - dirty_tx < priv->tx_ring_size - 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) ieee80211_wake_queue(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) priv->dirty_tx = dirty_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) spin_unlock(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static void adm8211_interrupt_rci(struct ieee80211_hw *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) unsigned int entry = priv->cur_rx % priv->rx_ring_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) unsigned int pktlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) struct sk_buff *skb, *newskb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) unsigned int limit = priv->rx_ring_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) u8 rssi, rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) while (!(priv->rx_ring[entry].status & cpu_to_le32(RDES0_STATUS_OWN))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if (!limit--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) status = le32_to_cpu(priv->rx_ring[entry].status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) rate = (status & RDES0_STATUS_RXDR) >> 12;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) rssi = le32_to_cpu(priv->rx_ring[entry].length) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) RDES1_STATUS_RSSI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) pktlen = status & RDES0_STATUS_FL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (pktlen > RX_PKT_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (net_ratelimit())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) wiphy_debug(dev->wiphy, "frame too long (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) pktlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) pktlen = RX_PKT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (!priv->soft_rx_crc && status & RDES0_STATUS_ES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) skb = NULL; /* old buffer will be reused */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /* TODO: update RX error stats */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) /* TODO: check RDES0_STATUS_CRC*E */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) } else if (pktlen < RX_COPY_BREAK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) skb = dev_alloc_skb(pktlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) dma_sync_single_for_cpu(&priv->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) priv->rx_buffers[entry].mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) pktlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) skb_put_data(skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) skb_tail_pointer(priv->rx_buffers[entry].skb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) pktlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) dma_sync_single_for_device(&priv->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) priv->rx_buffers[entry].mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) RX_PKT_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) newskb = dev_alloc_skb(RX_PKT_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (newskb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) skb = priv->rx_buffers[entry].skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) skb_put(skb, pktlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) dma_unmap_single(&priv->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) priv->rx_buffers[entry].mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) RX_PKT_SIZE, DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) priv->rx_buffers[entry].skb = newskb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) priv->rx_buffers[entry].mapping =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) dma_map_single(&priv->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) skb_tail_pointer(newskb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) RX_PKT_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (dma_mapping_error(&priv->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) priv->rx_buffers[entry].mapping)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) priv->rx_buffers[entry].skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) dev_kfree_skb(newskb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /* TODO: update rx dropped stats */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) /* TODO: update rx dropped stats */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) priv->rx_ring[entry].buffer1 =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) cpu_to_le32(priv->rx_buffers[entry].mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) priv->rx_ring[entry].status = cpu_to_le32(RDES0_STATUS_OWN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) RDES0_STATUS_SQL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) priv->rx_ring[entry].length =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) cpu_to_le32(RX_PKT_SIZE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) (entry == priv->rx_ring_size - 1 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) RDES1_CONTROL_RER : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) struct ieee80211_rx_status rx_status = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (priv->pdev->revision < ADM8211_REV_CA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) rx_status.signal = rssi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) rx_status.signal = 100 - rssi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) rx_status.rate_idx = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) rx_status.freq = adm8211_channels[priv->channel - 1].center_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) rx_status.band = NL80211_BAND_2GHZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) ieee80211_rx_irqsafe(dev, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) entry = (++priv->cur_rx) % priv->rx_ring_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) /* TODO: check LPC and update stats? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) static irqreturn_t adm8211_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) #define ADM8211_INT(x) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) if (unlikely(stsr & ADM8211_STSR_ ## x)) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) wiphy_debug(dev->wiphy, "%s\n", #x); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) struct ieee80211_hw *dev = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) u32 stsr = ADM8211_CSR_READ(STSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) ADM8211_CSR_WRITE(STSR, stsr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (stsr == 0xffffffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (!(stsr & (ADM8211_STSR_NISS | ADM8211_STSR_AISS)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (stsr & ADM8211_STSR_RCI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) adm8211_interrupt_rci(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (stsr & ADM8211_STSR_TCI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) adm8211_interrupt_tci(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) ADM8211_INT(PCF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) ADM8211_INT(BCNTC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) ADM8211_INT(GPINT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) ADM8211_INT(ATIMTC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) ADM8211_INT(TSFTF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) ADM8211_INT(TSCZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) ADM8211_INT(SQL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) ADM8211_INT(WEPTD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) ADM8211_INT(ATIME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) ADM8211_INT(TEIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) ADM8211_INT(FBE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ADM8211_INT(REIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) ADM8211_INT(GPTT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) ADM8211_INT(RPS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) ADM8211_INT(RDU);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) ADM8211_INT(TUF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) ADM8211_INT(TPS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) #undef ADM8211_INT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) #define WRITE_SYN(name,v_mask,v_shift,a_mask,a_shift,bits,prewrite,postwrite)\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) static void adm8211_rf_write_syn_ ## name (struct ieee80211_hw *dev, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) u16 addr, u32 value) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) struct adm8211_priv *priv = dev->priv; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) unsigned int i; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) u32 reg, bitbuf; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) value &= v_mask; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) addr &= a_mask; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) bitbuf = (value << v_shift) | (addr << a_shift); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) ADM8211_CSR_WRITE(SYNRF, ADM8211_SYNRF_IF_SELECT_1); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) ADM8211_CSR_READ(SYNRF); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) ADM8211_CSR_WRITE(SYNRF, ADM8211_SYNRF_IF_SELECT_0); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) ADM8211_CSR_READ(SYNRF); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (prewrite) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) ADM8211_CSR_WRITE(SYNRF, ADM8211_SYNRF_WRITE_SYNDATA_0); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) ADM8211_CSR_READ(SYNRF); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) for (i = 0; i <= bits; i++) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (bitbuf & (1 << (bits - i))) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) reg = ADM8211_SYNRF_WRITE_SYNDATA_1; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) else \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) reg = ADM8211_SYNRF_WRITE_SYNDATA_0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) ADM8211_CSR_WRITE(SYNRF, reg); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) ADM8211_CSR_READ(SYNRF); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) ADM8211_CSR_WRITE(SYNRF, reg | ADM8211_SYNRF_WRITE_CLOCK_1); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) ADM8211_CSR_READ(SYNRF); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) ADM8211_CSR_WRITE(SYNRF, reg | ADM8211_SYNRF_WRITE_CLOCK_0); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) ADM8211_CSR_READ(SYNRF); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (postwrite == 1) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) ADM8211_CSR_WRITE(SYNRF, reg | ADM8211_SYNRF_IF_SELECT_0); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) ADM8211_CSR_READ(SYNRF); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (postwrite == 2) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) ADM8211_CSR_WRITE(SYNRF, reg | ADM8211_SYNRF_IF_SELECT_1); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) ADM8211_CSR_READ(SYNRF); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) ADM8211_CSR_WRITE(SYNRF, 0); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) ADM8211_CSR_READ(SYNRF); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) WRITE_SYN(max2820, 0x00FFF, 0, 0x0F, 12, 15, 1, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) WRITE_SYN(al2210l, 0xFFFFF, 4, 0x0F, 0, 23, 1, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) WRITE_SYN(rfmd2958, 0x3FFFF, 0, 0x1F, 18, 23, 0, 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) WRITE_SYN(rfmd2948, 0x0FFFF, 4, 0x0F, 0, 21, 0, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) #undef WRITE_SYN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) static int adm8211_write_bbp(struct ieee80211_hw *dev, u8 addr, u8 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) unsigned int timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) timeout = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) while (timeout > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) reg = ADM8211_CSR_READ(BBPCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) if (!(reg & (ADM8211_BBPCTL_WR | ADM8211_BBPCTL_RD)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) timeout--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) msleep(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (timeout == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) wiphy_debug(dev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) "adm8211_write_bbp(%d,%d) failed prewrite (reg=0x%08x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) addr, data, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) switch (priv->bbp_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) case ADM8211_TYPE_INTERSIL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) reg = ADM8211_BBPCTL_MMISEL; /* three wire interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) case ADM8211_TYPE_RFMD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) reg = (0x20 << 24) | ADM8211_BBPCTL_TXCE | ADM8211_BBPCTL_CCAP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) (0x01 << 18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) case ADM8211_TYPE_ADMTEK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) reg = (0x20 << 24) | ADM8211_BBPCTL_TXCE | ADM8211_BBPCTL_CCAP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) (0x05 << 18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) reg |= ADM8211_BBPCTL_WR | (addr << 8) | data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) ADM8211_CSR_WRITE(BBPCTL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) timeout = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) while (timeout > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) reg = ADM8211_CSR_READ(BBPCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (!(reg & ADM8211_BBPCTL_WR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) timeout--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) msleep(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (timeout == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) ADM8211_CSR_WRITE(BBPCTL, ADM8211_CSR_READ(BBPCTL) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) ~ADM8211_BBPCTL_WR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) wiphy_debug(dev->wiphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) "adm8211_write_bbp(%d,%d) failed postwrite (reg=0x%08x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) addr, data, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) static int adm8211_rf_set_channel(struct ieee80211_hw *dev, unsigned int chan)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) static const u32 adm8211_rfmd2958_reg5[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) {0x22BD, 0x22D2, 0x22E8, 0x22FE, 0x2314, 0x232A, 0x2340,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 0x2355, 0x236B, 0x2381, 0x2397, 0x23AD, 0x23C2, 0x23F7};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) static const u32 adm8211_rfmd2958_reg6[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) {0x05D17, 0x3A2E8, 0x2E8BA, 0x22E8B, 0x1745D, 0x0BA2E, 0x00000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 0x345D1, 0x28BA2, 0x1D174, 0x11745, 0x05D17, 0x3A2E8, 0x11745};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) u8 ant_power = priv->ant_power > 0x3F ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) priv->eeprom->antenna_power[chan - 1] : priv->ant_power;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) u8 tx_power = priv->tx_power > 0x3F ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) priv->eeprom->tx_power[chan - 1] : priv->tx_power;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) u8 lpf_cutoff = priv->lpf_cutoff == 0xFF ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) priv->eeprom->lpf_cutoff[chan - 1] : priv->lpf_cutoff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) u8 lnags_thresh = priv->lnags_threshold == 0xFF ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) priv->eeprom->lnags_threshold[chan - 1] : priv->lnags_threshold;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) ADM8211_IDLE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) /* Program synthesizer to new channel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) switch (priv->transceiver_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) case ADM8211_RFMD2958:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) case ADM8211_RFMD2958_RF3000_CONTROL_POWER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) adm8211_rf_write_syn_rfmd2958(dev, 0x00, 0x04007);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) adm8211_rf_write_syn_rfmd2958(dev, 0x02, 0x00033);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) adm8211_rf_write_syn_rfmd2958(dev, 0x05,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) adm8211_rfmd2958_reg5[chan - 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) adm8211_rf_write_syn_rfmd2958(dev, 0x06,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) adm8211_rfmd2958_reg6[chan - 1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) case ADM8211_RFMD2948:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) adm8211_rf_write_syn_rfmd2948(dev, SI4126_MAIN_CONF,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) SI4126_MAIN_XINDIV2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) adm8211_rf_write_syn_rfmd2948(dev, SI4126_POWERDOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) SI4126_POWERDOWN_PDIB |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) SI4126_POWERDOWN_PDRB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) adm8211_rf_write_syn_rfmd2948(dev, SI4126_PHASE_DET_GAIN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) adm8211_rf_write_syn_rfmd2948(dev, SI4126_RF2_N_DIV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) (chan == 14 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 2110 : (2033 + (chan * 5))));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) adm8211_rf_write_syn_rfmd2948(dev, SI4126_IF_N_DIV, 1496);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) adm8211_rf_write_syn_rfmd2948(dev, SI4126_RF2_R_DIV, 44);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) adm8211_rf_write_syn_rfmd2948(dev, SI4126_IF_R_DIV, 44);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) case ADM8211_MAX2820:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) adm8211_rf_write_syn_max2820(dev, 0x3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) (chan == 14 ? 0x054 : (0x7 + (chan * 5))));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) case ADM8211_AL2210L:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) adm8211_rf_write_syn_al2210l(dev, 0x0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) (chan == 14 ? 0x229B4 : (0x22967 + (chan * 5))));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) wiphy_debug(dev->wiphy, "unsupported transceiver type %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) priv->transceiver_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) /* write BBP regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (priv->bbp_type == ADM8211_TYPE_RFMD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) /* SMC 2635W specific? adm8211b doesn't use the 2948 though.. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) /* TODO: remove if SMC 2635W doesn't need this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (priv->transceiver_type == ADM8211_RFMD2948) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) reg = ADM8211_CSR_READ(GPIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) reg &= 0xfffc0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) reg |= ADM8211_CSR_GPIO_EN0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) if (chan != 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) reg |= ADM8211_CSR_GPIO_O0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) ADM8211_CSR_WRITE(GPIO, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (priv->transceiver_type == ADM8211_RFMD2958) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) /* set PCNT2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) adm8211_rf_write_syn_rfmd2958(dev, 0x0B, 0x07100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) /* set PCNT1 P_DESIRED/MID_BIAS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) reg = le16_to_cpu(priv->eeprom->cr49);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) reg >>= 13;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) reg <<= 15;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) reg |= ant_power << 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) adm8211_rf_write_syn_rfmd2958(dev, 0x0A, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) /* set TXRX TX_GAIN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) adm8211_rf_write_syn_rfmd2958(dev, 0x09, 0x00050 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) (priv->pdev->revision < ADM8211_REV_CA ? tx_power : 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) reg = ADM8211_CSR_READ(PLCPHD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) reg &= 0xff00ffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) reg |= tx_power << 18;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) ADM8211_CSR_WRITE(PLCPHD, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) ADM8211_CSR_WRITE(SYNRF, ADM8211_SYNRF_SELRF |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) ADM8211_SYNRF_PE1 | ADM8211_SYNRF_PHYRST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) ADM8211_CSR_READ(SYNRF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) msleep(30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) /* RF3000 BBP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) if (priv->transceiver_type != ADM8211_RFMD2958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) adm8211_write_bbp(dev, RF3000_TX_VAR_GAIN__TX_LEN_EXT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) tx_power<<2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) adm8211_write_bbp(dev, RF3000_LOW_GAIN_CALIB, lpf_cutoff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) adm8211_write_bbp(dev, RF3000_HIGH_GAIN_CALIB, lnags_thresh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) adm8211_write_bbp(dev, 0x1c, priv->pdev->revision == ADM8211_REV_BA ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) priv->eeprom->cr28 : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) adm8211_write_bbp(dev, 0x1d, priv->eeprom->cr29);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) ADM8211_CSR_WRITE(SYNRF, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) /* Nothing to do for ADMtek BBP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) } else if (priv->bbp_type != ADM8211_TYPE_ADMTEK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) wiphy_debug(dev->wiphy, "unsupported BBP type %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) priv->bbp_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) ADM8211_RESTORE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) /* update current channel for adhoc (and maybe AP mode) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) reg = ADM8211_CSR_READ(CAP0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) reg &= ~0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) reg |= chan;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) ADM8211_CSR_WRITE(CAP0, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) static void adm8211_update_mode(struct ieee80211_hw *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) ADM8211_IDLE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) priv->soft_rx_crc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) switch (priv->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) priv->nar &= ~(ADM8211_NAR_PR | ADM8211_NAR_EA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) priv->nar |= ADM8211_NAR_ST | ADM8211_NAR_SR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) case NL80211_IFTYPE_ADHOC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) priv->nar &= ~ADM8211_NAR_PR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) priv->nar |= ADM8211_NAR_EA | ADM8211_NAR_ST | ADM8211_NAR_SR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) /* don't trust the error bits on rev 0x20 and up in adhoc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (priv->pdev->revision >= ADM8211_REV_BA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) priv->soft_rx_crc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) case NL80211_IFTYPE_MONITOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) priv->nar &= ~(ADM8211_NAR_EA | ADM8211_NAR_ST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) priv->nar |= ADM8211_NAR_PR | ADM8211_NAR_SR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) ADM8211_RESTORE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) static void adm8211_hw_init_syn(struct ieee80211_hw *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) switch (priv->transceiver_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) case ADM8211_RFMD2958:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) case ADM8211_RFMD2958_RF3000_CONTROL_POWER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) /* comments taken from ADMtek vendor driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) /* Reset RF2958 after power on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) adm8211_rf_write_syn_rfmd2958(dev, 0x1F, 0x00000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) /* Initialize RF VCO Core Bias to maximum */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) adm8211_rf_write_syn_rfmd2958(dev, 0x0C, 0x3001F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) /* Initialize IF PLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) adm8211_rf_write_syn_rfmd2958(dev, 0x01, 0x29C03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) /* Initialize IF PLL Coarse Tuning */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) adm8211_rf_write_syn_rfmd2958(dev, 0x03, 0x1FF6F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) /* Initialize RF PLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) adm8211_rf_write_syn_rfmd2958(dev, 0x04, 0x29403);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) /* Initialize RF PLL Coarse Tuning */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) adm8211_rf_write_syn_rfmd2958(dev, 0x07, 0x1456F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) /* Initialize TX gain and filter BW (R9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) adm8211_rf_write_syn_rfmd2958(dev, 0x09,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) (priv->transceiver_type == ADM8211_RFMD2958 ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 0x10050 : 0x00050));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) /* Initialize CAL register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) adm8211_rf_write_syn_rfmd2958(dev, 0x08, 0x3FFF8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) case ADM8211_MAX2820:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) adm8211_rf_write_syn_max2820(dev, 0x1, 0x01E);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) adm8211_rf_write_syn_max2820(dev, 0x2, 0x001);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) adm8211_rf_write_syn_max2820(dev, 0x3, 0x054);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) adm8211_rf_write_syn_max2820(dev, 0x4, 0x310);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) adm8211_rf_write_syn_max2820(dev, 0x5, 0x000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) case ADM8211_AL2210L:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) adm8211_rf_write_syn_al2210l(dev, 0x0, 0x0196C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) adm8211_rf_write_syn_al2210l(dev, 0x1, 0x007CB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) adm8211_rf_write_syn_al2210l(dev, 0x2, 0x3582F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) adm8211_rf_write_syn_al2210l(dev, 0x3, 0x010A9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) adm8211_rf_write_syn_al2210l(dev, 0x4, 0x77280);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) adm8211_rf_write_syn_al2210l(dev, 0x5, 0x45641);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) adm8211_rf_write_syn_al2210l(dev, 0x6, 0xEA130);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) adm8211_rf_write_syn_al2210l(dev, 0x7, 0x80000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) adm8211_rf_write_syn_al2210l(dev, 0x8, 0x7850F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) adm8211_rf_write_syn_al2210l(dev, 0x9, 0xF900C);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) adm8211_rf_write_syn_al2210l(dev, 0xA, 0x00000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) adm8211_rf_write_syn_al2210l(dev, 0xB, 0x00000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) case ADM8211_RFMD2948:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) static int adm8211_hw_init_bbp(struct ieee80211_hw *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) /* write addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (priv->bbp_type == ADM8211_TYPE_INTERSIL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) ADM8211_CSR_WRITE(MMIWA, 0x100E0C0A);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) ADM8211_CSR_WRITE(MMIRD0, 0x00007C7E);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) ADM8211_CSR_WRITE(MMIRD1, 0x00100000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) } else if (priv->bbp_type == ADM8211_TYPE_RFMD ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) priv->bbp_type == ADM8211_TYPE_ADMTEK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) /* check specific BBP type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) switch (priv->specific_bbptype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) case ADM8211_BBP_RFMD3000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) case ADM8211_BBP_RFMD3002:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) ADM8211_CSR_WRITE(MMIWA, 0x00009101);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) ADM8211_CSR_WRITE(MMIRD0, 0x00000301);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) case ADM8211_BBP_ADM8011:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) ADM8211_CSR_WRITE(MMIWA, 0x00008903);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) ADM8211_CSR_WRITE(MMIRD0, 0x00001716);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) reg = ADM8211_CSR_READ(BBPCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) reg &= ~ADM8211_BBPCTL_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) reg |= 0x5 << 18;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) ADM8211_CSR_WRITE(BBPCTL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) switch (priv->pdev->revision) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) case ADM8211_REV_CA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) if (priv->transceiver_type == ADM8211_RFMD2958 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) priv->transceiver_type == ADM8211_RFMD2958_RF3000_CONTROL_POWER ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) priv->transceiver_type == ADM8211_RFMD2948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) ADM8211_CSR_WRITE(SYNCTL, 0x1 << 22);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) else if (priv->transceiver_type == ADM8211_MAX2820 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) priv->transceiver_type == ADM8211_AL2210L)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) ADM8211_CSR_WRITE(SYNCTL, 0x3 << 22);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) case ADM8211_REV_BA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) reg = ADM8211_CSR_READ(MMIRD1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) reg &= 0x0000FFFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) reg |= 0x7e100000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) ADM8211_CSR_WRITE(MMIRD1, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) case ADM8211_REV_AB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) case ADM8211_REV_AF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) ADM8211_CSR_WRITE(MMIRD1, 0x7e100000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) /* For RFMD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) ADM8211_CSR_WRITE(MACTEST, 0x800);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) adm8211_hw_init_syn(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) /* Set RF Power control IF pin to PE1+PHYRST# */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) ADM8211_CSR_WRITE(SYNRF, ADM8211_SYNRF_SELRF |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) ADM8211_SYNRF_PE1 | ADM8211_SYNRF_PHYRST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) ADM8211_CSR_READ(SYNRF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) /* write BBP regs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (priv->bbp_type == ADM8211_TYPE_RFMD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) /* RF3000 BBP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) /* another set:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) * 11: c8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) * 14: 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) * 15: 50 (chan 1..13; chan 14: d0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) * 1c: 00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) * 1d: 84
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) adm8211_write_bbp(dev, RF3000_CCA_CTRL, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) /* antenna selection: diversity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) adm8211_write_bbp(dev, RF3000_DIVERSITY__RSSI, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) adm8211_write_bbp(dev, RF3000_TX_VAR_GAIN__TX_LEN_EXT, 0x74);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) adm8211_write_bbp(dev, RF3000_LOW_GAIN_CALIB, 0x38);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) adm8211_write_bbp(dev, RF3000_HIGH_GAIN_CALIB, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) if (priv->eeprom->major_version < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) adm8211_write_bbp(dev, 0x1c, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) adm8211_write_bbp(dev, 0x1d, 0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (priv->pdev->revision == ADM8211_REV_BA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) adm8211_write_bbp(dev, 0x1c, priv->eeprom->cr28);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) adm8211_write_bbp(dev, 0x1c, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) adm8211_write_bbp(dev, 0x1d, priv->eeprom->cr29);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) } else if (priv->bbp_type == ADM8211_TYPE_ADMTEK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) /* reset baseband */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) adm8211_write_bbp(dev, 0x00, 0xFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) /* antenna selection: diversity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) adm8211_write_bbp(dev, 0x07, 0x0A);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) /* TODO: find documentation for this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) switch (priv->transceiver_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) case ADM8211_RFMD2958:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) case ADM8211_RFMD2958_RF3000_CONTROL_POWER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) adm8211_write_bbp(dev, 0x00, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) adm8211_write_bbp(dev, 0x01, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) adm8211_write_bbp(dev, 0x02, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) adm8211_write_bbp(dev, 0x03, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) adm8211_write_bbp(dev, 0x06, 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) adm8211_write_bbp(dev, 0x09, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) adm8211_write_bbp(dev, 0x0a, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) adm8211_write_bbp(dev, 0x0b, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) adm8211_write_bbp(dev, 0x0c, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) adm8211_write_bbp(dev, 0x0f, 0xAA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) adm8211_write_bbp(dev, 0x10, 0x8c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) adm8211_write_bbp(dev, 0x11, 0x43);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) adm8211_write_bbp(dev, 0x18, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) adm8211_write_bbp(dev, 0x20, 0x23);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) adm8211_write_bbp(dev, 0x21, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) adm8211_write_bbp(dev, 0x22, 0x28);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) adm8211_write_bbp(dev, 0x23, 0x30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) adm8211_write_bbp(dev, 0x24, 0x2d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) adm8211_write_bbp(dev, 0x28, 0x35);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) adm8211_write_bbp(dev, 0x2a, 0x8c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) adm8211_write_bbp(dev, 0x2b, 0x81);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) adm8211_write_bbp(dev, 0x2c, 0x44);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) adm8211_write_bbp(dev, 0x2d, 0x0A);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) adm8211_write_bbp(dev, 0x29, 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) adm8211_write_bbp(dev, 0x60, 0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) adm8211_write_bbp(dev, 0x64, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) case ADM8211_MAX2820:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) adm8211_write_bbp(dev, 0x00, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) adm8211_write_bbp(dev, 0x01, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) adm8211_write_bbp(dev, 0x02, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) adm8211_write_bbp(dev, 0x03, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) adm8211_write_bbp(dev, 0x06, 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) adm8211_write_bbp(dev, 0x09, 0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) adm8211_write_bbp(dev, 0x0a, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) adm8211_write_bbp(dev, 0x0b, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) adm8211_write_bbp(dev, 0x0c, 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) adm8211_write_bbp(dev, 0x0f, 0x55);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) adm8211_write_bbp(dev, 0x10, 0x8d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) adm8211_write_bbp(dev, 0x11, 0x43);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) adm8211_write_bbp(dev, 0x18, 0x4a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) adm8211_write_bbp(dev, 0x20, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) adm8211_write_bbp(dev, 0x21, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) adm8211_write_bbp(dev, 0x22, 0x23);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) adm8211_write_bbp(dev, 0x23, 0x30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) adm8211_write_bbp(dev, 0x24, 0x2d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) adm8211_write_bbp(dev, 0x2a, 0x8c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) adm8211_write_bbp(dev, 0x2b, 0x81);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) adm8211_write_bbp(dev, 0x2c, 0x44);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) adm8211_write_bbp(dev, 0x29, 0x4a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) adm8211_write_bbp(dev, 0x60, 0x2b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) adm8211_write_bbp(dev, 0x64, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) case ADM8211_AL2210L:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) adm8211_write_bbp(dev, 0x00, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) adm8211_write_bbp(dev, 0x01, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) adm8211_write_bbp(dev, 0x02, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) adm8211_write_bbp(dev, 0x03, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) adm8211_write_bbp(dev, 0x06, 0x0f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) adm8211_write_bbp(dev, 0x07, 0x05);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) adm8211_write_bbp(dev, 0x08, 0x03);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) adm8211_write_bbp(dev, 0x09, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) adm8211_write_bbp(dev, 0x0a, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) adm8211_write_bbp(dev, 0x0b, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) adm8211_write_bbp(dev, 0x0c, 0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) adm8211_write_bbp(dev, 0x0f, 0x55);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) adm8211_write_bbp(dev, 0x10, 0x8d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) adm8211_write_bbp(dev, 0x11, 0x43);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) adm8211_write_bbp(dev, 0x18, 0x4a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) adm8211_write_bbp(dev, 0x20, 0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) adm8211_write_bbp(dev, 0x21, 0x02);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) adm8211_write_bbp(dev, 0x22, 0x23);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) adm8211_write_bbp(dev, 0x23, 0x30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) adm8211_write_bbp(dev, 0x24, 0x2d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) adm8211_write_bbp(dev, 0x2a, 0xaa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) adm8211_write_bbp(dev, 0x2b, 0x81);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) adm8211_write_bbp(dev, 0x2c, 0x44);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) adm8211_write_bbp(dev, 0x29, 0xfa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) adm8211_write_bbp(dev, 0x60, 0x2d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) adm8211_write_bbp(dev, 0x64, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) case ADM8211_RFMD2948:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) wiphy_debug(dev->wiphy, "unsupported transceiver %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) priv->transceiver_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) wiphy_debug(dev->wiphy, "unsupported BBP %d\n", priv->bbp_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) ADM8211_CSR_WRITE(SYNRF, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) /* Set RF CAL control source to MAC control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) reg = ADM8211_CSR_READ(SYNCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) reg |= ADM8211_SYNCTL_SELCAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) ADM8211_CSR_WRITE(SYNCTL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) /* configures hw beacons/probe responses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) static int adm8211_set_rate(struct ieee80211_hw *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) int i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) u8 rate_buf[12] = {0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) /* write supported rates */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) if (priv->pdev->revision != ADM8211_REV_BA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) rate_buf[0] = ARRAY_SIZE(adm8211_rates);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) for (i = 0; i < ARRAY_SIZE(adm8211_rates); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) rate_buf[i + 1] = (adm8211_rates[i].bitrate / 5) | 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) /* workaround for rev BA specific bug */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) rate_buf[0] = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) rate_buf[1] = 0x82;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) rate_buf[2] = 0x04;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) rate_buf[3] = 0x0b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) rate_buf[4] = 0x16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) adm8211_write_sram_bytes(dev, ADM8211_SRAM_SUPP_RATE, rate_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) ARRAY_SIZE(adm8211_rates) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) reg = ADM8211_CSR_READ(PLCPHD) & 0x00FFFFFF; /* keep bits 0-23 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) reg |= 1 << 15; /* short preamble */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) reg |= 110 << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) ADM8211_CSR_WRITE(PLCPHD, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) /* MTMLT = 512 TU (max TX MSDU lifetime)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) * BCNTSIG = plcp_signal (beacon, probe resp, and atim TX rate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) * SRTYLIM = 224 (short retry limit, TX header value is default) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) ADM8211_CSR_WRITE(TXLMT, (512 << 16) | (110 << 8) | (224 << 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) static void adm8211_hw_init(struct ieee80211_hw *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) u8 cline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) reg = ADM8211_CSR_READ(PAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) reg |= ADM8211_PAR_MRLE | ADM8211_PAR_MRME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) reg &= ~(ADM8211_PAR_BAR | ADM8211_PAR_CAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) if (!pci_set_mwi(priv->pdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) reg |= 0x1 << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) pci_read_config_byte(priv->pdev, PCI_CACHE_LINE_SIZE, &cline);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) switch (cline) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) case 0x8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) reg |= (0x1 << 14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) case 0x10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) reg |= (0x2 << 14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) case 0x20:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) reg |= (0x3 << 14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) reg |= (0x0 << 14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) ADM8211_CSR_WRITE(PAR, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) reg = ADM8211_CSR_READ(CSR_TEST1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) reg &= ~(0xF << 28);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) reg |= (1 << 28) | (1 << 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) ADM8211_CSR_WRITE(CSR_TEST1, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) /* lose link after 4 lost beacons */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) reg = (0x04 << 21) | ADM8211_WCSR_TSFTWE | ADM8211_WCSR_LSOE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) ADM8211_CSR_WRITE(WCSR, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) /* Disable APM, enable receive FIFO threshold, and set drain receive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) * threshold to store-and-forward */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) reg = ADM8211_CSR_READ(CMDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) reg &= ~(ADM8211_CMDR_APM | ADM8211_CMDR_DRT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) reg |= ADM8211_CMDR_RTE | ADM8211_CMDR_DRT_SF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) ADM8211_CSR_WRITE(CMDR, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) adm8211_set_rate(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) /* 4-bit values:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) * PWR1UP = 8 * 2 ms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) * PWR0PAPE = 8 us or 5 us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) * PWR1PAPE = 1 us or 3 us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) * PWR0TRSW = 5 us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) * PWR1TRSW = 12 us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) * PWR0PE2 = 13 us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) * PWR1PE2 = 1 us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) * PWR0TXPE = 8 or 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) if (priv->pdev->revision < ADM8211_REV_CA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) ADM8211_CSR_WRITE(TOFS2, 0x8815cd18);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) ADM8211_CSR_WRITE(TOFS2, 0x8535cd16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) /* Enable store and forward for transmit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) priv->nar = ADM8211_NAR_SF | ADM8211_NAR_PB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) ADM8211_CSR_WRITE(NAR, priv->nar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) /* Reset RF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) ADM8211_CSR_WRITE(SYNRF, ADM8211_SYNRF_RADIO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) ADM8211_CSR_READ(SYNRF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) ADM8211_CSR_WRITE(SYNRF, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) ADM8211_CSR_READ(SYNRF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) msleep(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) /* Set CFP Max Duration to 0x10 TU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) reg = ADM8211_CSR_READ(CFPP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) reg &= ~(0xffff << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) reg |= 0x0010 << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) ADM8211_CSR_WRITE(CFPP, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) /* USCNT = 0x16 (number of system clocks, 22 MHz, in 1us
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) * TUCNT = 0x3ff - Tu counter 1024 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) ADM8211_CSR_WRITE(TOFS0, (0x16 << 24) | 0x3ff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) /* SLOT=20 us, SIFS=110 cycles of 22 MHz (5 us),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) * DIFS=50 us, EIFS=100 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) if (priv->pdev->revision < ADM8211_REV_CA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) ADM8211_CSR_WRITE(IFST, (20 << 23) | (110 << 15) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) (50 << 9) | 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) ADM8211_CSR_WRITE(IFST, (20 << 23) | (24 << 15) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) (50 << 9) | 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) /* PCNT = 1 (MAC idle time awake/sleep, unit S)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) * RMRD = 2346 * 8 + 1 us (max RX duration) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) ADM8211_CSR_WRITE(RMD, (1 << 16) | 18769);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) /* MART=65535 us, MIRT=256 us, TSFTOFST=0 us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) ADM8211_CSR_WRITE(RSPT, 0xffffff00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) /* Initialize BBP (and SYN) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) adm8211_hw_init_bbp(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) /* make sure interrupts are off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) ADM8211_CSR_WRITE(IER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) /* ACK interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) ADM8211_CSR_WRITE(STSR, ADM8211_CSR_READ(STSR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) /* Setup WEP (turns it off for now) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) reg = ADM8211_CSR_READ(MACTEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) reg &= ~(7 << 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) ADM8211_CSR_WRITE(MACTEST, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) reg = ADM8211_CSR_READ(WEPCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) reg &= ~ADM8211_WEPCTL_WEPENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) reg |= ADM8211_WEPCTL_WEPRXBYP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) ADM8211_CSR_WRITE(WEPCTL, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) /* Clear the missed-packet counter. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) ADM8211_CSR_READ(LPC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) static int adm8211_hw_reset(struct ieee80211_hw *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) u32 reg, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) int timeout = 100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) /* Power-on issue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) /* TODO: check if this is necessary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) ADM8211_CSR_WRITE(FRCTL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) /* Reset the chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) tmp = ADM8211_CSR_READ(PAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) ADM8211_CSR_WRITE(PAR, ADM8211_PAR_SWR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) while ((ADM8211_CSR_READ(PAR) & ADM8211_PAR_SWR) && timeout--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) msleep(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) if (timeout <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) ADM8211_CSR_WRITE(PAR, tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) if (priv->pdev->revision == ADM8211_REV_BA &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) (priv->transceiver_type == ADM8211_RFMD2958_RF3000_CONTROL_POWER ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) priv->transceiver_type == ADM8211_RFMD2958)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) reg = ADM8211_CSR_READ(CSR_TEST1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) reg |= (1 << 4) | (1 << 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) ADM8211_CSR_WRITE(CSR_TEST1, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) } else if (priv->pdev->revision == ADM8211_REV_CA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) reg = ADM8211_CSR_READ(CSR_TEST1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) reg &= ~((1 << 4) | (1 << 5));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) ADM8211_CSR_WRITE(CSR_TEST1, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) ADM8211_CSR_WRITE(FRCTL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) reg = ADM8211_CSR_READ(CSR_TEST0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) reg |= ADM8211_CSR_TEST0_EPRLD; /* EEPROM Recall */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) ADM8211_CSR_WRITE(CSR_TEST0, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) adm8211_clear_sram(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) static u64 adm8211_get_tsft(struct ieee80211_hw *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) struct ieee80211_vif *vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) u32 tsftl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) u64 tsft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) tsftl = ADM8211_CSR_READ(TSFTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) tsft = ADM8211_CSR_READ(TSFTH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) tsft <<= 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) tsft |= tsftl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) return tsft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) static void adm8211_set_interval(struct ieee80211_hw *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) unsigned short bi, unsigned short li)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) /* BP (beacon interval) = data->beacon_interval
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) * LI (listen interval) = data->listen_interval (in beacon intervals) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) reg = (bi << 16) | li;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) ADM8211_CSR_WRITE(BPLI, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) static void adm8211_set_bssid(struct ieee80211_hw *dev, const u8 *bssid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) ADM8211_CSR_WRITE(BSSID0, le32_to_cpu(*(__le32 *)bssid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) reg = ADM8211_CSR_READ(ABDA1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) reg &= 0x0000ffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) reg |= (bssid[4] << 16) | (bssid[5] << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) ADM8211_CSR_WRITE(ABDA1, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) static int adm8211_config(struct ieee80211_hw *dev, u32 changed)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) struct ieee80211_conf *conf = &dev->conf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) int channel =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) ieee80211_frequency_to_channel(conf->chandef.chan->center_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) if (channel != priv->channel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) priv->channel = channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) adm8211_rf_set_channel(dev, priv->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) static void adm8211_bss_info_changed(struct ieee80211_hw *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) struct ieee80211_vif *vif,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) struct ieee80211_bss_conf *conf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) u32 changes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) if (!(changes & BSS_CHANGED_BSSID))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) if (!ether_addr_equal(conf->bssid, priv->bssid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) adm8211_set_bssid(dev, conf->bssid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) memcpy(priv->bssid, conf->bssid, ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) static u64 adm8211_prepare_multicast(struct ieee80211_hw *hw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) struct netdev_hw_addr_list *mc_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) unsigned int bit_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) u32 mc_filter[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) struct netdev_hw_addr *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) mc_filter[1] = mc_filter[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) netdev_hw_addr_list_for_each(ha, mc_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) bit_nr &= 0x3F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) return mc_filter[0] | ((u64)(mc_filter[1]) << 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) static void adm8211_configure_filter(struct ieee80211_hw *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) unsigned int changed_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) unsigned int *total_flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) u64 multicast)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) static const u8 bcast[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) unsigned int new_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) u32 mc_filter[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) mc_filter[0] = multicast;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) mc_filter[1] = multicast >> 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) new_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) if (*total_flags & FIF_ALLMULTI || multicast == ~(0ULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) new_flags |= FIF_ALLMULTI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) priv->nar &= ~ADM8211_NAR_PR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) priv->nar |= ADM8211_NAR_MM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) mc_filter[1] = mc_filter[0] = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) priv->nar &= ~(ADM8211_NAR_MM | ADM8211_NAR_PR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) ADM8211_IDLE_RX();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) ADM8211_CSR_WRITE(MAR0, mc_filter[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) ADM8211_CSR_WRITE(MAR1, mc_filter[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) ADM8211_CSR_READ(NAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) if (priv->nar & ADM8211_NAR_PR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) ieee80211_hw_set(dev, RX_INCLUDES_FCS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) __clear_bit(IEEE80211_HW_RX_INCLUDES_FCS, dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) adm8211_set_bssid(dev, bcast);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) adm8211_set_bssid(dev, priv->bssid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) ADM8211_RESTORE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) *total_flags = new_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) static int adm8211_add_interface(struct ieee80211_hw *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) struct ieee80211_vif *vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) if (priv->mode != NL80211_IFTYPE_MONITOR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) switch (vif->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) case NL80211_IFTYPE_STATION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) priv->mode = vif->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) ADM8211_IDLE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) ADM8211_CSR_WRITE(PAR0, le32_to_cpu(*(__le32 *)vif->addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) ADM8211_CSR_WRITE(PAR1, le16_to_cpu(*(__le16 *)(vif->addr + 4)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) adm8211_update_mode(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) ADM8211_RESTORE();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) static void adm8211_remove_interface(struct ieee80211_hw *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) struct ieee80211_vif *vif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) priv->mode = NL80211_IFTYPE_MONITOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) static int adm8211_init_rings(struct ieee80211_hw *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) struct adm8211_desc *desc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) struct adm8211_rx_ring_info *rx_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) struct adm8211_tx_ring_info *tx_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) for (i = 0; i < priv->rx_ring_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) desc = &priv->rx_ring[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) desc->status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) desc->length = cpu_to_le32(RX_PKT_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) priv->rx_buffers[i].skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) /* Mark the end of RX ring; hw returns to base address after this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) * descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) desc->length |= cpu_to_le32(RDES1_CONTROL_RER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) for (i = 0; i < priv->rx_ring_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) desc = &priv->rx_ring[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) rx_info = &priv->rx_buffers[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) rx_info->skb = dev_alloc_skb(RX_PKT_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) if (rx_info->skb == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) rx_info->mapping = dma_map_single(&priv->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) skb_tail_pointer(rx_info->skb),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) RX_PKT_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) if (dma_mapping_error(&priv->pdev->dev, rx_info->mapping)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) dev_kfree_skb(rx_info->skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) rx_info->skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) desc->buffer1 = cpu_to_le32(rx_info->mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) desc->status = cpu_to_le32(RDES0_STATUS_OWN | RDES0_STATUS_SQL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) /* Setup TX ring. TX buffers descriptors will be filled in as needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) for (i = 0; i < priv->tx_ring_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) desc = &priv->tx_ring[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) tx_info = &priv->tx_buffers[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) tx_info->skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) tx_info->mapping = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) desc->status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) desc->length = cpu_to_le32(TDES1_CONTROL_TER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) priv->cur_rx = priv->cur_tx = priv->dirty_tx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) ADM8211_CSR_WRITE(RDB, priv->rx_ring_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) ADM8211_CSR_WRITE(TDBD, priv->tx_ring_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) static void adm8211_free_rings(struct ieee80211_hw *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) for (i = 0; i < priv->rx_ring_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) if (!priv->rx_buffers[i].skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) dma_unmap_single(&priv->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) priv->rx_buffers[i].mapping, RX_PKT_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) dev_kfree_skb(priv->rx_buffers[i].skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) for (i = 0; i < priv->tx_ring_size; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) if (!priv->tx_buffers[i].skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) dma_unmap_single(&priv->pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) priv->tx_buffers[i].mapping,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) priv->tx_buffers[i].skb->len, DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) dev_kfree_skb(priv->tx_buffers[i].skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) static int adm8211_start(struct ieee80211_hw *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) /* Power up MAC and RF chips */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) retval = adm8211_hw_reset(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) wiphy_err(dev->wiphy, "hardware reset failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) retval = adm8211_init_rings(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) wiphy_err(dev->wiphy, "failed to initialize rings\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) /* Init hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) adm8211_hw_init(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) adm8211_rf_set_channel(dev, priv->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) retval = request_irq(priv->pdev->irq, adm8211_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) IRQF_SHARED, "adm8211", dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) wiphy_err(dev->wiphy, "failed to register IRQ handler\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) ADM8211_CSR_WRITE(IER, ADM8211_IER_NIE | ADM8211_IER_AIE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) ADM8211_IER_RCIE | ADM8211_IER_TCIE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) ADM8211_IER_TDUIE | ADM8211_IER_GPTIE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) priv->mode = NL80211_IFTYPE_MONITOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) adm8211_update_mode(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) ADM8211_CSR_WRITE(RDR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) adm8211_set_interval(dev, 100, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) static void adm8211_stop(struct ieee80211_hw *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) priv->mode = NL80211_IFTYPE_UNSPECIFIED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) priv->nar = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) ADM8211_CSR_WRITE(NAR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) ADM8211_CSR_WRITE(IER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) ADM8211_CSR_READ(NAR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) free_irq(priv->pdev->irq, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) adm8211_free_rings(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) static void adm8211_calc_durations(int *dur, int *plcp, size_t payload_len, int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) int plcp_signal, int short_preamble)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) /* Alternative calculation from NetBSD: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) /* IEEE 802.11b durations for DSSS PHY in microseconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) #define IEEE80211_DUR_DS_LONG_PREAMBLE 144
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) #define IEEE80211_DUR_DS_SHORT_PREAMBLE 72
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) #define IEEE80211_DUR_DS_FAST_PLCPHDR 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) #define IEEE80211_DUR_DS_SLOW_PLCPHDR 48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) #define IEEE80211_DUR_DS_SLOW_ACK 112
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) #define IEEE80211_DUR_DS_FAST_ACK 56
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) #define IEEE80211_DUR_DS_SLOW_CTS 112
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) #define IEEE80211_DUR_DS_FAST_CTS 56
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) #define IEEE80211_DUR_DS_SLOT 20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) #define IEEE80211_DUR_DS_SIFS 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) int remainder;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) *dur = (80 * (24 + payload_len) + plcp_signal - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) / plcp_signal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) if (plcp_signal <= PLCP_SIGNAL_2M)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) /* 1-2Mbps WLAN: send ACK/CTS at 1Mbps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) *dur += 3 * (IEEE80211_DUR_DS_SIFS +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) IEEE80211_DUR_DS_SHORT_PREAMBLE +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) IEEE80211_DUR_DS_FAST_PLCPHDR) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) IEEE80211_DUR_DS_SLOW_CTS + IEEE80211_DUR_DS_SLOW_ACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) /* 5-11Mbps WLAN: send ACK/CTS at 2Mbps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) *dur += 3 * (IEEE80211_DUR_DS_SIFS +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) IEEE80211_DUR_DS_SHORT_PREAMBLE +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) IEEE80211_DUR_DS_FAST_PLCPHDR) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) IEEE80211_DUR_DS_FAST_CTS + IEEE80211_DUR_DS_FAST_ACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) /* lengthen duration if long preamble */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) if (!short_preamble)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) *dur += 3 * (IEEE80211_DUR_DS_LONG_PREAMBLE -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) IEEE80211_DUR_DS_SHORT_PREAMBLE) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 3 * (IEEE80211_DUR_DS_SLOW_PLCPHDR -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) IEEE80211_DUR_DS_FAST_PLCPHDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) *plcp = (80 * len) / plcp_signal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) remainder = (80 * len) % plcp_signal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) if (plcp_signal == PLCP_SIGNAL_11M &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) remainder <= 30 && remainder > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) *plcp = (*plcp | 0x8000) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) else if (remainder)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) (*plcp)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) /* Transmit skb w/adm8211_tx_hdr (802.11 header created by hardware) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) static int adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) u16 plcp_signal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) size_t hdrlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) dma_addr_t mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) unsigned int entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) u32 flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) mapping = dma_map_single(&priv->pdev->dev, skb->data, skb->len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) DMA_TO_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) if (dma_mapping_error(&priv->pdev->dev, mapping))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) spin_lock_irqsave(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) if (priv->cur_tx - priv->dirty_tx == priv->tx_ring_size / 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) flag = TDES1_CONTROL_IC | TDES1_CONTROL_LS | TDES1_CONTROL_FS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) flag = TDES1_CONTROL_LS | TDES1_CONTROL_FS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) if (priv->cur_tx - priv->dirty_tx == priv->tx_ring_size - 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) ieee80211_stop_queue(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) entry = priv->cur_tx % priv->tx_ring_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) priv->tx_buffers[entry].skb = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) priv->tx_buffers[entry].mapping = mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) priv->tx_buffers[entry].hdrlen = hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) priv->tx_ring[entry].buffer1 = cpu_to_le32(mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) if (entry == priv->tx_ring_size - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) flag |= TDES1_CONTROL_TER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) priv->tx_ring[entry].length = cpu_to_le32(flag | skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) /* Set TX rate (SIGNAL field in PLCP PPDU format) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) flag = TDES0_CONTROL_OWN | (plcp_signal << 20) | 8 /* ? */;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) priv->tx_ring[entry].status = cpu_to_le32(flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) priv->cur_tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) spin_unlock_irqrestore(&priv->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) /* Trigger transmit poll */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) ADM8211_CSR_WRITE(TDR, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) /* Put adm8211_tx_hdr on skb and transmit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) static void adm8211_tx(struct ieee80211_hw *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) struct ieee80211_tx_control *control,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) struct adm8211_tx_hdr *txhdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) size_t payload_len, hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) int plcp, dur, len, plcp_signal, short_preamble;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) struct ieee80211_hdr *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) struct ieee80211_rate *txrate = ieee80211_get_tx_rate(dev, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) u8 rc_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) rc_flags = info->control.rates[0].flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) short_preamble = !!(rc_flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) plcp_signal = txrate->bitrate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) hdr = (struct ieee80211_hdr *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) hdrlen = ieee80211_hdrlen(hdr->frame_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) memcpy(skb->cb, skb->data, hdrlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) hdr = (struct ieee80211_hdr *)skb->cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) skb_pull(skb, hdrlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) payload_len = skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) txhdr = skb_push(skb, sizeof(*txhdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) memset(txhdr, 0, sizeof(*txhdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) memcpy(txhdr->da, ieee80211_get_DA(hdr), ETH_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) txhdr->signal = plcp_signal;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) txhdr->frame_body_size = cpu_to_le16(payload_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) txhdr->frame_control = hdr->frame_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) len = hdrlen + payload_len + FCS_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) txhdr->frag = cpu_to_le16(0x0FFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) adm8211_calc_durations(&dur, &plcp, payload_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) len, plcp_signal, short_preamble);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) txhdr->plcp_frag_head_len = cpu_to_le16(plcp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) txhdr->plcp_frag_tail_len = cpu_to_le16(plcp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) txhdr->dur_frag_head = cpu_to_le16(dur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) txhdr->dur_frag_tail = cpu_to_le16(dur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) txhdr->header_control = cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_EXTEND_HEADER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) if (short_preamble)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_SHORT_PREAMBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_RTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) txhdr->retry_limit = info->control.rates[0].count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) if (adm8211_tx_raw(dev, skb, plcp_signal, hdrlen)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) /* Drop packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) ieee80211_free_txskb(dev, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) static int adm8211_alloc_rings(struct ieee80211_hw *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) struct adm8211_priv *priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) unsigned int ring_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) priv->rx_buffers = kmalloc(sizeof(*priv->rx_buffers) * priv->rx_ring_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) sizeof(*priv->tx_buffers) * priv->tx_ring_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) if (!priv->rx_buffers)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) priv->tx_buffers = (void *)priv->rx_buffers +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) sizeof(*priv->rx_buffers) * priv->rx_ring_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) /* Allocate TX/RX descriptors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) ring_size = sizeof(struct adm8211_desc) * priv->rx_ring_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) sizeof(struct adm8211_desc) * priv->tx_ring_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) priv->rx_ring = dma_alloc_coherent(&priv->pdev->dev, ring_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) &priv->rx_ring_dma, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) if (!priv->rx_ring) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) kfree(priv->rx_buffers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) priv->rx_buffers = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) priv->tx_buffers = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) priv->tx_ring = priv->rx_ring + priv->rx_ring_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) priv->tx_ring_dma = priv->rx_ring_dma +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) sizeof(struct adm8211_desc) * priv->rx_ring_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) static const struct ieee80211_ops adm8211_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) .tx = adm8211_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) .start = adm8211_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) .stop = adm8211_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) .add_interface = adm8211_add_interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) .remove_interface = adm8211_remove_interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) .config = adm8211_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) .bss_info_changed = adm8211_bss_info_changed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) .prepare_multicast = adm8211_prepare_multicast,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) .configure_filter = adm8211_configure_filter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) .get_stats = adm8211_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) .get_tsf = adm8211_get_tsft
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) static int adm8211_probe(struct pci_dev *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) const struct pci_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) struct ieee80211_hw *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) struct adm8211_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) unsigned long mem_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) unsigned int io_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) u8 perm_addr[ETH_ALEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) err = pci_enable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) printk(KERN_ERR "%s (adm8211): Cannot enable new PCI device\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) pci_name(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) io_len = pci_resource_len(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) mem_len = pci_resource_len(pdev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) if (io_len < 256 || mem_len < 1024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) printk(KERN_ERR "%s (adm8211): Too short PCI resources\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) pci_name(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) goto err_disable_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) /* check signature */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) pci_read_config_dword(pdev, 0x80 /* CR32 */, ®);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) if (reg != ADM8211_SIG1 && reg != ADM8211_SIG2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) printk(KERN_ERR "%s (adm8211): Invalid signature (0x%x)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) pci_name(pdev), reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) goto err_disable_pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) err = pci_request_regions(pdev, "adm8211");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) printk(KERN_ERR "%s (adm8211): Cannot obtain PCI resources\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) pci_name(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) return err; /* someone else grabbed it? don't disable it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) printk(KERN_ERR "%s (adm8211): No suitable DMA available\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) pci_name(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) goto err_free_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) pci_set_master(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) dev = ieee80211_alloc_hw(sizeof(*priv), &adm8211_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) if (!dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) printk(KERN_ERR "%s (adm8211): ieee80211 alloc failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) pci_name(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) goto err_free_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) priv->pdev = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) spin_lock_init(&priv->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) SET_IEEE80211_DEV(dev, &pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) pci_set_drvdata(pdev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) priv->map = pci_iomap(pdev, 1, mem_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) if (!priv->map)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) priv->map = pci_iomap(pdev, 0, io_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) if (!priv->map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) printk(KERN_ERR "%s (adm8211): Cannot map device memory\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) pci_name(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) goto err_free_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) priv->rx_ring_size = rx_ring_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) priv->tx_ring_size = tx_ring_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) err = adm8211_alloc_rings(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) printk(KERN_ERR "%s (adm8211): Cannot allocate TX/RX ring\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) pci_name(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) goto err_iounmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) *(__le32 *)perm_addr = cpu_to_le32(ADM8211_CSR_READ(PAR0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) *(__le16 *)&perm_addr[4] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) cpu_to_le16(ADM8211_CSR_READ(PAR1) & 0xFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) if (!is_valid_ether_addr(perm_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) printk(KERN_WARNING "%s (adm8211): Invalid hwaddr in EEPROM!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) pci_name(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) eth_random_addr(perm_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) SET_IEEE80211_PERM_ADDR(dev, perm_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) /* dev->flags = RX_INCLUDES_FCS in promisc mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) ieee80211_hw_set(dev, SIGNAL_UNSPEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) dev->max_signal = 100; /* FIXME: find better value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) dev->queues = 1; /* ADM8211C supports more, maybe ADM8211B too */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) priv->retry_limit = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) priv->ant_power = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) priv->tx_power = 0x40;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) priv->lpf_cutoff = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) priv->lnags_threshold = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) priv->mode = NL80211_IFTYPE_UNSPECIFIED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) /* Power-on issue. EEPROM won't read correctly without */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) if (pdev->revision >= ADM8211_REV_BA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) ADM8211_CSR_WRITE(FRCTL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) ADM8211_CSR_READ(FRCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) ADM8211_CSR_WRITE(FRCTL, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) ADM8211_CSR_READ(FRCTL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) err = adm8211_read_eeprom(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) printk(KERN_ERR "%s (adm8211): Can't alloc eeprom buffer\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) pci_name(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) goto err_free_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) priv->channel = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) dev->wiphy->bands[NL80211_BAND_2GHZ] = &priv->band;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) wiphy_ext_feature_set(dev->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) err = ieee80211_register_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) printk(KERN_ERR "%s (adm8211): Cannot register device\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) pci_name(pdev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) goto err_free_eeprom;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) wiphy_info(dev->wiphy, "hwaddr %pM, Rev 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) dev->wiphy->perm_addr, pdev->revision);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) err_free_eeprom:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) kfree(priv->eeprom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) err_free_desc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) dma_free_coherent(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) sizeof(struct adm8211_desc) * priv->rx_ring_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) sizeof(struct adm8211_desc) * priv->tx_ring_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) priv->rx_ring, priv->rx_ring_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) kfree(priv->rx_buffers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) err_iounmap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) pci_iounmap(pdev, priv->map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) err_free_dev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) ieee80211_free_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) err_free_reg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) pci_release_regions(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) err_disable_pdev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) static void adm8211_remove(struct pci_dev *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) struct ieee80211_hw *dev = pci_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) struct adm8211_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) ieee80211_unregister_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) priv = dev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) dma_free_coherent(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) sizeof(struct adm8211_desc) * priv->rx_ring_size +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) sizeof(struct adm8211_desc) * priv->tx_ring_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) priv->rx_ring, priv->rx_ring_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) kfree(priv->rx_buffers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) kfree(priv->eeprom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) pci_iounmap(pdev, priv->map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) pci_release_regions(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) pci_disable_device(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) ieee80211_free_hw(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) #define adm8211_suspend NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) #define adm8211_resume NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) MODULE_DEVICE_TABLE(pci, adm8211_pci_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) static SIMPLE_DEV_PM_OPS(adm8211_pm_ops, adm8211_suspend, adm8211_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) /* TODO: implement enable_wake */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) static struct pci_driver adm8211_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) .name = "adm8211",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) .id_table = adm8211_pci_id_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) .probe = adm8211_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) .remove = adm8211_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) .driver.pm = &adm8211_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) module_pci_driver(adm8211_driver);