OSDN Git Service

rtl8180: avoid potential NULL deref in rtl8180_beacon_work
[uclinux-h8/linux.git] / drivers / net / wireless / rtl818x / rtl8180_dev.c
index 515817d..b50c39a 100644 (file)
@@ -103,6 +103,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
 {
        struct rtl8180_priv *priv = dev->priv;
        unsigned int count = 32;
+       u8 signal, agc, sq;
 
        while (count--) {
                struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx];
@@ -130,10 +131,18 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
                        skb_put(skb, flags & 0xFFF);
 
                        rx_status.antenna = (flags2 >> 15) & 1;
-                       /* TODO: improve signal/rssi reporting */
-                       rx_status.signal = (flags2 >> 8) & 0x7F;
-                       /* XXX: is this correct? */
                        rx_status.rate_idx = (flags >> 20) & 0xF;
+                       agc = (flags2 >> 17) & 0x7F;
+                       if (priv->r8185) {
+                               if (rx_status.rate_idx > 3)
+                                       signal = 90 - clamp_t(u8, agc, 25, 90);
+                               else
+                                       signal = 95 - clamp_t(u8, agc, 30, 95);
+                       } else {
+                               sq = flags2 & 0xff;
+                               signal = priv->rf->calc_rssi(agc, sq);
+                       }
+                       rx_status.signal = signal;
                        rx_status.freq = dev->conf.channel->center_freq;
                        rx_status.band = dev->conf.channel->band;
                        rx_status.mactime = le64_to_cpu(entry->tsft);
@@ -352,7 +361,7 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev)
 
        /* check success of reset */
        if (rtl818x_ioread8(priv, &priv->map->CMD) & RTL818X_CMD_RESET) {
-               printk(KERN_ERR "%s: reset timeout!\n", wiphy_name(dev->wiphy));
+               wiphy_err(dev->wiphy, "reset timeout!\n");
                return -ETIMEDOUT;
        }
 
@@ -436,8 +445,7 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev)
                                             &priv->rx_ring_dma);
 
        if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) {
-               printk(KERN_ERR "%s: Cannot allocate RX ring\n",
-                      wiphy_name(dev->wiphy));
+               wiphy_err(dev->wiphy, "cannot allocate rx ring\n");
                return -ENOMEM;
        }
 
@@ -494,8 +502,8 @@ static int rtl8180_init_tx_ring(struct ieee80211_hw *dev,
 
        ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma);
        if (!ring || (unsigned long)ring & 0xFF) {
-               printk(KERN_ERR "%s: Cannot allocate TX ring (prio = %d)\n",
-                      wiphy_name(dev->wiphy), prio);
+               wiphy_err(dev->wiphy, "cannot allocate tx ring (prio = %d)\n",
+                         prio);
                return -ENOMEM;
        }
 
@@ -560,8 +568,7 @@ static int rtl8180_start(struct ieee80211_hw *dev)
        ret = request_irq(priv->pdev->irq, rtl8180_interrupt,
                          IRQF_SHARED, KBUILD_MODNAME, dev);
        if (ret) {
-               printk(KERN_ERR "%s: failed to register IRQ handler\n",
-                      wiphy_name(dev->wiphy));
+               wiphy_err(dev->wiphy, "failed to register irq handler\n");
                goto err_free_rings;
        }
 
@@ -671,7 +678,7 @@ static u64 rtl8180_get_tsf(struct ieee80211_hw *dev)
               (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32;
 }
 
-void rtl8180_beacon_work(struct work_struct *work)
+static void rtl8180_beacon_work(struct work_struct *work)
 {
        struct rtl8180_vif *vif_priv =
                container_of(work, struct rtl8180_vif, beacon_work.work);
@@ -688,6 +695,8 @@ void rtl8180_beacon_work(struct work_struct *work)
 
        /* grab a fresh beacon */
        skb = ieee80211_beacon_get(dev, vif);
+       if (!skb)
+               goto resched;
 
        /*
         * update beacon timestamp w/ TSF value
@@ -1098,9 +1107,8 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
                goto err_iounmap;
        }
 
-       printk(KERN_INFO "%s: hwaddr %pM, %s + %s\n",
-              wiphy_name(dev->wiphy), mac_addr,
-              chip_name, priv->rf->name);
+       wiphy_info(dev->wiphy, "hwaddr %pm, %s + %s\n",
+                  mac_addr, chip_name, priv->rf->name);
 
        return 0;