[drivers rtl8180] Debugging tweaks, decrease ring size, ignore DMA errors
authorJoshua Oreman <oremanj@xenon.get-linux.org>
Tue, 9 Jun 2009 04:40:09 +0000 (21:40 -0700)
committerJoshua Oreman <oremanj@xenon.get-linux.org>
Tue, 9 Jun 2009 04:40:09 +0000 (21:40 -0700)
This card generates a very large number of RX packets with the DMA_FAIL
status flag set. As best I can tell, this is a somewhat brain-damaged way
of flagging packets that were garbled upon reception (as is rather common
on wireless networks). The Linux driver ignores such packets, and we will
too.

Also decreased the ring size from 16 to 8 descriptors in each of TX and RX,
so we don't do quite such a number on the heap. 802.11 frames can be up to
2356 bytes, so with the alignment constraints of io_buffers we need 4k off
the bat for each RX descriptor.

Finally, changed some debugging messages a bit. Changed the tx status code
for "this packet was not ACKed properly" from EBUSY to EIO as more befitting
the situation.

src/drivers/net/rtl818x/rtl8180.c
src/drivers/net/rtl818x/rtl8180.h

index e019d4d..2ab9211 100644 (file)
@@ -73,10 +73,14 @@ static void rtl8180_handle_rx(struct net80211_device *dev)
 
                if (flags & (RTL818X_RX_DESC_FLAG_DMA_FAIL |
                             RTL818X_RX_DESC_FLAG_FOF |
-                            RTL818X_RX_DESC_FLAG_RX_ERR |
-                            RTL818X_RX_DESC_FLAG_CRC32_ERR)) {
-                       DBG2("rtl8180 RX:%d fail: flags %08x\n", priv->rx_idx,
-                            flags);
+                            RTL818X_RX_DESC_FLAG_RX_ERR)) {
+                       /* This is crappy hardware. The Linux driver
+                          doesn't even log these. */
+                       goto done;
+               } else if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) {
+                       /* This is actually a corrupt packet. */
+                       DBG2("rtl8180 RX:%d CRC fail: flags %08x\n",
+                            priv->rx_idx, flags);                      
                        net80211_rx_err(dev, NULL, EIO);
                } else {
                        u32 flags2 = le32_to_cpu(entry->flags2);
@@ -86,7 +90,7 @@ static void rtl8180_handle_rx(struct net80211_device *dev)
                                goto done;
                        }
 
-                       DBG2("rtl8180 RX:%d success: flags %08x %08x\n",
+                       DBGP("rtl8180 RX:%d success: flags %08x %08x\n",
                             priv->rx_idx, flags, flags2);
 
                        iob_put(iob, flags & 0xFFF);
@@ -104,9 +108,6 @@ static void rtl8180_handle_rx(struct net80211_device *dev)
                if (priv->rx_idx == RTL8180_RX_RING_SIZE - 1)
                        entry->flags |= cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR);
 
-               DBG2("rtl8180 RX:%d prepare into %08x flags %08x\n",
-                    priv->rx_idx, entry->rx_buf, entry->flags);
-
                priv->rx_idx = (priv->rx_idx + 1) % RTL8180_RX_RING_SIZE;
        }
 }
@@ -128,7 +129,7 @@ static void rtl8180_handle_tx(struct net80211_device *dev)
                rc = 0;
                if (!(flags & RTL818X_TX_DESC_FLAG_TX_OK)) {
                        /* our packet was not ACKed properly */
-                       rc = EBUSY;
+                       rc = EIO;
                }
 
                net80211_tx_complete(dev, iob, rc);
@@ -143,6 +144,9 @@ static void rtl8180_poll(struct net80211_device *dev)
        struct rtl8180_priv *priv = dev->priv;
        u16 reg = rtl818x_ioread16(priv, &priv->map->INT_STATUS);
 
+       if (reg == 0xFFFF)
+               return;
+
        rtl818x_iowrite16(priv, &priv->map->INT_STATUS, reg);
 
        if (reg & (RTL818X_INT_TXN_OK | RTL818X_INT_TXN_ERR))
@@ -494,6 +498,8 @@ static int rtl8180_start(struct net80211_device *dev)
        reg |= RTL818X_CMD_TX_ENABLE;
        rtl818x_iowrite8(priv, &priv->map->CMD, reg);
 
+       DBG("%s rtl8180: started\n", dev->netdev->name);
+
        return 0;
 
  err_free_rings:
@@ -501,6 +507,8 @@ static int rtl8180_start(struct net80211_device *dev)
        if (priv->tx_ring)
                rtl8180_free_tx_ring(dev);
 
+       DBG("%s rtl8180: failed to start\n", dev->netdev->name);
+
        return ret;
 }
 
index 557cf3d..a2e1586 100644 (file)
@@ -27,8 +27,8 @@ FILE_LICENCE(GPL2_ONLY);
 #define ANAPARAM_PWR1_SHIFT    20
 #define ANAPARAM_PWR1_MASK     (0x7F << ANAPARAM_PWR1_SHIFT)
 
-#define RTL8180_RX_RING_SIZE   16 /* doesn't have to be a power of 2 */
-#define RTL8180_TX_RING_SIZE   16 /* nor this [but 2^n is very slightly faster] */
+#define RTL8180_RX_RING_SIZE   8 /* doesn't have to be a power of 2 */
+#define RTL8180_TX_RING_SIZE   8 /* nor this [but 2^n is very slightly faster] */
 #define RTL8180_RING_ALIGN     256
 
 #define RTL8180_MAX_RETRIES     4