rtl8180: support for rtl8187se RX descriptors
authorAndrea Merello <andrea.merello@gmail.com>
Wed, 26 Mar 2014 19:59:52 +0000 (20:59 +0100)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 27 Mar 2014 18:20:07 +0000 (14:20 -0400)
Currently RX status descriptor and RX command descriptor are
represented using the same struct type.
This patch splits this by introducing different types for
rx status and command descriptor.
Doing this make it possible to handle rtl8187se RX descriptors
easier.
This patch do also this by adding specific cases where needed.

Signed-off-by: Andrea Merello <andrea.merello@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/rtl818x/rtl8180/dev.c
drivers/net/wireless/rtl818x/rtl8180/rtl8180.h

index 6b237ed15eed6b6a1d1c9e93496f41f9df84fce8..867ec07da41457605b8a44b2648144c77dd18648 100644 (file)
@@ -129,14 +129,30 @@ void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data)
 static void rtl8180_handle_rx(struct ieee80211_hw *dev)
 {
        struct rtl8180_priv *priv = dev->priv;
+       struct rtl818x_rx_cmd_desc *cmd_desc;
        unsigned int count = 32;
        u8 signal, agc, sq;
        dma_addr_t mapping;
 
        while (count--) {
-               struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx];
+               void *entry = priv->rx_ring + priv->rx_idx * priv->rx_ring_sz;
                struct sk_buff *skb = priv->rx_buf[priv->rx_idx];
-               u32 flags = le32_to_cpu(entry->flags);
+               u32 flags, flags2;
+               u64 tsft;
+
+               if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) {
+                       struct rtl8187se_rx_desc *desc = entry;
+
+                       flags = le32_to_cpu(desc->flags);
+                       flags2 = le32_to_cpu(desc->flags2);
+                       tsft = le64_to_cpu(desc->tsft);
+               } else {
+                       struct rtl8180_rx_desc *desc = entry;
+
+                       flags = le32_to_cpu(desc->flags);
+                       flags2 = le32_to_cpu(desc->flags2);
+                       tsft = le64_to_cpu(desc->tsft);
+               }
 
                if (flags & RTL818X_RX_DESC_FLAG_OWN)
                        return;
@@ -146,7 +162,6 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
                                      RTL818X_RX_DESC_FLAG_RX_ERR)))
                        goto done;
                else {
-                       u32 flags2 = le32_to_cpu(entry->flags2);
                        struct ieee80211_rx_status rx_status = {0};
                        struct sk_buff *new_skb = dev_alloc_skb(MAX_RX_SIZE);
 
@@ -178,14 +193,18 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
                                        signal = 90 - clamp_t(u8, agc, 25, 90);
                                else
                                        signal = 95 - clamp_t(u8, agc, 30, 95);
-                       } else {
+                       } else if (priv->chip_family ==
+                                  RTL818X_CHIP_FAMILY_RTL8180) {
                                sq = flags2 & 0xff;
                                signal = priv->rf->calc_rssi(agc, sq);
+                       } else {
+                               /* TODO: rtl8187se rssi */
+                               signal = 10;
                        }
                        rx_status.signal = signal;
                        rx_status.freq = dev->conf.chandef.chan->center_freq;
                        rx_status.band = dev->conf.chandef.chan->band;
-                       rx_status.mactime = le64_to_cpu(entry->tsft);
+                       rx_status.mactime = tsft;
                        rx_status.flag |= RX_FLAG_MACTIME_START;
                        if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
                                rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
@@ -199,11 +218,13 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
                }
 
        done:
-               entry->rx_buf = cpu_to_le32(*((dma_addr_t *)skb->cb));
-               entry->flags = cpu_to_le32(RTL818X_RX_DESC_FLAG_OWN |
+               cmd_desc = entry;
+               cmd_desc->rx_buf = cpu_to_le32(*((dma_addr_t *)skb->cb));
+               cmd_desc->flags = cpu_to_le32(RTL818X_RX_DESC_FLAG_OWN |
                                           MAX_RX_SIZE);
                if (priv->rx_idx == 31)
-                       entry->flags |= cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR);
+                       cmd_desc->flags |=
+                               cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR);
                priv->rx_idx = (priv->rx_idx + 1) % 32;
        }
 }
@@ -529,11 +550,16 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev)
 static int rtl8180_init_rx_ring(struct ieee80211_hw *dev)
 {
        struct rtl8180_priv *priv = dev->priv;
-       struct rtl8180_rx_desc *entry;
+       struct rtl818x_rx_cmd_desc *entry;
        int i;
 
+       if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE)
+               priv->rx_ring_sz = sizeof(struct rtl8187se_rx_desc);
+       else
+               priv->rx_ring_sz = sizeof(struct rtl8180_rx_desc);
+
        priv->rx_ring = pci_alloc_consistent(priv->pdev,
-                                            sizeof(*priv->rx_ring) * 32,
+                                            priv->rx_ring_sz * 32,
                                             &priv->rx_ring_dma);
 
        if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) {
@@ -541,13 +567,13 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev)
                return -ENOMEM;
        }
 
-       memset(priv->rx_ring, 0, sizeof(*priv->rx_ring) * 32);
+       memset(priv->rx_ring, 0, priv->rx_ring_sz * 32);
        priv->rx_idx = 0;
 
        for (i = 0; i < 32; i++) {
                struct sk_buff *skb = dev_alloc_skb(MAX_RX_SIZE);
                dma_addr_t *mapping;
-               entry = &priv->rx_ring[i];
+               entry = priv->rx_ring + priv->rx_ring_sz*i;
                if (!skb) {
                        wiphy_err(dev->wiphy, "Cannot allocate RX skb\n");
                        return -ENOMEM;
@@ -587,7 +613,7 @@ static void rtl8180_free_rx_ring(struct ieee80211_hw *dev)
                kfree_skb(skb);
        }
 
-       pci_free_consistent(priv->pdev, sizeof(*priv->rx_ring) * 32,
+       pci_free_consistent(priv->pdev, priv->rx_ring_sz * 32,
                            priv->rx_ring, priv->rx_ring_dma);
        priv->rx_ring = NULL;
 }
index 47a084ccc5550b59ec1f53abc9e0180de81ced54..d866cc6a845f5fbd63c833e8dbc49a2cf75ce1f3 100644 (file)
@@ -55,13 +55,25 @@ struct rtl8180_tx_desc {
        __le16 frag_qsize;
 } __packed;
 
+struct rtl818x_rx_cmd_desc {
+       __le32 flags;
+       u32 reserved;
+       __le32 rx_buf;
+} __packed;
+
 struct rtl8180_rx_desc {
        __le32 flags;
        __le32 flags2;
-       union {
-               __le32 rx_buf;
-               __le64 tsft;
-       };
+       __le64 tsft;
+
+} __packed;
+
+struct rtl8187se_rx_desc {
+       __le32 flags;
+       __le64 tsft;
+       __le32 flags2;
+       __le32 flags3;
+       u32 reserved[3];
 } __packed;
 
 struct rtl8180_tx_ring {
@@ -88,7 +100,8 @@ struct rtl8180_priv {
 
        /* rtl8180 driver specific */
        spinlock_t lock;
-       struct rtl8180_rx_desc *rx_ring;
+       void *rx_ring;
+       u8 rx_ring_sz;
        dma_addr_t rx_ring_dma;
        unsigned int rx_idx;
        struct sk_buff *rx_buf[32];