aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rtl818x
diff options
context:
space:
mode:
authorAndrea Merello <andrea.merello@gmail.com>2014-03-26 15:59:52 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-03-27 14:20:07 -0400
commit21025920ccb2f0bc2870391467ba3ac7ab5f86cc (patch)
tree6b2a02a6277ac253a4874ba63233a7c55fb1f68a /drivers/net/wireless/rtl818x
parentd209f3b473e0135ee7d800b5fde50955dbdfc246 (diff)
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: Andrea Merello <andrea.merello@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rtl818x')
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/dev.c52
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/rtl8180.h23
2 files changed, 57 insertions, 18 deletions
diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c
index 6b237ed15eed..867ec07da414 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c
@@ -129,14 +129,30 @@ void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data)
129static void rtl8180_handle_rx(struct ieee80211_hw *dev) 129static void rtl8180_handle_rx(struct ieee80211_hw *dev)
130{ 130{
131 struct rtl8180_priv *priv = dev->priv; 131 struct rtl8180_priv *priv = dev->priv;
132 struct rtl818x_rx_cmd_desc *cmd_desc;
132 unsigned int count = 32; 133 unsigned int count = 32;
133 u8 signal, agc, sq; 134 u8 signal, agc, sq;
134 dma_addr_t mapping; 135 dma_addr_t mapping;
135 136
136 while (count--) { 137 while (count--) {
137 struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx]; 138 void *entry = priv->rx_ring + priv->rx_idx * priv->rx_ring_sz;
138 struct sk_buff *skb = priv->rx_buf[priv->rx_idx]; 139 struct sk_buff *skb = priv->rx_buf[priv->rx_idx];
139 u32 flags = le32_to_cpu(entry->flags); 140 u32 flags, flags2;
141 u64 tsft;
142
143 if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) {
144 struct rtl8187se_rx_desc *desc = entry;
145
146 flags = le32_to_cpu(desc->flags);
147 flags2 = le32_to_cpu(desc->flags2);
148 tsft = le64_to_cpu(desc->tsft);
149 } else {
150 struct rtl8180_rx_desc *desc = entry;
151
152 flags = le32_to_cpu(desc->flags);
153 flags2 = le32_to_cpu(desc->flags2);
154 tsft = le64_to_cpu(desc->tsft);
155 }
140 156
141 if (flags & RTL818X_RX_DESC_FLAG_OWN) 157 if (flags & RTL818X_RX_DESC_FLAG_OWN)
142 return; 158 return;
@@ -146,7 +162,6 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
146 RTL818X_RX_DESC_FLAG_RX_ERR))) 162 RTL818X_RX_DESC_FLAG_RX_ERR)))
147 goto done; 163 goto done;
148 else { 164 else {
149 u32 flags2 = le32_to_cpu(entry->flags2);
150 struct ieee80211_rx_status rx_status = {0}; 165 struct ieee80211_rx_status rx_status = {0};
151 struct sk_buff *new_skb = dev_alloc_skb(MAX_RX_SIZE); 166 struct sk_buff *new_skb = dev_alloc_skb(MAX_RX_SIZE);
152 167
@@ -178,14 +193,18 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
178 signal = 90 - clamp_t(u8, agc, 25, 90); 193 signal = 90 - clamp_t(u8, agc, 25, 90);
179 else 194 else
180 signal = 95 - clamp_t(u8, agc, 30, 95); 195 signal = 95 - clamp_t(u8, agc, 30, 95);
181 } else { 196 } else if (priv->chip_family ==
197 RTL818X_CHIP_FAMILY_RTL8180) {
182 sq = flags2 & 0xff; 198 sq = flags2 & 0xff;
183 signal = priv->rf->calc_rssi(agc, sq); 199 signal = priv->rf->calc_rssi(agc, sq);
200 } else {
201 /* TODO: rtl8187se rssi */
202 signal = 10;
184 } 203 }
185 rx_status.signal = signal; 204 rx_status.signal = signal;
186 rx_status.freq = dev->conf.chandef.chan->center_freq; 205 rx_status.freq = dev->conf.chandef.chan->center_freq;
187 rx_status.band = dev->conf.chandef.chan->band; 206 rx_status.band = dev->conf.chandef.chan->band;
188 rx_status.mactime = le64_to_cpu(entry->tsft); 207 rx_status.mactime = tsft;
189 rx_status.flag |= RX_FLAG_MACTIME_START; 208 rx_status.flag |= RX_FLAG_MACTIME_START;
190 if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) 209 if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
191 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; 210 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
@@ -199,11 +218,13 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
199 } 218 }
200 219
201 done: 220 done:
202 entry->rx_buf = cpu_to_le32(*((dma_addr_t *)skb->cb)); 221 cmd_desc = entry;
203 entry->flags = cpu_to_le32(RTL818X_RX_DESC_FLAG_OWN | 222 cmd_desc->rx_buf = cpu_to_le32(*((dma_addr_t *)skb->cb));
223 cmd_desc->flags = cpu_to_le32(RTL818X_RX_DESC_FLAG_OWN |
204 MAX_RX_SIZE); 224 MAX_RX_SIZE);
205 if (priv->rx_idx == 31) 225 if (priv->rx_idx == 31)
206 entry->flags |= cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR); 226 cmd_desc->flags |=
227 cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR);
207 priv->rx_idx = (priv->rx_idx + 1) % 32; 228 priv->rx_idx = (priv->rx_idx + 1) % 32;
208 } 229 }
209} 230}
@@ -529,11 +550,16 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev)
529static int rtl8180_init_rx_ring(struct ieee80211_hw *dev) 550static int rtl8180_init_rx_ring(struct ieee80211_hw *dev)
530{ 551{
531 struct rtl8180_priv *priv = dev->priv; 552 struct rtl8180_priv *priv = dev->priv;
532 struct rtl8180_rx_desc *entry; 553 struct rtl818x_rx_cmd_desc *entry;
533 int i; 554 int i;
534 555
556 if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE)
557 priv->rx_ring_sz = sizeof(struct rtl8187se_rx_desc);
558 else
559 priv->rx_ring_sz = sizeof(struct rtl8180_rx_desc);
560
535 priv->rx_ring = pci_alloc_consistent(priv->pdev, 561 priv->rx_ring = pci_alloc_consistent(priv->pdev,
536 sizeof(*priv->rx_ring) * 32, 562 priv->rx_ring_sz * 32,
537 &priv->rx_ring_dma); 563 &priv->rx_ring_dma);
538 564
539 if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) { 565 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 return -ENOMEM; 567 return -ENOMEM;
542 } 568 }
543 569
544 memset(priv->rx_ring, 0, sizeof(*priv->rx_ring) * 32); 570 memset(priv->rx_ring, 0, priv->rx_ring_sz * 32);
545 priv->rx_idx = 0; 571 priv->rx_idx = 0;
546 572
547 for (i = 0; i < 32; i++) { 573 for (i = 0; i < 32; i++) {
548 struct sk_buff *skb = dev_alloc_skb(MAX_RX_SIZE); 574 struct sk_buff *skb = dev_alloc_skb(MAX_RX_SIZE);
549 dma_addr_t *mapping; 575 dma_addr_t *mapping;
550 entry = &priv->rx_ring[i]; 576 entry = priv->rx_ring + priv->rx_ring_sz*i;
551 if (!skb) { 577 if (!skb) {
552 wiphy_err(dev->wiphy, "Cannot allocate RX skb\n"); 578 wiphy_err(dev->wiphy, "Cannot allocate RX skb\n");
553 return -ENOMEM; 579 return -ENOMEM;
@@ -587,7 +613,7 @@ static void rtl8180_free_rx_ring(struct ieee80211_hw *dev)
587 kfree_skb(skb); 613 kfree_skb(skb);
588 } 614 }
589 615
590 pci_free_consistent(priv->pdev, sizeof(*priv->rx_ring) * 32, 616 pci_free_consistent(priv->pdev, priv->rx_ring_sz * 32,
591 priv->rx_ring, priv->rx_ring_dma); 617 priv->rx_ring, priv->rx_ring_dma);
592 priv->rx_ring = NULL; 618 priv->rx_ring = NULL;
593} 619}
diff --git a/drivers/net/wireless/rtl818x/rtl8180/rtl8180.h b/drivers/net/wireless/rtl818x/rtl8180/rtl8180.h
index 47a084ccc555..d866cc6a845f 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/rtl8180.h
+++ b/drivers/net/wireless/rtl818x/rtl8180/rtl8180.h
@@ -55,13 +55,25 @@ struct rtl8180_tx_desc {
55 __le16 frag_qsize; 55 __le16 frag_qsize;
56} __packed; 56} __packed;
57 57
58struct rtl818x_rx_cmd_desc {
59 __le32 flags;
60 u32 reserved;
61 __le32 rx_buf;
62} __packed;
63
58struct rtl8180_rx_desc { 64struct rtl8180_rx_desc {
59 __le32 flags; 65 __le32 flags;
60 __le32 flags2; 66 __le32 flags2;
61 union { 67 __le64 tsft;
62 __le32 rx_buf; 68
63 __le64 tsft; 69} __packed;
64 }; 70
71struct rtl8187se_rx_desc {
72 __le32 flags;
73 __le64 tsft;
74 __le32 flags2;
75 __le32 flags3;
76 u32 reserved[3];
65} __packed; 77} __packed;
66 78
67struct rtl8180_tx_ring { 79struct rtl8180_tx_ring {
@@ -88,7 +100,8 @@ struct rtl8180_priv {
88 100
89 /* rtl8180 driver specific */ 101 /* rtl8180 driver specific */
90 spinlock_t lock; 102 spinlock_t lock;
91 struct rtl8180_rx_desc *rx_ring; 103 void *rx_ring;
104 u8 rx_ring_sz;
92 dma_addr_t rx_ring_dma; 105 dma_addr_t rx_ring_dma;
93 unsigned int rx_idx; 106 unsigned int rx_idx;
94 struct sk_buff *rx_buf[32]; 107 struct sk_buff *rx_buf[32];