Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Add rtl8180 wireless driver

This patch adds a mac80211 based wireless driver for the rtl8180 and
rtl8185 PCI wireless cards. Also included are some rtl8187 changes
required due to the relationship between that driver and this one.

Michael Wu is primarily responsible for the initial driver and rtl8185
support. Andreas Merello provided the additional rtl8180 support.

Thanks to Jukka Ruohonen for the donating a rtl8185 card! It was very
helpful for the rtl8225z2 code.

The Signed-off-by information below is collected from the individual
patches submitted to wireless-2.6 before merging this driver upstream.

Signed-off-by: Andrea Merello <andreamrl@tiscali.it>
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Pavel Roskin <proski@gnu.org>
Signed-off-by: Michael Wu <flamingice@sourmilk.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by

Michael Wu and committed by
David S. Miller
f6532111 fa1c114f

+2777 -60
+56
drivers/net/wireless/Kconfig
··· 545 545 To compile this driver as a module, choose M here: the 546 546 module will be called zd1201. 547 547 548 + config RTL8180 549 + tristate "Realtek 8180/8185 PCI support" 550 + depends on MAC80211 && PCI && WLAN_80211 && EXPERIMENTAL 551 + select EEPROM_93CX6 552 + ---help--- 553 + This is a driver for RTL8180 and RTL8185 based cards. 554 + These are PCI based chips found in cards such as: 555 + 556 + (RTL8185 802.11g) 557 + A-Link WL54PC 558 + 559 + (RTL8180 802.11b) 560 + Belkin F5D6020 v3 561 + Belkin F5D6020 v3 562 + Dlink DWL-610 563 + Dlink DWL-510 564 + Netgear MA521 565 + Level-One WPC-0101 566 + Acer Aspire 1357 LMi 567 + VCTnet PC-11B1 568 + Ovislink AirLive WL-1120PCM 569 + Mentor WL-PCI 570 + Linksys WPC11 v4 571 + TrendNET TEW-288PI 572 + D-Link DWL-520 Rev D 573 + Repotec RP-WP7126 574 + TP-Link TL-WN250/251 575 + Zonet ZEW1000 576 + Longshine LCS-8031-R 577 + HomeLine HLW-PCC200 578 + GigaFast WF721-AEX 579 + Planet WL-3553 580 + Encore ENLWI-PCI1-NT 581 + TrendNET TEW-266PC 582 + Gigabyte GN-WLMR101 583 + Siemens-fujitsu Amilo D1840W 584 + Edimax EW-7126 585 + PheeNet WL-11PCIR 586 + Tonze PC-2100T 587 + Planet WL-8303 588 + Dlink DWL-650 v M1 589 + Edimax EW-7106 590 + Q-Tec 770WC 591 + Topcom Skyr@cer 4011b 592 + Roper FreeLan 802.11b (edition 2004) 593 + Wistron Neweb Corp CB-200B 594 + Pentagram HorNET 595 + QTec 775WC 596 + TwinMOS Booming B Series 597 + Micronet SP906BB 598 + Sweex LC700010 599 + Surecom EP-9428 600 + Safecom SWLCR-1100 601 + 602 + Thanks to Realtek for their support! 603 + 548 604 config RTL8187 549 605 tristate "Realtek 8187 USB support" 550 606 depends on MAC80211 && USB && WLAN_80211 && EXPERIMENTAL
+3
drivers/net/wireless/Makefile
··· 47 47 obj-$(CONFIG_USB_ZD1201) += zd1201.o 48 48 obj-$(CONFIG_LIBERTAS) += libertas/ 49 49 50 + rtl8180-objs := rtl8180_dev.o rtl8180_rtl8225.o rtl8180_sa2400.o rtl8180_max2820.o rtl8180_grf5101.o 50 51 rtl8187-objs := rtl8187_dev.o rtl8187_rtl8225.o 52 + 53 + obj-$(CONFIG_RTL8180) += rtl8180.o 51 54 obj-$(CONFIG_RTL8187) += rtl8187.o 52 55 53 56 obj-$(CONFIG_ADM8211) += adm8211.o
+151
drivers/net/wireless/rtl8180.h
··· 1 + #ifndef RTL8180_H 2 + #define RTL8180_H 3 + 4 + #include "rtl818x.h" 5 + 6 + #define MAX_RX_SIZE IEEE80211_MAX_RTS_THRESHOLD 7 + 8 + #define RF_PARAM_ANALOGPHY (1 << 0) 9 + #define RF_PARAM_ANTBDEFAULT (1 << 1) 10 + #define RF_PARAM_CARRIERSENSE1 (1 << 2) 11 + #define RF_PARAM_CARRIERSENSE2 (1 << 3) 12 + 13 + #define BB_ANTATTEN_CHAN14 0x0C 14 + #define BB_ANTENNA_B 0x40 15 + 16 + #define BB_HOST_BANG (1 << 30) 17 + #define BB_HOST_BANG_EN (1 << 2) 18 + #define BB_HOST_BANG_CLK (1 << 1) 19 + #define BB_HOST_BANG_DATA 1 20 + 21 + #define ANAPARAM_TXDACOFF_SHIFT 27 22 + #define ANAPARAM_PWR0_SHIFT 28 23 + #define ANAPARAM_PWR0_MASK (0x07 << ANAPARAM_PWR0_SHIFT) 24 + #define ANAPARAM_PWR1_SHIFT 20 25 + #define ANAPARAM_PWR1_MASK (0x7F << ANAPARAM_PWR1_SHIFT) 26 + 27 + enum rtl8180_tx_desc_flags { 28 + RTL8180_TX_DESC_FLAG_NO_ENC = (1 << 15), 29 + RTL8180_TX_DESC_FLAG_TX_OK = (1 << 15), 30 + RTL8180_TX_DESC_FLAG_SPLCP = (1 << 16), 31 + RTL8180_TX_DESC_FLAG_RX_UNDER = (1 << 16), 32 + RTL8180_TX_DESC_FLAG_MOREFRAG = (1 << 17), 33 + RTL8180_TX_DESC_FLAG_CTS = (1 << 18), 34 + RTL8180_TX_DESC_FLAG_RTS = (1 << 23), 35 + RTL8180_TX_DESC_FLAG_LS = (1 << 28), 36 + RTL8180_TX_DESC_FLAG_FS = (1 << 29), 37 + RTL8180_TX_DESC_FLAG_DMA = (1 << 30), 38 + RTL8180_TX_DESC_FLAG_OWN = (1 << 31) 39 + }; 40 + 41 + struct rtl8180_tx_desc { 42 + __le32 flags; 43 + __le16 rts_duration; 44 + __le16 plcp_len; 45 + __le32 tx_buf; 46 + __le32 frame_len; 47 + __le32 next_tx_desc; 48 + u8 cw; 49 + u8 retry_limit; 50 + u8 agc; 51 + u8 flags2; 52 + u32 reserved[2]; 53 + } __attribute__ ((packed)); 54 + 55 + enum rtl8180_rx_desc_flags { 56 + RTL8180_RX_DESC_FLAG_ICV_ERR = (1 << 12), 57 + RTL8180_RX_DESC_FLAG_CRC32_ERR = (1 << 13), 58 + RTL8180_RX_DESC_FLAG_PM = (1 << 14), 59 + RTL8180_RX_DESC_FLAG_RX_ERR = (1 << 15), 60 + RTL8180_RX_DESC_FLAG_BCAST = (1 << 16), 61 + RTL8180_RX_DESC_FLAG_PAM = (1 << 17), 62 + RTL8180_RX_DESC_FLAG_MCAST = (1 << 18), 63 + RTL8180_RX_DESC_FLAG_SPLCP = (1 << 25), 64 + RTL8180_RX_DESC_FLAG_FOF = (1 << 26), 65 + RTL8180_RX_DESC_FLAG_DMA_FAIL = (1 << 27), 66 + RTL8180_RX_DESC_FLAG_LS = (1 << 28), 67 + RTL8180_RX_DESC_FLAG_FS = (1 << 29), 68 + RTL8180_RX_DESC_FLAG_EOR = (1 << 30), 69 + RTL8180_RX_DESC_FLAG_OWN = (1 << 31) 70 + }; 71 + 72 + struct rtl8180_rx_desc { 73 + __le32 flags; 74 + __le32 flags2; 75 + union { 76 + __le32 rx_buf; 77 + __le64 tsft; 78 + }; 79 + } __attribute__ ((packed)); 80 + 81 + struct rtl8180_tx_ring { 82 + struct rtl8180_tx_desc *desc; 83 + dma_addr_t dma; 84 + unsigned int idx; 85 + unsigned int entries; 86 + struct sk_buff_head queue; 87 + }; 88 + 89 + struct rtl8180_priv { 90 + /* common between rtl818x drivers */ 91 + struct rtl818x_csr __iomem *map; 92 + const struct rtl818x_rf_ops *rf; 93 + int mode; 94 + int if_id; 95 + 96 + /* rtl8180 driver specific */ 97 + spinlock_t lock; 98 + struct rtl8180_rx_desc *rx_ring; 99 + dma_addr_t rx_ring_dma; 100 + unsigned int rx_idx; 101 + struct sk_buff *rx_buf[32]; 102 + struct rtl8180_tx_ring tx_ring[4]; 103 + struct ieee80211_channel channels[14]; 104 + struct ieee80211_rate rates[12]; 105 + struct ieee80211_hw_mode modes[2]; 106 + struct pci_dev *pdev; 107 + u32 rx_conf; 108 + 109 + int r8185; 110 + u32 anaparam; 111 + u16 rfparam; 112 + u8 csthreshold; 113 + }; 114 + 115 + void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data); 116 + void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam); 117 + 118 + static inline u8 rtl818x_ioread8(struct rtl8180_priv *priv, u8 __iomem *addr) 119 + { 120 + return ioread8(addr); 121 + } 122 + 123 + static inline u16 rtl818x_ioread16(struct rtl8180_priv *priv, __le16 __iomem *addr) 124 + { 125 + return ioread16(addr); 126 + } 127 + 128 + static inline u32 rtl818x_ioread32(struct rtl8180_priv *priv, __le32 __iomem *addr) 129 + { 130 + return ioread32(addr); 131 + } 132 + 133 + static inline void rtl818x_iowrite8(struct rtl8180_priv *priv, 134 + u8 __iomem *addr, u8 val) 135 + { 136 + iowrite8(val, addr); 137 + } 138 + 139 + static inline void rtl818x_iowrite16(struct rtl8180_priv *priv, 140 + __le16 __iomem *addr, u16 val) 141 + { 142 + iowrite16(val, addr); 143 + } 144 + 145 + static inline void rtl818x_iowrite32(struct rtl8180_priv *priv, 146 + __le32 __iomem *addr, u32 val) 147 + { 148 + iowrite32(val, addr); 149 + } 150 + 151 + #endif /* RTL8180_H */
+1048
drivers/net/wireless/rtl8180_dev.c
··· 1 + 2 + /* 3 + * Linux device driver for RTL8180 / RTL8185 4 + * 5 + * Copyright 2007 Michael Wu <flamingice@sourmilk.net> 6 + * Copyright 2007 Andrea Merello <andreamrl@tiscali.it> 7 + * 8 + * Based on the r8180 driver, which is: 9 + * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al. 10 + * 11 + * Thanks to Realtek for their support! 12 + * 13 + * This program is free software; you can redistribute it and/or modify 14 + * it under the terms of the GNU General Public License version 2 as 15 + * published by the Free Software Foundation. 16 + */ 17 + 18 + #include <linux/init.h> 19 + #include <linux/pci.h> 20 + #include <linux/delay.h> 21 + #include <linux/etherdevice.h> 22 + #include <linux/eeprom_93cx6.h> 23 + #include <net/mac80211.h> 24 + 25 + #include "rtl8180.h" 26 + #include "rtl8180_rtl8225.h" 27 + #include "rtl8180_sa2400.h" 28 + #include "rtl8180_max2820.h" 29 + #include "rtl8180_grf5101.h" 30 + 31 + MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>"); 32 + MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>"); 33 + MODULE_DESCRIPTION("RTL8180 / RTL8185 PCI wireless driver"); 34 + MODULE_LICENSE("GPL"); 35 + 36 + static struct pci_device_id rtl8180_table[] __devinitdata = { 37 + /* rtl8185 */ 38 + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8185) }, 39 + { PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x701f) }, 40 + 41 + /* rtl8180 */ 42 + { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8180) }, 43 + { PCI_DEVICE(0x1799, 0x6001) }, 44 + { PCI_DEVICE(0x1799, 0x6020) }, 45 + { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x3300) }, 46 + { } 47 + }; 48 + 49 + MODULE_DEVICE_TABLE(pci, rtl8180_table); 50 + 51 + void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) 52 + { 53 + struct rtl8180_priv *priv = dev->priv; 54 + int i = 10; 55 + u32 buf; 56 + 57 + buf = (data << 8) | addr; 58 + 59 + rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->PHY[0], buf | 0x80); 60 + while (i--) { 61 + rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->PHY[0], buf); 62 + if (rtl818x_ioread8(priv, &priv->map->PHY[2]) == (data & 0xFF)) 63 + return; 64 + } 65 + } 66 + 67 + static void rtl8180_handle_rx(struct ieee80211_hw *dev) 68 + { 69 + struct rtl8180_priv *priv = dev->priv; 70 + unsigned int count = 32; 71 + 72 + while (count--) { 73 + struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx]; 74 + struct sk_buff *skb = priv->rx_buf[priv->rx_idx]; 75 + u32 flags = le32_to_cpu(entry->flags); 76 + 77 + if (flags & RTL8180_RX_DESC_FLAG_OWN) 78 + return; 79 + 80 + if (unlikely(flags & (RTL8180_RX_DESC_FLAG_DMA_FAIL | 81 + RTL8180_RX_DESC_FLAG_FOF | 82 + RTL8180_RX_DESC_FLAG_RX_ERR))) 83 + goto done; 84 + else { 85 + u32 flags2 = le32_to_cpu(entry->flags2); 86 + struct ieee80211_rx_status rx_status = {0}; 87 + struct sk_buff *new_skb = dev_alloc_skb(MAX_RX_SIZE); 88 + 89 + if (unlikely(!new_skb)) 90 + goto done; 91 + 92 + pci_unmap_single(priv->pdev, 93 + *((dma_addr_t *)skb->cb), 94 + MAX_RX_SIZE, PCI_DMA_FROMDEVICE); 95 + skb_put(skb, flags & 0xFFF); 96 + 97 + rx_status.antenna = (flags2 >> 15) & 1; 98 + /* TODO: improve signal/rssi reporting */ 99 + rx_status.signal = flags2 & 0xFF; 100 + rx_status.ssi = (flags2 >> 8) & 0x7F; 101 + rx_status.rate = (flags >> 20) & 0xF; 102 + rx_status.freq = dev->conf.freq; 103 + rx_status.channel = dev->conf.channel; 104 + rx_status.phymode = dev->conf.phymode; 105 + rx_status.mactime = le64_to_cpu(entry->tsft); 106 + rx_status.flag |= RX_FLAG_TSFT; 107 + if (flags & RTL8180_RX_DESC_FLAG_CRC32_ERR) 108 + rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; 109 + 110 + ieee80211_rx_irqsafe(dev, skb, &rx_status); 111 + 112 + skb = new_skb; 113 + priv->rx_buf[priv->rx_idx] = skb; 114 + *((dma_addr_t *) skb->cb) = 115 + pci_map_single(priv->pdev, skb_tail_pointer(skb), 116 + MAX_RX_SIZE, PCI_DMA_FROMDEVICE); 117 + } 118 + 119 + done: 120 + entry->rx_buf = cpu_to_le32(*((dma_addr_t *)skb->cb)); 121 + entry->flags = cpu_to_le32(RTL8180_RX_DESC_FLAG_OWN | 122 + MAX_RX_SIZE); 123 + if (priv->rx_idx == 31) 124 + entry->flags |= cpu_to_le32(RTL8180_RX_DESC_FLAG_EOR); 125 + priv->rx_idx = (priv->rx_idx + 1) % 32; 126 + } 127 + } 128 + 129 + static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio) 130 + { 131 + struct rtl8180_priv *priv = dev->priv; 132 + struct rtl8180_tx_ring *ring = &priv->tx_ring[prio]; 133 + 134 + while (skb_queue_len(&ring->queue)) { 135 + struct rtl8180_tx_desc *entry = &ring->desc[ring->idx]; 136 + struct sk_buff *skb; 137 + struct ieee80211_tx_status status = { {0} }; 138 + struct ieee80211_tx_control *control; 139 + u32 flags = le32_to_cpu(entry->flags); 140 + 141 + if (flags & RTL8180_TX_DESC_FLAG_OWN) 142 + return; 143 + 144 + ring->idx = (ring->idx + 1) % ring->entries; 145 + skb = __skb_dequeue(&ring->queue); 146 + pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf), 147 + skb->len, PCI_DMA_TODEVICE); 148 + 149 + control = *((struct ieee80211_tx_control **)skb->cb); 150 + if (control) 151 + memcpy(&status.control, control, sizeof(*control)); 152 + kfree(control); 153 + 154 + if (!(status.control.flags & IEEE80211_TXCTL_NO_ACK)) { 155 + if (flags & RTL8180_TX_DESC_FLAG_TX_OK) 156 + status.flags = IEEE80211_TX_STATUS_ACK; 157 + else 158 + status.excessive_retries = 1; 159 + } 160 + status.retry_count = flags & 0xFF; 161 + 162 + ieee80211_tx_status_irqsafe(dev, skb, &status); 163 + if (ring->entries - skb_queue_len(&ring->queue) == 2) 164 + ieee80211_wake_queue(dev, prio); 165 + } 166 + } 167 + 168 + static irqreturn_t rtl8180_interrupt(int irq, void *dev_id) 169 + { 170 + struct ieee80211_hw *dev = dev_id; 171 + struct rtl8180_priv *priv = dev->priv; 172 + u16 reg; 173 + 174 + spin_lock(&priv->lock); 175 + reg = rtl818x_ioread16(priv, &priv->map->INT_STATUS); 176 + if (unlikely(reg == 0xFFFF)) { 177 + spin_unlock(&priv->lock); 178 + return IRQ_HANDLED; 179 + } 180 + 181 + rtl818x_iowrite16(priv, &priv->map->INT_STATUS, reg); 182 + 183 + if (reg & (RTL818X_INT_TXB_OK | RTL818X_INT_TXB_ERR)) 184 + rtl8180_handle_tx(dev, 3); 185 + 186 + if (reg & (RTL818X_INT_TXH_OK | RTL818X_INT_TXH_ERR)) 187 + rtl8180_handle_tx(dev, 2); 188 + 189 + if (reg & (RTL818X_INT_TXN_OK | RTL818X_INT_TXN_ERR)) 190 + rtl8180_handle_tx(dev, 1); 191 + 192 + if (reg & (RTL818X_INT_TXL_OK | RTL818X_INT_TXL_ERR)) 193 + rtl8180_handle_tx(dev, 0); 194 + 195 + if (reg & (RTL818X_INT_RX_OK | RTL818X_INT_RX_ERR)) 196 + rtl8180_handle_rx(dev); 197 + 198 + spin_unlock(&priv->lock); 199 + 200 + return IRQ_HANDLED; 201 + } 202 + 203 + static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb, 204 + struct ieee80211_tx_control *control) 205 + { 206 + struct rtl8180_priv *priv = dev->priv; 207 + struct rtl8180_tx_ring *ring; 208 + struct rtl8180_tx_desc *entry; 209 + unsigned long flags; 210 + unsigned int idx, prio; 211 + dma_addr_t mapping; 212 + u32 tx_flags; 213 + u16 plcp_len = 0; 214 + __le16 rts_duration = 0; 215 + 216 + prio = control->queue; 217 + ring = &priv->tx_ring[prio]; 218 + 219 + mapping = pci_map_single(priv->pdev, skb->data, 220 + skb->len, PCI_DMA_TODEVICE); 221 + 222 + tx_flags = RTL8180_TX_DESC_FLAG_OWN | RTL8180_TX_DESC_FLAG_FS | 223 + RTL8180_TX_DESC_FLAG_LS | (control->tx_rate << 24) | 224 + (control->rts_cts_rate << 19) | skb->len; 225 + 226 + if (priv->r8185) 227 + tx_flags |= RTL8180_TX_DESC_FLAG_DMA | 228 + RTL8180_TX_DESC_FLAG_NO_ENC; 229 + 230 + if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) 231 + tx_flags |= RTL8180_TX_DESC_FLAG_RTS; 232 + else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) 233 + tx_flags |= RTL8180_TX_DESC_FLAG_CTS; 234 + 235 + *((struct ieee80211_tx_control **) skb->cb) = 236 + kmemdup(control, sizeof(*control), GFP_ATOMIC); 237 + 238 + if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) 239 + rts_duration = ieee80211_rts_duration(dev, priv->if_id, skb->len, control); 240 + 241 + if (!priv->r8185) { 242 + unsigned int remainder; 243 + 244 + plcp_len = DIV_ROUND_UP(16 * (skb->len + 4), 245 + (control->rate->rate * 2) / 10); 246 + remainder = (16 * (skb->len + 4)) % 247 + ((control->rate->rate * 2) / 10); 248 + if (remainder > 0 && remainder <= 6) 249 + plcp_len |= 1 << 15; 250 + } 251 + 252 + spin_lock_irqsave(&priv->lock, flags); 253 + idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries; 254 + entry = &ring->desc[idx]; 255 + 256 + entry->rts_duration = rts_duration; 257 + entry->plcp_len = cpu_to_le16(plcp_len); 258 + entry->tx_buf = cpu_to_le32(mapping); 259 + entry->frame_len = cpu_to_le32(skb->len); 260 + entry->flags2 = control->alt_retry_rate != -1 ? 261 + control->alt_retry_rate << 4 : 0; 262 + entry->retry_limit = control->retry_limit; 263 + entry->flags = cpu_to_le32(tx_flags); 264 + __skb_queue_tail(&ring->queue, skb); 265 + if (ring->entries - skb_queue_len(&ring->queue) < 2) 266 + ieee80211_stop_queue(dev, control->queue); 267 + spin_unlock_irqrestore(&priv->lock, flags); 268 + 269 + rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << (prio + 4))); 270 + 271 + return 0; 272 + } 273 + 274 + void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam) 275 + { 276 + u8 reg; 277 + 278 + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 279 + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); 280 + rtl818x_iowrite8(priv, &priv->map->CONFIG3, 281 + reg | RTL818X_CONFIG3_ANAPARAM_WRITE); 282 + rtl818x_iowrite32(priv, &priv->map->ANAPARAM, anaparam); 283 + rtl818x_iowrite8(priv, &priv->map->CONFIG3, 284 + reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); 285 + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 286 + } 287 + 288 + static int rtl8180_init_hw(struct ieee80211_hw *dev) 289 + { 290 + struct rtl8180_priv *priv = dev->priv; 291 + u16 reg; 292 + 293 + rtl818x_iowrite8(priv, &priv->map->CMD, 0); 294 + rtl818x_ioread8(priv, &priv->map->CMD); 295 + msleep(10); 296 + 297 + /* reset */ 298 + rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); 299 + rtl818x_ioread8(priv, &priv->map->CMD); 300 + 301 + reg = rtl818x_ioread8(priv, &priv->map->CMD); 302 + reg &= (1 << 1); 303 + reg |= RTL818X_CMD_RESET; 304 + rtl818x_iowrite8(priv, &priv->map->CMD, RTL818X_CMD_RESET); 305 + rtl818x_ioread8(priv, &priv->map->CMD); 306 + msleep(200); 307 + 308 + /* check success of reset */ 309 + if (rtl818x_ioread8(priv, &priv->map->CMD) & RTL818X_CMD_RESET) { 310 + printk(KERN_ERR "%s: reset timeout!\n", wiphy_name(dev->wiphy)); 311 + return -ETIMEDOUT; 312 + } 313 + 314 + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_LOAD); 315 + rtl818x_ioread8(priv, &priv->map->CMD); 316 + msleep(200); 317 + 318 + if (rtl818x_ioread8(priv, &priv->map->CONFIG3) & (1 << 3)) { 319 + /* For cardbus */ 320 + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); 321 + reg |= 1 << 1; 322 + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg); 323 + reg = rtl818x_ioread16(priv, &priv->map->FEMR); 324 + reg |= (1 << 15) | (1 << 14) | (1 << 4); 325 + rtl818x_iowrite16(priv, &priv->map->FEMR, reg); 326 + } 327 + 328 + rtl818x_iowrite8(priv, &priv->map->MSR, 0); 329 + 330 + if (!priv->r8185) 331 + rtl8180_set_anaparam(priv, priv->anaparam); 332 + 333 + rtl818x_iowrite32(priv, &priv->map->RDSAR, priv->rx_ring_dma); 334 + rtl818x_iowrite32(priv, &priv->map->TBDA, priv->tx_ring[3].dma); 335 + rtl818x_iowrite32(priv, &priv->map->THPDA, priv->tx_ring[2].dma); 336 + rtl818x_iowrite32(priv, &priv->map->TNPDA, priv->tx_ring[1].dma); 337 + rtl818x_iowrite32(priv, &priv->map->TLPDA, priv->tx_ring[0].dma); 338 + 339 + /* TODO: necessary? specs indicate not */ 340 + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 341 + reg = rtl818x_ioread8(priv, &priv->map->CONFIG2); 342 + rtl818x_iowrite8(priv, &priv->map->CONFIG2, reg & ~(1 << 3)); 343 + if (priv->r8185) { 344 + reg = rtl818x_ioread8(priv, &priv->map->CONFIG2); 345 + rtl818x_iowrite8(priv, &priv->map->CONFIG2, reg | (1 << 4)); 346 + } 347 + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 348 + 349 + /* TODO: set CONFIG5 for calibrating AGC on rtl8180 + philips radio? */ 350 + 351 + /* TODO: turn off hw wep on rtl8180 */ 352 + 353 + rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0); 354 + 355 + if (priv->r8185) { 356 + rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0); 357 + rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0x81); 358 + rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (8 << 4) | 0); 359 + 360 + rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3); 361 + 362 + /* TODO: set ClkRun enable? necessary? */ 363 + reg = rtl818x_ioread8(priv, &priv->map->GP_ENABLE); 364 + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, reg & ~(1 << 6)); 365 + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 366 + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); 367 + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | (1 << 2)); 368 + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 369 + } else { 370 + rtl818x_iowrite16(priv, &priv->map->BRSR, 0x1); 371 + rtl818x_iowrite8(priv, &priv->map->SECURITY, 0); 372 + 373 + rtl818x_iowrite8(priv, &priv->map->PHY_DELAY, 0x6); 374 + rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER, 0x4C); 375 + } 376 + 377 + priv->rf->init(dev); 378 + if (priv->r8185) 379 + rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3); 380 + return 0; 381 + } 382 + 383 + static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) 384 + { 385 + struct rtl8180_priv *priv = dev->priv; 386 + struct rtl8180_rx_desc *entry; 387 + int i; 388 + 389 + priv->rx_ring = pci_alloc_consistent(priv->pdev, 390 + sizeof(*priv->rx_ring) * 32, 391 + &priv->rx_ring_dma); 392 + 393 + if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) { 394 + printk(KERN_ERR "%s: Cannot allocate RX ring\n", 395 + wiphy_name(dev->wiphy)); 396 + return -ENOMEM; 397 + } 398 + 399 + memset(priv->rx_ring, 0, sizeof(*priv->rx_ring) * 32); 400 + priv->rx_idx = 0; 401 + 402 + for (i = 0; i < 32; i++) { 403 + struct sk_buff *skb = dev_alloc_skb(MAX_RX_SIZE); 404 + dma_addr_t *mapping; 405 + entry = &priv->rx_ring[i]; 406 + if (!skb) 407 + return 0; 408 + 409 + priv->rx_buf[i] = skb; 410 + mapping = (dma_addr_t *)skb->cb; 411 + *mapping = pci_map_single(priv->pdev, skb_tail_pointer(skb), 412 + MAX_RX_SIZE, PCI_DMA_FROMDEVICE); 413 + entry->rx_buf = cpu_to_le32(*mapping); 414 + entry->flags = cpu_to_le32(RTL8180_RX_DESC_FLAG_OWN | 415 + MAX_RX_SIZE); 416 + } 417 + entry->flags |= cpu_to_le32(RTL8180_RX_DESC_FLAG_EOR); 418 + return 0; 419 + } 420 + 421 + static void rtl8180_free_rx_ring(struct ieee80211_hw *dev) 422 + { 423 + struct rtl8180_priv *priv = dev->priv; 424 + int i; 425 + 426 + for (i = 0; i < 32; i++) { 427 + struct sk_buff *skb = priv->rx_buf[i]; 428 + if (!skb) 429 + continue; 430 + 431 + pci_unmap_single(priv->pdev, 432 + *((dma_addr_t *)skb->cb), 433 + MAX_RX_SIZE, PCI_DMA_FROMDEVICE); 434 + kfree_skb(skb); 435 + } 436 + 437 + pci_free_consistent(priv->pdev, sizeof(*priv->rx_ring) * 32, 438 + priv->rx_ring, priv->rx_ring_dma); 439 + priv->rx_ring = NULL; 440 + } 441 + 442 + static int rtl8180_init_tx_ring(struct ieee80211_hw *dev, 443 + unsigned int prio, unsigned int entries) 444 + { 445 + struct rtl8180_priv *priv = dev->priv; 446 + struct rtl8180_tx_desc *ring; 447 + dma_addr_t dma; 448 + int i; 449 + 450 + ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma); 451 + if (!ring || (unsigned long)ring & 0xFF) { 452 + printk(KERN_ERR "%s: Cannot allocate TX ring (prio = %d)\n", 453 + wiphy_name(dev->wiphy), prio); 454 + return -ENOMEM; 455 + } 456 + 457 + memset(ring, 0, sizeof(*ring)*entries); 458 + priv->tx_ring[prio].desc = ring; 459 + priv->tx_ring[prio].dma = dma; 460 + priv->tx_ring[prio].idx = 0; 461 + priv->tx_ring[prio].entries = entries; 462 + skb_queue_head_init(&priv->tx_ring[prio].queue); 463 + 464 + for (i = 0; i < entries; i++) 465 + ring[i].next_tx_desc = 466 + cpu_to_le32((u32)dma + ((i + 1) % entries) * sizeof(*ring)); 467 + 468 + return 0; 469 + } 470 + 471 + static void rtl8180_free_tx_ring(struct ieee80211_hw *dev, unsigned int prio) 472 + { 473 + struct rtl8180_priv *priv = dev->priv; 474 + struct rtl8180_tx_ring *ring = &priv->tx_ring[prio]; 475 + 476 + while (skb_queue_len(&ring->queue)) { 477 + struct rtl8180_tx_desc *entry = &ring->desc[ring->idx]; 478 + struct sk_buff *skb = __skb_dequeue(&ring->queue); 479 + 480 + pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf), 481 + skb->len, PCI_DMA_TODEVICE); 482 + kfree(*((struct ieee80211_tx_control **) skb->cb)); 483 + kfree_skb(skb); 484 + ring->idx = (ring->idx + 1) % ring->entries; 485 + } 486 + 487 + pci_free_consistent(priv->pdev, sizeof(*ring->desc)*ring->entries, 488 + ring->desc, ring->dma); 489 + ring->desc = NULL; 490 + } 491 + 492 + static int rtl8180_start(struct ieee80211_hw *dev) 493 + { 494 + struct rtl8180_priv *priv = dev->priv; 495 + int ret, i; 496 + u32 reg; 497 + 498 + ret = rtl8180_init_rx_ring(dev); 499 + if (ret) 500 + return ret; 501 + 502 + for (i = 0; i < 4; i++) 503 + if ((ret = rtl8180_init_tx_ring(dev, i, 16))) 504 + goto err_free_rings; 505 + 506 + ret = rtl8180_init_hw(dev); 507 + if (ret) 508 + goto err_free_rings; 509 + 510 + rtl818x_iowrite32(priv, &priv->map->RDSAR, priv->rx_ring_dma); 511 + rtl818x_iowrite32(priv, &priv->map->TBDA, priv->tx_ring[3].dma); 512 + rtl818x_iowrite32(priv, &priv->map->THPDA, priv->tx_ring[2].dma); 513 + rtl818x_iowrite32(priv, &priv->map->TNPDA, priv->tx_ring[1].dma); 514 + rtl818x_iowrite32(priv, &priv->map->TLPDA, priv->tx_ring[0].dma); 515 + 516 + ret = request_irq(priv->pdev->irq, &rtl8180_interrupt, 517 + IRQF_SHARED, KBUILD_MODNAME, dev); 518 + if (ret) { 519 + printk(KERN_ERR "%s: failed to register IRQ handler\n", 520 + wiphy_name(dev->wiphy)); 521 + goto err_free_rings; 522 + } 523 + 524 + rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF); 525 + 526 + rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0); 527 + rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0); 528 + 529 + reg = RTL818X_RX_CONF_ONLYERLPKT | 530 + RTL818X_RX_CONF_RX_AUTORESETPHY | 531 + RTL818X_RX_CONF_MGMT | 532 + RTL818X_RX_CONF_DATA | 533 + (7 << 8 /* MAX RX DMA */) | 534 + RTL818X_RX_CONF_BROADCAST | 535 + RTL818X_RX_CONF_NICMAC; 536 + 537 + if (priv->r8185) 538 + reg |= RTL818X_RX_CONF_CSDM1 | RTL818X_RX_CONF_CSDM2; 539 + else { 540 + reg |= (priv->rfparam & RF_PARAM_CARRIERSENSE1) 541 + ? RTL818X_RX_CONF_CSDM1 : 0; 542 + reg |= (priv->rfparam & RF_PARAM_CARRIERSENSE2) 543 + ? RTL818X_RX_CONF_CSDM2 : 0; 544 + } 545 + 546 + priv->rx_conf = reg; 547 + rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg); 548 + 549 + if (priv->r8185) { 550 + reg = rtl818x_ioread8(priv, &priv->map->CW_CONF); 551 + reg &= ~RTL818X_CW_CONF_PERPACKET_CW_SHIFT; 552 + reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT; 553 + rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg); 554 + 555 + reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL); 556 + reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT; 557 + reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT; 558 + reg |= RTL818X_TX_AGC_CTL_FEEDBACK_ANT; 559 + rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg); 560 + 561 + /* disable early TX */ 562 + rtl818x_iowrite8(priv, (u8 __iomem *)priv->map + 0xec, 0x3f); 563 + } 564 + 565 + reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); 566 + reg |= (6 << 21 /* MAX TX DMA */) | 567 + RTL818X_TX_CONF_NO_ICV; 568 + 569 + if (priv->r8185) 570 + reg &= ~RTL818X_TX_CONF_PROBE_DTS; 571 + else 572 + reg &= ~RTL818X_TX_CONF_HW_SEQNUM; 573 + 574 + /* different meaning, same value on both rtl8185 and rtl8180 */ 575 + reg &= ~RTL818X_TX_CONF_SAT_HWPLCP; 576 + 577 + rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg); 578 + 579 + reg = rtl818x_ioread8(priv, &priv->map->CMD); 580 + reg |= RTL818X_CMD_RX_ENABLE; 581 + reg |= RTL818X_CMD_TX_ENABLE; 582 + rtl818x_iowrite8(priv, &priv->map->CMD, reg); 583 + 584 + priv->mode = IEEE80211_IF_TYPE_MNTR; 585 + return 0; 586 + 587 + err_free_rings: 588 + rtl8180_free_rx_ring(dev); 589 + for (i = 0; i < 4; i++) 590 + if (priv->tx_ring[i].desc) 591 + rtl8180_free_tx_ring(dev, i); 592 + 593 + return ret; 594 + } 595 + 596 + static void rtl8180_stop(struct ieee80211_hw *dev) 597 + { 598 + struct rtl8180_priv *priv = dev->priv; 599 + u8 reg; 600 + int i; 601 + 602 + priv->mode = IEEE80211_IF_TYPE_INVALID; 603 + 604 + rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0); 605 + 606 + reg = rtl818x_ioread8(priv, &priv->map->CMD); 607 + reg &= ~RTL818X_CMD_TX_ENABLE; 608 + reg &= ~RTL818X_CMD_RX_ENABLE; 609 + rtl818x_iowrite8(priv, &priv->map->CMD, reg); 610 + 611 + priv->rf->stop(dev); 612 + 613 + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 614 + reg = rtl818x_ioread8(priv, &priv->map->CONFIG4); 615 + rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF); 616 + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 617 + 618 + free_irq(priv->pdev->irq, dev); 619 + 620 + rtl8180_free_rx_ring(dev); 621 + for (i = 0; i < 4; i++) 622 + rtl8180_free_tx_ring(dev, i); 623 + } 624 + 625 + static int rtl8180_add_interface(struct ieee80211_hw *dev, 626 + struct ieee80211_if_init_conf *conf) 627 + { 628 + struct rtl8180_priv *priv = dev->priv; 629 + 630 + if (priv->mode != IEEE80211_IF_TYPE_MNTR) 631 + return -EOPNOTSUPP; 632 + 633 + switch (conf->type) { 634 + case IEEE80211_IF_TYPE_STA: 635 + priv->mode = conf->type; 636 + break; 637 + default: 638 + return -EOPNOTSUPP; 639 + } 640 + 641 + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 642 + rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->MAC[0], 643 + cpu_to_le32(*(u32 *)conf->mac_addr)); 644 + rtl818x_iowrite16(priv, (__le16 __iomem *)&priv->map->MAC[4], 645 + cpu_to_le16(*(u16 *)(conf->mac_addr + 4))); 646 + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 647 + 648 + return 0; 649 + } 650 + 651 + static void rtl8180_remove_interface(struct ieee80211_hw *dev, 652 + struct ieee80211_if_init_conf *conf) 653 + { 654 + struct rtl8180_priv *priv = dev->priv; 655 + priv->mode = IEEE80211_IF_TYPE_MNTR; 656 + } 657 + 658 + static int rtl8180_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) 659 + { 660 + struct rtl8180_priv *priv = dev->priv; 661 + 662 + priv->rf->set_chan(dev, conf); 663 + 664 + return 0; 665 + } 666 + 667 + static int rtl8180_config_interface(struct ieee80211_hw *dev, int if_id, 668 + struct ieee80211_if_conf *conf) 669 + { 670 + struct rtl8180_priv *priv = dev->priv; 671 + int i; 672 + 673 + priv->if_id = if_id; 674 + 675 + for (i = 0; i < ETH_ALEN; i++) 676 + rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]); 677 + 678 + if (is_valid_ether_addr(conf->bssid)) 679 + rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_INFRA); 680 + else 681 + rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_NO_LINK); 682 + 683 + return 0; 684 + } 685 + 686 + static void rtl8180_configure_filter(struct ieee80211_hw *dev, 687 + unsigned int changed_flags, 688 + unsigned int *total_flags, 689 + int mc_count, struct dev_addr_list *mclist) 690 + { 691 + struct rtl8180_priv *priv = dev->priv; 692 + 693 + if (changed_flags & FIF_FCSFAIL) 694 + priv->rx_conf ^= RTL818X_RX_CONF_FCS; 695 + if (changed_flags & FIF_CONTROL) 696 + priv->rx_conf ^= RTL818X_RX_CONF_CTRL; 697 + if (changed_flags & FIF_OTHER_BSS) 698 + priv->rx_conf ^= RTL818X_RX_CONF_MONITOR; 699 + if (*total_flags & FIF_ALLMULTI || mc_count > 0) 700 + priv->rx_conf |= RTL818X_RX_CONF_MULTICAST; 701 + else 702 + priv->rx_conf &= ~RTL818X_RX_CONF_MULTICAST; 703 + 704 + *total_flags = 0; 705 + 706 + if (priv->rx_conf & RTL818X_RX_CONF_FCS) 707 + *total_flags |= FIF_FCSFAIL; 708 + if (priv->rx_conf & RTL818X_RX_CONF_CTRL) 709 + *total_flags |= FIF_CONTROL; 710 + if (priv->rx_conf & RTL818X_RX_CONF_MONITOR) 711 + *total_flags |= FIF_OTHER_BSS; 712 + if (priv->rx_conf & RTL818X_RX_CONF_MULTICAST) 713 + *total_flags |= FIF_ALLMULTI; 714 + 715 + rtl818x_iowrite32(priv, &priv->map->RX_CONF, priv->rx_conf); 716 + } 717 + 718 + static const struct ieee80211_ops rtl8180_ops = { 719 + .tx = rtl8180_tx, 720 + .start = rtl8180_start, 721 + .stop = rtl8180_stop, 722 + .add_interface = rtl8180_add_interface, 723 + .remove_interface = rtl8180_remove_interface, 724 + .config = rtl8180_config, 725 + .config_interface = rtl8180_config_interface, 726 + .configure_filter = rtl8180_configure_filter, 727 + }; 728 + 729 + static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom) 730 + { 731 + struct ieee80211_hw *dev = eeprom->data; 732 + struct rtl8180_priv *priv = dev->priv; 733 + u8 reg = rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 734 + 735 + eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE; 736 + eeprom->reg_data_out = reg & RTL818X_EEPROM_CMD_READ; 737 + eeprom->reg_data_clock = reg & RTL818X_EEPROM_CMD_CK; 738 + eeprom->reg_chip_select = reg & RTL818X_EEPROM_CMD_CS; 739 + } 740 + 741 + static void rtl8180_eeprom_register_write(struct eeprom_93cx6 *eeprom) 742 + { 743 + struct ieee80211_hw *dev = eeprom->data; 744 + struct rtl8180_priv *priv = dev->priv; 745 + u8 reg = 2 << 6; 746 + 747 + if (eeprom->reg_data_in) 748 + reg |= RTL818X_EEPROM_CMD_WRITE; 749 + if (eeprom->reg_data_out) 750 + reg |= RTL818X_EEPROM_CMD_READ; 751 + if (eeprom->reg_data_clock) 752 + reg |= RTL818X_EEPROM_CMD_CK; 753 + if (eeprom->reg_chip_select) 754 + reg |= RTL818X_EEPROM_CMD_CS; 755 + 756 + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, reg); 757 + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 758 + udelay(10); 759 + } 760 + 761 + static int __devinit rtl8180_probe(struct pci_dev *pdev, 762 + const struct pci_device_id *id) 763 + { 764 + struct ieee80211_hw *dev; 765 + struct rtl8180_priv *priv; 766 + unsigned long mem_addr, mem_len; 767 + unsigned int io_addr, io_len; 768 + int err, i; 769 + struct eeprom_93cx6 eeprom; 770 + const char *chip_name, *rf_name = NULL; 771 + u32 reg; 772 + u16 eeprom_val; 773 + DECLARE_MAC_BUF(mac); 774 + 775 + err = pci_enable_device(pdev); 776 + if (err) { 777 + printk(KERN_ERR "%s (rtl8180): Cannot enable new PCI device\n", 778 + pci_name(pdev)); 779 + return err; 780 + } 781 + 782 + err = pci_request_regions(pdev, KBUILD_MODNAME); 783 + if (err) { 784 + printk(KERN_ERR "%s (rtl8180): Cannot obtain PCI resources\n", 785 + pci_name(pdev)); 786 + return err; 787 + } 788 + 789 + io_addr = pci_resource_start(pdev, 0); 790 + io_len = pci_resource_len(pdev, 0); 791 + mem_addr = pci_resource_start(pdev, 1); 792 + mem_len = pci_resource_len(pdev, 1); 793 + 794 + if (mem_len < sizeof(struct rtl818x_csr) || 795 + io_len < sizeof(struct rtl818x_csr)) { 796 + printk(KERN_ERR "%s (rtl8180): Too short PCI resources\n", 797 + pci_name(pdev)); 798 + err = -ENOMEM; 799 + goto err_free_reg; 800 + } 801 + 802 + if ((err = pci_set_dma_mask(pdev, 0xFFFFFF00ULL)) || 803 + (err = pci_set_consistent_dma_mask(pdev, 0xFFFFFF00ULL))) { 804 + printk(KERN_ERR "%s (rtl8180): No suitable DMA available\n", 805 + pci_name(pdev)); 806 + goto err_free_reg; 807 + } 808 + 809 + pci_set_master(pdev); 810 + 811 + dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8180_ops); 812 + if (!dev) { 813 + printk(KERN_ERR "%s (rtl8180): ieee80211 alloc failed\n", 814 + pci_name(pdev)); 815 + err = -ENOMEM; 816 + goto err_free_reg; 817 + } 818 + 819 + priv = dev->priv; 820 + priv->pdev = pdev; 821 + 822 + SET_IEEE80211_DEV(dev, &pdev->dev); 823 + pci_set_drvdata(pdev, dev); 824 + 825 + priv->map = pci_iomap(pdev, 1, mem_len); 826 + if (!priv->map) 827 + priv->map = pci_iomap(pdev, 0, io_len); 828 + 829 + if (!priv->map) { 830 + printk(KERN_ERR "%s (rtl8180): Cannot map device memory\n", 831 + pci_name(pdev)); 832 + goto err_free_dev; 833 + } 834 + 835 + memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels)); 836 + memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates)); 837 + priv->modes[0].mode = MODE_IEEE80211G; 838 + priv->modes[0].num_rates = ARRAY_SIZE(rtl818x_rates); 839 + priv->modes[0].rates = priv->rates; 840 + priv->modes[0].num_channels = ARRAY_SIZE(rtl818x_channels); 841 + priv->modes[0].channels = priv->channels; 842 + priv->modes[1].mode = MODE_IEEE80211B; 843 + priv->modes[1].num_rates = 4; 844 + priv->modes[1].rates = priv->rates; 845 + priv->modes[1].num_channels = ARRAY_SIZE(rtl818x_channels); 846 + priv->modes[1].channels = priv->channels; 847 + priv->mode = IEEE80211_IF_TYPE_INVALID; 848 + dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | 849 + IEEE80211_HW_RX_INCLUDES_FCS; 850 + dev->queues = 1; 851 + dev->max_rssi = 65; 852 + 853 + reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); 854 + reg &= RTL818X_TX_CONF_HWVER_MASK; 855 + switch (reg) { 856 + case RTL818X_TX_CONF_R8180_ABCD: 857 + chip_name = "RTL8180"; 858 + break; 859 + case RTL818X_TX_CONF_R8180_F: 860 + chip_name = "RTL8180vF"; 861 + break; 862 + case RTL818X_TX_CONF_R8185_ABC: 863 + chip_name = "RTL8185"; 864 + break; 865 + case RTL818X_TX_CONF_R8185_D: 866 + chip_name = "RTL8185vD"; 867 + break; 868 + default: 869 + printk(KERN_ERR "%s (rtl8180): Unknown chip! (0x%x)\n", 870 + pci_name(pdev), reg >> 25); 871 + goto err_iounmap; 872 + } 873 + 874 + priv->r8185 = reg & RTL818X_TX_CONF_R8185_ABC; 875 + if (priv->r8185) { 876 + if ((err = ieee80211_register_hwmode(dev, &priv->modes[0]))) 877 + goto err_iounmap; 878 + 879 + pci_try_set_mwi(pdev); 880 + } 881 + 882 + if ((err = ieee80211_register_hwmode(dev, &priv->modes[1]))) 883 + goto err_iounmap; 884 + 885 + eeprom.data = dev; 886 + eeprom.register_read = rtl8180_eeprom_register_read; 887 + eeprom.register_write = rtl8180_eeprom_register_write; 888 + if (rtl818x_ioread32(priv, &priv->map->RX_CONF) & (1 << 6)) 889 + eeprom.width = PCI_EEPROM_WIDTH_93C66; 890 + else 891 + eeprom.width = PCI_EEPROM_WIDTH_93C46; 892 + 893 + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_PROGRAM); 894 + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 895 + udelay(10); 896 + 897 + eeprom_93cx6_read(&eeprom, 0x06, &eeprom_val); 898 + eeprom_val &= 0xFF; 899 + switch (eeprom_val) { 900 + case 1: rf_name = "Intersil"; 901 + break; 902 + case 2: rf_name = "RFMD"; 903 + break; 904 + case 3: priv->rf = &sa2400_rf_ops; 905 + break; 906 + case 4: priv->rf = &max2820_rf_ops; 907 + break; 908 + case 5: priv->rf = &grf5101_rf_ops; 909 + break; 910 + case 9: priv->rf = rtl8180_detect_rf(dev); 911 + break; 912 + case 10: 913 + rf_name = "RTL8255"; 914 + break; 915 + default: 916 + printk(KERN_ERR "%s (rtl8180): Unknown RF! (0x%x)\n", 917 + pci_name(pdev), eeprom_val); 918 + goto err_iounmap; 919 + } 920 + 921 + if (!priv->rf) { 922 + printk(KERN_ERR "%s (rtl8180): %s RF frontend not supported!\n", 923 + pci_name(pdev), rf_name); 924 + goto err_iounmap; 925 + } 926 + 927 + eeprom_93cx6_read(&eeprom, 0x17, &eeprom_val); 928 + priv->csthreshold = eeprom_val >> 8; 929 + if (!priv->r8185) { 930 + __le32 anaparam; 931 + eeprom_93cx6_multiread(&eeprom, 0xD, (__le16 *)&anaparam, 2); 932 + priv->anaparam = le32_to_cpu(anaparam); 933 + eeprom_93cx6_read(&eeprom, 0x19, &priv->rfparam); 934 + } 935 + 936 + eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)dev->wiphy->perm_addr, 3); 937 + if (!is_valid_ether_addr(dev->wiphy->perm_addr)) { 938 + printk(KERN_WARNING "%s (rtl8180): Invalid hwaddr! Using" 939 + " randomly generated MAC addr\n", pci_name(pdev)); 940 + random_ether_addr(dev->wiphy->perm_addr); 941 + } 942 + 943 + /* CCK TX power */ 944 + for (i = 0; i < 14; i += 2) { 945 + u16 txpwr; 946 + eeprom_93cx6_read(&eeprom, 0x10 + (i >> 1), &txpwr); 947 + priv->channels[i].val = txpwr & 0xFF; 948 + priv->channels[i + 1].val = txpwr >> 8; 949 + } 950 + 951 + /* OFDM TX power */ 952 + if (priv->r8185) { 953 + for (i = 0; i < 14; i += 2) { 954 + u16 txpwr; 955 + eeprom_93cx6_read(&eeprom, 0x20 + (i >> 1), &txpwr); 956 + priv->channels[i].val |= (txpwr & 0xFF) << 8; 957 + priv->channels[i + 1].val |= txpwr & 0xFF00; 958 + } 959 + } 960 + 961 + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 962 + 963 + spin_lock_init(&priv->lock); 964 + 965 + err = ieee80211_register_hw(dev); 966 + if (err) { 967 + printk(KERN_ERR "%s (rtl8180): Cannot register device\n", 968 + pci_name(pdev)); 969 + goto err_iounmap; 970 + } 971 + 972 + printk(KERN_INFO "%s: hwaddr %s, %s + %s\n", 973 + wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr), 974 + chip_name, priv->rf->name); 975 + 976 + return 0; 977 + 978 + err_iounmap: 979 + iounmap(priv->map); 980 + 981 + err_free_dev: 982 + pci_set_drvdata(pdev, NULL); 983 + ieee80211_free_hw(dev); 984 + 985 + err_free_reg: 986 + pci_release_regions(pdev); 987 + pci_disable_device(pdev); 988 + return err; 989 + } 990 + 991 + static void __devexit rtl8180_remove(struct pci_dev *pdev) 992 + { 993 + struct ieee80211_hw *dev = pci_get_drvdata(pdev); 994 + struct rtl8180_priv *priv; 995 + 996 + if (!dev) 997 + return; 998 + 999 + ieee80211_unregister_hw(dev); 1000 + 1001 + priv = dev->priv; 1002 + 1003 + pci_iounmap(pdev, priv->map); 1004 + pci_release_regions(pdev); 1005 + pci_disable_device(pdev); 1006 + ieee80211_free_hw(dev); 1007 + } 1008 + 1009 + #ifdef CONFIG_PM 1010 + static int rtl8180_suspend(struct pci_dev *pdev, pm_message_t state) 1011 + { 1012 + pci_save_state(pdev); 1013 + pci_set_power_state(pdev, pci_choose_state(pdev, state)); 1014 + return 0; 1015 + } 1016 + 1017 + static int rtl8180_resume(struct pci_dev *pdev) 1018 + { 1019 + pci_set_power_state(pdev, PCI_D0); 1020 + pci_restore_state(pdev); 1021 + return 0; 1022 + } 1023 + 1024 + #endif /* CONFIG_PM */ 1025 + 1026 + static struct pci_driver rtl8180_driver = { 1027 + .name = KBUILD_MODNAME, 1028 + .id_table = rtl8180_table, 1029 + .probe = rtl8180_probe, 1030 + .remove = __devexit_p(rtl8180_remove), 1031 + #ifdef CONFIG_PM 1032 + .suspend = rtl8180_suspend, 1033 + .resume = rtl8180_resume, 1034 + #endif /* CONFIG_PM */ 1035 + }; 1036 + 1037 + static int __init rtl8180_init(void) 1038 + { 1039 + return pci_register_driver(&rtl8180_driver); 1040 + } 1041 + 1042 + static void __exit rtl8180_exit(void) 1043 + { 1044 + pci_unregister_driver(&rtl8180_driver); 1045 + } 1046 + 1047 + module_init(rtl8180_init); 1048 + module_exit(rtl8180_exit);
+179
drivers/net/wireless/rtl8180_grf5101.c
··· 1 + 2 + /* 3 + * Radio tuning for GCT GRF5101 on RTL8180 4 + * 5 + * Copyright 2007 Andrea Merello <andreamrl@tiscali.it> 6 + * 7 + * Code from the BSD driver and the rtl8181 project have been 8 + * very useful to understand certain things 9 + * 10 + * I want to thanks the Authors of such projects and the Ndiswrapper 11 + * project Authors. 12 + * 13 + * A special Big Thanks also is for all people who donated me cards, 14 + * making possible the creation of the original rtl8180 driver 15 + * from which this code is derived! 16 + * 17 + * This program is free software; you can redistribute it and/or modify 18 + * it under the terms of the GNU General Public License version 2 as 19 + * published by the Free Software Foundation. 20 + */ 21 + 22 + #include <linux/init.h> 23 + #include <linux/pci.h> 24 + #include <linux/delay.h> 25 + #include <net/mac80211.h> 26 + 27 + #include "rtl8180.h" 28 + #include "rtl8180_grf5101.h" 29 + 30 + static const int grf5101_encode[] = { 31 + 0x0, 0x8, 0x4, 0xC, 32 + 0x2, 0xA, 0x6, 0xE, 33 + 0x1, 0x9, 0x5, 0xD, 34 + 0x3, 0xB, 0x7, 0xF 35 + }; 36 + 37 + static void write_grf5101(struct ieee80211_hw *dev, u8 addr, u32 data) 38 + { 39 + struct rtl8180_priv *priv = dev->priv; 40 + u32 phy_config; 41 + 42 + phy_config = grf5101_encode[(data >> 8) & 0xF]; 43 + phy_config |= grf5101_encode[(data >> 4) & 0xF] << 4; 44 + phy_config |= grf5101_encode[data & 0xF] << 8; 45 + phy_config |= grf5101_encode[(addr >> 1) & 0xF] << 12; 46 + phy_config |= (addr & 1) << 16; 47 + phy_config |= grf5101_encode[(data & 0xf000) >> 12] << 24; 48 + 49 + /* MAC will bang bits to the chip */ 50 + phy_config |= 0x90000000; 51 + 52 + rtl818x_iowrite32(priv, 53 + (__le32 __iomem *) &priv->map->RFPinsOutput, phy_config); 54 + 55 + msleep(3); 56 + } 57 + 58 + static void grf5101_write_phy_antenna(struct ieee80211_hw *dev, short chan) 59 + { 60 + struct rtl8180_priv *priv = dev->priv; 61 + u8 ant = GRF5101_ANTENNA; 62 + 63 + if (priv->rfparam & RF_PARAM_ANTBDEFAULT) 64 + ant |= BB_ANTENNA_B; 65 + 66 + if (chan == 14) 67 + ant |= BB_ANTATTEN_CHAN14; 68 + 69 + rtl8180_write_phy(dev, 0x10, ant); 70 + } 71 + 72 + static void grf5101_rf_set_channel(struct ieee80211_hw *dev, 73 + struct ieee80211_conf *conf) 74 + { 75 + struct rtl8180_priv *priv = dev->priv; 76 + u32 txpw = priv->channels[conf->channel - 1].val & 0xFF; 77 + u32 chan = conf->channel - 1; 78 + 79 + /* set TX power */ 80 + write_grf5101(dev, 0x15, 0x0); 81 + write_grf5101(dev, 0x06, txpw); 82 + write_grf5101(dev, 0x15, 0x10); 83 + write_grf5101(dev, 0x15, 0x0); 84 + 85 + /* set frequency */ 86 + write_grf5101(dev, 0x07, 0x0); 87 + write_grf5101(dev, 0x0B, chan); 88 + write_grf5101(dev, 0x07, 0x1000); 89 + 90 + grf5101_write_phy_antenna(dev, chan); 91 + } 92 + 93 + static void grf5101_rf_stop(struct ieee80211_hw *dev) 94 + { 95 + struct rtl8180_priv *priv = dev->priv; 96 + u32 anaparam; 97 + 98 + anaparam = priv->anaparam; 99 + anaparam &= 0x000fffff; 100 + anaparam |= 0x3f900000; 101 + rtl8180_set_anaparam(priv, anaparam); 102 + 103 + write_grf5101(dev, 0x07, 0x0); 104 + write_grf5101(dev, 0x1f, 0x45); 105 + write_grf5101(dev, 0x1f, 0x5); 106 + write_grf5101(dev, 0x00, 0x8e4); 107 + } 108 + 109 + static void grf5101_rf_init(struct ieee80211_hw *dev) 110 + { 111 + struct rtl8180_priv *priv = dev->priv; 112 + 113 + rtl8180_set_anaparam(priv, priv->anaparam); 114 + 115 + write_grf5101(dev, 0x1f, 0x0); 116 + write_grf5101(dev, 0x1f, 0x0); 117 + write_grf5101(dev, 0x1f, 0x40); 118 + write_grf5101(dev, 0x1f, 0x60); 119 + write_grf5101(dev, 0x1f, 0x61); 120 + write_grf5101(dev, 0x1f, 0x61); 121 + write_grf5101(dev, 0x00, 0xae4); 122 + write_grf5101(dev, 0x1f, 0x1); 123 + write_grf5101(dev, 0x1f, 0x41); 124 + write_grf5101(dev, 0x1f, 0x61); 125 + 126 + write_grf5101(dev, 0x01, 0x1a23); 127 + write_grf5101(dev, 0x02, 0x4971); 128 + write_grf5101(dev, 0x03, 0x41de); 129 + write_grf5101(dev, 0x04, 0x2d80); 130 + write_grf5101(dev, 0x05, 0x68ff); /* 0x61ff original value */ 131 + write_grf5101(dev, 0x06, 0x0); 132 + write_grf5101(dev, 0x07, 0x0); 133 + write_grf5101(dev, 0x08, 0x7533); 134 + write_grf5101(dev, 0x09, 0xc401); 135 + write_grf5101(dev, 0x0a, 0x0); 136 + write_grf5101(dev, 0x0c, 0x1c7); 137 + write_grf5101(dev, 0x0d, 0x29d3); 138 + write_grf5101(dev, 0x0e, 0x2e8); 139 + write_grf5101(dev, 0x10, 0x192); 140 + write_grf5101(dev, 0x11, 0x248); 141 + write_grf5101(dev, 0x12, 0x0); 142 + write_grf5101(dev, 0x13, 0x20c4); 143 + write_grf5101(dev, 0x14, 0xf4fc); 144 + write_grf5101(dev, 0x15, 0x0); 145 + write_grf5101(dev, 0x16, 0x1500); 146 + 147 + write_grf5101(dev, 0x07, 0x1000); 148 + 149 + /* baseband configuration */ 150 + rtl8180_write_phy(dev, 0, 0xa8); 151 + rtl8180_write_phy(dev, 3, 0x0); 152 + rtl8180_write_phy(dev, 4, 0xc0); 153 + rtl8180_write_phy(dev, 5, 0x90); 154 + rtl8180_write_phy(dev, 6, 0x1e); 155 + rtl8180_write_phy(dev, 7, 0x64); 156 + 157 + grf5101_write_phy_antenna(dev, 1); 158 + 159 + rtl8180_write_phy(dev, 0x11, 0x88); 160 + 161 + if (rtl818x_ioread8(priv, &priv->map->CONFIG2) & 162 + RTL818X_CONFIG2_ANTENNA_DIV) 163 + rtl8180_write_phy(dev, 0x12, 0xc0); /* enable ant diversity */ 164 + else 165 + rtl8180_write_phy(dev, 0x12, 0x40); /* disable ant diversity */ 166 + 167 + rtl8180_write_phy(dev, 0x13, 0x90 | priv->csthreshold); 168 + 169 + rtl8180_write_phy(dev, 0x19, 0x0); 170 + rtl8180_write_phy(dev, 0x1a, 0xa0); 171 + rtl8180_write_phy(dev, 0x1b, 0x44); 172 + } 173 + 174 + const struct rtl818x_rf_ops grf5101_rf_ops = { 175 + .name = "GCT", 176 + .init = grf5101_rf_init, 177 + .stop = grf5101_rf_stop, 178 + .set_chan = grf5101_rf_set_channel 179 + };
+28
drivers/net/wireless/rtl8180_grf5101.h
··· 1 + #ifndef RTL8180_GRF5101_H 2 + #define RTL8180_GRF5101_H 3 + 4 + /* 5 + * Radio tuning for GCT GRF5101 on RTL8180 6 + * 7 + * Copyright 2007 Andrea Merello <andreamrl@tiscali.it> 8 + * 9 + * Code from the BSD driver and the rtl8181 project have been 10 + * very useful to understand certain things 11 + * 12 + * I want to thanks the Authors of such projects and the Ndiswrapper 13 + * project Authors. 14 + * 15 + * A special Big Thanks also is for all people who donated me cards, 16 + * making possible the creation of the original rtl8180 driver 17 + * from which this code is derived! 18 + * 19 + * This program is free software; you can redistribute it and/or modify 20 + * it under the terms of the GNU General Public License version 2 as 21 + * published by the Free Software Foundation. 22 + */ 23 + 24 + #define GRF5101_ANTENNA 0xA3 25 + 26 + extern const struct rtl818x_rf_ops grf5101_rf_ops; 27 + 28 + #endif /* RTL8180_GRF5101_H */
+150
drivers/net/wireless/rtl8180_max2820.c
··· 1 + /* 2 + * Radio tuning for Maxim max2820 on RTL8180 3 + * 4 + * Copyright 2007 Andrea Merello <andreamrl@tiscali.it> 5 + * 6 + * Code from the BSD driver and the rtl8181 project have been 7 + * very useful to understand certain things 8 + * 9 + * I want to thanks the Authors of such projects and the Ndiswrapper 10 + * project Authors. 11 + * 12 + * A special Big Thanks also is for all people who donated me cards, 13 + * making possible the creation of the original rtl8180 driver 14 + * from which this code is derived! 15 + * 16 + * This program is free software; you can redistribute it and/or modify 17 + * it under the terms of the GNU General Public License version 2 as 18 + * published by the Free Software Foundation. 19 + */ 20 + 21 + #include <linux/init.h> 22 + #include <linux/pci.h> 23 + #include <linux/delay.h> 24 + #include <net/mac80211.h> 25 + 26 + #include "rtl8180.h" 27 + #include "rtl8180_max2820.h" 28 + 29 + static const u32 max2820_chan[] = { 30 + 12, /* CH 1 */ 31 + 17, 32 + 22, 33 + 27, 34 + 32, 35 + 37, 36 + 42, 37 + 47, 38 + 52, 39 + 57, 40 + 62, 41 + 67, 42 + 72, 43 + 84, /* CH 14 */ 44 + }; 45 + 46 + static void write_max2820(struct ieee80211_hw *dev, u8 addr, u32 data) 47 + { 48 + struct rtl8180_priv *priv = dev->priv; 49 + u32 phy_config; 50 + 51 + phy_config = 0x90 + (data & 0xf); 52 + phy_config <<= 16; 53 + phy_config += addr; 54 + phy_config <<= 8; 55 + phy_config += (data >> 4) & 0xff; 56 + 57 + rtl818x_iowrite32(priv, 58 + (__le32 __iomem *) &priv->map->RFPinsOutput, phy_config); 59 + 60 + msleep(1); 61 + } 62 + 63 + static void max2820_write_phy_antenna(struct ieee80211_hw *dev, short chan) 64 + { 65 + struct rtl8180_priv *priv = dev->priv; 66 + u8 ant; 67 + 68 + ant = MAXIM_ANTENNA; 69 + if (priv->rfparam & RF_PARAM_ANTBDEFAULT) 70 + ant |= BB_ANTENNA_B; 71 + if (chan == 14) 72 + ant |= BB_ANTATTEN_CHAN14; 73 + 74 + rtl8180_write_phy(dev, 0x10, ant); 75 + } 76 + 77 + static void max2820_rf_set_channel(struct ieee80211_hw *dev, 78 + struct ieee80211_conf *conf) 79 + { 80 + struct rtl8180_priv *priv = dev->priv; 81 + unsigned int chan_idx = conf ? conf->channel - 1 : 0; 82 + u32 txpw = priv->channels[chan_idx].val & 0xFF; 83 + u32 chan = max2820_chan[chan_idx]; 84 + 85 + /* While philips SA2400 drive the PA bias from 86 + * sa2400, for MAXIM we do this directly from BB */ 87 + rtl8180_write_phy(dev, 3, txpw); 88 + 89 + max2820_write_phy_antenna(dev, chan); 90 + write_max2820(dev, 3, chan); 91 + } 92 + 93 + static void max2820_rf_stop(struct ieee80211_hw *dev) 94 + { 95 + rtl8180_write_phy(dev, 3, 0x8); 96 + write_max2820(dev, 1, 0); 97 + } 98 + 99 + 100 + static void max2820_rf_init(struct ieee80211_hw *dev) 101 + { 102 + struct rtl8180_priv *priv = dev->priv; 103 + 104 + /* MAXIM from netbsd driver */ 105 + write_max2820(dev, 0, 0x007); /* test mode as indicated in datasheet */ 106 + write_max2820(dev, 1, 0x01e); /* enable register */ 107 + write_max2820(dev, 2, 0x001); /* synt register */ 108 + 109 + max2820_rf_set_channel(dev, NULL); 110 + 111 + write_max2820(dev, 4, 0x313); /* rx register */ 112 + 113 + /* PA is driven directly by the BB, we keep the MAXIM bias 114 + * at the highest value in case that setting it to lower 115 + * values may introduce some further attenuation somewhere.. 116 + */ 117 + write_max2820(dev, 5, 0x00f); 118 + 119 + /* baseband configuration */ 120 + rtl8180_write_phy(dev, 0, 0x88); /* sys1 */ 121 + rtl8180_write_phy(dev, 3, 0x08); /* txagc */ 122 + rtl8180_write_phy(dev, 4, 0xf8); /* lnadet */ 123 + rtl8180_write_phy(dev, 5, 0x90); /* ifagcinit */ 124 + rtl8180_write_phy(dev, 6, 0x1a); /* ifagclimit */ 125 + rtl8180_write_phy(dev, 7, 0x64); /* ifagcdet */ 126 + 127 + max2820_write_phy_antenna(dev, 1); 128 + 129 + rtl8180_write_phy(dev, 0x11, 0x88); /* trl */ 130 + 131 + if (rtl818x_ioread8(priv, &priv->map->CONFIG2) & 132 + RTL818X_CONFIG2_ANTENNA_DIV) 133 + rtl8180_write_phy(dev, 0x12, 0xc7); 134 + else 135 + rtl8180_write_phy(dev, 0x12, 0x47); 136 + 137 + rtl8180_write_phy(dev, 0x13, 0x9b); 138 + 139 + rtl8180_write_phy(dev, 0x19, 0x0); /* CHESTLIM */ 140 + rtl8180_write_phy(dev, 0x1a, 0x9f); /* CHSQLIM */ 141 + 142 + max2820_rf_set_channel(dev, NULL); 143 + } 144 + 145 + const struct rtl818x_rf_ops max2820_rf_ops = { 146 + .name = "Maxim", 147 + .init = max2820_rf_init, 148 + .stop = max2820_rf_stop, 149 + .set_chan = max2820_rf_set_channel 150 + };
+28
drivers/net/wireless/rtl8180_max2820.h
··· 1 + #ifndef RTL8180_MAX2820_H 2 + #define RTL8180_MAX2820_H 3 + 4 + /* 5 + * Radio tuning for Maxim max2820 on RTL8180 6 + * 7 + * Copyright 2007 Andrea Merello <andreamrl@tiscali.it> 8 + * 9 + * Code from the BSD driver and the rtl8181 project have been 10 + * very useful to understand certain things 11 + * 12 + * I want to thanks the Authors of such projects and the Ndiswrapper 13 + * project Authors. 14 + * 15 + * A special Big Thanks also is for all people who donated me cards, 16 + * making possible the creation of the original rtl8180 driver 17 + * from which this code is derived! 18 + * 19 + * This program is free software; you can redistribute it and/or modify 20 + * it under the terms of the GNU General Public License version 2 as 21 + * published by the Free Software Foundation. 22 + */ 23 + 24 + #define MAXIM_ANTENNA 0xb3 25 + 26 + extern const struct rtl818x_rf_ops max2820_rf_ops; 27 + 28 + #endif /* RTL8180_MAX2820_H */
+779
drivers/net/wireless/rtl8180_rtl8225.c
··· 1 + 2 + /* 3 + * Radio tuning for RTL8225 on RTL8180 4 + * 5 + * Copyright 2007 Michael Wu <flamingice@sourmilk.net> 6 + * Copyright 2007 Andrea Merello <andreamrl@tiscali.it> 7 + * 8 + * Based on the r8180 driver, which is: 9 + * Copyright 2005 Andrea Merello <andreamrl@tiscali.it>, et al. 10 + * 11 + * Thanks to Realtek for their support! 12 + * 13 + * This program is free software; you can redistribute it and/or modify 14 + * it under the terms of the GNU General Public License version 2 as 15 + * published by the Free Software Foundation. 16 + */ 17 + 18 + #include <linux/init.h> 19 + #include <linux/pci.h> 20 + #include <linux/delay.h> 21 + #include <net/mac80211.h> 22 + 23 + #include "rtl8180.h" 24 + #include "rtl8180_rtl8225.h" 25 + 26 + static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data) 27 + { 28 + struct rtl8180_priv *priv = dev->priv; 29 + u16 reg80, reg84, reg82; 30 + u32 bangdata; 31 + int i; 32 + 33 + bangdata = (data << 4) | (addr & 0xf); 34 + 35 + reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput) & 0xfff3; 36 + reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable); 37 + 38 + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x7); 39 + 40 + reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect); 41 + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x7 | 0x400); 42 + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 43 + udelay(10); 44 + 45 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); 46 + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 47 + udelay(2); 48 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); 49 + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 50 + udelay(10); 51 + 52 + for (i = 15; i >= 0; i--) { 53 + u16 reg = reg80 | !!(bangdata & (1 << i)); 54 + 55 + if (i & 1) 56 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); 57 + 58 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1)); 59 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg | (1 << 1)); 60 + 61 + if (!(i & 1)) 62 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); 63 + } 64 + 65 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); 66 + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 67 + udelay(10); 68 + 69 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); 70 + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x400); 71 + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); 72 + } 73 + 74 + static u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr) 75 + { 76 + struct rtl8180_priv *priv = dev->priv; 77 + u16 reg80, reg82, reg84, out; 78 + int i; 79 + 80 + reg80 = rtl818x_ioread16(priv, &priv->map->RFPinsOutput); 81 + reg82 = rtl818x_ioread16(priv, &priv->map->RFPinsEnable); 82 + reg84 = rtl818x_ioread16(priv, &priv->map->RFPinsSelect) | 0x400; 83 + 84 + reg80 &= ~0xF; 85 + 86 + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82 | 0x000F); 87 + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84 | 0x000F); 88 + 89 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80 | (1 << 2)); 90 + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 91 + udelay(4); 92 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg80); 93 + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 94 + udelay(5); 95 + 96 + for (i = 4; i >= 0; i--) { 97 + u16 reg = reg80 | ((addr >> i) & 1); 98 + 99 + if (!(i & 1)) { 100 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); 101 + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 102 + udelay(1); 103 + } 104 + 105 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 106 + reg | (1 << 1)); 107 + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 108 + udelay(2); 109 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 110 + reg | (1 << 1)); 111 + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 112 + udelay(2); 113 + 114 + if (i & 1) { 115 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg); 116 + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 117 + udelay(1); 118 + } 119 + } 120 + 121 + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x000E); 122 + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x040E); 123 + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 124 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 125 + reg80 | (1 << 3) | (1 << 1)); 126 + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 127 + udelay(2); 128 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 129 + reg80 | (1 << 3)); 130 + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 131 + udelay(2); 132 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 133 + reg80 | (1 << 3)); 134 + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 135 + udelay(2); 136 + 137 + out = 0; 138 + for (i = 11; i >= 0; i--) { 139 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 140 + reg80 | (1 << 3)); 141 + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 142 + udelay(1); 143 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 144 + reg80 | (1 << 3) | (1 << 1)); 145 + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 146 + udelay(2); 147 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 148 + reg80 | (1 << 3) | (1 << 1)); 149 + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 150 + udelay(2); 151 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 152 + reg80 | (1 << 3) | (1 << 1)); 153 + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 154 + udelay(2); 155 + 156 + if (rtl818x_ioread16(priv, &priv->map->RFPinsInput) & (1 << 1)) 157 + out |= 1 << i; 158 + 159 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 160 + reg80 | (1 << 3)); 161 + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 162 + udelay(2); 163 + } 164 + 165 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 166 + reg80 | (1 << 3) | (1 << 2)); 167 + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 168 + udelay(2); 169 + 170 + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, reg82); 171 + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, reg84); 172 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x03A0); 173 + 174 + return out; 175 + } 176 + 177 + static const u16 rtl8225bcd_rxgain[] = { 178 + 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409, 179 + 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541, 180 + 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583, 181 + 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644, 182 + 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688, 183 + 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745, 184 + 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789, 185 + 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793, 186 + 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d, 187 + 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9, 188 + 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3, 189 + 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb 190 + }; 191 + 192 + static const u8 rtl8225_agc[] = { 193 + 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 194 + 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96, 195 + 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e, 196 + 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86, 197 + 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e, 198 + 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36, 199 + 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e, 200 + 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 201 + 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e, 202 + 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16, 203 + 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e, 204 + 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 205 + 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 206 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 207 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 208 + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 209 + }; 210 + 211 + static const u8 rtl8225_gain[] = { 212 + 0x23, 0x88, 0x7c, 0xa5, /* -82dbm */ 213 + 0x23, 0x88, 0x7c, 0xb5, /* -82dbm */ 214 + 0x23, 0x88, 0x7c, 0xc5, /* -82dbm */ 215 + 0x33, 0x80, 0x79, 0xc5, /* -78dbm */ 216 + 0x43, 0x78, 0x76, 0xc5, /* -74dbm */ 217 + 0x53, 0x60, 0x73, 0xc5, /* -70dbm */ 218 + 0x63, 0x58, 0x70, 0xc5, /* -66dbm */ 219 + }; 220 + 221 + static const u8 rtl8225_threshold[] = { 222 + 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd 223 + }; 224 + 225 + static const u8 rtl8225_tx_gain_cck_ofdm[] = { 226 + 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e 227 + }; 228 + 229 + static const u8 rtl8225_tx_power_cck[] = { 230 + 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02, 231 + 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02, 232 + 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02, 233 + 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02, 234 + 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03, 235 + 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03 236 + }; 237 + 238 + static const u8 rtl8225_tx_power_cck_ch14[] = { 239 + 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00, 240 + 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00, 241 + 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00, 242 + 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00, 243 + 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, 244 + 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00 245 + }; 246 + 247 + static const u8 rtl8225_tx_power_ofdm[] = { 248 + 0x80, 0x90, 0xa2, 0xb5, 0xcb, 0xe4 249 + }; 250 + 251 + static const u32 rtl8225_chan[] = { 252 + 0x085c, 0x08dc, 0x095c, 0x09dc, 0x0a5c, 0x0adc, 0x0b5c, 253 + 0x0bdc, 0x0c5c, 0x0cdc, 0x0d5c, 0x0ddc, 0x0e5c, 0x0f72 254 + }; 255 + 256 + static void rtl8225_rf_set_tx_power(struct ieee80211_hw *dev, int channel) 257 + { 258 + struct rtl8180_priv *priv = dev->priv; 259 + u8 cck_power, ofdm_power; 260 + const u8 *tmp; 261 + u32 reg; 262 + int i; 263 + 264 + cck_power = priv->channels[channel - 1].val & 0xFF; 265 + ofdm_power = priv->channels[channel - 1].val >> 8; 266 + 267 + cck_power = min(cck_power, (u8)35); 268 + ofdm_power = min(ofdm_power, (u8)35); 269 + 270 + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, 271 + rtl8225_tx_gain_cck_ofdm[cck_power / 6] >> 1); 272 + 273 + if (channel == 14) 274 + tmp = &rtl8225_tx_power_cck_ch14[(cck_power % 6) * 8]; 275 + else 276 + tmp = &rtl8225_tx_power_cck[(cck_power % 6) * 8]; 277 + 278 + for (i = 0; i < 8; i++) 279 + rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++); 280 + 281 + msleep(1); /* FIXME: optional? */ 282 + 283 + /* anaparam2 on */ 284 + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 285 + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); 286 + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE); 287 + rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_ON); 288 + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); 289 + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 290 + 291 + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, 292 + rtl8225_tx_gain_cck_ofdm[ofdm_power/6] >> 1); 293 + 294 + tmp = &rtl8225_tx_power_ofdm[ofdm_power % 6]; 295 + 296 + rtl8225_write_phy_ofdm(dev, 5, *tmp); 297 + rtl8225_write_phy_ofdm(dev, 7, *tmp); 298 + 299 + msleep(1); 300 + } 301 + 302 + static void rtl8225_rf_init(struct ieee80211_hw *dev) 303 + { 304 + struct rtl8180_priv *priv = dev->priv; 305 + int i; 306 + 307 + rtl8180_set_anaparam(priv, RTL8225_ANAPARAM_ON); 308 + 309 + /* host_pci_init */ 310 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480); 311 + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); 312 + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488); 313 + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0); 314 + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 315 + msleep(200); /* FIXME: ehh?? */ 316 + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0xFF & ~(1 << 6)); 317 + 318 + rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x000a8008); 319 + 320 + /* TODO: check if we need really to change BRSR to do RF config */ 321 + rtl818x_ioread16(priv, &priv->map->BRSR); 322 + rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF); 323 + rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044); 324 + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 325 + rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44); 326 + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 327 + 328 + rtl8225_write(dev, 0x0, 0x067); 329 + rtl8225_write(dev, 0x1, 0xFE0); 330 + rtl8225_write(dev, 0x2, 0x44D); 331 + rtl8225_write(dev, 0x3, 0x441); 332 + rtl8225_write(dev, 0x4, 0x8BE); 333 + rtl8225_write(dev, 0x5, 0xBF0); /* TODO: minipci */ 334 + rtl8225_write(dev, 0x6, 0xAE6); 335 + rtl8225_write(dev, 0x7, rtl8225_chan[0]); 336 + rtl8225_write(dev, 0x8, 0x01F); 337 + rtl8225_write(dev, 0x9, 0x334); 338 + rtl8225_write(dev, 0xA, 0xFD4); 339 + rtl8225_write(dev, 0xB, 0x391); 340 + rtl8225_write(dev, 0xC, 0x050); 341 + rtl8225_write(dev, 0xD, 0x6DB); 342 + rtl8225_write(dev, 0xE, 0x029); 343 + rtl8225_write(dev, 0xF, 0x914); msleep(1); 344 + 345 + rtl8225_write(dev, 0x2, 0xC4D); msleep(100); 346 + 347 + rtl8225_write(dev, 0x0, 0x127); 348 + 349 + for (i = 0; i < ARRAY_SIZE(rtl8225bcd_rxgain); i++) { 350 + rtl8225_write(dev, 0x1, i + 1); 351 + rtl8225_write(dev, 0x2, rtl8225bcd_rxgain[i]); 352 + } 353 + 354 + rtl8225_write(dev, 0x0, 0x027); 355 + rtl8225_write(dev, 0x0, 0x22F); 356 + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); 357 + 358 + for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) { 359 + rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]); 360 + msleep(1); 361 + rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i); 362 + msleep(1); 363 + } 364 + 365 + msleep(1); 366 + 367 + rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1); 368 + rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1); 369 + rtl8225_write_phy_ofdm(dev, 0x02, 0x62); msleep(1); 370 + rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1); 371 + rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1); 372 + rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1); 373 + rtl8225_write_phy_ofdm(dev, 0x06, 0x00); msleep(1); 374 + rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1); 375 + rtl8225_write_phy_ofdm(dev, 0x08, 0x00); msleep(1); 376 + rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1); 377 + rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); msleep(1); 378 + rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1); 379 + rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1); 380 + rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1); 381 + rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1); 382 + rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1); 383 + rtl8225_write_phy_ofdm(dev, 0x11, 0x03); msleep(1); 384 + rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1); 385 + rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1); 386 + rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1); 387 + rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1); 388 + rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1); 389 + rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1); 390 + rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1); 391 + rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1); 392 + rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1); 393 + rtl8225_write_phy_ofdm(dev, 0x1b, 0x76); msleep(1); 394 + rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1); 395 + rtl8225_write_phy_ofdm(dev, 0x1e, 0x95); msleep(1); 396 + rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1); 397 + rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1); 398 + rtl8225_write_phy_ofdm(dev, 0x21, 0x27); msleep(1); 399 + rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1); 400 + rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1); 401 + rtl8225_write_phy_ofdm(dev, 0x25, 0x20); msleep(1); 402 + rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); 403 + rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1); 404 + 405 + rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1); 406 + rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1); 407 + rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1); 408 + rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1); 409 + rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1); 410 + rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1); 411 + rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1); 412 + rtl8225_write_phy_cck(dev, 0x10, 0x93); msleep(1); 413 + rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1); 414 + rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1); 415 + rtl8225_write_phy_cck(dev, 0x13, 0xd0); 416 + rtl8225_write_phy_cck(dev, 0x19, 0x00); 417 + rtl8225_write_phy_cck(dev, 0x1a, 0xa0); 418 + rtl8225_write_phy_cck(dev, 0x1b, 0x08); 419 + rtl8225_write_phy_cck(dev, 0x40, 0x86); 420 + rtl8225_write_phy_cck(dev, 0x41, 0x8d); msleep(1); 421 + rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1); 422 + rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1); 423 + rtl8225_write_phy_cck(dev, 0x44, 0x1f); msleep(1); 424 + rtl8225_write_phy_cck(dev, 0x45, 0x1e); msleep(1); 425 + rtl8225_write_phy_cck(dev, 0x46, 0x1a); msleep(1); 426 + rtl8225_write_phy_cck(dev, 0x47, 0x15); msleep(1); 427 + rtl8225_write_phy_cck(dev, 0x48, 0x10); msleep(1); 428 + rtl8225_write_phy_cck(dev, 0x49, 0x0a); msleep(1); 429 + rtl8225_write_phy_cck(dev, 0x4a, 0x05); msleep(1); 430 + rtl8225_write_phy_cck(dev, 0x4b, 0x02); msleep(1); 431 + rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1); 432 + 433 + rtl818x_iowrite8(priv, &priv->map->TESTR, 0x0D); msleep(1); 434 + 435 + rtl8225_rf_set_tx_power(dev, 1); 436 + 437 + /* RX antenna default to A */ 438 + rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1); /* B: 0xDB */ 439 + rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); /* B: 0x10 */ 440 + 441 + rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */ 442 + msleep(1); 443 + rtl818x_iowrite32(priv, (__le32 __iomem *)((void __iomem *)priv->map + 0x94), 0x15c00002); 444 + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); 445 + 446 + rtl8225_write(dev, 0x0c, 0x50); 447 + /* set OFDM initial gain */ 448 + rtl8225_write_phy_ofdm(dev, 0x0d, rtl8225_gain[4 * 4]); 449 + rtl8225_write_phy_ofdm(dev, 0x23, rtl8225_gain[4 * 4 + 1]); 450 + rtl8225_write_phy_ofdm(dev, 0x1b, rtl8225_gain[4 * 4 + 2]); 451 + rtl8225_write_phy_ofdm(dev, 0x1d, rtl8225_gain[4 * 4 + 3]); 452 + /* set CCK threshold */ 453 + rtl8225_write_phy_cck(dev, 0x41, rtl8225_threshold[0]); 454 + } 455 + 456 + static const u8 rtl8225z2_tx_power_cck_ch14[] = { 457 + 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00 458 + }; 459 + 460 + static const u8 rtl8225z2_tx_power_cck_B[] = { 461 + 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x04 462 + }; 463 + 464 + static const u8 rtl8225z2_tx_power_cck_A[] = { 465 + 0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04 466 + }; 467 + 468 + static const u8 rtl8225z2_tx_power_cck[] = { 469 + 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04 470 + }; 471 + 472 + static void rtl8225z2_rf_set_tx_power(struct ieee80211_hw *dev, int channel) 473 + { 474 + struct rtl8180_priv *priv = dev->priv; 475 + u8 cck_power, ofdm_power; 476 + const u8 *tmp; 477 + int i; 478 + 479 + cck_power = priv->channels[channel - 1].val & 0xFF; 480 + ofdm_power = priv->channels[channel - 1].val >> 8; 481 + 482 + if (channel == 14) 483 + tmp = rtl8225z2_tx_power_cck_ch14; 484 + else if (cck_power == 12) 485 + tmp = rtl8225z2_tx_power_cck_B; 486 + else if (cck_power == 13) 487 + tmp = rtl8225z2_tx_power_cck_A; 488 + else 489 + tmp = rtl8225z2_tx_power_cck; 490 + 491 + for (i = 0; i < 8; i++) 492 + rtl8225_write_phy_cck(dev, 0x44 + i, *tmp++); 493 + 494 + cck_power = min(cck_power, (u8)35); 495 + if (cck_power == 13 || cck_power == 14) 496 + cck_power = 12; 497 + if (cck_power >= 15) 498 + cck_power -= 2; 499 + 500 + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_CCK, cck_power); 501 + rtl818x_ioread8(priv, &priv->map->TX_GAIN_CCK); 502 + msleep(1); 503 + 504 + ofdm_power = min(ofdm_power, (u8)35); 505 + rtl818x_iowrite8(priv, &priv->map->TX_GAIN_OFDM, ofdm_power); 506 + 507 + rtl8225_write_phy_ofdm(dev, 2, 0x62); 508 + rtl8225_write_phy_ofdm(dev, 5, 0x00); 509 + rtl8225_write_phy_ofdm(dev, 6, 0x40); 510 + rtl8225_write_phy_ofdm(dev, 7, 0x00); 511 + rtl8225_write_phy_ofdm(dev, 8, 0x40); 512 + 513 + msleep(1); 514 + } 515 + 516 + static const u16 rtl8225z2_rxgain[] = { 517 + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0008, 0x0009, 518 + 0x000a, 0x000b, 0x0102, 0x0103, 0x0104, 0x0105, 0x0140, 0x0141, 519 + 0x0142, 0x0143, 0x0144, 0x0145, 0x0180, 0x0181, 0x0182, 0x0183, 520 + 0x0184, 0x0185, 0x0188, 0x0189, 0x018a, 0x018b, 0x0243, 0x0244, 521 + 0x0245, 0x0280, 0x0281, 0x0282, 0x0283, 0x0284, 0x0285, 0x0288, 522 + 0x0289, 0x028a, 0x028b, 0x028c, 0x0342, 0x0343, 0x0344, 0x0345, 523 + 0x0380, 0x0381, 0x0382, 0x0383, 0x0384, 0x0385, 0x0388, 0x0389, 524 + 0x038a, 0x038b, 0x038c, 0x038d, 0x0390, 0x0391, 0x0392, 0x0393, 525 + 0x0394, 0x0395, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 526 + 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a8, 0x03a9, 527 + 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3, 528 + 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb 529 + }; 530 + 531 + static void rtl8225z2_rf_init(struct ieee80211_hw *dev) 532 + { 533 + struct rtl8180_priv *priv = dev->priv; 534 + int i; 535 + 536 + rtl8180_set_anaparam(priv, RTL8225_ANAPARAM_ON); 537 + 538 + /* host_pci_init */ 539 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480); 540 + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); 541 + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488); 542 + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0); 543 + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 544 + msleep(200); /* FIXME: ehh?? */ 545 + rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, 0xFF & ~(1 << 6)); 546 + 547 + rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x00088008); 548 + 549 + /* TODO: check if we need really to change BRSR to do RF config */ 550 + rtl818x_ioread16(priv, &priv->map->BRSR); 551 + rtl818x_iowrite16(priv, &priv->map->BRSR, 0xFFFF); 552 + rtl818x_iowrite32(priv, &priv->map->RF_PARA, 0x00100044); 553 + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 554 + rtl818x_iowrite8(priv, &priv->map->CONFIG3, 0x44); 555 + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 556 + 557 + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); 558 + 559 + rtl8225_write(dev, 0x0, 0x0B7); msleep(1); 560 + rtl8225_write(dev, 0x1, 0xEE0); msleep(1); 561 + rtl8225_write(dev, 0x2, 0x44D); msleep(1); 562 + rtl8225_write(dev, 0x3, 0x441); msleep(1); 563 + rtl8225_write(dev, 0x4, 0x8C3); msleep(1); 564 + rtl8225_write(dev, 0x5, 0xC72); msleep(1); 565 + rtl8225_write(dev, 0x6, 0x0E6); msleep(1); 566 + rtl8225_write(dev, 0x7, 0x82A); msleep(1); 567 + rtl8225_write(dev, 0x8, 0x03F); msleep(1); 568 + rtl8225_write(dev, 0x9, 0x335); msleep(1); 569 + rtl8225_write(dev, 0xa, 0x9D4); msleep(1); 570 + rtl8225_write(dev, 0xb, 0x7BB); msleep(1); 571 + rtl8225_write(dev, 0xc, 0x850); msleep(1); 572 + rtl8225_write(dev, 0xd, 0xCDF); msleep(1); 573 + rtl8225_write(dev, 0xe, 0x02B); msleep(1); 574 + rtl8225_write(dev, 0xf, 0x114); msleep(100); 575 + 576 + if (!(rtl8225_read(dev, 6) & (1 << 7))) { 577 + rtl8225_write(dev, 0x02, 0x0C4D); 578 + msleep(200); 579 + rtl8225_write(dev, 0x02, 0x044D); 580 + msleep(100); 581 + /* TODO: readd calibration failure message when the calibration 582 + check works */ 583 + } 584 + 585 + rtl8225_write(dev, 0x0, 0x1B7); 586 + rtl8225_write(dev, 0x3, 0x002); 587 + rtl8225_write(dev, 0x5, 0x004); 588 + 589 + for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) { 590 + rtl8225_write(dev, 0x1, i + 1); 591 + rtl8225_write(dev, 0x2, rtl8225z2_rxgain[i]); 592 + } 593 + 594 + rtl8225_write(dev, 0x0, 0x0B7); msleep(100); 595 + rtl8225_write(dev, 0x2, 0xC4D); 596 + 597 + msleep(200); 598 + rtl8225_write(dev, 0x2, 0x44D); 599 + msleep(100); 600 + 601 + rtl8225_write(dev, 0x00, 0x2BF); 602 + rtl8225_write(dev, 0xFF, 0xFFFF); 603 + 604 + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); 605 + 606 + for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) { 607 + rtl8225_write_phy_ofdm(dev, 0xB, rtl8225_agc[i]); 608 + msleep(1); 609 + rtl8225_write_phy_ofdm(dev, 0xA, 0x80 + i); 610 + msleep(1); 611 + } 612 + 613 + msleep(1); 614 + 615 + rtl8225_write_phy_ofdm(dev, 0x00, 0x01); msleep(1); 616 + rtl8225_write_phy_ofdm(dev, 0x01, 0x02); msleep(1); 617 + rtl8225_write_phy_ofdm(dev, 0x02, 0x62); msleep(1); 618 + rtl8225_write_phy_ofdm(dev, 0x03, 0x00); msleep(1); 619 + rtl8225_write_phy_ofdm(dev, 0x04, 0x00); msleep(1); 620 + rtl8225_write_phy_ofdm(dev, 0x05, 0x00); msleep(1); 621 + rtl8225_write_phy_ofdm(dev, 0x06, 0x40); msleep(1); 622 + rtl8225_write_phy_ofdm(dev, 0x07, 0x00); msleep(1); 623 + rtl8225_write_phy_ofdm(dev, 0x08, 0x40); msleep(1); 624 + rtl8225_write_phy_ofdm(dev, 0x09, 0xfe); msleep(1); 625 + rtl8225_write_phy_ofdm(dev, 0x0a, 0x09); msleep(1); 626 + rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1); 627 + rtl8225_write_phy_ofdm(dev, 0x0b, 0x80); msleep(1); 628 + rtl8225_write_phy_ofdm(dev, 0x0c, 0x01); msleep(1); 629 + rtl8225_write_phy_ofdm(dev, 0x0d, 0x43); 630 + rtl8225_write_phy_ofdm(dev, 0x0e, 0xd3); msleep(1); 631 + rtl8225_write_phy_ofdm(dev, 0x0f, 0x38); msleep(1); 632 + rtl8225_write_phy_ofdm(dev, 0x10, 0x84); msleep(1); 633 + rtl8225_write_phy_ofdm(dev, 0x11, 0x06); msleep(1); 634 + rtl8225_write_phy_ofdm(dev, 0x12, 0x20); msleep(1); 635 + rtl8225_write_phy_ofdm(dev, 0x13, 0x20); msleep(1); 636 + rtl8225_write_phy_ofdm(dev, 0x14, 0x00); msleep(1); 637 + rtl8225_write_phy_ofdm(dev, 0x15, 0x40); msleep(1); 638 + rtl8225_write_phy_ofdm(dev, 0x16, 0x00); msleep(1); 639 + rtl8225_write_phy_ofdm(dev, 0x17, 0x40); msleep(1); 640 + rtl8225_write_phy_ofdm(dev, 0x18, 0xef); msleep(1); 641 + rtl8225_write_phy_ofdm(dev, 0x19, 0x19); msleep(1); 642 + rtl8225_write_phy_ofdm(dev, 0x1a, 0x20); msleep(1); 643 + rtl8225_write_phy_ofdm(dev, 0x1b, 0x11); msleep(1); 644 + rtl8225_write_phy_ofdm(dev, 0x1c, 0x04); msleep(1); 645 + rtl8225_write_phy_ofdm(dev, 0x1d, 0xc5); msleep(1); 646 + rtl8225_write_phy_ofdm(dev, 0x1e, 0xb3); msleep(1); 647 + rtl8225_write_phy_ofdm(dev, 0x1f, 0x75); msleep(1); 648 + rtl8225_write_phy_ofdm(dev, 0x20, 0x1f); msleep(1); 649 + rtl8225_write_phy_ofdm(dev, 0x21, 0x27); msleep(1); 650 + rtl8225_write_phy_ofdm(dev, 0x22, 0x16); msleep(1); 651 + rtl8225_write_phy_ofdm(dev, 0x23, 0x80); msleep(1); /* FIXME: not needed? */ 652 + rtl8225_write_phy_ofdm(dev, 0x24, 0x46); msleep(1); 653 + rtl8225_write_phy_ofdm(dev, 0x25, 0x20); msleep(1); 654 + rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); 655 + rtl8225_write_phy_ofdm(dev, 0x27, 0x88); msleep(1); 656 + 657 + rtl8225_write_phy_cck(dev, 0x00, 0x98); msleep(1); 658 + rtl8225_write_phy_cck(dev, 0x03, 0x20); msleep(1); 659 + rtl8225_write_phy_cck(dev, 0x04, 0x7e); msleep(1); 660 + rtl8225_write_phy_cck(dev, 0x05, 0x12); msleep(1); 661 + rtl8225_write_phy_cck(dev, 0x06, 0xfc); msleep(1); 662 + rtl8225_write_phy_cck(dev, 0x07, 0x78); msleep(1); 663 + rtl8225_write_phy_cck(dev, 0x08, 0x2e); msleep(1); 664 + rtl8225_write_phy_cck(dev, 0x10, 0x93); msleep(1); 665 + rtl8225_write_phy_cck(dev, 0x11, 0x88); msleep(1); 666 + rtl8225_write_phy_cck(dev, 0x12, 0x47); msleep(1); 667 + rtl8225_write_phy_cck(dev, 0x13, 0xd0); 668 + rtl8225_write_phy_cck(dev, 0x19, 0x00); 669 + rtl8225_write_phy_cck(dev, 0x1a, 0xa0); 670 + rtl8225_write_phy_cck(dev, 0x1b, 0x08); 671 + rtl8225_write_phy_cck(dev, 0x40, 0x86); 672 + rtl8225_write_phy_cck(dev, 0x41, 0x8a); msleep(1); 673 + rtl8225_write_phy_cck(dev, 0x42, 0x15); msleep(1); 674 + rtl8225_write_phy_cck(dev, 0x43, 0x18); msleep(1); 675 + rtl8225_write_phy_cck(dev, 0x44, 0x36); msleep(1); 676 + rtl8225_write_phy_cck(dev, 0x45, 0x35); msleep(1); 677 + rtl8225_write_phy_cck(dev, 0x46, 0x2e); msleep(1); 678 + rtl8225_write_phy_cck(dev, 0x47, 0x25); msleep(1); 679 + rtl8225_write_phy_cck(dev, 0x48, 0x1c); msleep(1); 680 + rtl8225_write_phy_cck(dev, 0x49, 0x12); msleep(1); 681 + rtl8225_write_phy_cck(dev, 0x4a, 0x09); msleep(1); 682 + rtl8225_write_phy_cck(dev, 0x4b, 0x04); msleep(1); 683 + rtl8225_write_phy_cck(dev, 0x4c, 0x05); msleep(1); 684 + 685 + rtl818x_iowrite8(priv, (u8 __iomem *)((void __iomem *)priv->map + 0x5B), 0x0D); msleep(1); 686 + 687 + rtl8225z2_rf_set_tx_power(dev, 1); 688 + 689 + /* RX antenna default to A */ 690 + rtl8225_write_phy_cck(dev, 0x10, 0x9b); msleep(1); /* B: 0xDB */ 691 + rtl8225_write_phy_ofdm(dev, 0x26, 0x90); msleep(1); /* B: 0x10 */ 692 + 693 + rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03); /* B: 0x00 */ 694 + msleep(1); 695 + rtl818x_iowrite32(priv, (__le32 __iomem *)((void __iomem *)priv->map + 0x94), 0x15c00002); 696 + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); 697 + } 698 + 699 + static void rtl8225_rf_stop(struct ieee80211_hw *dev) 700 + { 701 + struct rtl8180_priv *priv = dev->priv; 702 + u8 reg; 703 + 704 + rtl8225_write(dev, 0x4, 0x1f); msleep(1); 705 + 706 + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 707 + reg = rtl818x_ioread8(priv, &priv->map->CONFIG3); 708 + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | RTL818X_CONFIG3_ANAPARAM_WRITE); 709 + rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, RTL8225_ANAPARAM2_OFF); 710 + rtl818x_iowrite32(priv, &priv->map->ANAPARAM, RTL8225_ANAPARAM_OFF); 711 + rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE); 712 + rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 713 + } 714 + 715 + static void rtl8225_rf_set_channel(struct ieee80211_hw *dev, 716 + struct ieee80211_conf *conf) 717 + { 718 + struct rtl8180_priv *priv = dev->priv; 719 + 720 + if (priv->rf->init == rtl8225_rf_init) 721 + rtl8225_rf_set_tx_power(dev, conf->channel); 722 + else 723 + rtl8225z2_rf_set_tx_power(dev, conf->channel); 724 + 725 + rtl8225_write(dev, 0x7, rtl8225_chan[conf->channel - 1]); 726 + msleep(10); 727 + 728 + if (conf->flags & IEEE80211_CONF_SHORT_SLOT_TIME) { 729 + rtl818x_iowrite8(priv, &priv->map->SLOT, 0x9); 730 + rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22); 731 + rtl818x_iowrite8(priv, &priv->map->DIFS, 0x14); 732 + rtl818x_iowrite8(priv, &priv->map->EIFS, 81); 733 + rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0x73); 734 + } else { 735 + rtl818x_iowrite8(priv, &priv->map->SLOT, 0x14); 736 + rtl818x_iowrite8(priv, &priv->map->SIFS, 0x44); 737 + rtl818x_iowrite8(priv, &priv->map->DIFS, 0x24); 738 + rtl818x_iowrite8(priv, &priv->map->EIFS, 81); 739 + rtl818x_iowrite8(priv, &priv->map->CW_VAL, 0xa5); 740 + } 741 + } 742 + 743 + static const struct rtl818x_rf_ops rtl8225_ops = { 744 + .name = "rtl8225", 745 + .init = rtl8225_rf_init, 746 + .stop = rtl8225_rf_stop, 747 + .set_chan = rtl8225_rf_set_channel 748 + }; 749 + 750 + static const struct rtl818x_rf_ops rtl8225z2_ops = { 751 + .name = "rtl8225z2", 752 + .init = rtl8225z2_rf_init, 753 + .stop = rtl8225_rf_stop, 754 + .set_chan = rtl8225_rf_set_channel 755 + }; 756 + 757 + const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *dev) 758 + { 759 + struct rtl8180_priv *priv = dev->priv; 760 + u16 reg8, reg9; 761 + 762 + rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480); 763 + rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x0488); 764 + rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FFF); 765 + rtl818x_ioread8(priv, &priv->map->EEPROM_CMD); 766 + msleep(100); 767 + 768 + rtl8225_write(dev, 0, 0x1B7); 769 + 770 + reg8 = rtl8225_read(dev, 8); 771 + reg9 = rtl8225_read(dev, 9); 772 + 773 + rtl8225_write(dev, 0, 0x0B7); 774 + 775 + if (reg8 != 0x588 || reg9 != 0x700) 776 + return &rtl8225_ops; 777 + 778 + return &rtl8225z2_ops; 779 + }
+23
drivers/net/wireless/rtl8180_rtl8225.h
··· 1 + #ifndef RTL8180_RTL8225_H 2 + #define RTL8180_RTL8225_H 3 + 4 + #define RTL8225_ANAPARAM_ON 0xa0000b59 5 + #define RTL8225_ANAPARAM2_ON 0x860dec11 6 + #define RTL8225_ANAPARAM_OFF 0xa00beb59 7 + #define RTL8225_ANAPARAM2_OFF 0x840dec11 8 + 9 + const struct rtl818x_rf_ops * rtl8180_detect_rf(struct ieee80211_hw *); 10 + 11 + static inline void rtl8225_write_phy_ofdm(struct ieee80211_hw *dev, 12 + u8 addr, u8 data) 13 + { 14 + rtl8180_write_phy(dev, addr, data); 15 + } 16 + 17 + static inline void rtl8225_write_phy_cck(struct ieee80211_hw *dev, 18 + u8 addr, u8 data) 19 + { 20 + rtl8180_write_phy(dev, addr, data | 0x10000); 21 + } 22 + 23 + #endif /* RTL8180_RTL8225_H */
+201
drivers/net/wireless/rtl8180_sa2400.c
··· 1 + 2 + /* 3 + * Radio tuning for Philips SA2400 on RTL8180 4 + * 5 + * Copyright 2007 Andrea Merello <andreamrl@tiscali.it> 6 + * 7 + * Code from the BSD driver and the rtl8181 project have been 8 + * very useful to understand certain things 9 + * 10 + * I want to thanks the Authors of such projects and the Ndiswrapper 11 + * project Authors. 12 + * 13 + * A special Big Thanks also is for all people who donated me cards, 14 + * making possible the creation of the original rtl8180 driver 15 + * from which this code is derived! 16 + * 17 + * This program is free software; you can redistribute it and/or modify 18 + * it under the terms of the GNU General Public License version 2 as 19 + * published by the Free Software Foundation. 20 + */ 21 + 22 + #include <linux/init.h> 23 + #include <linux/pci.h> 24 + #include <linux/delay.h> 25 + #include <net/mac80211.h> 26 + 27 + #include "rtl8180.h" 28 + #include "rtl8180_sa2400.h" 29 + 30 + static const u32 sa2400_chan[] = { 31 + 0x00096c, /* ch1 */ 32 + 0x080970, 33 + 0x100974, 34 + 0x180978, 35 + 0x000980, 36 + 0x080984, 37 + 0x100988, 38 + 0x18098c, 39 + 0x000994, 40 + 0x080998, 41 + 0x10099c, 42 + 0x1809a0, 43 + 0x0009a8, 44 + 0x0009b4, /* ch 14 */ 45 + }; 46 + 47 + static void write_sa2400(struct ieee80211_hw *dev, u8 addr, u32 data) 48 + { 49 + struct rtl8180_priv *priv = dev->priv; 50 + u32 phy_config; 51 + 52 + /* MAC will bang bits to the sa2400. sw 3-wire is NOT used */ 53 + phy_config = 0xb0000000; 54 + 55 + phy_config |= ((u32)(addr & 0xf)) << 24; 56 + phy_config |= data & 0xffffff; 57 + 58 + rtl818x_iowrite32(priv, 59 + (__le32 __iomem *) &priv->map->RFPinsOutput, phy_config); 60 + 61 + msleep(3); 62 + } 63 + 64 + static void sa2400_write_phy_antenna(struct ieee80211_hw *dev, short chan) 65 + { 66 + struct rtl8180_priv *priv = dev->priv; 67 + u8 ant = SA2400_ANTENNA; 68 + 69 + if (priv->rfparam & RF_PARAM_ANTBDEFAULT) 70 + ant |= BB_ANTENNA_B; 71 + 72 + if (chan == 14) 73 + ant |= BB_ANTATTEN_CHAN14; 74 + 75 + rtl8180_write_phy(dev, 0x10, ant); 76 + 77 + } 78 + 79 + static void sa2400_rf_set_channel(struct ieee80211_hw *dev, 80 + struct ieee80211_conf *conf) 81 + { 82 + struct rtl8180_priv *priv = dev->priv; 83 + u32 txpw = priv->channels[conf->channel - 1].val & 0xFF; 84 + u32 chan = sa2400_chan[conf->channel - 1]; 85 + 86 + write_sa2400(dev, 7, txpw); 87 + 88 + sa2400_write_phy_antenna(dev, chan); 89 + 90 + write_sa2400(dev, 0, chan); 91 + write_sa2400(dev, 1, 0xbb50); 92 + write_sa2400(dev, 2, 0x80); 93 + write_sa2400(dev, 3, 0); 94 + } 95 + 96 + static void sa2400_rf_stop(struct ieee80211_hw *dev) 97 + { 98 + write_sa2400(dev, 4, 0); 99 + } 100 + 101 + static void sa2400_rf_init(struct ieee80211_hw *dev) 102 + { 103 + struct rtl8180_priv *priv = dev->priv; 104 + u32 anaparam, txconf; 105 + u8 firdac; 106 + int analogphy = priv->rfparam & RF_PARAM_ANALOGPHY; 107 + 108 + anaparam = priv->anaparam; 109 + anaparam &= ~(1 << ANAPARAM_TXDACOFF_SHIFT); 110 + anaparam &= ~ANAPARAM_PWR1_MASK; 111 + anaparam &= ~ANAPARAM_PWR0_MASK; 112 + 113 + if (analogphy) { 114 + anaparam |= SA2400_ANA_ANAPARAM_PWR1_ON << ANAPARAM_PWR1_SHIFT; 115 + firdac = 0; 116 + } else { 117 + anaparam |= (SA2400_DIG_ANAPARAM_PWR1_ON << ANAPARAM_PWR1_SHIFT); 118 + anaparam |= (SA2400_ANAPARAM_PWR0_ON << ANAPARAM_PWR0_SHIFT); 119 + firdac = 1 << SA2400_REG4_FIRDAC_SHIFT; 120 + } 121 + 122 + rtl8180_set_anaparam(priv, anaparam); 123 + 124 + write_sa2400(dev, 0, sa2400_chan[0]); 125 + write_sa2400(dev, 1, 0xbb50); 126 + write_sa2400(dev, 2, 0x80); 127 + write_sa2400(dev, 3, 0); 128 + write_sa2400(dev, 4, 0x19340 | firdac); 129 + write_sa2400(dev, 5, 0x1dfb | (SA2400_MAX_SENS - 54) << 15); 130 + write_sa2400(dev, 4, 0x19348 | firdac); /* calibrate VCO */ 131 + 132 + if (!analogphy) 133 + write_sa2400(dev, 4, 0x1938c); /*???*/ 134 + 135 + write_sa2400(dev, 4, 0x19340 | firdac); 136 + 137 + write_sa2400(dev, 0, sa2400_chan[0]); 138 + write_sa2400(dev, 1, 0xbb50); 139 + write_sa2400(dev, 2, 0x80); 140 + write_sa2400(dev, 3, 0); 141 + write_sa2400(dev, 4, 0x19344 | firdac); /* calibrate filter */ 142 + 143 + /* new from rtl8180 embedded driver (rtl8181 project) */ 144 + write_sa2400(dev, 6, 0x13ff | (1 << 23)); /* MANRX */ 145 + write_sa2400(dev, 8, 0); /* VCO */ 146 + 147 + if (analogphy) { 148 + rtl8180_set_anaparam(priv, anaparam | 149 + (1 << ANAPARAM_TXDACOFF_SHIFT)); 150 + 151 + txconf = rtl818x_ioread32(priv, &priv->map->TX_CONF); 152 + rtl818x_iowrite32(priv, &priv->map->TX_CONF, 153 + txconf | RTL818X_TX_CONF_LOOPBACK_CONT); 154 + 155 + write_sa2400(dev, 4, 0x19341); /* calibrates DC */ 156 + 157 + /* a 5us sleep is required here, 158 + * we rely on the 3ms delay introduced in write_sa2400 */ 159 + write_sa2400(dev, 4, 0x19345); 160 + 161 + /* a 20us sleep is required here, 162 + * we rely on the 3ms delay introduced in write_sa2400 */ 163 + 164 + rtl818x_iowrite32(priv, &priv->map->TX_CONF, txconf); 165 + 166 + rtl8180_set_anaparam(priv, anaparam); 167 + } 168 + /* end new code */ 169 + 170 + write_sa2400(dev, 4, 0x19341 | firdac); /* RTX MODE */ 171 + 172 + /* baseband configuration */ 173 + rtl8180_write_phy(dev, 0, 0x98); 174 + rtl8180_write_phy(dev, 3, 0x38); 175 + rtl8180_write_phy(dev, 4, 0xe0); 176 + rtl8180_write_phy(dev, 5, 0x90); 177 + rtl8180_write_phy(dev, 6, 0x1a); 178 + rtl8180_write_phy(dev, 7, 0x64); 179 + 180 + sa2400_write_phy_antenna(dev, 1); 181 + 182 + rtl8180_write_phy(dev, 0x11, 0x80); 183 + 184 + if (rtl818x_ioread8(priv, &priv->map->CONFIG2) & 185 + RTL818X_CONFIG2_ANTENNA_DIV) 186 + rtl8180_write_phy(dev, 0x12, 0xc7); /* enable ant diversity */ 187 + else 188 + rtl8180_write_phy(dev, 0x12, 0x47); /* disable ant diversity */ 189 + 190 + rtl8180_write_phy(dev, 0x13, 0x90 | priv->csthreshold); 191 + 192 + rtl8180_write_phy(dev, 0x19, 0x0); 193 + rtl8180_write_phy(dev, 0x1a, 0xa0); 194 + } 195 + 196 + const struct rtl818x_rf_ops sa2400_rf_ops = { 197 + .name = "Philips", 198 + .init = sa2400_rf_init, 199 + .stop = sa2400_rf_stop, 200 + .set_chan = sa2400_rf_set_channel 201 + };
+36
drivers/net/wireless/rtl8180_sa2400.h
··· 1 + #ifndef RTL8180_SA2400_H 2 + #define RTL8180_SA2400_H 3 + 4 + /* 5 + * Radio tuning for Philips SA2400 on RTL8180 6 + * 7 + * Copyright 2007 Andrea Merello <andreamrl@tiscali.it> 8 + * 9 + * Code from the BSD driver and the rtl8181 project have been 10 + * very useful to understand certain things 11 + * 12 + * I want to thanks the Authors of such projects and the Ndiswrapper 13 + * project Authors. 14 + * 15 + * A special Big Thanks also is for all people who donated me cards, 16 + * making possible the creation of the original rtl8180 driver 17 + * from which this code is derived! 18 + * 19 + * This program is free software; you can redistribute it and/or modify 20 + * it under the terms of the GNU General Public License version 2 as 21 + * published by the Free Software Foundation. 22 + */ 23 + 24 + #define SA2400_ANTENNA 0x91 25 + #define SA2400_DIG_ANAPARAM_PWR1_ON 0x8 26 + #define SA2400_ANA_ANAPARAM_PWR1_ON 0x28 27 + #define SA2400_ANAPARAM_PWR0_ON 0x3 28 + 29 + /* RX sensitivity in dbm */ 30 + #define SA2400_MAX_SENS 85 31 + 32 + #define SA2400_REG4_FIRDAC_SHIFT 7 33 + 34 + extern const struct rtl818x_rf_ops sa2400_rf_ops; 35 + 36 + #endif /* RTL8180_SA2400_H */
+1 -1
drivers/net/wireless/rtl8187.h
··· 64 64 struct rtl8187_priv { 65 65 /* common between rtl818x drivers */ 66 66 struct rtl818x_csr *map; 67 - void (*rf_init)(struct ieee80211_hw *); 67 + const struct rtl818x_rf_ops *rf; 68 68 int mode; 69 69 int if_id; 70 70
+23 -37
drivers/net/wireless/rtl8187_dev.c
··· 393 393 rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FF7); 394 394 msleep(100); 395 395 396 - priv->rf_init(dev); 396 + priv->rf->init(dev); 397 397 398 398 rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3); 399 - reg = rtl818x_ioread16(priv, &priv->map->PGSELECT) & 0xfffe; 400 - rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg | 0x1); 399 + reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~1; 400 + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg | 1); 401 401 rtl818x_iowrite16(priv, (__le16 *)0xFFFE, 0x10); 402 402 rtl818x_iowrite8(priv, &priv->map->TALLY_SEL, 0x80); 403 403 rtl818x_iowrite8(priv, (u8 *)0xFFFF, 0x60); 404 - rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg); 404 + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); 405 405 406 406 return 0; 407 - } 408 - 409 - static void rtl8187_set_channel(struct ieee80211_hw *dev, int channel) 410 - { 411 - u32 reg; 412 - struct rtl8187_priv *priv = dev->priv; 413 - 414 - reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); 415 - /* Enable TX loopback on MAC level to avoid TX during channel 416 - * changes, as this has be seen to causes problems and the 417 - * card will stop work until next reset 418 - */ 419 - rtl818x_iowrite32(priv, &priv->map->TX_CONF, 420 - reg | RTL818X_TX_CONF_LOOPBACK_MAC); 421 - msleep(10); 422 - rtl8225_rf_set_channel(dev, channel); 423 - msleep(10); 424 - rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg); 425 407 } 426 408 427 409 static int rtl8187_start(struct ieee80211_hw *dev) ··· 474 492 reg &= ~RTL818X_CMD_RX_ENABLE; 475 493 rtl818x_iowrite8(priv, &priv->map->CMD, reg); 476 494 477 - rtl8225_rf_stop(dev); 495 + priv->rf->stop(dev); 478 496 479 497 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); 480 498 reg = rtl818x_ioread8(priv, &priv->map->CONFIG4); ··· 525 543 static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) 526 544 { 527 545 struct rtl8187_priv *priv = dev->priv; 528 - rtl8187_set_channel(dev, conf->channel); 546 + u32 reg; 547 + 548 + reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); 549 + /* Enable TX loopback on MAC level to avoid TX during channel 550 + * changes, as this has be seen to causes problems and the 551 + * card will stop work until next reset 552 + */ 553 + rtl818x_iowrite32(priv, &priv->map->TX_CONF, 554 + reg | RTL818X_TX_CONF_LOOPBACK_MAC); 555 + msleep(10); 556 + priv->rf->set_chan(dev, conf); 557 + msleep(10); 558 + rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg); 529 559 530 560 rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22); 531 561 ··· 747 753 eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_BASE, 748 754 &priv->txpwr_base); 749 755 750 - reg = rtl818x_ioread16(priv, &priv->map->PGSELECT) & ~1; 751 - rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg | 1); 756 + reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~1; 757 + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg | 1); 752 758 /* 0 means asic B-cut, we should use SW 3 wire 753 759 * bit-by-bit banging for radio. 1 means we can use 754 760 * USB specific request to write radio registers */ 755 761 priv->asic_rev = rtl818x_ioread8(priv, (u8 *)0xFFFE) & 0x3; 756 - rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg); 762 + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); 757 763 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 758 764 759 - rtl8225_write(dev, 0, 0x1B7); 760 - 761 - if (rtl8225_read(dev, 8) != 0x588 || rtl8225_read(dev, 9) != 0x700) 762 - priv->rf_init = rtl8225_rf_init; 763 - else 764 - priv->rf_init = rtl8225z2_rf_init; 765 - 766 - rtl8225_write(dev, 0, 0x0B7); 765 + priv->rf = rtl8187_detect_rf(dev); 767 766 768 767 err = ieee80211_register_hw(dev); 769 768 if (err) { ··· 766 779 767 780 printk(KERN_INFO "%s: hwaddr %s, rtl8187 V%d + %s\n", 768 781 wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr), 769 - priv->asic_rev, priv->rf_init == rtl8225_rf_init ? 770 - "rtl8225" : "rtl8225z2"); 782 + priv->asic_rev, priv->rf->name); 771 783 772 784 return 0; 773 785
+42 -10
drivers/net/wireless/rtl8187_rtl8225.c
··· 101 101 msleep(2); 102 102 } 103 103 104 - void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data) 104 + static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data) 105 105 { 106 106 struct rtl8187_priv *priv = dev->priv; 107 107 ··· 111 111 rtl8225_write_bitbang(dev, addr, data); 112 112 } 113 113 114 - u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr) 114 + static u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr) 115 115 { 116 116 struct rtl8187_priv *priv = dev->priv; 117 117 u16 reg80, reg82, reg84, out; ··· 325 325 msleep(1); 326 326 } 327 327 328 - void rtl8225_rf_init(struct ieee80211_hw *dev) 328 + static void rtl8225_rf_init(struct ieee80211_hw *dev) 329 329 { 330 330 struct rtl8187_priv *priv = dev->priv; 331 331 int i; ··· 567 567 0x63, 0x15, 0xc5 /* -66dBm */ 568 568 }; 569 569 570 - void rtl8225z2_rf_init(struct ieee80211_hw *dev) 570 + static void rtl8225z2_rf_init(struct ieee80211_hw *dev) 571 571 { 572 572 struct rtl8187_priv *priv = dev->priv; 573 573 int i; ··· 715 715 rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002); 716 716 } 717 717 718 - void rtl8225_rf_stop(struct ieee80211_hw *dev) 718 + static void rtl8225_rf_stop(struct ieee80211_hw *dev) 719 719 { 720 720 u8 reg; 721 721 struct rtl8187_priv *priv = dev->priv; ··· 731 731 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); 732 732 } 733 733 734 - void rtl8225_rf_set_channel(struct ieee80211_hw *dev, int channel) 734 + static void rtl8225_rf_set_channel(struct ieee80211_hw *dev, 735 + struct ieee80211_conf *conf) 735 736 { 736 737 struct rtl8187_priv *priv = dev->priv; 737 738 738 - if (priv->rf_init == rtl8225_rf_init) 739 - rtl8225_rf_set_tx_power(dev, channel); 739 + if (priv->rf->init == rtl8225_rf_init) 740 + rtl8225_rf_set_tx_power(dev, conf->channel); 740 741 else 741 - rtl8225z2_rf_set_tx_power(dev, channel); 742 + rtl8225z2_rf_set_tx_power(dev, conf->channel); 742 743 743 - rtl8225_write(dev, 0x7, rtl8225_chan[channel - 1]); 744 + rtl8225_write(dev, 0x7, rtl8225_chan[conf->channel - 1]); 744 745 msleep(10); 746 + } 747 + 748 + static const struct rtl818x_rf_ops rtl8225_ops = { 749 + .name = "rtl8225", 750 + .init = rtl8225_rf_init, 751 + .stop = rtl8225_rf_stop, 752 + .set_chan = rtl8225_rf_set_channel 753 + }; 754 + 755 + static const struct rtl818x_rf_ops rtl8225z2_ops = { 756 + .name = "rtl8225z2", 757 + .init = rtl8225z2_rf_init, 758 + .stop = rtl8225_rf_stop, 759 + .set_chan = rtl8225_rf_set_channel 760 + }; 761 + 762 + const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *dev) 763 + { 764 + u16 reg8, reg9; 765 + 766 + rtl8225_write(dev, 0, 0x1B7); 767 + 768 + reg8 = rtl8225_read(dev, 8); 769 + reg9 = rtl8225_read(dev, 9); 770 + 771 + rtl8225_write(dev, 0, 0x0B7); 772 + 773 + if (reg8 != 0x588 || reg9 != 0x700) 774 + return &rtl8225_ops; 775 + 776 + return &rtl8225z2_ops; 745 777 }
+1 -8
drivers/net/wireless/rtl8187_rtl8225.h
··· 20 20 #define RTL8225_ANAPARAM_OFF 0xa00beb59 21 21 #define RTL8225_ANAPARAM2_OFF 0x840dec11 22 22 23 - void rtl8225_write(struct ieee80211_hw *, u8 addr, u16 data); 24 - u16 rtl8225_read(struct ieee80211_hw *, u8 addr); 25 - 26 - void rtl8225_rf_init(struct ieee80211_hw *); 27 - void rtl8225z2_rf_init(struct ieee80211_hw *); 28 - void rtl8225_rf_stop(struct ieee80211_hw *); 29 - void rtl8225_rf_set_channel(struct ieee80211_hw *, int); 30 - 23 + const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *); 31 24 32 25 static inline void rtl8225_write_phy_ofdm(struct ieee80211_hw *dev, 33 26 u8 addr, u32 data)
+25 -4
drivers/net/wireless/rtl818x.h
··· 58 58 #define RTL818X_INT_TX_FO (1 << 15) 59 59 __le32 TX_CONF; 60 60 #define RTL818X_TX_CONF_LOOPBACK_MAC (1 << 17) 61 + #define RTL818X_TX_CONF_LOOPBACK_CONT (3 << 17) 61 62 #define RTL818X_TX_CONF_NO_ICV (1 << 19) 62 63 #define RTL818X_TX_CONF_DISCW (1 << 20) 64 + #define RTL818X_TX_CONF_SAT_HWPLCP (1 << 24) 63 65 #define RTL818X_TX_CONF_R8180_ABCD (2 << 25) 64 66 #define RTL818X_TX_CONF_R8180_F (3 << 25) 65 67 #define RTL818X_TX_CONF_R8185_ABC (4 << 25) 66 68 #define RTL818X_TX_CONF_R8185_D (5 << 25) 67 69 #define RTL818X_TX_CONF_HWVER_MASK (7 << 25) 70 + #define RTL818X_TX_CONF_PROBE_DTS (1 << 29) 71 + #define RTL818X_TX_CONF_HW_SEQNUM (1 << 30) 68 72 #define RTL818X_TX_CONF_CW_MIN (1 << 31) 69 73 __le32 RX_CONF; 70 74 #define RTL818X_RX_CONF_MONITOR (1 << 0) ··· 79 75 #define RTL818X_RX_CONF_DATA (1 << 18) 80 76 #define RTL818X_RX_CONF_CTRL (1 << 19) 81 77 #define RTL818X_RX_CONF_MGMT (1 << 20) 78 + #define RTL818X_RX_CONF_ADDR3 (1 << 21) 79 + #define RTL818X_RX_CONF_PM (1 << 22) 82 80 #define RTL818X_RX_CONF_BSSID (1 << 23) 83 81 #define RTL818X_RX_CONF_RX_AUTORESETPHY (1 << 28) 82 + #define RTL818X_RX_CONF_CSDM1 (1 << 29) 83 + #define RTL818X_RX_CONF_CSDM2 (1 << 30) 84 84 #define RTL818X_RX_CONF_ONLYERLPKT (1 << 31) 85 85 __le32 INT_TIMEOUT; 86 86 __le32 TBDA; ··· 100 92 u8 CONFIG0; 101 93 u8 CONFIG1; 102 94 u8 CONFIG2; 95 + #define RTL818X_CONFIG2_ANTENNA_DIV (1 << 6) 103 96 __le32 ANAPARAM; 104 97 u8 MSR; 105 98 #define RTL818X_MSR_NO_LINK (0 << 2) ··· 113 104 #define RTL818X_CONFIG4_VCOOFF (1 << 7) 114 105 u8 TESTR; 115 106 u8 reserved_9[2]; 116 - __le16 PGSELECT; 107 + u8 PGSELECT; 108 + u8 SECURITY; 117 109 __le32 ANAPARAM2; 118 110 u8 reserved_10[12]; 119 111 __le16 BEACON_INTERVAL; 120 112 __le16 ATIM_WND; 121 113 __le16 BEACON_INTERVAL_TIME; 122 114 __le16 ATIMTR_INTERVAL; 123 - u8 reserved_11[4]; 115 + u8 PHY_DELAY; 116 + u8 CARRIER_SENSE_COUNTER; 117 + u8 reserved_11[2]; 124 118 u8 PHY[4]; 125 119 __le16 RFPinsOutput; 126 120 __le16 RFPinsEnable; ··· 161 149 u8 RETRY_CTR; 162 150 u8 reserved_18[5]; 163 151 __le32 RDSAR; 164 - u8 reserved_19[18]; 165 - u16 TALLY_CNT; 152 + u8 reserved_19[12]; 153 + __le16 FEMR; 154 + u8 reserved_20[4]; 155 + __le16 TALLY_CNT; 166 156 u8 TALLY_SEL; 167 157 } __attribute__((packed)); 158 + 159 + struct rtl818x_rf_ops { 160 + char *name; 161 + void (*init)(struct ieee80211_hw *); 162 + void (*stop)(struct ieee80211_hw *); 163 + void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *); 164 + }; 168 165 169 166 static const struct ieee80211_rate rtl818x_rates[] = { 170 167 { .rate = 10,
+3
include/linux/pci_ids.h
··· 2082 2082 #define PCI_DEVICE_ID_ALTIMA_AC9100 0x03ea 2083 2083 #define PCI_DEVICE_ID_ALTIMA_AC1003 0x03eb 2084 2084 2085 + #define PCI_VENDOR_ID_BELKIN 0x1799 2086 + #define PCI_DEVICE_ID_BELKIN_F5D7010V7 0x701f 2087 + 2085 2088 #define PCI_VENDOR_ID_LENOVO 0x17aa 2086 2089 2087 2090 #define PCI_VENDOR_ID_ARECA 0x17d3