rtl818x.c

Go to the documentation of this file.
00001 
00002 /*
00003  * Linux device driver for RTL8180 / RTL8185
00004  *
00005  * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
00006  * Copyright 2007 Andrea Merello <andreamrl@tiscali.it>
00007  *
00008  * Modified for gPXE, June 2009, by Joshua Oreman <oremanj@rwcr.net>
00009  *
00010  * Based on the r8180 driver, which is:
00011  * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al.
00012  *
00013  * Thanks to Realtek for their support!
00014  *
00015  * This program is free software; you can redistribute it and/or modify
00016  * it under the terms of the GNU General Public License version 2 as
00017  * published by the Free Software Foundation.
00018  */
00019 
00020 FILE_LICENCE(GPL2_ONLY);
00021 
00022 #include <stdint.h>
00023 #include <errno.h>
00024 #include <stdio.h>
00025 #include <unistd.h>
00026 #include <byteswap.h>
00027 #include <gpxe/iobuf.h>
00028 #include <gpxe/malloc.h>
00029 #include <gpxe/pci.h>
00030 #include <gpxe/net80211.h>
00031 #include <gpxe/netdevice.h>
00032 #include <gpxe/threewire.h>
00033 
00034 #include "rtl818x.h"
00035 
00036 /* rtl818x_rates[hw rate number] = rate in 100kbps units */
00037 static const u16 rtl818x_rates[] = {
00038         10, 20, 55, 110, /* 802.11b */
00039         60, 90, 120, 180, 240, 360, 480, 540, /* 802.11g */
00040         0, 0, 0, 0,             /* index safely using a value masked with 0xF */
00041 };
00042 #define RTL818X_NR_B_RATES  4
00043 #define RTL818X_NR_RATES    12
00044 
00045 /* used by RF drivers */
00046 void rtl818x_write_phy(struct net80211_device *dev, u8 addr, u32 data)
00047 {
00048         struct rtl818x_priv *priv = dev->priv;
00049         int i = 10;
00050         u32 buf;
00051 
00052         buf = (data << 8) | addr;
00053 
00054         rtl818x_iowrite32(priv, (u32 *)&priv->map->PHY[0], buf | 0x80);
00055         while (i--) {
00056                 rtl818x_iowrite32(priv, (u32 *)&priv->map->PHY[0], buf);
00057                 if (rtl818x_ioread8(priv, &priv->map->PHY[2]) == (data & 0xFF))
00058                         return;
00059         }
00060 }
00061 
00062 static void rtl818x_handle_rx(struct net80211_device *dev)
00063 {
00064         struct rtl818x_priv *priv = dev->priv;
00065         unsigned int count = RTL818X_RX_RING_SIZE;
00066 
00067         while (count--) {
00068                 struct rtl818x_rx_desc *entry = &priv->rx_ring[priv->rx_idx];
00069                 struct io_buffer *iob = priv->rx_buf[priv->rx_idx];
00070                 u32 flags = le32_to_cpu(entry->flags);
00071 
00072                 if (flags & RTL818X_RX_DESC_FLAG_OWN)
00073                         return;
00074 
00075                 if (flags & (RTL818X_RX_DESC_FLAG_DMA_FAIL |
00076                              RTL818X_RX_DESC_FLAG_FOF |
00077                              RTL818X_RX_DESC_FLAG_RX_ERR)) {
00078                         /* This is crappy hardware. The Linux driver
00079                            doesn't even log these. */
00080                         goto done;
00081                 } else if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) {
00082                         /* This is actually a corrupt packet. */
00083                         DBG2("rtl818x RX:%d CRC fail: flags %08x\n",
00084                              priv->rx_idx, flags);
00085                         net80211_rx_err(dev, NULL, EIO);
00086                 } else {
00087                         u32 flags2 = le32_to_cpu(entry->flags2);
00088                         struct io_buffer *new_iob = alloc_iob(MAX_RX_SIZE);
00089                         if (!new_iob) {
00090                                 net80211_rx_err(dev, NULL, ENOMEM);
00091                                 goto done;
00092                         }
00093 
00094                         DBGP("rtl818x RX:%d success: flags %08x %08x\n",
00095                              priv->rx_idx, flags, flags2);
00096 
00097                         iob_put(iob, flags & 0xFFF);
00098 
00099                         net80211_rx(dev, iob, (flags2 >> 8) & 0x7f,
00100                                     rtl818x_rates[(flags >> 20) & 0xf]);
00101 
00102                         iob = new_iob;
00103                         priv->rx_buf[priv->rx_idx] = iob;
00104                 }
00105 
00106         done:
00107                 entry->rx_buf = cpu_to_le32(virt_to_bus(iob->data));
00108                 entry->flags = cpu_to_le32(RTL818X_RX_DESC_FLAG_OWN | MAX_RX_SIZE);
00109 
00110                 if (priv->rx_idx == RTL818X_RX_RING_SIZE - 1)
00111                         entry->flags |= cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR);
00112 
00113                 priv->rx_idx = (priv->rx_idx + 1) % RTL818X_RX_RING_SIZE;
00114         }
00115 }
00116 
00117 static void rtl818x_handle_tx(struct net80211_device *dev)
00118 {
00119         struct rtl818x_priv *priv = dev->priv;
00120         unsigned int count = RTL818X_TX_RING_SIZE;
00121 
00122         while (count--) {
00123                 struct rtl818x_tx_desc *entry = &priv->tx_ring[priv->tx_cons];
00124                 struct io_buffer *iob = priv->tx_buf[priv->tx_cons];
00125                 u32 flags = le32_to_cpu(entry->flags);
00126                 int rc;
00127 
00128                 if ((flags & RTL818X_TX_DESC_FLAG_OWN) || !iob)
00129                         return;
00130 
00131                 rc = 0;
00132                 if (!(flags & RTL818X_TX_DESC_FLAG_TX_OK)) {
00133                         /* our packet was not ACKed properly */
00134                         rc = EIO;
00135                 }
00136 
00137                 net80211_tx_complete(dev, iob, flags & 0xFF, rc);
00138 
00139                 priv->tx_buf[priv->tx_cons] = NULL;
00140                 priv->tx_cons = (priv->tx_cons + 1) % RTL818X_TX_RING_SIZE;
00141         }
00142 }
00143 
00144 static void rtl818x_poll(struct net80211_device *dev)
00145 {
00146         struct rtl818x_priv *priv = dev->priv;
00147         u16 reg = rtl818x_ioread16(priv, &priv->map->INT_STATUS);
00148 
00149         if (reg == 0xFFFF)
00150                 return;
00151 
00152         rtl818x_iowrite16(priv, &priv->map->INT_STATUS, reg);
00153 
00154         if (reg & (RTL818X_INT_TXN_OK | RTL818X_INT_TXN_ERR))
00155                 rtl818x_handle_tx(dev);
00156 
00157         if (reg & (RTL818X_INT_RX_OK | RTL818X_INT_RX_ERR))
00158                 rtl818x_handle_rx(dev);
00159 }
00160 
00161 #define DIV_ROUND_UP(n,d) (((n)+(d)-1)/(d))
00162 
00163 static int rtl818x_tx(struct net80211_device *dev, struct io_buffer *iob)
00164 {
00165         struct rtl818x_priv *priv = dev->priv;
00166         struct rtl818x_tx_desc *entry;
00167         u32 tx_flags;
00168         u16 plcp_len = 0;
00169         int len = iob_len(iob);
00170 
00171         tx_flags = RTL818X_TX_DESC_FLAG_OWN | RTL818X_TX_DESC_FLAG_FS |
00172                 RTL818X_TX_DESC_FLAG_LS | (priv->hw_rate << 24) | len;
00173 
00174         if (priv->r8185) {
00175                 tx_flags |= RTL818X_TX_DESC_FLAG_DMA |
00176                             RTL818X_TX_DESC_FLAG_NO_ENC;
00177         } else {
00178                 unsigned int remainder;
00179 
00180                 plcp_len = DIV_ROUND_UP(16 * (len + 4),
00181                                         (dev->rates[dev->rate] * 2) / 10);
00182                 remainder = (16 * (len + 4)) %
00183                             ((dev->rates[dev->rate] * 2) / 10);
00184 
00185                 if (remainder > 0 && remainder <= 6)
00186                         plcp_len |= 1 << 15;
00187         }
00188 
00189         entry = &priv->tx_ring[priv->tx_prod];
00190 
00191         if (dev->phy_flags & NET80211_PHY_USE_PROTECTION) {
00192                 tx_flags |= RTL818X_TX_DESC_FLAG_CTS;
00193                 tx_flags |= priv->hw_rtscts_rate << 19;
00194                 entry->rts_duration = net80211_cts_duration(dev, len);
00195         } else {
00196                 entry->rts_duration = 0;
00197         }
00198 
00199         if (entry->flags & RTL818X_TX_DESC_FLAG_OWN) {
00200                 /* card hasn't processed the old packet yet! */
00201                 return -EBUSY;
00202         }
00203 
00204         priv->tx_buf[priv->tx_prod] = iob;
00205         priv->tx_prod = (priv->tx_prod + 1) % RTL818X_TX_RING_SIZE;
00206 
00207         entry->plcp_len = cpu_to_le16(plcp_len);
00208         entry->tx_buf = cpu_to_le32(virt_to_bus(iob->data));
00209         entry->frame_len = cpu_to_le32(len);
00210         entry->flags2 = /* alternate retry rate in 100kbps << 4 */ 0;
00211         entry->retry_limit = RTL818X_MAX_RETRIES;
00212         entry->flags = cpu_to_le32(tx_flags);
00213 
00214         rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING, (1 << 5));
00215 
00216         return 0;
00217 }
00218 
00219 void rtl818x_set_anaparam(struct rtl818x_priv *priv, u32 anaparam)
00220 {
00221         u8 reg;
00222 
00223         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
00224         reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
00225         rtl818x_iowrite8(priv, &priv->map->CONFIG3,
00226                  reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
00227         rtl818x_iowrite32(priv, &priv->map->ANAPARAM, anaparam);
00228         rtl818x_iowrite8(priv, &priv->map->CONFIG3,
00229                  reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
00230         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
00231 }
00232 
00233 static int rtl818x_init_hw(struct net80211_device *dev)
00234 {
00235         struct rtl818x_priv *priv = dev->priv;
00236         u16 reg;
00237 
00238         rtl818x_iowrite8(priv, &priv->map->CMD, 0);
00239         rtl818x_ioread8(priv, &priv->map->CMD);
00240         mdelay(10);
00241 
00242         /* reset */
00243         rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
00244         rtl818x_ioread8(priv, &priv->map->CMD);
00245 
00246         reg = rtl818x_ioread8(priv, &priv->map->CMD);
00247         reg &= (1 << 1);
00248         reg |= RTL818X_CMD_RESET;
00249         rtl818x_iowrite8(priv, &priv->map->CMD, RTL818X_CMD_RESET);
00250         rtl818x_ioread8(priv, &priv->map->CMD);
00251         mdelay(200);
00252 
00253         /* check success of reset */
00254         if (rtl818x_ioread8(priv, &priv->map->CMD) & RTL818X_CMD_RESET) {
00255                 DBG("rtl818x %s: reset timeout!\n", dev->netdev->name);
00256                 return -ETIMEDOUT;
00257         }
00258 
00259         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_LOAD);
00260         rtl818x_ioread8(priv, &priv->map->CMD);
00261         mdelay(200);
00262 
00263         if (rtl818x_ioread8(priv, &priv->map->CONFIG3) & (1 << 3)) {
00264                 /* For cardbus */
00265                 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
00266                 reg |= 1 << 1;
00267                 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg);
00268                 reg = rtl818x_ioread16(priv, &priv->map->FEMR);
00269                 reg |= (1 << 15) | (1 << 14) | (1 << 4);
00270                 rtl818x_iowrite16(priv, &priv->map->FEMR, reg);
00271         }
00272 
00273         rtl818x_iowrite8(priv, &priv->map->MSR, 0);
00274 
00275         if (!priv->r8185)
00276                 rtl818x_set_anaparam(priv, priv->anaparam);
00277 
00278         rtl818x_iowrite32(priv, &priv->map->RDSAR, priv->rx_ring_dma);
00279         rtl818x_iowrite32(priv, &priv->map->TNPDA, priv->tx_ring_dma);
00280 
00281         /* TODO: necessary? specs indicate not */
00282         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
00283         reg = rtl818x_ioread8(priv, &priv->map->CONFIG2);
00284         rtl818x_iowrite8(priv, &priv->map->CONFIG2, reg & ~(1 << 3));
00285         if (priv->r8185) {
00286                 reg = rtl818x_ioread8(priv, &priv->map->CONFIG2);
00287                 rtl818x_iowrite8(priv, &priv->map->CONFIG2, reg | (1 << 4));
00288         }
00289         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
00290 
00291         /* TODO: set CONFIG5 for calibrating AGC on rtl8180 + philips radio? */
00292 
00293         /* TODO: turn off hw wep on rtl8180 */
00294 
00295         rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0);
00296 
00297         if (priv->r8185) {
00298                 rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0);
00299                 rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0x81);
00300                 rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (8 << 4) | 0);
00301 
00302                 rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3);
00303 
00304                 /* TODO: set ClkRun enable? necessary? */
00305                 reg = rtl818x_ioread8(priv, &priv->map->GP_ENABLE);
00306                 rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, reg & ~(1 << 6));
00307                 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
00308                 reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
00309                 rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | (1 << 2));
00310                 rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
00311         } else {
00312                 rtl818x_iowrite16(priv, &priv->map->BRSR, 0x1);
00313                 rtl818x_iowrite8(priv, &priv->map->SECURITY, 0);
00314 
00315                 rtl818x_iowrite8(priv, &priv->map->PHY_DELAY, 0x6);
00316                 rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER, 0x4C);
00317         }
00318 
00319         priv->rf->init(dev);
00320         if (priv->r8185)
00321                 rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3);
00322         return 0;
00323 }
00324 
00325 static int rtl818x_init_rx_ring(struct net80211_device *dev)
00326 {
00327         struct rtl818x_priv *priv = dev->priv;
00328         struct rtl818x_rx_desc *entry;
00329         int i;
00330 
00331         priv->rx_ring = malloc_dma(sizeof(*priv->rx_ring) * RTL818X_RX_RING_SIZE,
00332                                    RTL818X_RING_ALIGN);
00333         priv->rx_ring_dma = virt_to_bus(priv->rx_ring);
00334         if (!priv->rx_ring) {
00335                 DBG("rtl818x %s: cannot allocate RX ring\n", dev->netdev->name);
00336                 return -ENOMEM;
00337         }
00338 
00339         memset(priv->rx_ring, 0, sizeof(*priv->rx_ring) * RTL818X_RX_RING_SIZE);
00340         priv->rx_idx = 0;
00341 
00342         for (i = 0; i < RTL818X_RX_RING_SIZE; i++) {
00343                 struct io_buffer *iob = alloc_iob(MAX_RX_SIZE);
00344                 entry = &priv->rx_ring[i];
00345                 if (!iob)
00346                         return -ENOMEM;
00347 
00348                 priv->rx_buf[i] = iob;
00349                 entry->rx_buf = cpu_to_le32(virt_to_bus(iob->data));
00350                 entry->flags = cpu_to_le32(RTL818X_RX_DESC_FLAG_OWN |
00351                                            MAX_RX_SIZE);
00352         }
00353         entry->flags |= cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR);
00354         return 0;
00355 }
00356 
00357 static void rtl818x_free_rx_ring(struct net80211_device *dev)
00358 {
00359         struct rtl818x_priv *priv = dev->priv;
00360         int i;
00361 
00362         for (i = 0; i < RTL818X_RX_RING_SIZE; i++) {
00363                 free_iob(priv->rx_buf[i]);
00364                 priv->rx_buf[i] = NULL;
00365         }
00366 
00367         free_dma(priv->rx_ring, sizeof(*priv->rx_ring) * RTL818X_RX_RING_SIZE);
00368         priv->rx_ring = NULL;
00369 }
00370 
00371 static int rtl818x_init_tx_ring(struct net80211_device *dev)
00372 {
00373         struct rtl818x_priv *priv = dev->priv;
00374         int i;
00375 
00376         priv->tx_ring = malloc_dma(sizeof(*priv->tx_ring) * RTL818X_TX_RING_SIZE,
00377                                    RTL818X_RING_ALIGN);
00378         priv->tx_ring_dma = virt_to_bus(priv->tx_ring);
00379         if (!priv->tx_ring) {
00380                 DBG("rtl818x %s: cannot allocate TX ring\n", dev->netdev->name);
00381                 return -ENOMEM;
00382         }
00383 
00384         memset(priv->tx_ring, 0, sizeof(*priv->tx_ring) * RTL818X_TX_RING_SIZE);
00385         priv->tx_prod = priv->tx_cons = 0;
00386 
00387         for (i = 0; i < RTL818X_TX_RING_SIZE; i++)
00388                 priv->tx_ring[i].next_tx_desc = cpu_to_le32(priv->tx_ring_dma +
00389                                 ((i + 1) % RTL818X_TX_RING_SIZE) * sizeof(*priv->tx_ring));
00390 
00391         return 0;
00392 }
00393 
00394 static void rtl818x_free_tx_ring(struct net80211_device *dev)
00395 {
00396         struct rtl818x_priv *priv = dev->priv;
00397         int i;
00398 
00399         for (i = 0; i < RTL818X_TX_RING_SIZE; i++) {
00400                 if (priv->tx_buf[i])
00401                         net80211_tx_complete(dev, priv->tx_buf[i], 0, ECANCELED);
00402                 priv->tx_buf[i] = NULL;
00403         }
00404 
00405         free_dma(priv->tx_ring, sizeof(*priv->tx_ring) * RTL818X_TX_RING_SIZE);
00406         priv->tx_ring = NULL;
00407 }
00408 
00409 static void rtl818x_irq(struct net80211_device *dev, int enable)
00410 {
00411         struct rtl818x_priv *priv = dev->priv;
00412         rtl818x_iowrite16(priv, &priv->map->INT_MASK, enable? 0xFFFF : 0);
00413 }
00414 
00415 /* Sets the MAC address of the card. */
00416 static void rtl818x_set_hwaddr(struct net80211_device *dev, u8 *hwaddr)
00417 {
00418         struct rtl818x_priv *priv = dev->priv;
00419         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
00420         rtl818x_iowrite32(priv, (u32 *)&priv->map->MAC[0],
00421                           le32_to_cpu(*(u32 *)hwaddr));
00422         rtl818x_iowrite16(priv, (u16 *)&priv->map->MAC[4],
00423                           le16_to_cpu(*(u16 *)(hwaddr + 4)));
00424         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
00425 }
00426 
00427 static int rtl818x_start(struct net80211_device *dev)
00428 {
00429         struct rtl818x_priv *priv = dev->priv;
00430         int ret;
00431         u32 reg;
00432 
00433         ret = rtl818x_init_rx_ring(dev);
00434         if (ret)
00435                 return ret;
00436 
00437         ret = rtl818x_init_tx_ring(dev);
00438         if (ret)
00439                 goto err_free_rings;
00440 
00441         ret = rtl818x_init_hw(dev);
00442         if (ret)
00443                 goto err_free_rings;
00444 
00445         rtl818x_set_hwaddr(dev, dev->netdev->ll_addr);
00446 
00447         rtl818x_iowrite32(priv, &priv->map->RDSAR, priv->rx_ring_dma);
00448         rtl818x_iowrite32(priv, &priv->map->TNPDA, priv->tx_ring_dma);
00449 
00450         rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
00451 
00452         rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0);
00453         rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0);
00454 
00455         reg = RTL818X_RX_CONF_ONLYERLPKT |
00456               RTL818X_RX_CONF_RX_AUTORESETPHY |
00457               RTL818X_RX_CONF_MGMT |
00458               RTL818X_RX_CONF_DATA |
00459               (7 << 8 /* MAX RX DMA */) |
00460               RTL818X_RX_CONF_BROADCAST |
00461               RTL818X_RX_CONF_NICMAC;
00462 
00463         if (priv->r8185)
00464                 reg |= RTL818X_RX_CONF_CSDM1 | RTL818X_RX_CONF_CSDM2;
00465         else {
00466                 reg |= (priv->rfparam & RF_PARAM_CARRIERSENSE1)
00467                         ? RTL818X_RX_CONF_CSDM1 : 0;
00468                 reg |= (priv->rfparam & RF_PARAM_CARRIERSENSE2)
00469                         ? RTL818X_RX_CONF_CSDM2 : 0;
00470         }
00471 
00472         priv->rx_conf = reg;
00473         rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg);
00474 
00475         if (priv->r8185) {
00476                 reg = rtl818x_ioread8(priv, &priv->map->CW_CONF);
00477                 reg &= ~RTL818X_CW_CONF_PERPACKET_CW_SHIFT;
00478                 reg |= RTL818X_CW_CONF_PERPACKET_RETRY_SHIFT;
00479                 rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg);
00480 
00481                 reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL);
00482                 reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN_SHIFT;
00483                 reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT;
00484                 reg |=  RTL818X_TX_AGC_CTL_FEEDBACK_ANT;
00485                 rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg);
00486 
00487                 /* disable early TX */
00488                 rtl818x_iowrite8(priv, (u8 *)priv->map + 0xec, 0x3f);
00489         }
00490 
00491         reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
00492         reg |= (6 << 21 /* MAX TX DMA */) |
00493                RTL818X_TX_CONF_NO_ICV;
00494 
00495         if (priv->r8185)
00496                 reg &= ~RTL818X_TX_CONF_PROBE_DTS;
00497         else
00498                 reg &= ~RTL818X_TX_CONF_HW_SEQNUM;
00499 
00500         /* different meaning, same value on both rtl8185 and rtl8180 */
00501         reg &= ~RTL818X_TX_CONF_SAT_HWPLCP;
00502 
00503         rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg);
00504 
00505         reg = rtl818x_ioread8(priv, &priv->map->CMD);
00506         reg |= RTL818X_CMD_RX_ENABLE;
00507         reg |= RTL818X_CMD_TX_ENABLE;
00508         rtl818x_iowrite8(priv, &priv->map->CMD, reg);
00509 
00510         DBG("%s rtl818x: started\n", dev->netdev->name);
00511 
00512         return 0;
00513 
00514  err_free_rings:
00515         rtl818x_free_rx_ring(dev);
00516         if (priv->tx_ring)
00517                 rtl818x_free_tx_ring(dev);
00518 
00519         DBG("%s rtl818x: failed to start\n", dev->netdev->name);
00520 
00521         return ret;
00522 }
00523 
00524 static void rtl818x_stop(struct net80211_device *dev)
00525 {
00526         struct rtl818x_priv *priv = dev->priv;
00527         u8 reg;
00528 
00529         rtl818x_irq(dev, 0);
00530 
00531         reg = rtl818x_ioread8(priv, &priv->map->CMD);
00532         reg &= ~RTL818X_CMD_TX_ENABLE;
00533         reg &= ~RTL818X_CMD_RX_ENABLE;
00534         rtl818x_iowrite8(priv, &priv->map->CMD, reg);
00535 
00536         priv->rf->stop(dev);
00537 
00538         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
00539         reg = rtl818x_ioread8(priv, &priv->map->CONFIG4);
00540         rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF);
00541         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
00542 
00543         rtl818x_free_rx_ring(dev);
00544         rtl818x_free_tx_ring(dev);
00545 }
00546 
00547 static int rtl818x_config(struct net80211_device *dev, int changed)
00548 {
00549         struct rtl818x_priv *priv = dev->priv;
00550         int i;
00551 
00552         if (changed & NET80211_CFG_CHANNEL)
00553                 priv->rf->set_chan(dev, &dev->channels[dev->channel]);
00554 
00555         if (changed & NET80211_CFG_ASSOC) {
00556                 for (i = 0; i < ETH_ALEN; i++)
00557                         rtl818x_iowrite8(priv, &priv->map->BSSID[i], dev->bssid[i]);
00558                 rtl818x_iowrite8(priv, &priv->map->MSR,
00559                                  dev->state & NET80211_ASSOCIATED?
00560                                         RTL818X_MSR_INFRA : RTL818X_MSR_NO_LINK);
00561         }
00562 
00563         if (changed & NET80211_CFG_PHY_PARAMS)
00564                 priv->rf->conf_erp(dev);
00565 
00566         if (changed & NET80211_CFG_RATE) {
00567                 /* figure out the hardware rate number for the new
00568                    logical rate */
00569                 int hw_rate;
00570                 for (hw_rate = 0; hw_rate < RTL818X_NR_RATES &&
00571                              rtl818x_rates[hw_rate] != dev->rates[dev->rate];
00572                      hw_rate++)
00573                         ;
00574                 if (hw_rate >= RTL818X_NR_RATES)
00575                         return -EINVAL;
00576 
00577                 priv->hw_rate = hw_rate;
00578 
00579                 /* and the RTS/CTS rate */
00580                 for (hw_rate = 0; hw_rate < RTL818X_NR_RATES &&
00581                              rtl818x_rates[hw_rate] !=
00582                                 dev->rates[dev->rtscts_rate];
00583                      hw_rate++)
00584                         ;
00585                 if (hw_rate >= RTL818X_NR_RATES)
00586                         hw_rate = priv->hw_rate;
00587 
00588                 priv->hw_rtscts_rate = hw_rate;
00589         }
00590 
00591         return 0;
00592 }
00593 
00594 static const u8 rtl818x_eeprom_bits[] = {
00595         [SPI_BIT_SCLK] = RTL818X_EEPROM_CMD_CK,
00596         [SPI_BIT_MISO] = RTL818X_EEPROM_CMD_READ,
00597         [SPI_BIT_MOSI] = RTL818X_EEPROM_CMD_WRITE,
00598         [SPI_BIT_SS(0)] = RTL818X_EEPROM_CMD_CS,
00599 };
00600 
00601 static int rtl818x_spi_read_bit(struct bit_basher *basher, unsigned int bit_id)
00602 {
00603         struct rtl818x_priv *priv = container_of(basher, struct rtl818x_priv,
00604                                                  spibit.basher);
00605 
00606         u8 reg = rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00607         return reg & rtl818x_eeprom_bits[bit_id];
00608 }
00609 
00610 static void rtl818x_spi_write_bit(struct bit_basher *basher,
00611                                   unsigned int bit_id, unsigned long data)
00612 {
00613         struct rtl818x_priv *priv = container_of(basher, struct rtl818x_priv,
00614                                                  spibit.basher);
00615 
00616         u8 reg = rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00617         u8 mask = rtl818x_eeprom_bits[bit_id];
00618         reg = (reg & ~mask) | (data & mask);
00619 
00620         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, reg);
00621 
00622         rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00623         udelay(10);
00624 }
00625 
00626 static struct bit_basher_operations rtl818x_basher_ops = {
00627         .read = rtl818x_spi_read_bit,
00628         .write = rtl818x_spi_write_bit,
00629 };
00630 
00631 #if DBGLVL_MAX
00632 static const char *rtl818x_rf_names[] = {
00633         NULL,                   /* no 0 */
00634         "Intersil", "RFMD",     /* unsupported 1-2 */
00635         "SA2400", "max2820", "GRF5101", /* supported 3-5 */
00636         NULL, NULL, NULL,       /* no 6-8 */
00637         "RTL8225",              /* supported 9 */
00638         "RTL8255",              /* unsupported 10 */
00639 };
00640 #define RTL818X_NR_RF_NAMES 11
00641 #endif
00642 
00643 struct net80211_device_operations rtl818x_operations = {
00644         .open = rtl818x_start,
00645         .close = rtl818x_stop,
00646         .transmit = rtl818x_tx,
00647         .poll = rtl818x_poll,
00648         .irq = rtl818x_irq,
00649         .config = rtl818x_config,
00650 };
00651 
00652 static int rtl818x_probe(struct pci_device *pdev,
00653                          const struct pci_device_id *id __unused)
00654 {
00655         struct net80211_device *dev;
00656         struct rtl818x_priv *priv;
00657         struct rtl818x_rf_ops *rf;
00658         int err, i;
00659         const char *chip_name;
00660         u32 reg;
00661         u16 eeprom_val;
00662         struct net80211_hw_info *hwinfo;
00663 
00664         hwinfo = zalloc(sizeof(*hwinfo));
00665         if (!hwinfo) {
00666                 DBG("rtl818x: hwinfo alloc failed\n");
00667                 return -ENOMEM;
00668         }
00669 
00670         adjust_pci_device(pdev);
00671 
00672         dev = net80211_alloc(sizeof(*priv));
00673         if (!dev) {
00674                 DBG("rtl818x: net80211 alloc failed\n");
00675                 return -ENOMEM;
00676         }
00677 
00678         priv = dev->priv;
00679         priv->pdev = pdev;
00680         dev->netdev->dev = &pdev->dev;
00681 
00682         priv->map = (struct rtl818x_csr *)pdev->ioaddr;
00683         if (!priv->map) {
00684                 DBG("rtl818x: cannot find device memory\n");
00685                 err = -ENXIO;
00686                 goto err_free_dev;
00687         }
00688 
00689         reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
00690         reg &= RTL818X_TX_CONF_HWVER_MASK;
00691         switch (reg) {
00692         case RTL818X_TX_CONF_R8180_ABCD:
00693                 chip_name = "0";
00694                 break;
00695         case RTL818X_TX_CONF_R8180_F:
00696                 chip_name = "0vF";
00697                 break;
00698         case RTL818X_TX_CONF_R8185_ABC:
00699                 chip_name = "5";
00700                 break;
00701         case RTL818X_TX_CONF_R8185_D:
00702                 chip_name = "5vD";
00703                 break;
00704         default:
00705                 DBG("rtl818x: Unknown chip! (0x%x)\n", reg >> 25);
00706                 err = -ENOSYS;
00707                 goto err_free_dev;
00708         }
00709 
00710         priv->r8185 = reg & RTL818X_TX_CONF_R8185_ABC;
00711 
00712         hwinfo->bands = NET80211_BAND_BIT_2GHZ;
00713         hwinfo->flags = NET80211_HW_RX_HAS_FCS;
00714         hwinfo->signal_type = NET80211_SIGNAL_ARBITRARY;
00715         hwinfo->signal_max = 65;
00716         hwinfo->channel_change_time = 1000;
00717 
00718         memcpy(hwinfo->rates[NET80211_BAND_2GHZ], rtl818x_rates,
00719                sizeof(*rtl818x_rates) * RTL818X_NR_RATES);
00720 
00721         if (priv->r8185) {
00722                 hwinfo->modes = NET80211_MODE_B | NET80211_MODE_G;
00723                 hwinfo->nr_rates[NET80211_BAND_2GHZ] = RTL818X_NR_RATES;
00724         } else {
00725                 hwinfo->modes = NET80211_MODE_B;
00726                 hwinfo->nr_rates[NET80211_BAND_2GHZ] = RTL818X_NR_B_RATES;
00727         }
00728 
00729         priv->spibit.basher.op = &rtl818x_basher_ops;
00730         priv->spibit.bus.mode = SPI_MODE_THREEWIRE;
00731         init_spi_bit_basher(&priv->spibit);
00732 
00733         DBG2("rtl818x RX_CONF: %08x\n", rtl818x_ioread32(priv, &priv->map->RX_CONF));
00734 
00735         if (rtl818x_ioread32(priv, &priv->map->RX_CONF) & (1 << 6))
00736                 init_at93c66(&priv->eeprom, 16);
00737         else
00738                 init_at93c46(&priv->eeprom, 16);
00739         priv->eeprom.bus = &priv->spibit.bus;
00740 
00741         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_PROGRAM);
00742         rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
00743         udelay(10);
00744 
00745         nvs_read(&priv->eeprom.nvs, 0x06, &eeprom_val, 2);
00746         DBG2("rtl818x eeprom val = %04x\n", eeprom_val);
00747         eeprom_val &= 0xFF;
00748 
00749         priv->rf = NULL;
00750         for_each_table_entry(rf, RTL818X_RF_DRIVERS) {
00751                 if (rf->id == eeprom_val) {
00752                         priv->rf = rf;
00753                         break;
00754                 }
00755         }
00756 
00757         if (!priv->rf) {
00758 #if DBGLVL_MAX
00759                 if (eeprom_val < RTL818X_NR_RF_NAMES &&
00760                     rtl818x_rf_names[eeprom_val] != NULL)
00761                         DBG("rtl818x: %s RF frontend not supported!\n",
00762                             rtl818x_rf_names[eeprom_val]);
00763                 else
00764                         DBG("rtl818x: RF frontend #%d not recognized!\n",
00765                             eeprom_val);
00766 #endif
00767 
00768                 err = -ENOSYS;
00769                 goto err_free_dev;
00770         }
00771 
00772         nvs_read(&priv->eeprom.nvs, 0x17, &eeprom_val, 2);
00773         priv->csthreshold = eeprom_val >> 8;
00774         if (!priv->r8185) {
00775                 nvs_read(&priv->eeprom.nvs, 0xD, &priv->anaparam, 4);
00776                 nvs_read(&priv->eeprom.nvs, 0x19, &priv->rfparam, 2);
00777                 priv->anaparam = le32_to_cpu(priv->anaparam);
00778                 priv->rfparam = le16_to_cpu(priv->rfparam);
00779         }
00780 
00781         /* read the MAC address */
00782         nvs_read(&priv->eeprom.nvs, 0x7, hwinfo->hwaddr, 6);
00783 
00784         /* CCK TX power */
00785         for (i = 0; i < 14; i += 2) {
00786                 u16 txpwr;
00787                 nvs_read(&priv->eeprom.nvs, 0x10 + (i >> 1), &txpwr, 2);
00788                 priv->txpower[i] = txpwr & 0xFF;
00789                 priv->txpower[i + 1] = txpwr >> 8;
00790         }
00791 
00792         /* OFDM TX power */
00793         if (priv->r8185) {
00794                 for (i = 0; i < 14; i += 2) {
00795                         u16 txpwr;
00796                         nvs_read(&priv->eeprom.nvs, 0x20 + (i >> 1), &txpwr, 2);
00797                         priv->txpower[i] |= (txpwr & 0xFF) << 8;
00798                         priv->txpower[i + 1] |= txpwr & 0xFF00;
00799                 }
00800         }
00801 
00802         rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
00803 
00804         err = net80211_register(dev, &rtl818x_operations, hwinfo);
00805         if (err) {
00806                 DBG("rtl818x: cannot register device\n");
00807                 goto err_free_dev;
00808         }
00809 
00810         free(hwinfo);
00811 
00812         DBG("rtl818x: Realtek RTL818%s (RF chip %s) with address %s\n",
00813             chip_name, priv->rf->name, netdev_addr(dev->netdev));
00814 
00815         return 0;
00816 
00817  err_free_dev:
00818         pci_set_drvdata(pdev, NULL);
00819         net80211_free(dev);
00820         free(hwinfo);
00821         return err;
00822 }
00823 
00824 static void rtl818x_remove(struct pci_device *pdev)
00825 {
00826         struct net80211_device *dev = pci_get_drvdata(pdev);
00827 
00828         if (!dev)
00829                 return;
00830 
00831         net80211_unregister(dev);
00832         net80211_free(dev);
00833 }
00834 
00835 /* Hide PCI_ROM definitions in here from parserom.pl; the definitions
00836    that should be used are in rtl8180.c and rtl8185.c. */
00837 #define RTL_ROM PCI_ROM
00838 
00839 static struct pci_device_id rtl818x_nics[] = {
00840         RTL_ROM(0x10ec, 0x8185, "rtl8185", "Realtek 8185", 0),
00841         RTL_ROM(0x1799, 0x700f, "f5d7000", "Belkin F5D7000", 0),
00842         RTL_ROM(0x1799, 0x701f, "f5d7010", "Belkin F5D7010", 0),
00843 
00844         RTL_ROM(0x10ec, 0x8180, "rtl8180", "Realtek 8180", 0),
00845         RTL_ROM(0x1799, 0x6001, "f5d6001", "Belkin F5D6001", 0),
00846         RTL_ROM(0x1799, 0x6020, "f5d6020", "Belkin F5D6020", 0),
00847         RTL_ROM(0x1186, 0x3300, "dwl510",  "D-Link DWL-510", 0),
00848 };
00849 
00850 struct pci_driver rtl818x_driver __pci_driver = {
00851         .ids            = rtl818x_nics,
00852         .id_count       = sizeof(rtl818x_nics) / sizeof(rtl818x_nics[0]),
00853         .probe          = rtl818x_probe,
00854         .remove         = rtl818x_remove,
00855 };

Generated on Tue Apr 6 20:01:03 2010 for gPXE by  doxygen 1.5.7.1