Commit 21025920 authored by Andrea Merello's avatar Andrea Merello Committed by John W. Linville

rtl8180: support for rtl8187se RX descriptors

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: default avatarAndrea Merello <andrea.merello@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent d209f3b4
...@@ -129,14 +129,30 @@ void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) ...@@ -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) static void rtl8180_handle_rx(struct ieee80211_hw *dev)
{ {
struct rtl8180_priv *priv = dev->priv; struct rtl8180_priv *priv = dev->priv;
struct rtl818x_rx_cmd_desc *cmd_desc;
unsigned int count = 32; unsigned int count = 32;
u8 signal, agc, sq; u8 signal, agc, sq;
dma_addr_t mapping; dma_addr_t mapping;
while (count--) { 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]; 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) if (flags & RTL818X_RX_DESC_FLAG_OWN)
return; return;
...@@ -146,7 +162,6 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) ...@@ -146,7 +162,6 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
RTL818X_RX_DESC_FLAG_RX_ERR))) RTL818X_RX_DESC_FLAG_RX_ERR)))
goto done; goto done;
else { else {
u32 flags2 = le32_to_cpu(entry->flags2);
struct ieee80211_rx_status rx_status = {0}; struct ieee80211_rx_status rx_status = {0};
struct sk_buff *new_skb = dev_alloc_skb(MAX_RX_SIZE); struct sk_buff *new_skb = dev_alloc_skb(MAX_RX_SIZE);
...@@ -178,14 +193,18 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) ...@@ -178,14 +193,18 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
signal = 90 - clamp_t(u8, agc, 25, 90); signal = 90 - clamp_t(u8, agc, 25, 90);
else else
signal = 95 - clamp_t(u8, agc, 30, 95); signal = 95 - clamp_t(u8, agc, 30, 95);
} else { } else if (priv->chip_family ==
RTL818X_CHIP_FAMILY_RTL8180) {
sq = flags2 & 0xff; sq = flags2 & 0xff;
signal = priv->rf->calc_rssi(agc, sq); signal = priv->rf->calc_rssi(agc, sq);
} else {
/* TODO: rtl8187se rssi */
signal = 10;
} }
rx_status.signal = signal; rx_status.signal = signal;
rx_status.freq = dev->conf.chandef.chan->center_freq; rx_status.freq = dev->conf.chandef.chan->center_freq;
rx_status.band = dev->conf.chandef.chan->band; 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; rx_status.flag |= RX_FLAG_MACTIME_START;
if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
...@@ -199,11 +218,13 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev) ...@@ -199,11 +218,13 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
} }
done: done:
entry->rx_buf = cpu_to_le32(*((dma_addr_t *)skb->cb)); cmd_desc = entry;
entry->flags = cpu_to_le32(RTL818X_RX_DESC_FLAG_OWN | 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); MAX_RX_SIZE);
if (priv->rx_idx == 31) 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; priv->rx_idx = (priv->rx_idx + 1) % 32;
} }
} }
...@@ -529,11 +550,16 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev) ...@@ -529,11 +550,16 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev)
static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) static int rtl8180_init_rx_ring(struct ieee80211_hw *dev)
{ {
struct rtl8180_priv *priv = dev->priv; struct rtl8180_priv *priv = dev->priv;
struct rtl8180_rx_desc *entry; struct rtl818x_rx_cmd_desc *entry;
int i; 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, priv->rx_ring = pci_alloc_consistent(priv->pdev,
sizeof(*priv->rx_ring) * 32, priv->rx_ring_sz * 32,
&priv->rx_ring_dma); &priv->rx_ring_dma);
if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) { if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) {
...@@ -541,13 +567,13 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) ...@@ -541,13 +567,13 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev)
return -ENOMEM; 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; priv->rx_idx = 0;
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
struct sk_buff *skb = dev_alloc_skb(MAX_RX_SIZE); struct sk_buff *skb = dev_alloc_skb(MAX_RX_SIZE);
dma_addr_t *mapping; dma_addr_t *mapping;
entry = &priv->rx_ring[i]; entry = priv->rx_ring + priv->rx_ring_sz*i;
if (!skb) { if (!skb) {
wiphy_err(dev->wiphy, "Cannot allocate RX skb\n"); wiphy_err(dev->wiphy, "Cannot allocate RX skb\n");
return -ENOMEM; return -ENOMEM;
...@@ -587,7 +613,7 @@ static void rtl8180_free_rx_ring(struct ieee80211_hw *dev) ...@@ -587,7 +613,7 @@ static void rtl8180_free_rx_ring(struct ieee80211_hw *dev)
kfree_skb(skb); 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, priv->rx_ring_dma);
priv->rx_ring = NULL; priv->rx_ring = NULL;
} }
......
...@@ -55,13 +55,25 @@ struct rtl8180_tx_desc { ...@@ -55,13 +55,25 @@ struct rtl8180_tx_desc {
__le16 frag_qsize; __le16 frag_qsize;
} __packed; } __packed;
struct rtl818x_rx_cmd_desc {
__le32 flags;
u32 reserved;
__le32 rx_buf;
} __packed;
struct rtl8180_rx_desc { struct rtl8180_rx_desc {
__le32 flags; __le32 flags;
__le32 flags2; __le32 flags2;
union { __le64 tsft;
__le32 rx_buf;
__le64 tsft; } __packed;
};
struct rtl8187se_rx_desc {
__le32 flags;
__le64 tsft;
__le32 flags2;
__le32 flags3;
u32 reserved[3];
} __packed; } __packed;
struct rtl8180_tx_ring { struct rtl8180_tx_ring {
...@@ -88,7 +100,8 @@ struct rtl8180_priv { ...@@ -88,7 +100,8 @@ struct rtl8180_priv {
/* rtl8180 driver specific */ /* rtl8180 driver specific */
spinlock_t lock; spinlock_t lock;
struct rtl8180_rx_desc *rx_ring; void *rx_ring;
u8 rx_ring_sz;
dma_addr_t rx_ring_dma; dma_addr_t rx_ring_dma;
unsigned int rx_idx; unsigned int rx_idx;
struct sk_buff *rx_buf[32]; struct sk_buff *rx_buf[32];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment