xref: /openbmc/linux/drivers/net/wireless/realtek/rtl818x/rtl8180/dev.c (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
1f1d2b4d3SLarry Finger 
2f1d2b4d3SLarry Finger /* Linux device driver for RTL8180 / RTL8185 / RTL8187SE
3f1d2b4d3SLarry Finger  *
4f1d2b4d3SLarry Finger  * Copyright 2007 Michael Wu <flamingice@sourmilk.net>
5f1d2b4d3SLarry Finger  * Copyright 2007,2014 Andrea Merello <andrea.merello@gmail.com>
6f1d2b4d3SLarry Finger  *
7f1d2b4d3SLarry Finger  * Based on the r8180 driver, which is:
8f1d2b4d3SLarry Finger  * Copyright 2004-2005 Andrea Merello <andrea.merello@gmail.com>, et al.
9f1d2b4d3SLarry Finger  *
10f1d2b4d3SLarry Finger  * Thanks to Realtek for their support!
11f1d2b4d3SLarry Finger  *
12f1d2b4d3SLarry Finger  ************************************************************************
13f1d2b4d3SLarry Finger  *
14f1d2b4d3SLarry Finger  * The driver was extended to the RTL8187SE in 2014 by
15f1d2b4d3SLarry Finger  * Andrea Merello <andrea.merello@gmail.com>
16f1d2b4d3SLarry Finger  *
17f1d2b4d3SLarry Finger  * based also on:
18f1d2b4d3SLarry Finger  *  - portions of rtl8187se Linux staging driver, Copyright Realtek corp.
19f1d2b4d3SLarry Finger  *    (available in drivers/staging/rtl8187se directory of Linux 3.14)
20f1d2b4d3SLarry Finger  *  - other GPL, unpublished (until now), Linux driver code,
21f1d2b4d3SLarry Finger  *    Copyright Larry Finger <Larry.Finger@lwfinger.net>
22f1d2b4d3SLarry Finger  *
23f1d2b4d3SLarry Finger  * A huge thanks goes to Sara V. Nari who forgives me when I'm
24f1d2b4d3SLarry Finger  * sitting in front of my laptop at evening, week-end, night...
25f1d2b4d3SLarry Finger  *
26f1d2b4d3SLarry Finger  * A special thanks goes to Antonio Cuni, who helped me with
27f1d2b4d3SLarry Finger  * some python userspace stuff I used to debug RTL8187SE code, and who
28f1d2b4d3SLarry Finger  * bought a laptop with an unsupported Wi-Fi card some years ago...
29f1d2b4d3SLarry Finger  *
30f1d2b4d3SLarry Finger  * Thanks to Larry Finger for writing some code for rtl8187se and for
31f1d2b4d3SLarry Finger  * his suggestions.
32f1d2b4d3SLarry Finger  *
33f1d2b4d3SLarry Finger  * Thanks to Dan Carpenter for reviewing my initial patch and for his
34f1d2b4d3SLarry Finger  * suggestions.
35f1d2b4d3SLarry Finger  *
36f1d2b4d3SLarry Finger  * Thanks to Bernhard Schiffner for his help in testing and for his
37f1d2b4d3SLarry Finger  * suggestions.
38f1d2b4d3SLarry Finger  *
39f1d2b4d3SLarry Finger  ************************************************************************
40f1d2b4d3SLarry Finger  *
41f1d2b4d3SLarry Finger  * This program is free software; you can redistribute it and/or modify
42f1d2b4d3SLarry Finger  * it under the terms of the GNU General Public License version 2 as
43f1d2b4d3SLarry Finger  * published by the Free Software Foundation.
44f1d2b4d3SLarry Finger  */
45f1d2b4d3SLarry Finger 
46f1d2b4d3SLarry Finger #include <linux/interrupt.h>
47f1d2b4d3SLarry Finger #include <linux/pci.h>
48f1d2b4d3SLarry Finger #include <linux/slab.h>
49f1d2b4d3SLarry Finger #include <linux/delay.h>
50f1d2b4d3SLarry Finger #include <linux/etherdevice.h>
51f1d2b4d3SLarry Finger #include <linux/eeprom_93cx6.h>
52f1d2b4d3SLarry Finger #include <linux/module.h>
53f1d2b4d3SLarry Finger #include <net/mac80211.h>
54f1d2b4d3SLarry Finger 
55f1d2b4d3SLarry Finger #include "rtl8180.h"
56f1d2b4d3SLarry Finger #include "rtl8225.h"
57f1d2b4d3SLarry Finger #include "sa2400.h"
58f1d2b4d3SLarry Finger #include "max2820.h"
59f1d2b4d3SLarry Finger #include "grf5101.h"
60f1d2b4d3SLarry Finger #include "rtl8225se.h"
61f1d2b4d3SLarry Finger 
62f1d2b4d3SLarry Finger MODULE_AUTHOR("Michael Wu <flamingice@sourmilk.net>");
63f1d2b4d3SLarry Finger MODULE_AUTHOR("Andrea Merello <andrea.merello@gmail.com>");
64f1d2b4d3SLarry Finger MODULE_DESCRIPTION("RTL8180 / RTL8185 / RTL8187SE PCI wireless driver");
65f1d2b4d3SLarry Finger MODULE_LICENSE("GPL");
66f1d2b4d3SLarry Finger 
67f1d2b4d3SLarry Finger static const struct pci_device_id rtl8180_table[] = {
68f1d2b4d3SLarry Finger 
69f1d2b4d3SLarry Finger 	/* rtl8187se */
70f1d2b4d3SLarry Finger 	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8199) },
71f1d2b4d3SLarry Finger 
72f1d2b4d3SLarry Finger 	/* rtl8185 */
73f1d2b4d3SLarry Finger 	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8185) },
74f1d2b4d3SLarry Finger 	{ PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x700f) },
75f1d2b4d3SLarry Finger 	{ PCI_DEVICE(PCI_VENDOR_ID_BELKIN, 0x701f) },
76f1d2b4d3SLarry Finger 
77f1d2b4d3SLarry Finger 	/* rtl8180 */
78f1d2b4d3SLarry Finger 	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8180) },
79f1d2b4d3SLarry Finger 	{ PCI_DEVICE(0x1799, 0x6001) },
80f1d2b4d3SLarry Finger 	{ PCI_DEVICE(0x1799, 0x6020) },
81f1d2b4d3SLarry Finger 	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x3300) },
82f1d2b4d3SLarry Finger 	{ PCI_DEVICE(0x1186, 0x3301) },
83f1d2b4d3SLarry Finger 	{ PCI_DEVICE(0x1432, 0x7106) },
84f1d2b4d3SLarry Finger 	{ }
85f1d2b4d3SLarry Finger };
86f1d2b4d3SLarry Finger 
87f1d2b4d3SLarry Finger MODULE_DEVICE_TABLE(pci, rtl8180_table);
88f1d2b4d3SLarry Finger 
89f1d2b4d3SLarry Finger static const struct ieee80211_rate rtl818x_rates[] = {
90f1d2b4d3SLarry Finger 	{ .bitrate = 10, .hw_value = 0, },
91f1d2b4d3SLarry Finger 	{ .bitrate = 20, .hw_value = 1, },
92f1d2b4d3SLarry Finger 	{ .bitrate = 55, .hw_value = 2, },
93f1d2b4d3SLarry Finger 	{ .bitrate = 110, .hw_value = 3, },
94f1d2b4d3SLarry Finger 	{ .bitrate = 60, .hw_value = 4, },
95f1d2b4d3SLarry Finger 	{ .bitrate = 90, .hw_value = 5, },
96f1d2b4d3SLarry Finger 	{ .bitrate = 120, .hw_value = 6, },
97f1d2b4d3SLarry Finger 	{ .bitrate = 180, .hw_value = 7, },
98f1d2b4d3SLarry Finger 	{ .bitrate = 240, .hw_value = 8, },
99f1d2b4d3SLarry Finger 	{ .bitrate = 360, .hw_value = 9, },
100f1d2b4d3SLarry Finger 	{ .bitrate = 480, .hw_value = 10, },
101f1d2b4d3SLarry Finger 	{ .bitrate = 540, .hw_value = 11, },
102f1d2b4d3SLarry Finger };
103f1d2b4d3SLarry Finger 
104f1d2b4d3SLarry Finger static const struct ieee80211_channel rtl818x_channels[] = {
105f1d2b4d3SLarry Finger 	{ .center_freq = 2412 },
106f1d2b4d3SLarry Finger 	{ .center_freq = 2417 },
107f1d2b4d3SLarry Finger 	{ .center_freq = 2422 },
108f1d2b4d3SLarry Finger 	{ .center_freq = 2427 },
109f1d2b4d3SLarry Finger 	{ .center_freq = 2432 },
110f1d2b4d3SLarry Finger 	{ .center_freq = 2437 },
111f1d2b4d3SLarry Finger 	{ .center_freq = 2442 },
112f1d2b4d3SLarry Finger 	{ .center_freq = 2447 },
113f1d2b4d3SLarry Finger 	{ .center_freq = 2452 },
114f1d2b4d3SLarry Finger 	{ .center_freq = 2457 },
115f1d2b4d3SLarry Finger 	{ .center_freq = 2462 },
116f1d2b4d3SLarry Finger 	{ .center_freq = 2467 },
117f1d2b4d3SLarry Finger 	{ .center_freq = 2472 },
118f1d2b4d3SLarry Finger 	{ .center_freq = 2484 },
119f1d2b4d3SLarry Finger };
120f1d2b4d3SLarry Finger 
121f1d2b4d3SLarry Finger /* Queues for rtl8187se card
122f1d2b4d3SLarry Finger  *
123f1d2b4d3SLarry Finger  * name | reg  |  queue
124f1d2b4d3SLarry Finger  *  BC  |  7   |   6
125f1d2b4d3SLarry Finger  *  MG  |  1   |   0
126f1d2b4d3SLarry Finger  *  HI  |  6   |   1
127f1d2b4d3SLarry Finger  *  VO  |  5   |   2
128f1d2b4d3SLarry Finger  *  VI  |  4   |   3
129f1d2b4d3SLarry Finger  *  BE  |  3   |   4
130f1d2b4d3SLarry Finger  *  BK  |  2   |   5
131f1d2b4d3SLarry Finger  *
132f1d2b4d3SLarry Finger  * The complete map for DMA kick reg using use all queue is:
133f1d2b4d3SLarry Finger  * static const int rtl8187se_queues_map[RTL8187SE_NR_TX_QUEUES] =
134f1d2b4d3SLarry Finger  *	{1, 6, 5, 4, 3, 2, 7};
135f1d2b4d3SLarry Finger  *
136f1d2b4d3SLarry Finger  * .. but.. Because for mac80211 4 queues are enough for QoS we use this
137f1d2b4d3SLarry Finger  *
138f1d2b4d3SLarry Finger  * name | reg  |  queue
139f1d2b4d3SLarry Finger  *  BC  |  7   |   4  <- currently not used yet
140f1d2b4d3SLarry Finger  *  MG  |  1   |   x  <- Not used
141f1d2b4d3SLarry Finger  *  HI  |  6   |   x  <- Not used
142f1d2b4d3SLarry Finger  *  VO  |  5   |   0  <- used
143f1d2b4d3SLarry Finger  *  VI  |  4   |   1  <- used
144f1d2b4d3SLarry Finger  *  BE  |  3   |   2  <- used
145f1d2b4d3SLarry Finger  *  BK  |  2   |   3  <- used
146f1d2b4d3SLarry Finger  *
147f1d2b4d3SLarry Finger  * Beacon queue could be used, but this is not finished yet.
148f1d2b4d3SLarry Finger  *
149f1d2b4d3SLarry Finger  * I thougth about using the other two queues but I decided not to do this:
150f1d2b4d3SLarry Finger  *
151f1d2b4d3SLarry Finger  * - I'm unsure whether the mac80211 will ever try to use more than 4 queues
152f1d2b4d3SLarry Finger  *   by itself.
153f1d2b4d3SLarry Finger  *
154f1d2b4d3SLarry Finger  * - I could route MGMT frames (currently sent over VO queue) to the MGMT
155f1d2b4d3SLarry Finger  *   queue but since mac80211 will do not know about it, I will probably gain
156f1d2b4d3SLarry Finger  *   some HW priority whenever the VO queue is not empty, but this gain is
157f1d2b4d3SLarry Finger  *   limited by the fact that I had to stop the mac80211 queue whenever one of
158f1d2b4d3SLarry Finger  *   the VO or MGMT queues is full, stopping also submitting of MGMT frame
159f1d2b4d3SLarry Finger  *   to the driver.
160f1d2b4d3SLarry Finger  *
161f1d2b4d3SLarry Finger  * - I don't know how to set in the HW the contention window params for MGMT
162f1d2b4d3SLarry Finger  *   and HI-prio queues.
163f1d2b4d3SLarry Finger  */
164f1d2b4d3SLarry Finger 
165f1d2b4d3SLarry Finger static const int rtl8187se_queues_map[RTL8187SE_NR_TX_QUEUES] = {5, 4, 3, 2, 7};
166f1d2b4d3SLarry Finger 
167f1d2b4d3SLarry Finger /* Queues for rtl8180/rtl8185 cards
168f1d2b4d3SLarry Finger  *
169f1d2b4d3SLarry Finger  * name | reg  |  prio
170f1d2b4d3SLarry Finger  *  BC  |  7   |   3
171f1d2b4d3SLarry Finger  *  HI  |  6   |   0
172f1d2b4d3SLarry Finger  *  NO  |  5   |   1
173f1d2b4d3SLarry Finger  *  LO  |  4   |   2
174f1d2b4d3SLarry Finger  *
175f1d2b4d3SLarry Finger  * The complete map for DMA kick reg using all queue is:
176f1d2b4d3SLarry Finger  * static const int rtl8180_queues_map[RTL8180_NR_TX_QUEUES] = {6, 5, 4, 7};
177f1d2b4d3SLarry Finger  *
178f1d2b4d3SLarry Finger  * .. but .. Because the mac80211 needs at least 4 queues for QoS or
179f1d2b4d3SLarry Finger  * otherwise QoS can't be done, we use just one.
180f1d2b4d3SLarry Finger  * Beacon queue could be used, but this is not finished yet.
181f1d2b4d3SLarry Finger  * Actual map is:
182f1d2b4d3SLarry Finger  *
183f1d2b4d3SLarry Finger  * name | reg  |  prio
184f1d2b4d3SLarry Finger  *  BC  |  7   |   1  <- currently not used yet.
185f1d2b4d3SLarry Finger  *  HI  |  6   |   x  <- not used
186f1d2b4d3SLarry Finger  *  NO  |  5   |   x  <- not used
187f1d2b4d3SLarry Finger  *  LO  |  4   |   0  <- used
188f1d2b4d3SLarry Finger  */
189f1d2b4d3SLarry Finger 
190f1d2b4d3SLarry Finger static const int rtl8180_queues_map[RTL8180_NR_TX_QUEUES] = {4, 7};
191f1d2b4d3SLarry Finger 
192f1d2b4d3SLarry Finger /* LNA gain table for rtl8187se */
193f1d2b4d3SLarry Finger static const u8 rtl8187se_lna_gain[4] = {02, 17, 29, 39};
194f1d2b4d3SLarry Finger 
rtl8180_write_phy(struct ieee80211_hw * dev,u8 addr,u32 data)195f1d2b4d3SLarry Finger void rtl8180_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data)
196f1d2b4d3SLarry Finger {
197f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
198f1d2b4d3SLarry Finger 	int i = 10;
199f1d2b4d3SLarry Finger 	u32 buf;
200f1d2b4d3SLarry Finger 
201f1d2b4d3SLarry Finger 	buf = (data << 8) | addr;
202f1d2b4d3SLarry Finger 
203f1d2b4d3SLarry Finger 	rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->PHY[0], buf | 0x80);
204f1d2b4d3SLarry Finger 	while (i--) {
205f1d2b4d3SLarry Finger 		rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->PHY[0], buf);
206f1d2b4d3SLarry Finger 		if (rtl818x_ioread8(priv, &priv->map->PHY[2]) == (data & 0xFF))
207f1d2b4d3SLarry Finger 			return;
208f1d2b4d3SLarry Finger 	}
209f1d2b4d3SLarry Finger }
210f1d2b4d3SLarry Finger 
rtl8180_handle_rx(struct ieee80211_hw * dev)211f1d2b4d3SLarry Finger static void rtl8180_handle_rx(struct ieee80211_hw *dev)
212f1d2b4d3SLarry Finger {
213f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
214f1d2b4d3SLarry Finger 	struct rtl818x_rx_cmd_desc *cmd_desc;
215f1d2b4d3SLarry Finger 	unsigned int count = 32;
216f1d2b4d3SLarry Finger 	u8 agc, sq;
217f1d2b4d3SLarry Finger 	s8 signal = 1;
218f1d2b4d3SLarry Finger 	dma_addr_t mapping;
219f1d2b4d3SLarry Finger 
220f1d2b4d3SLarry Finger 	while (count--) {
221f1d2b4d3SLarry Finger 		void *entry = priv->rx_ring + priv->rx_idx * priv->rx_ring_sz;
222f1d2b4d3SLarry Finger 		struct sk_buff *skb = priv->rx_buf[priv->rx_idx];
223f1d2b4d3SLarry Finger 		u32 flags, flags2, flags3 = 0;
224f1d2b4d3SLarry Finger 		u64 tsft;
225f1d2b4d3SLarry Finger 
226f1d2b4d3SLarry Finger 		if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) {
227f1d2b4d3SLarry Finger 			struct rtl8187se_rx_desc *desc = entry;
228f1d2b4d3SLarry Finger 
229f1d2b4d3SLarry Finger 			flags = le32_to_cpu(desc->flags);
230f1d2b4d3SLarry Finger 			/* if ownership flag is set, then we can trust the
231f1d2b4d3SLarry Finger 			 * HW has written other fields. We must not trust
232f1d2b4d3SLarry Finger 			 * other descriptor data read before we checked (read)
233f1d2b4d3SLarry Finger 			 * the ownership flag
234f1d2b4d3SLarry Finger 			 */
235f1d2b4d3SLarry Finger 			rmb();
236f1d2b4d3SLarry Finger 			flags3 = le32_to_cpu(desc->flags3);
237f1d2b4d3SLarry Finger 			flags2 = le32_to_cpu(desc->flags2);
238f1d2b4d3SLarry Finger 			tsft = le64_to_cpu(desc->tsft);
239f1d2b4d3SLarry Finger 		} else {
240f1d2b4d3SLarry Finger 			struct rtl8180_rx_desc *desc = entry;
241f1d2b4d3SLarry Finger 
242f1d2b4d3SLarry Finger 			flags = le32_to_cpu(desc->flags);
243f1d2b4d3SLarry Finger 			/* same as above */
244f1d2b4d3SLarry Finger 			rmb();
245f1d2b4d3SLarry Finger 			flags2 = le32_to_cpu(desc->flags2);
246f1d2b4d3SLarry Finger 			tsft = le64_to_cpu(desc->tsft);
247f1d2b4d3SLarry Finger 		}
248f1d2b4d3SLarry Finger 
249f1d2b4d3SLarry Finger 		if (flags & RTL818X_RX_DESC_FLAG_OWN)
250f1d2b4d3SLarry Finger 			return;
251f1d2b4d3SLarry Finger 
252f1d2b4d3SLarry Finger 		if (unlikely(flags & (RTL818X_RX_DESC_FLAG_DMA_FAIL |
253f1d2b4d3SLarry Finger 				      RTL818X_RX_DESC_FLAG_FOF |
254f1d2b4d3SLarry Finger 				      RTL818X_RX_DESC_FLAG_RX_ERR)))
255f1d2b4d3SLarry Finger 			goto done;
256f1d2b4d3SLarry Finger 		else {
257f1d2b4d3SLarry Finger 			struct ieee80211_rx_status rx_status = {0};
258f1d2b4d3SLarry Finger 			struct sk_buff *new_skb = dev_alloc_skb(MAX_RX_SIZE);
259f1d2b4d3SLarry Finger 
260f1d2b4d3SLarry Finger 			if (unlikely(!new_skb))
261f1d2b4d3SLarry Finger 				goto done;
262f1d2b4d3SLarry Finger 
263f4ce4bf6SChristophe JAILLET 			mapping = dma_map_single(&priv->pdev->dev,
264f1d2b4d3SLarry Finger 						 skb_tail_pointer(new_skb),
265f4ce4bf6SChristophe JAILLET 						 MAX_RX_SIZE, DMA_FROM_DEVICE);
266f1d2b4d3SLarry Finger 
267f4ce4bf6SChristophe JAILLET 			if (dma_mapping_error(&priv->pdev->dev, mapping)) {
268f1d2b4d3SLarry Finger 				kfree_skb(new_skb);
269f1d2b4d3SLarry Finger 				dev_err(&priv->pdev->dev, "RX DMA map error\n");
270f1d2b4d3SLarry Finger 
271f1d2b4d3SLarry Finger 				goto done;
272f1d2b4d3SLarry Finger 			}
273f1d2b4d3SLarry Finger 
274f4ce4bf6SChristophe JAILLET 			dma_unmap_single(&priv->pdev->dev,
275f1d2b4d3SLarry Finger 					 *((dma_addr_t *)skb->cb),
276f4ce4bf6SChristophe JAILLET 					 MAX_RX_SIZE, DMA_FROM_DEVICE);
277f1d2b4d3SLarry Finger 			skb_put(skb, flags & 0xFFF);
278f1d2b4d3SLarry Finger 
279f1d2b4d3SLarry Finger 			rx_status.antenna = (flags2 >> 15) & 1;
280f1d2b4d3SLarry Finger 			rx_status.rate_idx = (flags >> 20) & 0xF;
281f1d2b4d3SLarry Finger 			agc = (flags2 >> 17) & 0x7F;
282f1d2b4d3SLarry Finger 
283f1d2b4d3SLarry Finger 			switch (priv->chip_family) {
284f1d2b4d3SLarry Finger 			case RTL818X_CHIP_FAMILY_RTL8185:
285f1d2b4d3SLarry Finger 				if (rx_status.rate_idx > 3)
286f1d2b4d3SLarry Finger 					signal = -clamp_t(u8, agc, 25, 90) - 9;
287f1d2b4d3SLarry Finger 				else
288f1d2b4d3SLarry Finger 					signal = -clamp_t(u8, agc, 30, 95);
289f1d2b4d3SLarry Finger 				break;
290f1d2b4d3SLarry Finger 			case RTL818X_CHIP_FAMILY_RTL8180:
291f1d2b4d3SLarry Finger 				sq = flags2 & 0xff;
292f1d2b4d3SLarry Finger 				signal = priv->rf->calc_rssi(agc, sq);
293f1d2b4d3SLarry Finger 				break;
294f1d2b4d3SLarry Finger 			case RTL818X_CHIP_FAMILY_RTL8187SE:
295f1d2b4d3SLarry Finger 				/* OFDM measure reported by HW is signed,
296f1d2b4d3SLarry Finger 				 * in 0.5dBm unit, with zero centered @ -41dBm
297f1d2b4d3SLarry Finger 				 * input signal.
298f1d2b4d3SLarry Finger 				 */
299f1d2b4d3SLarry Finger 				if (rx_status.rate_idx > 3) {
300f1d2b4d3SLarry Finger 					signal = (s8)((flags3 >> 16) & 0xff);
301f1d2b4d3SLarry Finger 					signal = signal / 2 - 41;
302f1d2b4d3SLarry Finger 				} else {
303f1d2b4d3SLarry Finger 					int idx, bb;
304f1d2b4d3SLarry Finger 
305f1d2b4d3SLarry Finger 					idx = (agc & 0x60) >> 5;
306f1d2b4d3SLarry Finger 					bb = (agc & 0x1F) * 2;
307f1d2b4d3SLarry Finger 					/* bias + BB gain + LNA gain */
308f1d2b4d3SLarry Finger 					signal = 4 - bb - rtl8187se_lna_gain[idx];
309f1d2b4d3SLarry Finger 				}
310f1d2b4d3SLarry Finger 				break;
311f1d2b4d3SLarry Finger 			}
312f1d2b4d3SLarry Finger 			rx_status.signal = signal;
313f1d2b4d3SLarry Finger 			rx_status.freq = dev->conf.chandef.chan->center_freq;
314f1d2b4d3SLarry Finger 			rx_status.band = dev->conf.chandef.chan->band;
315f1d2b4d3SLarry Finger 			rx_status.mactime = tsft;
316f1d2b4d3SLarry Finger 			rx_status.flag |= RX_FLAG_MACTIME_START;
317f1d2b4d3SLarry Finger 			if (flags & RTL818X_RX_DESC_FLAG_SPLCP)
3187fdd69c5SJohannes Berg 				rx_status.enc_flags |= RX_ENC_FLAG_SHORTPRE;
319f1d2b4d3SLarry Finger 			if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
320f1d2b4d3SLarry Finger 				rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
321f1d2b4d3SLarry Finger 
322f1d2b4d3SLarry Finger 			memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
323f1d2b4d3SLarry Finger 			ieee80211_rx_irqsafe(dev, skb);
324f1d2b4d3SLarry Finger 
325f1d2b4d3SLarry Finger 			skb = new_skb;
326f1d2b4d3SLarry Finger 			priv->rx_buf[priv->rx_idx] = skb;
327f1d2b4d3SLarry Finger 			*((dma_addr_t *) skb->cb) = mapping;
328f1d2b4d3SLarry Finger 		}
329f1d2b4d3SLarry Finger 
330f1d2b4d3SLarry Finger 	done:
331f1d2b4d3SLarry Finger 		cmd_desc = entry;
332f1d2b4d3SLarry Finger 		cmd_desc->rx_buf = cpu_to_le32(*((dma_addr_t *)skb->cb));
333f1d2b4d3SLarry Finger 		cmd_desc->flags = cpu_to_le32(RTL818X_RX_DESC_FLAG_OWN |
334f1d2b4d3SLarry Finger 					   MAX_RX_SIZE);
335f1d2b4d3SLarry Finger 		if (priv->rx_idx == 31)
336f1d2b4d3SLarry Finger 			cmd_desc->flags |=
337f1d2b4d3SLarry Finger 				cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR);
338f1d2b4d3SLarry Finger 		priv->rx_idx = (priv->rx_idx + 1) % 32;
339f1d2b4d3SLarry Finger 	}
340f1d2b4d3SLarry Finger }
341f1d2b4d3SLarry Finger 
rtl8180_handle_tx(struct ieee80211_hw * dev,unsigned int prio)342f1d2b4d3SLarry Finger static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio)
343f1d2b4d3SLarry Finger {
344f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
345f1d2b4d3SLarry Finger 	struct rtl8180_tx_ring *ring = &priv->tx_ring[prio];
346f1d2b4d3SLarry Finger 
347f1d2b4d3SLarry Finger 	while (skb_queue_len(&ring->queue)) {
348f1d2b4d3SLarry Finger 		struct rtl8180_tx_desc *entry = &ring->desc[ring->idx];
349f1d2b4d3SLarry Finger 		struct sk_buff *skb;
350f1d2b4d3SLarry Finger 		struct ieee80211_tx_info *info;
351f1d2b4d3SLarry Finger 		u32 flags = le32_to_cpu(entry->flags);
352f1d2b4d3SLarry Finger 
353f1d2b4d3SLarry Finger 		if (flags & RTL818X_TX_DESC_FLAG_OWN)
354f1d2b4d3SLarry Finger 			return;
355f1d2b4d3SLarry Finger 
356f1d2b4d3SLarry Finger 		ring->idx = (ring->idx + 1) % ring->entries;
357f1d2b4d3SLarry Finger 		skb = __skb_dequeue(&ring->queue);
358f4ce4bf6SChristophe JAILLET 		dma_unmap_single(&priv->pdev->dev, le32_to_cpu(entry->tx_buf),
359f4ce4bf6SChristophe JAILLET 				 skb->len, DMA_TO_DEVICE);
360f1d2b4d3SLarry Finger 
361f1d2b4d3SLarry Finger 		info = IEEE80211_SKB_CB(skb);
362f1d2b4d3SLarry Finger 		ieee80211_tx_info_clear_status(info);
363f1d2b4d3SLarry Finger 
364f1d2b4d3SLarry Finger 		if (!(info->flags & IEEE80211_TX_CTL_NO_ACK) &&
365f1d2b4d3SLarry Finger 		    (flags & RTL818X_TX_DESC_FLAG_TX_OK))
366f1d2b4d3SLarry Finger 			info->flags |= IEEE80211_TX_STAT_ACK;
367f1d2b4d3SLarry Finger 
368f1d2b4d3SLarry Finger 		info->status.rates[0].count = (flags & 0xFF) + 1;
369f1d2b4d3SLarry Finger 
370f1d2b4d3SLarry Finger 		ieee80211_tx_status_irqsafe(dev, skb);
371f1d2b4d3SLarry Finger 		if (ring->entries - skb_queue_len(&ring->queue) == 2)
372f1d2b4d3SLarry Finger 			ieee80211_wake_queue(dev, prio);
373f1d2b4d3SLarry Finger 	}
374f1d2b4d3SLarry Finger }
375f1d2b4d3SLarry Finger 
rtl8187se_interrupt(int irq,void * dev_id)376f1d2b4d3SLarry Finger static irqreturn_t rtl8187se_interrupt(int irq, void *dev_id)
377f1d2b4d3SLarry Finger {
378f1d2b4d3SLarry Finger 	struct ieee80211_hw *dev = dev_id;
379f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
380f1d2b4d3SLarry Finger 	u32 reg;
381f1d2b4d3SLarry Finger 	unsigned long flags;
382f1d2b4d3SLarry Finger 	static int desc_err;
383f1d2b4d3SLarry Finger 
384f1d2b4d3SLarry Finger 	spin_lock_irqsave(&priv->lock, flags);
385f1d2b4d3SLarry Finger 	/* Note: 32-bit interrupt status */
386f1d2b4d3SLarry Finger 	reg = rtl818x_ioread32(priv, &priv->map->INT_STATUS_SE);
387f1d2b4d3SLarry Finger 	if (unlikely(reg == 0xFFFFFFFF)) {
388f1d2b4d3SLarry Finger 		spin_unlock_irqrestore(&priv->lock, flags);
389f1d2b4d3SLarry Finger 		return IRQ_HANDLED;
390f1d2b4d3SLarry Finger 	}
391f1d2b4d3SLarry Finger 
392f1d2b4d3SLarry Finger 	rtl818x_iowrite32(priv, &priv->map->INT_STATUS_SE, reg);
393f1d2b4d3SLarry Finger 
394f1d2b4d3SLarry Finger 	if (reg & IMR_TIMEOUT1)
395f1d2b4d3SLarry Finger 		rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0);
396f1d2b4d3SLarry Finger 
397f1d2b4d3SLarry Finger 	if (reg & (IMR_TBDOK | IMR_TBDER))
398f1d2b4d3SLarry Finger 		rtl8180_handle_tx(dev, 4);
399f1d2b4d3SLarry Finger 
400f1d2b4d3SLarry Finger 	if (reg & (IMR_TVODOK | IMR_TVODER))
401f1d2b4d3SLarry Finger 		rtl8180_handle_tx(dev, 0);
402f1d2b4d3SLarry Finger 
403f1d2b4d3SLarry Finger 	if (reg & (IMR_TVIDOK | IMR_TVIDER))
404f1d2b4d3SLarry Finger 		rtl8180_handle_tx(dev, 1);
405f1d2b4d3SLarry Finger 
406f1d2b4d3SLarry Finger 	if (reg & (IMR_TBEDOK | IMR_TBEDER))
407f1d2b4d3SLarry Finger 		rtl8180_handle_tx(dev, 2);
408f1d2b4d3SLarry Finger 
409f1d2b4d3SLarry Finger 	if (reg & (IMR_TBKDOK | IMR_TBKDER))
410f1d2b4d3SLarry Finger 		rtl8180_handle_tx(dev, 3);
411f1d2b4d3SLarry Finger 
412f1d2b4d3SLarry Finger 	if (reg & (IMR_ROK | IMR_RER | RTL818X_INT_SE_RX_DU | IMR_RQOSOK))
413f1d2b4d3SLarry Finger 		rtl8180_handle_rx(dev);
414f1d2b4d3SLarry Finger 	/* The interface sometimes generates several RX DMA descriptor errors
415f1d2b4d3SLarry Finger 	 * at startup. Do not report these.
416f1d2b4d3SLarry Finger 	 */
417f1d2b4d3SLarry Finger 	if ((reg & RTL818X_INT_SE_RX_DU) && desc_err++ > 2)
418f1d2b4d3SLarry Finger 		if (net_ratelimit())
419f1d2b4d3SLarry Finger 			wiphy_err(dev->wiphy, "No RX DMA Descriptor avail\n");
420f1d2b4d3SLarry Finger 
421f1d2b4d3SLarry Finger 	spin_unlock_irqrestore(&priv->lock, flags);
422f1d2b4d3SLarry Finger 	return IRQ_HANDLED;
423f1d2b4d3SLarry Finger }
424f1d2b4d3SLarry Finger 
rtl8180_interrupt(int irq,void * dev_id)425f1d2b4d3SLarry Finger static irqreturn_t rtl8180_interrupt(int irq, void *dev_id)
426f1d2b4d3SLarry Finger {
427f1d2b4d3SLarry Finger 	struct ieee80211_hw *dev = dev_id;
428f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
429f1d2b4d3SLarry Finger 	u16 reg;
430f1d2b4d3SLarry Finger 
431f1d2b4d3SLarry Finger 	spin_lock(&priv->lock);
432f1d2b4d3SLarry Finger 	reg = rtl818x_ioread16(priv, &priv->map->INT_STATUS);
433f1d2b4d3SLarry Finger 	if (unlikely(reg == 0xFFFF)) {
434f1d2b4d3SLarry Finger 		spin_unlock(&priv->lock);
435f1d2b4d3SLarry Finger 		return IRQ_HANDLED;
436f1d2b4d3SLarry Finger 	}
437f1d2b4d3SLarry Finger 
438f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->INT_STATUS, reg);
439f1d2b4d3SLarry Finger 
440f1d2b4d3SLarry Finger 	if (reg & (RTL818X_INT_TXB_OK | RTL818X_INT_TXB_ERR))
441f1d2b4d3SLarry Finger 		rtl8180_handle_tx(dev, 1);
442f1d2b4d3SLarry Finger 
443f1d2b4d3SLarry Finger 	if (reg & (RTL818X_INT_TXL_OK | RTL818X_INT_TXL_ERR))
444f1d2b4d3SLarry Finger 		rtl8180_handle_tx(dev, 0);
445f1d2b4d3SLarry Finger 
446f1d2b4d3SLarry Finger 	if (reg & (RTL818X_INT_RX_OK | RTL818X_INT_RX_ERR))
447f1d2b4d3SLarry Finger 		rtl8180_handle_rx(dev);
448f1d2b4d3SLarry Finger 
449f1d2b4d3SLarry Finger 	spin_unlock(&priv->lock);
450f1d2b4d3SLarry Finger 
451f1d2b4d3SLarry Finger 	return IRQ_HANDLED;
452f1d2b4d3SLarry Finger }
453f1d2b4d3SLarry Finger 
rtl8180_tx(struct ieee80211_hw * dev,struct ieee80211_tx_control * control,struct sk_buff * skb)454f1d2b4d3SLarry Finger static void rtl8180_tx(struct ieee80211_hw *dev,
455f1d2b4d3SLarry Finger 		       struct ieee80211_tx_control *control,
456f1d2b4d3SLarry Finger 		       struct sk_buff *skb)
457f1d2b4d3SLarry Finger {
458f1d2b4d3SLarry Finger 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
459f1d2b4d3SLarry Finger 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
460f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
461f1d2b4d3SLarry Finger 	struct rtl8180_tx_ring *ring;
462f1d2b4d3SLarry Finger 	struct rtl8180_tx_desc *entry;
463746285cfSAlexander Wetzel 	unsigned int prio = 0;
464f1d2b4d3SLarry Finger 	unsigned long flags;
465746285cfSAlexander Wetzel 	unsigned int idx, hw_prio;
466746285cfSAlexander Wetzel 
467f1d2b4d3SLarry Finger 	dma_addr_t mapping;
468f1d2b4d3SLarry Finger 	u32 tx_flags;
469f1d2b4d3SLarry Finger 	u8 rc_flags;
470f1d2b4d3SLarry Finger 	u16 plcp_len = 0;
471f1d2b4d3SLarry Finger 	__le16 rts_duration = 0;
472f1d2b4d3SLarry Finger 	/* do arithmetic and then convert to le16 */
473f1d2b4d3SLarry Finger 	u16 frame_duration = 0;
474f1d2b4d3SLarry Finger 
475746285cfSAlexander Wetzel 	/* rtl8180/rtl8185 only has one useable tx queue */
476746285cfSAlexander Wetzel 	if (dev->queues > IEEE80211_AC_BK)
477f1d2b4d3SLarry Finger 		prio = skb_get_queue_mapping(skb);
478f1d2b4d3SLarry Finger 	ring = &priv->tx_ring[prio];
479f1d2b4d3SLarry Finger 
480f4ce4bf6SChristophe JAILLET 	mapping = dma_map_single(&priv->pdev->dev, skb->data, skb->len,
481f4ce4bf6SChristophe JAILLET 				 DMA_TO_DEVICE);
482f1d2b4d3SLarry Finger 
483f4ce4bf6SChristophe JAILLET 	if (dma_mapping_error(&priv->pdev->dev, mapping)) {
484f1d2b4d3SLarry Finger 		kfree_skb(skb);
485f1d2b4d3SLarry Finger 		dev_err(&priv->pdev->dev, "TX DMA mapping error\n");
486f1d2b4d3SLarry Finger 		return;
487f1d2b4d3SLarry Finger 	}
488f1d2b4d3SLarry Finger 
489f1d2b4d3SLarry Finger 	tx_flags = RTL818X_TX_DESC_FLAG_OWN | RTL818X_TX_DESC_FLAG_FS |
490f1d2b4d3SLarry Finger 		   RTL818X_TX_DESC_FLAG_LS |
491f1d2b4d3SLarry Finger 		   (ieee80211_get_tx_rate(dev, info)->hw_value << 24) |
492f1d2b4d3SLarry Finger 		   skb->len;
493f1d2b4d3SLarry Finger 
494f1d2b4d3SLarry Finger 	if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180)
495f1d2b4d3SLarry Finger 		tx_flags |= RTL818X_TX_DESC_FLAG_DMA |
496f1d2b4d3SLarry Finger 			    RTL818X_TX_DESC_FLAG_NO_ENC;
497f1d2b4d3SLarry Finger 
498f1d2b4d3SLarry Finger 	rc_flags = info->control.rates[0].flags;
499f1d2b4d3SLarry Finger 
500f1d2b4d3SLarry Finger 	/* HW will perform RTS-CTS when only RTS flags is set.
501f1d2b4d3SLarry Finger 	 * HW will perform CTS-to-self when both RTS and CTS flags are set.
502f1d2b4d3SLarry Finger 	 * RTS rate and RTS duration will be used also for CTS-to-self.
503f1d2b4d3SLarry Finger 	 */
504f1d2b4d3SLarry Finger 	if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
505f1d2b4d3SLarry Finger 		tx_flags |= RTL818X_TX_DESC_FLAG_RTS;
506f1d2b4d3SLarry Finger 		tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
507f1d2b4d3SLarry Finger 		rts_duration = ieee80211_rts_duration(dev, priv->vif,
508f1d2b4d3SLarry Finger 						skb->len, info);
509f1d2b4d3SLarry Finger 	} else if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
510f1d2b4d3SLarry Finger 		tx_flags |= RTL818X_TX_DESC_FLAG_RTS | RTL818X_TX_DESC_FLAG_CTS;
511f1d2b4d3SLarry Finger 		tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
512f1d2b4d3SLarry Finger 		rts_duration = ieee80211_ctstoself_duration(dev, priv->vif,
513f1d2b4d3SLarry Finger 						skb->len, info);
514f1d2b4d3SLarry Finger 	}
515f1d2b4d3SLarry Finger 
516f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8180) {
517f1d2b4d3SLarry Finger 		unsigned int remainder;
518f1d2b4d3SLarry Finger 
519f1d2b4d3SLarry Finger 		plcp_len = DIV_ROUND_UP(16 * (skb->len + 4),
520f1d2b4d3SLarry Finger 				(ieee80211_get_tx_rate(dev, info)->bitrate * 2) / 10);
521f1d2b4d3SLarry Finger 		remainder = (16 * (skb->len + 4)) %
522f1d2b4d3SLarry Finger 			    ((ieee80211_get_tx_rate(dev, info)->bitrate * 2) / 10);
523f1d2b4d3SLarry Finger 		if (remainder <= 6)
524f1d2b4d3SLarry Finger 			plcp_len |= 1 << 15;
525f1d2b4d3SLarry Finger 	}
526f1d2b4d3SLarry Finger 
527f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) {
528f1d2b4d3SLarry Finger 		__le16 duration;
529f1d2b4d3SLarry Finger 		/* SIFS time (required by HW) is already included by
530f1d2b4d3SLarry Finger 		 * ieee80211_generic_frame_duration
531f1d2b4d3SLarry Finger 		 */
532f1d2b4d3SLarry Finger 		duration = ieee80211_generic_frame_duration(dev, priv->vif,
53357fbcce3SJohannes Berg 					NL80211_BAND_2GHZ, skb->len,
534f1d2b4d3SLarry Finger 					ieee80211_get_tx_rate(dev, info));
535f1d2b4d3SLarry Finger 
536f1d2b4d3SLarry Finger 		frame_duration =  priv->ack_time + le16_to_cpu(duration);
537f1d2b4d3SLarry Finger 	}
538f1d2b4d3SLarry Finger 
539f1d2b4d3SLarry Finger 	spin_lock_irqsave(&priv->lock, flags);
540f1d2b4d3SLarry Finger 
541f1d2b4d3SLarry Finger 	if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
542f1d2b4d3SLarry Finger 		if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
543f1d2b4d3SLarry Finger 			priv->seqno += 0x10;
544f1d2b4d3SLarry Finger 		hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
545f1d2b4d3SLarry Finger 		hdr->seq_ctrl |= cpu_to_le16(priv->seqno);
546f1d2b4d3SLarry Finger 	}
547f1d2b4d3SLarry Finger 
548f1d2b4d3SLarry Finger 	idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries;
549f1d2b4d3SLarry Finger 	entry = &ring->desc[idx];
550f1d2b4d3SLarry Finger 
551f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) {
552f1d2b4d3SLarry Finger 		entry->frame_duration = cpu_to_le16(frame_duration);
553f1d2b4d3SLarry Finger 		entry->frame_len_se = cpu_to_le16(skb->len);
554f1d2b4d3SLarry Finger 
555f1d2b4d3SLarry Finger 		/* tpc polarity */
556f1d2b4d3SLarry Finger 		entry->flags3 = cpu_to_le16(1<<4);
557f1d2b4d3SLarry Finger 	} else
558f1d2b4d3SLarry Finger 		entry->frame_len = cpu_to_le32(skb->len);
559f1d2b4d3SLarry Finger 
560f1d2b4d3SLarry Finger 	entry->rts_duration = rts_duration;
561f1d2b4d3SLarry Finger 	entry->plcp_len = cpu_to_le16(plcp_len);
562f1d2b4d3SLarry Finger 	entry->tx_buf = cpu_to_le32(mapping);
563f1d2b4d3SLarry Finger 
564f1d2b4d3SLarry Finger 	entry->retry_limit = info->control.rates[0].count - 1;
565f1d2b4d3SLarry Finger 
566f1d2b4d3SLarry Finger 	/* We must be sure that tx_flags is written last because the HW
567f1d2b4d3SLarry Finger 	 * looks at it to check if the rest of data is valid or not
568f1d2b4d3SLarry Finger 	 */
569f1d2b4d3SLarry Finger 	wmb();
570f1d2b4d3SLarry Finger 	entry->flags = cpu_to_le32(tx_flags);
571f1d2b4d3SLarry Finger 	/* We must be sure this has been written before followings HW
572f1d2b4d3SLarry Finger 	 * register write, because this write will made the HW attempts
573f1d2b4d3SLarry Finger 	 * to DMA the just-written data
574f1d2b4d3SLarry Finger 	 */
575f1d2b4d3SLarry Finger 	wmb();
576f1d2b4d3SLarry Finger 
577f1d2b4d3SLarry Finger 	__skb_queue_tail(&ring->queue, skb);
578f1d2b4d3SLarry Finger 	if (ring->entries - skb_queue_len(&ring->queue) < 2)
579f1d2b4d3SLarry Finger 		ieee80211_stop_queue(dev, prio);
580f1d2b4d3SLarry Finger 
581f1d2b4d3SLarry Finger 	spin_unlock_irqrestore(&priv->lock, flags);
582f1d2b4d3SLarry Finger 
583f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) {
584f1d2b4d3SLarry Finger 		/* just poll: rings are stopped with TPPollStop reg */
585f1d2b4d3SLarry Finger 		hw_prio = rtl8187se_queues_map[prio];
586f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING,
587f1d2b4d3SLarry Finger 			 (1 << hw_prio));
588f1d2b4d3SLarry Finger 	} else {
589f1d2b4d3SLarry Finger 		hw_prio = rtl8180_queues_map[prio];
590f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING,
591f1d2b4d3SLarry Finger 			 (1 << hw_prio) | /* ring to poll  */
592f1d2b4d3SLarry Finger 			 (1<<1) | (1<<2));/* stopped rings */
593f1d2b4d3SLarry Finger 	}
594f1d2b4d3SLarry Finger }
595f1d2b4d3SLarry Finger 
rtl8180_set_anaparam3(struct rtl8180_priv * priv,u16 anaparam3)596f1d2b4d3SLarry Finger static void rtl8180_set_anaparam3(struct rtl8180_priv *priv, u16 anaparam3)
597f1d2b4d3SLarry Finger {
598f1d2b4d3SLarry Finger 	u8 reg;
599f1d2b4d3SLarry Finger 
600f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
601f1d2b4d3SLarry Finger 			 RTL818X_EEPROM_CMD_CONFIG);
602f1d2b4d3SLarry Finger 
603f1d2b4d3SLarry Finger 	reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
604f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->CONFIG3,
605f1d2b4d3SLarry Finger 		 reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
606f1d2b4d3SLarry Finger 
607f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, &priv->map->ANAPARAM3, anaparam3);
608f1d2b4d3SLarry Finger 
609f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->CONFIG3,
610f1d2b4d3SLarry Finger 		 reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
611f1d2b4d3SLarry Finger 
612f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
613f1d2b4d3SLarry Finger 			 RTL818X_EEPROM_CMD_NORMAL);
614f1d2b4d3SLarry Finger }
615f1d2b4d3SLarry Finger 
rtl8180_set_anaparam2(struct rtl8180_priv * priv,u32 anaparam2)616f1d2b4d3SLarry Finger void rtl8180_set_anaparam2(struct rtl8180_priv *priv, u32 anaparam2)
617f1d2b4d3SLarry Finger {
618f1d2b4d3SLarry Finger 	u8 reg;
619f1d2b4d3SLarry Finger 
620f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
621f1d2b4d3SLarry Finger 			 RTL818X_EEPROM_CMD_CONFIG);
622f1d2b4d3SLarry Finger 
623f1d2b4d3SLarry Finger 	reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
624f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->CONFIG3,
625f1d2b4d3SLarry Finger 		 reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
626f1d2b4d3SLarry Finger 
627f1d2b4d3SLarry Finger 	rtl818x_iowrite32(priv, &priv->map->ANAPARAM2, anaparam2);
628f1d2b4d3SLarry Finger 
629f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->CONFIG3,
630f1d2b4d3SLarry Finger 		 reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
631f1d2b4d3SLarry Finger 
632f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
633f1d2b4d3SLarry Finger 			 RTL818X_EEPROM_CMD_NORMAL);
634f1d2b4d3SLarry Finger }
635f1d2b4d3SLarry Finger 
rtl8180_set_anaparam(struct rtl8180_priv * priv,u32 anaparam)636f1d2b4d3SLarry Finger void rtl8180_set_anaparam(struct rtl8180_priv *priv, u32 anaparam)
637f1d2b4d3SLarry Finger {
638f1d2b4d3SLarry Finger 	u8 reg;
639f1d2b4d3SLarry Finger 
640f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
641f1d2b4d3SLarry Finger 	reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
642f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->CONFIG3,
643f1d2b4d3SLarry Finger 		 reg | RTL818X_CONFIG3_ANAPARAM_WRITE);
644f1d2b4d3SLarry Finger 	rtl818x_iowrite32(priv, &priv->map->ANAPARAM, anaparam);
645f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->CONFIG3,
646f1d2b4d3SLarry Finger 		 reg & ~RTL818X_CONFIG3_ANAPARAM_WRITE);
647f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
648f1d2b4d3SLarry Finger }
649f1d2b4d3SLarry Finger 
rtl8187se_mac_config(struct ieee80211_hw * dev)650f1d2b4d3SLarry Finger static void rtl8187se_mac_config(struct ieee80211_hw *dev)
651f1d2b4d3SLarry Finger {
652f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
653f1d2b4d3SLarry Finger 	u8 reg;
654f1d2b4d3SLarry Finger 
655f1d2b4d3SLarry Finger 	rtl818x_iowrite32(priv, REG_ADDR4(0x1F0), 0);
656f1d2b4d3SLarry Finger 	rtl818x_ioread32(priv, REG_ADDR4(0x1F0));
657f1d2b4d3SLarry Finger 	rtl818x_iowrite32(priv, REG_ADDR4(0x1F4), 0);
658f1d2b4d3SLarry Finger 	rtl818x_ioread32(priv, REG_ADDR4(0x1F4));
659f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, REG_ADDR1(0x1F8), 0);
660f1d2b4d3SLarry Finger 	rtl818x_ioread8(priv, REG_ADDR1(0x1F8));
661f1d2b4d3SLarry Finger 	/* Enable DA10 TX power saving */
662f1d2b4d3SLarry Finger 	reg = rtl818x_ioread8(priv, &priv->map->PHY_PR);
663f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->PHY_PR, reg | 0x04);
664f1d2b4d3SLarry Finger 	/* Power */
665f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, PI_DATA_REG, 0x1000);
666f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, SI_DATA_REG, 0x1000);
667f1d2b4d3SLarry Finger 	/* AFE - default to power ON */
668f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, REG_ADDR2(0x370), 0x0560);
669f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, REG_ADDR2(0x372), 0x0560);
670f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, REG_ADDR2(0x374), 0x0DA4);
671f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, REG_ADDR2(0x376), 0x0DA4);
672f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, REG_ADDR2(0x378), 0x0560);
673f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, REG_ADDR2(0x37A), 0x0560);
674f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, REG_ADDR2(0x37C), 0x00EC);
675f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, REG_ADDR2(0x37E), 0x00EC);
676f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, REG_ADDR1(0x24E), 0x01);
677f1d2b4d3SLarry Finger 	/* unknown, needed for suspend to RAM resume */
678f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, REG_ADDR1(0x0A), 0x72);
679f1d2b4d3SLarry Finger }
680f1d2b4d3SLarry Finger 
rtl8187se_set_antenna_config(struct ieee80211_hw * dev,u8 def_ant,bool diversity)681f1d2b4d3SLarry Finger static void rtl8187se_set_antenna_config(struct ieee80211_hw *dev, u8 def_ant,
682f1d2b4d3SLarry Finger 					 bool diversity)
683f1d2b4d3SLarry Finger {
684f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
685f1d2b4d3SLarry Finger 
686f1d2b4d3SLarry Finger 	rtl8225_write_phy_cck(dev, 0x0C, 0x09);
687f1d2b4d3SLarry Finger 	if (diversity) {
688f1d2b4d3SLarry Finger 		if (def_ant == 1) {
689f1d2b4d3SLarry Finger 			rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x00);
690f1d2b4d3SLarry Finger 			rtl8225_write_phy_cck(dev, 0x11, 0xBB);
691f1d2b4d3SLarry Finger 			rtl8225_write_phy_cck(dev, 0x01, 0xC7);
692f1d2b4d3SLarry Finger 			rtl8225_write_phy_ofdm(dev, 0x0D, 0x54);
693f1d2b4d3SLarry Finger 			rtl8225_write_phy_ofdm(dev, 0x18, 0xB2);
694f1d2b4d3SLarry Finger 		} else { /* main antenna */
695f1d2b4d3SLarry Finger 			rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);
696f1d2b4d3SLarry Finger 			rtl8225_write_phy_cck(dev, 0x11, 0x9B);
697f1d2b4d3SLarry Finger 			rtl8225_write_phy_cck(dev, 0x01, 0xC7);
698f1d2b4d3SLarry Finger 			rtl8225_write_phy_ofdm(dev, 0x0D, 0x5C);
699f1d2b4d3SLarry Finger 			rtl8225_write_phy_ofdm(dev, 0x18, 0xB2);
700f1d2b4d3SLarry Finger 		}
701f1d2b4d3SLarry Finger 	} else { /* disable antenna diversity */
702f1d2b4d3SLarry Finger 		if (def_ant == 1) {
703f1d2b4d3SLarry Finger 			rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x00);
704f1d2b4d3SLarry Finger 			rtl8225_write_phy_cck(dev, 0x11, 0xBB);
705f1d2b4d3SLarry Finger 			rtl8225_write_phy_cck(dev, 0x01, 0x47);
706f1d2b4d3SLarry Finger 			rtl8225_write_phy_ofdm(dev, 0x0D, 0x54);
707f1d2b4d3SLarry Finger 			rtl8225_write_phy_ofdm(dev, 0x18, 0x32);
708f1d2b4d3SLarry Finger 		} else { /* main antenna */
709f1d2b4d3SLarry Finger 			rtl818x_iowrite8(priv, &priv->map->TX_ANTENNA, 0x03);
710f1d2b4d3SLarry Finger 			rtl8225_write_phy_cck(dev, 0x11, 0x9B);
711f1d2b4d3SLarry Finger 			rtl8225_write_phy_cck(dev, 0x01, 0x47);
712f1d2b4d3SLarry Finger 			rtl8225_write_phy_ofdm(dev, 0x0D, 0x5C);
713f1d2b4d3SLarry Finger 			rtl8225_write_phy_ofdm(dev, 0x18, 0x32);
714f1d2b4d3SLarry Finger 		}
715f1d2b4d3SLarry Finger 	}
716f1d2b4d3SLarry Finger 	/* priv->curr_ant = def_ant; */
717f1d2b4d3SLarry Finger }
718f1d2b4d3SLarry Finger 
rtl8180_int_enable(struct ieee80211_hw * dev)719f1d2b4d3SLarry Finger static void rtl8180_int_enable(struct ieee80211_hw *dev)
720f1d2b4d3SLarry Finger {
721f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
722f1d2b4d3SLarry Finger 
723f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) {
724f1d2b4d3SLarry Finger 		rtl818x_iowrite32(priv, &priv->map->IMR,
725f1d2b4d3SLarry Finger 			  IMR_TBDER | IMR_TBDOK |
726f1d2b4d3SLarry Finger 			  IMR_TVODER | IMR_TVODOK |
727f1d2b4d3SLarry Finger 			  IMR_TVIDER | IMR_TVIDOK |
728f1d2b4d3SLarry Finger 			  IMR_TBEDER | IMR_TBEDOK |
729f1d2b4d3SLarry Finger 			  IMR_TBKDER | IMR_TBKDOK |
730f1d2b4d3SLarry Finger 			  IMR_RDU | IMR_RER |
731f1d2b4d3SLarry Finger 			  IMR_ROK | IMR_RQOSOK);
732f1d2b4d3SLarry Finger 	} else {
733f1d2b4d3SLarry Finger 		rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF);
734f1d2b4d3SLarry Finger 	}
735f1d2b4d3SLarry Finger }
736f1d2b4d3SLarry Finger 
rtl8180_int_disable(struct ieee80211_hw * dev)737f1d2b4d3SLarry Finger static void rtl8180_int_disable(struct ieee80211_hw *dev)
738f1d2b4d3SLarry Finger {
739f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
740f1d2b4d3SLarry Finger 
741f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) {
742f1d2b4d3SLarry Finger 		rtl818x_iowrite32(priv, &priv->map->IMR, 0);
743f1d2b4d3SLarry Finger 	} else {
744f1d2b4d3SLarry Finger 		rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0);
745f1d2b4d3SLarry Finger 	}
746f1d2b4d3SLarry Finger }
747f1d2b4d3SLarry Finger 
rtl8180_conf_basic_rates(struct ieee80211_hw * dev,u32 basic_mask)748f1d2b4d3SLarry Finger static void rtl8180_conf_basic_rates(struct ieee80211_hw *dev,
749f1d2b4d3SLarry Finger 			    u32 basic_mask)
750f1d2b4d3SLarry Finger {
751f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
752f1d2b4d3SLarry Finger 	u16 reg;
753f1d2b4d3SLarry Finger 	u32 resp_mask;
754f1d2b4d3SLarry Finger 	u8 basic_max;
755f1d2b4d3SLarry Finger 	u8 resp_max, resp_min;
756f1d2b4d3SLarry Finger 
757f1d2b4d3SLarry Finger 	resp_mask = basic_mask;
758f1d2b4d3SLarry Finger 	/* IEEE80211 says the response rate should be equal to the highest basic
759f1d2b4d3SLarry Finger 	 * rate that is not faster than received frame. But it says also that if
760f1d2b4d3SLarry Finger 	 * the basic rate set does not contains any rate for the current
761f1d2b4d3SLarry Finger 	 * modulation class then mandatory rate set must be used for that
762f1d2b4d3SLarry Finger 	 * modulation class. Eventually add OFDM mandatory rates..
763f1d2b4d3SLarry Finger 	 */
764f1d2b4d3SLarry Finger 	if ((resp_mask & 0xf) == resp_mask)
765f1d2b4d3SLarry Finger 		resp_mask |= 0x150; /* 6, 12, 24Mbps */
766f1d2b4d3SLarry Finger 
767f1d2b4d3SLarry Finger 	switch (priv->chip_family) {
768f1d2b4d3SLarry Finger 
769f1d2b4d3SLarry Finger 	case RTL818X_CHIP_FAMILY_RTL8180:
770f1d2b4d3SLarry Finger 		/* in 8180 this is NOT a BITMAP */
771f1d2b4d3SLarry Finger 		basic_max = fls(basic_mask) - 1;
772f1d2b4d3SLarry Finger 		reg = rtl818x_ioread16(priv, &priv->map->BRSR);
773f1d2b4d3SLarry Finger 		reg &= ~3;
774f1d2b4d3SLarry Finger 		reg |= basic_max;
775f1d2b4d3SLarry Finger 		rtl818x_iowrite16(priv, &priv->map->BRSR, reg);
776f1d2b4d3SLarry Finger 		break;
777f1d2b4d3SLarry Finger 
778f1d2b4d3SLarry Finger 	case RTL818X_CHIP_FAMILY_RTL8185:
779f1d2b4d3SLarry Finger 		resp_max = fls(resp_mask) - 1;
780f1d2b4d3SLarry Finger 		resp_min = ffs(resp_mask) - 1;
781f1d2b4d3SLarry Finger 		/* in 8185 this is a BITMAP */
782f1d2b4d3SLarry Finger 		rtl818x_iowrite16(priv, &priv->map->BRSR, basic_mask);
783f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->RESP_RATE, (resp_max << 4) |
784f1d2b4d3SLarry Finger 				resp_min);
785f1d2b4d3SLarry Finger 		break;
786f1d2b4d3SLarry Finger 
787f1d2b4d3SLarry Finger 	case RTL818X_CHIP_FAMILY_RTL8187SE:
788f1d2b4d3SLarry Finger 		/* in 8187se this is a BITMAP. BRSR reg actually sets
789f1d2b4d3SLarry Finger 		 * response rates.
790f1d2b4d3SLarry Finger 		 */
791f1d2b4d3SLarry Finger 		rtl818x_iowrite16(priv, &priv->map->BRSR_8187SE, resp_mask);
792f1d2b4d3SLarry Finger 		break;
793f1d2b4d3SLarry Finger 	}
794f1d2b4d3SLarry Finger }
795f1d2b4d3SLarry Finger 
rtl8180_config_cardbus(struct ieee80211_hw * dev)796f1d2b4d3SLarry Finger static void rtl8180_config_cardbus(struct ieee80211_hw *dev)
797f1d2b4d3SLarry Finger {
798f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
799f1d2b4d3SLarry Finger 	u16 reg16;
800f1d2b4d3SLarry Finger 	u8 reg8;
801f1d2b4d3SLarry Finger 
802f1d2b4d3SLarry Finger 	reg8 = rtl818x_ioread8(priv, &priv->map->CONFIG3);
803f1d2b4d3SLarry Finger 	reg8 |= 1 << 1;
804f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg8);
805f1d2b4d3SLarry Finger 
806f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) {
807f1d2b4d3SLarry Finger 		rtl818x_iowrite16(priv, FEMR_SE, 0xffff);
808f1d2b4d3SLarry Finger 	} else {
809f1d2b4d3SLarry Finger 		reg16 = rtl818x_ioread16(priv, &priv->map->FEMR);
810f1d2b4d3SLarry Finger 		reg16 |= (1 << 15) | (1 << 14) | (1 << 4);
811f1d2b4d3SLarry Finger 		rtl818x_iowrite16(priv, &priv->map->FEMR, reg16);
812f1d2b4d3SLarry Finger 	}
813f1d2b4d3SLarry Finger 
814f1d2b4d3SLarry Finger }
815f1d2b4d3SLarry Finger 
rtl8180_init_hw(struct ieee80211_hw * dev)816f1d2b4d3SLarry Finger static int rtl8180_init_hw(struct ieee80211_hw *dev)
817f1d2b4d3SLarry Finger {
818f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
819f1d2b4d3SLarry Finger 	u16 reg;
820f1d2b4d3SLarry Finger 	u32 reg32;
821f1d2b4d3SLarry Finger 
822f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->CMD, 0);
823f1d2b4d3SLarry Finger 	rtl818x_ioread8(priv, &priv->map->CMD);
824f1d2b4d3SLarry Finger 	msleep(10);
825f1d2b4d3SLarry Finger 
826f1d2b4d3SLarry Finger 	/* reset */
827f1d2b4d3SLarry Finger 	rtl8180_int_disable(dev);
828f1d2b4d3SLarry Finger 	rtl818x_ioread8(priv, &priv->map->CMD);
829f1d2b4d3SLarry Finger 
830f1d2b4d3SLarry Finger 	reg = rtl818x_ioread8(priv, &priv->map->CMD);
831f1d2b4d3SLarry Finger 	reg &= (1 << 1);
832f1d2b4d3SLarry Finger 	reg |= RTL818X_CMD_RESET;
833f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->CMD, RTL818X_CMD_RESET);
834f1d2b4d3SLarry Finger 	rtl818x_ioread8(priv, &priv->map->CMD);
835f1d2b4d3SLarry Finger 	msleep(200);
836f1d2b4d3SLarry Finger 
837f1d2b4d3SLarry Finger 	/* check success of reset */
838f1d2b4d3SLarry Finger 	if (rtl818x_ioread8(priv, &priv->map->CMD) & RTL818X_CMD_RESET) {
839f1d2b4d3SLarry Finger 		wiphy_err(dev->wiphy, "reset timeout!\n");
840f1d2b4d3SLarry Finger 		return -ETIMEDOUT;
841f1d2b4d3SLarry Finger 	}
842f1d2b4d3SLarry Finger 
843f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_LOAD);
844f1d2b4d3SLarry Finger 	rtl818x_ioread8(priv, &priv->map->CMD);
845f1d2b4d3SLarry Finger 	msleep(200);
846f1d2b4d3SLarry Finger 
847f1d2b4d3SLarry Finger 	if (rtl818x_ioread8(priv, &priv->map->CONFIG3) & (1 << 3)) {
848f1d2b4d3SLarry Finger 		rtl8180_config_cardbus(dev);
849f1d2b4d3SLarry Finger 	}
850f1d2b4d3SLarry Finger 
851f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE)
852f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->MSR, RTL818X_MSR_ENEDCA);
853f1d2b4d3SLarry Finger 	else
854f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->MSR, 0);
855f1d2b4d3SLarry Finger 
856f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8180)
857f1d2b4d3SLarry Finger 		rtl8180_set_anaparam(priv, priv->anaparam);
858f1d2b4d3SLarry Finger 
859f1d2b4d3SLarry Finger 	rtl818x_iowrite32(priv, &priv->map->RDSAR, priv->rx_ring_dma);
860f1d2b4d3SLarry Finger 	/* mac80211 queue have higher prio for lower index. The last queue
861f1d2b4d3SLarry Finger 	 * (that mac80211 is not aware of) is reserved for beacons (and have
862f1d2b4d3SLarry Finger 	 * the highest priority on the NIC)
863f1d2b4d3SLarry Finger 	 */
864f1d2b4d3SLarry Finger 	if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8187SE) {
865f1d2b4d3SLarry Finger 		rtl818x_iowrite32(priv, &priv->map->TBDA,
866f1d2b4d3SLarry Finger 				  priv->tx_ring[1].dma);
867f1d2b4d3SLarry Finger 		rtl818x_iowrite32(priv, &priv->map->TLPDA,
868f1d2b4d3SLarry Finger 				  priv->tx_ring[0].dma);
869f1d2b4d3SLarry Finger 	} else {
870f1d2b4d3SLarry Finger 		rtl818x_iowrite32(priv, &priv->map->TBDA,
871f1d2b4d3SLarry Finger 				  priv->tx_ring[4].dma);
872f1d2b4d3SLarry Finger 		rtl818x_iowrite32(priv, &priv->map->TVODA,
873f1d2b4d3SLarry Finger 				  priv->tx_ring[0].dma);
874f1d2b4d3SLarry Finger 		rtl818x_iowrite32(priv, &priv->map->TVIDA,
875f1d2b4d3SLarry Finger 				  priv->tx_ring[1].dma);
876f1d2b4d3SLarry Finger 		rtl818x_iowrite32(priv, &priv->map->TBEDA,
877f1d2b4d3SLarry Finger 				  priv->tx_ring[2].dma);
878f1d2b4d3SLarry Finger 		rtl818x_iowrite32(priv, &priv->map->TBKDA,
879f1d2b4d3SLarry Finger 				  priv->tx_ring[3].dma);
880f1d2b4d3SLarry Finger 	}
881f1d2b4d3SLarry Finger 
882f1d2b4d3SLarry Finger 	/* TODO: necessary? specs indicate not */
883f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
884f1d2b4d3SLarry Finger 	reg = rtl818x_ioread8(priv, &priv->map->CONFIG2);
885f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->CONFIG2, reg & ~(1 << 3));
886f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8185) {
887f1d2b4d3SLarry Finger 		reg = rtl818x_ioread8(priv, &priv->map->CONFIG2);
888f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->CONFIG2, reg | (1 << 4));
889f1d2b4d3SLarry Finger 	}
890f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
891f1d2b4d3SLarry Finger 
892f1d2b4d3SLarry Finger 	/* TODO: set CONFIG5 for calibrating AGC on rtl8180 + philips radio? */
893f1d2b4d3SLarry Finger 
894f1d2b4d3SLarry Finger 	/* TODO: turn off hw wep on rtl8180 */
895f1d2b4d3SLarry Finger 
896f1d2b4d3SLarry Finger 	rtl818x_iowrite32(priv, &priv->map->INT_TIMEOUT, 0);
897f1d2b4d3SLarry Finger 
898f1d2b4d3SLarry Finger 	if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) {
899f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->WPA_CONF, 0);
900f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->RATE_FALLBACK, 0);
901f1d2b4d3SLarry Finger 	} else {
902f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->SECURITY, 0);
903f1d2b4d3SLarry Finger 
904f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->PHY_DELAY, 0x6);
905f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER, 0x4C);
906f1d2b4d3SLarry Finger 	}
907f1d2b4d3SLarry Finger 
908f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8185) {
909f1d2b4d3SLarry Finger 		/* TODO: set ClkRun enable? necessary? */
910f1d2b4d3SLarry Finger 		reg = rtl818x_ioread8(priv, &priv->map->GP_ENABLE);
911f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->GP_ENABLE, reg & ~(1 << 6));
912f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
913f1d2b4d3SLarry Finger 		reg = rtl818x_ioread8(priv, &priv->map->CONFIG3);
914f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->CONFIG3, reg | (1 << 2));
915f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
916f1d2b4d3SLarry Finger 		/* fix eccessive IFS after CTS-to-self */
917f1d2b4d3SLarry Finger 		if (priv->map_pio) {
918f1d2b4d3SLarry Finger 			u8 reg;
919f1d2b4d3SLarry Finger 
920f1d2b4d3SLarry Finger 			reg = rtl818x_ioread8(priv, &priv->map->PGSELECT);
921f1d2b4d3SLarry Finger 			rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg | 1);
922f1d2b4d3SLarry Finger 			rtl818x_iowrite8(priv, REG_ADDR1(0xff), 0x35);
923f1d2b4d3SLarry Finger 			rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg);
924f1d2b4d3SLarry Finger 		} else
925f1d2b4d3SLarry Finger 			rtl818x_iowrite8(priv, REG_ADDR1(0x1ff), 0x35);
926f1d2b4d3SLarry Finger 	}
927f1d2b4d3SLarry Finger 
928f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) {
929f1d2b4d3SLarry Finger 
930f1d2b4d3SLarry Finger 		/* the set auto rate fallback bitmask from 1M to 54 Mb/s */
931f1d2b4d3SLarry Finger 		rtl818x_iowrite16(priv, ARFR, 0xFFF);
932f1d2b4d3SLarry Finger 		rtl818x_ioread16(priv, ARFR);
933f1d2b4d3SLarry Finger 
934f1d2b4d3SLarry Finger 		/* stop unused queus (no dma alloc) */
935f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->TPPOLL_STOP,
936f1d2b4d3SLarry Finger 			       RTL818x_TPPOLL_STOP_MG | RTL818x_TPPOLL_STOP_HI);
937f1d2b4d3SLarry Finger 
938f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->ACM_CONTROL, 0x00);
939f1d2b4d3SLarry Finger 		rtl818x_iowrite16(priv, &priv->map->TID_AC_MAP, 0xFA50);
940f1d2b4d3SLarry Finger 
941f1d2b4d3SLarry Finger 		rtl818x_iowrite16(priv, &priv->map->INT_MIG, 0);
942f1d2b4d3SLarry Finger 
943f1d2b4d3SLarry Finger 		/* some black magic here.. */
944f1d2b4d3SLarry Finger 		rtl8187se_mac_config(dev);
945f1d2b4d3SLarry Finger 
946f1d2b4d3SLarry Finger 		rtl818x_iowrite16(priv, RFSW_CTRL, 0x569A);
947f1d2b4d3SLarry Finger 		rtl818x_ioread16(priv, RFSW_CTRL);
948f1d2b4d3SLarry Finger 
949f1d2b4d3SLarry Finger 		rtl8180_set_anaparam(priv, RTL8225SE_ANAPARAM_ON);
950f1d2b4d3SLarry Finger 		rtl8180_set_anaparam2(priv, RTL8225SE_ANAPARAM2_ON);
951f1d2b4d3SLarry Finger 		rtl8180_set_anaparam3(priv, RTL8225SE_ANAPARAM3);
952f1d2b4d3SLarry Finger 
953f1d2b4d3SLarry Finger 
954f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->CONFIG5,
955f1d2b4d3SLarry Finger 			    rtl818x_ioread8(priv, &priv->map->CONFIG5) & 0x7F);
956f1d2b4d3SLarry Finger 
957f1d2b4d3SLarry Finger 		/*probably this switch led on */
958f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->PGSELECT,
959f1d2b4d3SLarry Finger 			    rtl818x_ioread8(priv, &priv->map->PGSELECT) | 0x08);
960f1d2b4d3SLarry Finger 
961f1d2b4d3SLarry Finger 		rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, 0x0480);
962f1d2b4d3SLarry Finger 		rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1BFF);
963f1d2b4d3SLarry Finger 		rtl818x_iowrite16(priv, &priv->map->RFPinsSelect, 0x2488);
964f1d2b4d3SLarry Finger 
965f1d2b4d3SLarry Finger 		rtl818x_iowrite32(priv, &priv->map->RF_TIMING, 0x4003);
966f1d2b4d3SLarry Finger 
967f1d2b4d3SLarry Finger 		/* the reference code mac hardcode table write
968f1d2b4d3SLarry Finger 		 * this reg by doing byte-wide accesses.
969f1d2b4d3SLarry Finger 		 * It does it just for lowest and highest byte..
970f1d2b4d3SLarry Finger 		 */
971f1d2b4d3SLarry Finger 		reg32 = rtl818x_ioread32(priv, &priv->map->RF_PARA);
972f1d2b4d3SLarry Finger 		reg32 &= 0x00ffff00;
973f1d2b4d3SLarry Finger 		reg32 |= 0xb8000054;
974f1d2b4d3SLarry Finger 		rtl818x_iowrite32(priv, &priv->map->RF_PARA, reg32);
975f1d2b4d3SLarry Finger 	} else
976f1d2b4d3SLarry Finger 		/* stop unused queus (no dma alloc) */
977f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->TX_DMA_POLLING,
978f1d2b4d3SLarry Finger 			    (1<<1) | (1<<2));
979f1d2b4d3SLarry Finger 
980f1d2b4d3SLarry Finger 	priv->rf->init(dev);
981f1d2b4d3SLarry Finger 
982f1d2b4d3SLarry Finger 	/* default basic rates are 1,2 Mbps for rtl8180. 1,2,6,9,12,18,24 Mbps
983f1d2b4d3SLarry Finger 	 * otherwise. bitmask 0x3 and 0x01f3 respectively.
984f1d2b4d3SLarry Finger 	 * NOTE: currenty rtl8225 RF code changes basic rates, so we need to do
985f1d2b4d3SLarry Finger 	 * this after rf init.
986f1d2b4d3SLarry Finger 	 * TODO: try to find out whether RF code really needs to do this..
987f1d2b4d3SLarry Finger 	 */
988f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8180)
989f1d2b4d3SLarry Finger 		rtl8180_conf_basic_rates(dev, 0x3);
990f1d2b4d3SLarry Finger 	else
991f1d2b4d3SLarry Finger 		rtl8180_conf_basic_rates(dev, 0x1f3);
992f1d2b4d3SLarry Finger 
993f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE)
994f1d2b4d3SLarry Finger 		rtl8187se_set_antenna_config(dev,
995f1d2b4d3SLarry Finger 					     priv->antenna_diversity_default,
996f1d2b4d3SLarry Finger 					     priv->antenna_diversity_en);
997f1d2b4d3SLarry Finger 	return 0;
998f1d2b4d3SLarry Finger }
999f1d2b4d3SLarry Finger 
rtl8180_init_rx_ring(struct ieee80211_hw * dev)1000f1d2b4d3SLarry Finger static int rtl8180_init_rx_ring(struct ieee80211_hw *dev)
1001f1d2b4d3SLarry Finger {
1002f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
1003f1d2b4d3SLarry Finger 	struct rtl818x_rx_cmd_desc *entry;
1004f1d2b4d3SLarry Finger 	int i;
1005f1d2b4d3SLarry Finger 
1006f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE)
1007f1d2b4d3SLarry Finger 		priv->rx_ring_sz = sizeof(struct rtl8187se_rx_desc);
1008f1d2b4d3SLarry Finger 	else
1009f1d2b4d3SLarry Finger 		priv->rx_ring_sz = sizeof(struct rtl8180_rx_desc);
1010f1d2b4d3SLarry Finger 
1011f4ce4bf6SChristophe JAILLET 	priv->rx_ring = dma_alloc_coherent(&priv->pdev->dev,
1012f4ce4bf6SChristophe JAILLET 					   priv->rx_ring_sz * 32,
1013f4ce4bf6SChristophe JAILLET 					   &priv->rx_ring_dma, GFP_KERNEL);
1014f1d2b4d3SLarry Finger 	if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) {
1015f1d2b4d3SLarry Finger 		wiphy_err(dev->wiphy, "Cannot allocate RX ring\n");
1016f1d2b4d3SLarry Finger 		return -ENOMEM;
1017f1d2b4d3SLarry Finger 	}
1018f1d2b4d3SLarry Finger 
1019f1d2b4d3SLarry Finger 	priv->rx_idx = 0;
1020f1d2b4d3SLarry Finger 
1021f1d2b4d3SLarry Finger 	for (i = 0; i < 32; i++) {
1022f1d2b4d3SLarry Finger 		struct sk_buff *skb = dev_alloc_skb(MAX_RX_SIZE);
1023f1d2b4d3SLarry Finger 		dma_addr_t *mapping;
1024f1d2b4d3SLarry Finger 		entry = priv->rx_ring + priv->rx_ring_sz*i;
1025f1d2b4d3SLarry Finger 		if (!skb) {
1026f4ce4bf6SChristophe JAILLET 			dma_free_coherent(&priv->pdev->dev,
1027f4ce4bf6SChristophe JAILLET 					  priv->rx_ring_sz * 32,
1028e4c8b456SJia-Ju Bai 					  priv->rx_ring, priv->rx_ring_dma);
1029f1d2b4d3SLarry Finger 			wiphy_err(dev->wiphy, "Cannot allocate RX skb\n");
1030f1d2b4d3SLarry Finger 			return -ENOMEM;
1031f1d2b4d3SLarry Finger 		}
1032f1d2b4d3SLarry Finger 		priv->rx_buf[i] = skb;
1033f1d2b4d3SLarry Finger 		mapping = (dma_addr_t *)skb->cb;
1034f4ce4bf6SChristophe JAILLET 		*mapping = dma_map_single(&priv->pdev->dev,
1035f4ce4bf6SChristophe JAILLET 					  skb_tail_pointer(skb), MAX_RX_SIZE,
1036f4ce4bf6SChristophe JAILLET 					  DMA_FROM_DEVICE);
1037f1d2b4d3SLarry Finger 
1038f4ce4bf6SChristophe JAILLET 		if (dma_mapping_error(&priv->pdev->dev, *mapping)) {
1039f1d2b4d3SLarry Finger 			kfree_skb(skb);
1040f4ce4bf6SChristophe JAILLET 			dma_free_coherent(&priv->pdev->dev,
1041f4ce4bf6SChristophe JAILLET 					  priv->rx_ring_sz * 32,
1042e4c8b456SJia-Ju Bai 					  priv->rx_ring, priv->rx_ring_dma);
1043f1d2b4d3SLarry Finger 			wiphy_err(dev->wiphy, "Cannot map DMA for RX skb\n");
1044f1d2b4d3SLarry Finger 			return -ENOMEM;
1045f1d2b4d3SLarry Finger 		}
1046f1d2b4d3SLarry Finger 
1047f1d2b4d3SLarry Finger 		entry->rx_buf = cpu_to_le32(*mapping);
1048f1d2b4d3SLarry Finger 		entry->flags = cpu_to_le32(RTL818X_RX_DESC_FLAG_OWN |
1049f1d2b4d3SLarry Finger 					   MAX_RX_SIZE);
1050f1d2b4d3SLarry Finger 	}
1051f1d2b4d3SLarry Finger 	entry->flags |= cpu_to_le32(RTL818X_RX_DESC_FLAG_EOR);
1052f1d2b4d3SLarry Finger 	return 0;
1053f1d2b4d3SLarry Finger }
1054f1d2b4d3SLarry Finger 
rtl8180_free_rx_ring(struct ieee80211_hw * dev)1055f1d2b4d3SLarry Finger static void rtl8180_free_rx_ring(struct ieee80211_hw *dev)
1056f1d2b4d3SLarry Finger {
1057f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
1058f1d2b4d3SLarry Finger 	int i;
1059f1d2b4d3SLarry Finger 
1060f1d2b4d3SLarry Finger 	for (i = 0; i < 32; i++) {
1061f1d2b4d3SLarry Finger 		struct sk_buff *skb = priv->rx_buf[i];
1062f1d2b4d3SLarry Finger 		if (!skb)
1063f1d2b4d3SLarry Finger 			continue;
1064f1d2b4d3SLarry Finger 
1065f4ce4bf6SChristophe JAILLET 		dma_unmap_single(&priv->pdev->dev, *((dma_addr_t *)skb->cb),
1066f4ce4bf6SChristophe JAILLET 				 MAX_RX_SIZE, DMA_FROM_DEVICE);
1067f1d2b4d3SLarry Finger 		kfree_skb(skb);
1068f1d2b4d3SLarry Finger 	}
1069f1d2b4d3SLarry Finger 
1070f4ce4bf6SChristophe JAILLET 	dma_free_coherent(&priv->pdev->dev, priv->rx_ring_sz * 32,
1071f1d2b4d3SLarry Finger 			  priv->rx_ring, priv->rx_ring_dma);
1072f1d2b4d3SLarry Finger 	priv->rx_ring = NULL;
1073f1d2b4d3SLarry Finger }
1074f1d2b4d3SLarry Finger 
rtl8180_init_tx_ring(struct ieee80211_hw * dev,unsigned int prio,unsigned int entries)1075f1d2b4d3SLarry Finger static int rtl8180_init_tx_ring(struct ieee80211_hw *dev,
1076f1d2b4d3SLarry Finger 				unsigned int prio, unsigned int entries)
1077f1d2b4d3SLarry Finger {
1078f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
1079f1d2b4d3SLarry Finger 	struct rtl8180_tx_desc *ring;
1080f1d2b4d3SLarry Finger 	dma_addr_t dma;
1081f1d2b4d3SLarry Finger 	int i;
1082f1d2b4d3SLarry Finger 
1083f4ce4bf6SChristophe JAILLET 	ring = dma_alloc_coherent(&priv->pdev->dev, sizeof(*ring) * entries,
1084f4ce4bf6SChristophe JAILLET 				  &dma, GFP_KERNEL);
1085f1d2b4d3SLarry Finger 	if (!ring || (unsigned long)ring & 0xFF) {
1086f1d2b4d3SLarry Finger 		wiphy_err(dev->wiphy, "Cannot allocate TX ring (prio = %d)\n",
1087f1d2b4d3SLarry Finger 			  prio);
1088f1d2b4d3SLarry Finger 		return -ENOMEM;
1089f1d2b4d3SLarry Finger 	}
1090f1d2b4d3SLarry Finger 
1091f1d2b4d3SLarry Finger 	priv->tx_ring[prio].desc = ring;
1092f1d2b4d3SLarry Finger 	priv->tx_ring[prio].dma = dma;
1093f1d2b4d3SLarry Finger 	priv->tx_ring[prio].idx = 0;
1094f1d2b4d3SLarry Finger 	priv->tx_ring[prio].entries = entries;
1095f1d2b4d3SLarry Finger 	skb_queue_head_init(&priv->tx_ring[prio].queue);
1096f1d2b4d3SLarry Finger 
1097f1d2b4d3SLarry Finger 	for (i = 0; i < entries; i++)
1098f1d2b4d3SLarry Finger 		ring[i].next_tx_desc =
1099f1d2b4d3SLarry Finger 			cpu_to_le32((u32)dma + ((i + 1) % entries) * sizeof(*ring));
1100f1d2b4d3SLarry Finger 
1101f1d2b4d3SLarry Finger 	return 0;
1102f1d2b4d3SLarry Finger }
1103f1d2b4d3SLarry Finger 
rtl8180_free_tx_ring(struct ieee80211_hw * dev,unsigned int prio)1104f1d2b4d3SLarry Finger static void rtl8180_free_tx_ring(struct ieee80211_hw *dev, unsigned int prio)
1105f1d2b4d3SLarry Finger {
1106f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
1107f1d2b4d3SLarry Finger 	struct rtl8180_tx_ring *ring = &priv->tx_ring[prio];
1108f1d2b4d3SLarry Finger 
1109f1d2b4d3SLarry Finger 	while (skb_queue_len(&ring->queue)) {
1110f1d2b4d3SLarry Finger 		struct rtl8180_tx_desc *entry = &ring->desc[ring->idx];
1111f1d2b4d3SLarry Finger 		struct sk_buff *skb = __skb_dequeue(&ring->queue);
1112f1d2b4d3SLarry Finger 
1113f4ce4bf6SChristophe JAILLET 		dma_unmap_single(&priv->pdev->dev, le32_to_cpu(entry->tx_buf),
1114f4ce4bf6SChristophe JAILLET 				 skb->len, DMA_TO_DEVICE);
1115f1d2b4d3SLarry Finger 		kfree_skb(skb);
1116f1d2b4d3SLarry Finger 		ring->idx = (ring->idx + 1) % ring->entries;
1117f1d2b4d3SLarry Finger 	}
1118f1d2b4d3SLarry Finger 
1119f4ce4bf6SChristophe JAILLET 	dma_free_coherent(&priv->pdev->dev,
1120f4ce4bf6SChristophe JAILLET 			  sizeof(*ring->desc) * ring->entries, ring->desc,
1121f4ce4bf6SChristophe JAILLET 			  ring->dma);
1122f1d2b4d3SLarry Finger 	ring->desc = NULL;
1123f1d2b4d3SLarry Finger }
1124f1d2b4d3SLarry Finger 
rtl8180_start(struct ieee80211_hw * dev)1125f1d2b4d3SLarry Finger static int rtl8180_start(struct ieee80211_hw *dev)
1126f1d2b4d3SLarry Finger {
1127f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
1128f1d2b4d3SLarry Finger 	int ret, i;
1129f1d2b4d3SLarry Finger 	u32 reg;
1130f1d2b4d3SLarry Finger 
1131f1d2b4d3SLarry Finger 	ret = rtl8180_init_rx_ring(dev);
1132f1d2b4d3SLarry Finger 	if (ret)
1133f1d2b4d3SLarry Finger 		return ret;
1134f1d2b4d3SLarry Finger 
1135f1d2b4d3SLarry Finger 	for (i = 0; i < (dev->queues + 1); i++)
1136f1d2b4d3SLarry Finger 		if ((ret = rtl8180_init_tx_ring(dev, i, 16)))
1137f1d2b4d3SLarry Finger 			goto err_free_rings;
1138f1d2b4d3SLarry Finger 
1139f1d2b4d3SLarry Finger 	ret = rtl8180_init_hw(dev);
1140f1d2b4d3SLarry Finger 	if (ret)
1141f1d2b4d3SLarry Finger 		goto err_free_rings;
1142f1d2b4d3SLarry Finger 
1143f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) {
1144f1d2b4d3SLarry Finger 		ret = request_irq(priv->pdev->irq, rtl8187se_interrupt,
1145f1d2b4d3SLarry Finger 			  IRQF_SHARED, KBUILD_MODNAME, dev);
1146f1d2b4d3SLarry Finger 	} else {
1147f1d2b4d3SLarry Finger 		ret = request_irq(priv->pdev->irq, rtl8180_interrupt,
1148f1d2b4d3SLarry Finger 			  IRQF_SHARED, KBUILD_MODNAME, dev);
1149f1d2b4d3SLarry Finger 	}
1150f1d2b4d3SLarry Finger 
1151f1d2b4d3SLarry Finger 	if (ret) {
1152f1d2b4d3SLarry Finger 		wiphy_err(dev->wiphy, "failed to register IRQ handler\n");
1153f1d2b4d3SLarry Finger 		goto err_free_rings;
1154f1d2b4d3SLarry Finger 	}
1155f1d2b4d3SLarry Finger 
1156f1d2b4d3SLarry Finger 	rtl8180_int_enable(dev);
1157f1d2b4d3SLarry Finger 
1158f1d2b4d3SLarry Finger 	/* in rtl8187se at MAR regs offset there is the management
1159f1d2b4d3SLarry Finger 	 * TX descriptor DMA addres..
1160f1d2b4d3SLarry Finger 	 */
1161f1d2b4d3SLarry Finger 	if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8187SE) {
1162f1d2b4d3SLarry Finger 		rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0);
1163f1d2b4d3SLarry Finger 		rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0);
1164f1d2b4d3SLarry Finger 	}
1165f1d2b4d3SLarry Finger 
1166f1d2b4d3SLarry Finger 	reg = RTL818X_RX_CONF_ONLYERLPKT |
1167f1d2b4d3SLarry Finger 	      RTL818X_RX_CONF_RX_AUTORESETPHY |
1168f1d2b4d3SLarry Finger 	      RTL818X_RX_CONF_MGMT |
1169f1d2b4d3SLarry Finger 	      RTL818X_RX_CONF_DATA |
1170f1d2b4d3SLarry Finger 	      (7 << 8 /* MAX RX DMA */) |
1171f1d2b4d3SLarry Finger 	      RTL818X_RX_CONF_BROADCAST |
1172f1d2b4d3SLarry Finger 	      RTL818X_RX_CONF_NICMAC;
1173f1d2b4d3SLarry Finger 
1174f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8185)
1175f1d2b4d3SLarry Finger 		reg |= RTL818X_RX_CONF_CSDM1 | RTL818X_RX_CONF_CSDM2;
1176f1d2b4d3SLarry Finger 	else if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8180) {
1177f1d2b4d3SLarry Finger 		reg |= (priv->rfparam & RF_PARAM_CARRIERSENSE1)
1178f1d2b4d3SLarry Finger 			? RTL818X_RX_CONF_CSDM1 : 0;
1179f1d2b4d3SLarry Finger 		reg |= (priv->rfparam & RF_PARAM_CARRIERSENSE2)
1180f1d2b4d3SLarry Finger 			? RTL818X_RX_CONF_CSDM2 : 0;
1181f1d2b4d3SLarry Finger 	} else {
1182f1d2b4d3SLarry Finger 		reg &= ~(RTL818X_RX_CONF_CSDM1 | RTL818X_RX_CONF_CSDM2);
1183f1d2b4d3SLarry Finger 	}
1184f1d2b4d3SLarry Finger 
1185f1d2b4d3SLarry Finger 	priv->rx_conf = reg;
1186f1d2b4d3SLarry Finger 	rtl818x_iowrite32(priv, &priv->map->RX_CONF, reg);
1187f1d2b4d3SLarry Finger 
1188f1d2b4d3SLarry Finger 	if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) {
1189f1d2b4d3SLarry Finger 		reg = rtl818x_ioread8(priv, &priv->map->CW_CONF);
1190f1d2b4d3SLarry Finger 
1191f1d2b4d3SLarry Finger 		/* CW is not on per-packet basis.
1192f1d2b4d3SLarry Finger 		 * in rtl8185 the CW_VALUE reg is used.
1193f1d2b4d3SLarry Finger 		 * in rtl8187se the AC param regs are used.
1194f1d2b4d3SLarry Finger 		 */
1195f1d2b4d3SLarry Finger 		reg &= ~RTL818X_CW_CONF_PERPACKET_CW;
1196f1d2b4d3SLarry Finger 		/* retry limit IS on per-packet basis.
1197f1d2b4d3SLarry Finger 		 * the short and long retry limit in TX_CONF
1198f1d2b4d3SLarry Finger 		 * reg are ignored
1199f1d2b4d3SLarry Finger 		 */
1200f1d2b4d3SLarry Finger 		reg |= RTL818X_CW_CONF_PERPACKET_RETRY;
1201f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->CW_CONF, reg);
1202f1d2b4d3SLarry Finger 
1203f1d2b4d3SLarry Finger 		reg = rtl818x_ioread8(priv, &priv->map->TX_AGC_CTL);
1204f1d2b4d3SLarry Finger 		/* TX antenna and TX gain are not on per-packet basis.
1205f1d2b4d3SLarry Finger 		 * TX Antenna is selected by ANTSEL reg (RX in BB regs).
1206f1d2b4d3SLarry Finger 		 * TX gain is selected with CCK_TX_AGC and OFDM_TX_AGC regs
1207f1d2b4d3SLarry Finger 		 */
1208f1d2b4d3SLarry Finger 		reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_GAIN;
1209f1d2b4d3SLarry Finger 		reg &= ~RTL818X_TX_AGC_CTL_PERPACKET_ANTSEL;
1210f1d2b4d3SLarry Finger 		reg |=  RTL818X_TX_AGC_CTL_FEEDBACK_ANT;
1211f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->TX_AGC_CTL, reg);
1212f1d2b4d3SLarry Finger 
1213f1d2b4d3SLarry Finger 		/* disable early TX */
1214f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, (u8 __iomem *)priv->map + 0xec, 0x3f);
1215f1d2b4d3SLarry Finger 	}
1216f1d2b4d3SLarry Finger 
1217f1d2b4d3SLarry Finger 	reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
1218f1d2b4d3SLarry Finger 	reg |= (6 << 21 /* MAX TX DMA */) |
1219f1d2b4d3SLarry Finger 	       RTL818X_TX_CONF_NO_ICV;
1220f1d2b4d3SLarry Finger 
1221f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE)
1222f1d2b4d3SLarry Finger 		reg |= 1<<30;  /*  "duration procedure mode" */
1223f1d2b4d3SLarry Finger 
1224f1d2b4d3SLarry Finger 	if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180)
1225f1d2b4d3SLarry Finger 		reg &= ~RTL818X_TX_CONF_PROBE_DTS;
1226f1d2b4d3SLarry Finger 	else
1227f1d2b4d3SLarry Finger 		reg &= ~RTL818X_TX_CONF_HW_SEQNUM;
1228f1d2b4d3SLarry Finger 
1229f1d2b4d3SLarry Finger 	reg &= ~RTL818X_TX_CONF_DISCW;
1230f1d2b4d3SLarry Finger 
1231f1d2b4d3SLarry Finger 	/* different meaning, same value on both rtl8185 and rtl8180 */
1232f1d2b4d3SLarry Finger 	reg &= ~RTL818X_TX_CONF_SAT_HWPLCP;
1233f1d2b4d3SLarry Finger 
1234f1d2b4d3SLarry Finger 	rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg);
1235f1d2b4d3SLarry Finger 
1236f1d2b4d3SLarry Finger 	reg = rtl818x_ioread8(priv, &priv->map->CMD);
1237f1d2b4d3SLarry Finger 	reg |= RTL818X_CMD_RX_ENABLE;
1238f1d2b4d3SLarry Finger 	reg |= RTL818X_CMD_TX_ENABLE;
1239f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->CMD, reg);
1240f1d2b4d3SLarry Finger 
1241f1d2b4d3SLarry Finger 	return 0;
1242f1d2b4d3SLarry Finger 
1243f1d2b4d3SLarry Finger  err_free_rings:
1244f1d2b4d3SLarry Finger 	rtl8180_free_rx_ring(dev);
1245f1d2b4d3SLarry Finger 	for (i = 0; i < (dev->queues + 1); i++)
1246f1d2b4d3SLarry Finger 		if (priv->tx_ring[i].desc)
1247f1d2b4d3SLarry Finger 			rtl8180_free_tx_ring(dev, i);
1248f1d2b4d3SLarry Finger 
1249f1d2b4d3SLarry Finger 	return ret;
1250f1d2b4d3SLarry Finger }
1251f1d2b4d3SLarry Finger 
rtl8180_stop(struct ieee80211_hw * dev)1252f1d2b4d3SLarry Finger static void rtl8180_stop(struct ieee80211_hw *dev)
1253f1d2b4d3SLarry Finger {
1254f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
1255f1d2b4d3SLarry Finger 	u8 reg;
1256f1d2b4d3SLarry Finger 	int i;
1257f1d2b4d3SLarry Finger 
1258f1d2b4d3SLarry Finger 	rtl8180_int_disable(dev);
1259f1d2b4d3SLarry Finger 
1260f1d2b4d3SLarry Finger 	reg = rtl818x_ioread8(priv, &priv->map->CMD);
1261f1d2b4d3SLarry Finger 	reg &= ~RTL818X_CMD_TX_ENABLE;
1262f1d2b4d3SLarry Finger 	reg &= ~RTL818X_CMD_RX_ENABLE;
1263f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->CMD, reg);
1264f1d2b4d3SLarry Finger 
1265f1d2b4d3SLarry Finger 	priv->rf->stop(dev);
1266f1d2b4d3SLarry Finger 
1267f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
1268f1d2b4d3SLarry Finger 	reg = rtl818x_ioread8(priv, &priv->map->CONFIG4);
1269f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->CONFIG4, reg | RTL818X_CONFIG4_VCOOFF);
1270f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
1271f1d2b4d3SLarry Finger 
1272f1d2b4d3SLarry Finger 	free_irq(priv->pdev->irq, dev);
1273f1d2b4d3SLarry Finger 
1274f1d2b4d3SLarry Finger 	rtl8180_free_rx_ring(dev);
1275f1d2b4d3SLarry Finger 	for (i = 0; i < (dev->queues + 1); i++)
1276f1d2b4d3SLarry Finger 		rtl8180_free_tx_ring(dev, i);
1277f1d2b4d3SLarry Finger }
1278f1d2b4d3SLarry Finger 
rtl8180_get_tsf(struct ieee80211_hw * dev,struct ieee80211_vif * vif)1279f1d2b4d3SLarry Finger static u64 rtl8180_get_tsf(struct ieee80211_hw *dev,
1280f1d2b4d3SLarry Finger 			   struct ieee80211_vif *vif)
1281f1d2b4d3SLarry Finger {
1282f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
1283f1d2b4d3SLarry Finger 
1284f1d2b4d3SLarry Finger 	return rtl818x_ioread32(priv, &priv->map->TSFT[0]) |
1285f1d2b4d3SLarry Finger 	       (u64)(rtl818x_ioread32(priv, &priv->map->TSFT[1])) << 32;
1286f1d2b4d3SLarry Finger }
1287f1d2b4d3SLarry Finger 
rtl8180_beacon_work(struct work_struct * work)1288f1d2b4d3SLarry Finger static void rtl8180_beacon_work(struct work_struct *work)
1289f1d2b4d3SLarry Finger {
1290f1d2b4d3SLarry Finger 	struct rtl8180_vif *vif_priv =
1291f1d2b4d3SLarry Finger 		container_of(work, struct rtl8180_vif, beacon_work.work);
1292f1d2b4d3SLarry Finger 	struct ieee80211_vif *vif =
1293f1d2b4d3SLarry Finger 		container_of((void *)vif_priv, struct ieee80211_vif, drv_priv);
1294f1d2b4d3SLarry Finger 	struct ieee80211_hw *dev = vif_priv->dev;
1295f1d2b4d3SLarry Finger 	struct ieee80211_mgmt *mgmt;
1296f1d2b4d3SLarry Finger 	struct sk_buff *skb;
1297f1d2b4d3SLarry Finger 
1298f1d2b4d3SLarry Finger 	/* don't overflow the tx ring */
1299f1d2b4d3SLarry Finger 	if (ieee80211_queue_stopped(dev, 0))
1300f1d2b4d3SLarry Finger 		goto resched;
1301f1d2b4d3SLarry Finger 
1302f1d2b4d3SLarry Finger 	/* grab a fresh beacon */
13036e8912a5SShaul Triebitz 	skb = ieee80211_beacon_get(dev, vif, 0);
1304f1d2b4d3SLarry Finger 	if (!skb)
1305f1d2b4d3SLarry Finger 		goto resched;
1306f1d2b4d3SLarry Finger 
1307f1d2b4d3SLarry Finger 	/*
1308f1d2b4d3SLarry Finger 	 * update beacon timestamp w/ TSF value
1309f1d2b4d3SLarry Finger 	 * TODO: make hardware update beacon timestamp
1310f1d2b4d3SLarry Finger 	 */
1311f1d2b4d3SLarry Finger 	mgmt = (struct ieee80211_mgmt *)skb->data;
1312f1d2b4d3SLarry Finger 	mgmt->u.beacon.timestamp = cpu_to_le64(rtl8180_get_tsf(dev, vif));
1313f1d2b4d3SLarry Finger 
1314f1d2b4d3SLarry Finger 	/* TODO: use actual beacon queue */
1315f1d2b4d3SLarry Finger 	skb_set_queue_mapping(skb, 0);
1316f1d2b4d3SLarry Finger 
1317f1d2b4d3SLarry Finger 	rtl8180_tx(dev, NULL, skb);
1318f1d2b4d3SLarry Finger 
1319f1d2b4d3SLarry Finger resched:
1320f1d2b4d3SLarry Finger 	/*
1321f1d2b4d3SLarry Finger 	 * schedule next beacon
1322f1d2b4d3SLarry Finger 	 * TODO: use hardware support for beacon timing
1323f1d2b4d3SLarry Finger 	 */
1324f1d2b4d3SLarry Finger 	schedule_delayed_work(&vif_priv->beacon_work,
1325f1d2b4d3SLarry Finger 			usecs_to_jiffies(1024 * vif->bss_conf.beacon_int));
1326f1d2b4d3SLarry Finger }
1327f1d2b4d3SLarry Finger 
rtl8180_add_interface(struct ieee80211_hw * dev,struct ieee80211_vif * vif)1328f1d2b4d3SLarry Finger static int rtl8180_add_interface(struct ieee80211_hw *dev,
1329f1d2b4d3SLarry Finger 				 struct ieee80211_vif *vif)
1330f1d2b4d3SLarry Finger {
1331f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
1332f1d2b4d3SLarry Finger 	struct rtl8180_vif *vif_priv;
1333f1d2b4d3SLarry Finger 
1334f1d2b4d3SLarry Finger 	/*
1335f1d2b4d3SLarry Finger 	 * We only support one active interface at a time.
1336f1d2b4d3SLarry Finger 	 */
1337f1d2b4d3SLarry Finger 	if (priv->vif)
1338f1d2b4d3SLarry Finger 		return -EBUSY;
1339f1d2b4d3SLarry Finger 
1340f1d2b4d3SLarry Finger 	switch (vif->type) {
1341f1d2b4d3SLarry Finger 	case NL80211_IFTYPE_STATION:
1342f1d2b4d3SLarry Finger 	case NL80211_IFTYPE_ADHOC:
1343f1d2b4d3SLarry Finger 		break;
1344f1d2b4d3SLarry Finger 	default:
1345f1d2b4d3SLarry Finger 		return -EOPNOTSUPP;
1346f1d2b4d3SLarry Finger 	}
1347f1d2b4d3SLarry Finger 
1348f1d2b4d3SLarry Finger 	priv->vif = vif;
1349f1d2b4d3SLarry Finger 
1350f1d2b4d3SLarry Finger 	/* Initialize driver private area */
1351f1d2b4d3SLarry Finger 	vif_priv = (struct rtl8180_vif *)&vif->drv_priv;
1352f1d2b4d3SLarry Finger 	vif_priv->dev = dev;
1353f1d2b4d3SLarry Finger 	INIT_DELAYED_WORK(&vif_priv->beacon_work, rtl8180_beacon_work);
1354f1d2b4d3SLarry Finger 	vif_priv->enable_beacon = false;
1355f1d2b4d3SLarry Finger 
1356f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
1357f1d2b4d3SLarry Finger 	rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->MAC[0],
1358f1d2b4d3SLarry Finger 			  le32_to_cpu(*(__le32 *)vif->addr));
1359f1d2b4d3SLarry Finger 	rtl818x_iowrite16(priv, (__le16 __iomem *)&priv->map->MAC[4],
1360f1d2b4d3SLarry Finger 			  le16_to_cpu(*(__le16 *)(vif->addr + 4)));
1361f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);
1362f1d2b4d3SLarry Finger 
1363f1d2b4d3SLarry Finger 	return 0;
1364f1d2b4d3SLarry Finger }
1365f1d2b4d3SLarry Finger 
rtl8180_remove_interface(struct ieee80211_hw * dev,struct ieee80211_vif * vif)1366f1d2b4d3SLarry Finger static void rtl8180_remove_interface(struct ieee80211_hw *dev,
1367f1d2b4d3SLarry Finger 				     struct ieee80211_vif *vif)
1368f1d2b4d3SLarry Finger {
1369f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
1370f1d2b4d3SLarry Finger 	priv->vif = NULL;
1371f1d2b4d3SLarry Finger }
1372f1d2b4d3SLarry Finger 
rtl8180_config(struct ieee80211_hw * dev,u32 changed)1373f1d2b4d3SLarry Finger static int rtl8180_config(struct ieee80211_hw *dev, u32 changed)
1374f1d2b4d3SLarry Finger {
1375f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
1376f1d2b4d3SLarry Finger 	struct ieee80211_conf *conf = &dev->conf;
1377f1d2b4d3SLarry Finger 
1378f1d2b4d3SLarry Finger 	priv->rf->set_chan(dev, conf);
1379f1d2b4d3SLarry Finger 
1380f1d2b4d3SLarry Finger 	return 0;
1381f1d2b4d3SLarry Finger }
1382f1d2b4d3SLarry Finger 
rtl8187se_conf_ac_parm(struct ieee80211_hw * dev,u8 queue)1383f1d2b4d3SLarry Finger static void rtl8187se_conf_ac_parm(struct ieee80211_hw *dev, u8 queue)
1384f1d2b4d3SLarry Finger {
1385f1d2b4d3SLarry Finger 	const struct ieee80211_tx_queue_params *params;
1386f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
1387f1d2b4d3SLarry Finger 
1388f1d2b4d3SLarry Finger 	/* hw value */
1389f1d2b4d3SLarry Finger 	u32 ac_param;
1390f1d2b4d3SLarry Finger 
1391f1d2b4d3SLarry Finger 	u8 aifs;
1392f1d2b4d3SLarry Finger 	u8 txop;
1393f1d2b4d3SLarry Finger 	u8 cw_min, cw_max;
1394f1d2b4d3SLarry Finger 
1395f1d2b4d3SLarry Finger 	params = &priv->queue_param[queue];
1396f1d2b4d3SLarry Finger 
1397f1d2b4d3SLarry Finger 	cw_min = fls(params->cw_min);
1398f1d2b4d3SLarry Finger 	cw_max = fls(params->cw_max);
1399f1d2b4d3SLarry Finger 
1400f1d2b4d3SLarry Finger 	aifs = 10 + params->aifs * priv->slot_time;
1401f1d2b4d3SLarry Finger 
1402f1d2b4d3SLarry Finger 	/* TODO: check if txop HW is in us (mult by 32) */
1403f1d2b4d3SLarry Finger 	txop = params->txop;
1404f1d2b4d3SLarry Finger 
1405f1d2b4d3SLarry Finger 	ac_param = txop << AC_PARAM_TXOP_LIMIT_SHIFT |
1406f1d2b4d3SLarry Finger 		cw_max << AC_PARAM_ECW_MAX_SHIFT |
1407f1d2b4d3SLarry Finger 		cw_min << AC_PARAM_ECW_MIN_SHIFT |
1408f1d2b4d3SLarry Finger 		aifs << AC_PARAM_AIFS_SHIFT;
1409f1d2b4d3SLarry Finger 
1410f1d2b4d3SLarry Finger 	switch (queue) {
1411f1d2b4d3SLarry Finger 	case IEEE80211_AC_BK:
1412f1d2b4d3SLarry Finger 		rtl818x_iowrite32(priv, &priv->map->AC_BK_PARAM, ac_param);
1413f1d2b4d3SLarry Finger 		break;
1414f1d2b4d3SLarry Finger 	case IEEE80211_AC_BE:
1415f1d2b4d3SLarry Finger 		rtl818x_iowrite32(priv, &priv->map->AC_BE_PARAM, ac_param);
1416f1d2b4d3SLarry Finger 		break;
1417f1d2b4d3SLarry Finger 	case IEEE80211_AC_VI:
1418f1d2b4d3SLarry Finger 		rtl818x_iowrite32(priv, &priv->map->AC_VI_PARAM, ac_param);
1419f1d2b4d3SLarry Finger 		break;
1420f1d2b4d3SLarry Finger 	case IEEE80211_AC_VO:
1421f1d2b4d3SLarry Finger 		rtl818x_iowrite32(priv, &priv->map->AC_VO_PARAM, ac_param);
1422f1d2b4d3SLarry Finger 		break;
1423f1d2b4d3SLarry Finger 	}
1424f1d2b4d3SLarry Finger }
1425f1d2b4d3SLarry Finger 
rtl8180_conf_tx(struct ieee80211_hw * dev,struct ieee80211_vif * vif,unsigned int link_id,u16 queue,const struct ieee80211_tx_queue_params * params)1426f1d2b4d3SLarry Finger static int rtl8180_conf_tx(struct ieee80211_hw *dev,
1427b3e2130bSJohannes Berg 			    struct ieee80211_vif *vif,
1428b3e2130bSJohannes Berg 			    unsigned int link_id, u16 queue,
1429f1d2b4d3SLarry Finger 			    const struct ieee80211_tx_queue_params *params)
1430f1d2b4d3SLarry Finger {
1431f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
1432f1d2b4d3SLarry Finger 	u8 cw_min, cw_max;
1433f1d2b4d3SLarry Finger 
1434f1d2b4d3SLarry Finger 	/* nothing to do ? */
1435f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8180)
1436f1d2b4d3SLarry Finger 		return 0;
1437f1d2b4d3SLarry Finger 
1438f1d2b4d3SLarry Finger 	cw_min = fls(params->cw_min);
1439f1d2b4d3SLarry Finger 	cw_max = fls(params->cw_max);
1440f1d2b4d3SLarry Finger 
1441f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) {
1442f1d2b4d3SLarry Finger 		priv->queue_param[queue] = *params;
1443f1d2b4d3SLarry Finger 		rtl8187se_conf_ac_parm(dev, queue);
1444f1d2b4d3SLarry Finger 	} else
1445f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->CW_VAL,
1446f1d2b4d3SLarry Finger 				 (cw_max << 4) | cw_min);
1447f1d2b4d3SLarry Finger 	return 0;
1448f1d2b4d3SLarry Finger }
1449f1d2b4d3SLarry Finger 
rtl8180_conf_erp(struct ieee80211_hw * dev,struct ieee80211_bss_conf * info)1450f1d2b4d3SLarry Finger static void rtl8180_conf_erp(struct ieee80211_hw *dev,
1451f1d2b4d3SLarry Finger 			    struct ieee80211_bss_conf *info)
1452f1d2b4d3SLarry Finger {
1453f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
1454f1d2b4d3SLarry Finger 	u8 sifs, difs;
1455f1d2b4d3SLarry Finger 	int eifs;
1456f1d2b4d3SLarry Finger 	u8 hw_eifs;
1457f1d2b4d3SLarry Finger 
1458f1d2b4d3SLarry Finger 	/* TODO: should we do something ? */
1459f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8180)
1460f1d2b4d3SLarry Finger 		return;
1461f1d2b4d3SLarry Finger 
1462f1d2b4d3SLarry Finger 	/* I _hope_ this means 10uS for the HW.
1463f1d2b4d3SLarry Finger 	 * In reference code it is 0x22 for
1464f1d2b4d3SLarry Finger 	 * both rtl8187L and rtl8187SE
1465f1d2b4d3SLarry Finger 	 */
1466f1d2b4d3SLarry Finger 	sifs = 0x22;
1467f1d2b4d3SLarry Finger 
1468f1d2b4d3SLarry Finger 	if (info->use_short_slot)
1469f1d2b4d3SLarry Finger 		priv->slot_time = 9;
1470f1d2b4d3SLarry Finger 	else
1471f1d2b4d3SLarry Finger 		priv->slot_time = 20;
1472f1d2b4d3SLarry Finger 
1473f1d2b4d3SLarry Finger 	/* 10 is SIFS time in uS */
1474f1d2b4d3SLarry Finger 	difs = 10 + 2 * priv->slot_time;
1475f1d2b4d3SLarry Finger 	eifs = 10 + difs + priv->ack_time;
1476f1d2b4d3SLarry Finger 
1477f1d2b4d3SLarry Finger 	/* HW should use 4uS units for EIFS (I'm sure for rtl8185)*/
1478f1d2b4d3SLarry Finger 	hw_eifs = DIV_ROUND_UP(eifs, 4);
1479f1d2b4d3SLarry Finger 
1480f1d2b4d3SLarry Finger 
1481f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->SLOT, priv->slot_time);
1482f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->SIFS, sifs);
1483f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->DIFS, difs);
1484f1d2b4d3SLarry Finger 
1485f1d2b4d3SLarry Finger 	/* from reference code. set ack timeout reg = eifs reg */
1486f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->CARRIER_SENSE_COUNTER, hw_eifs);
1487f1d2b4d3SLarry Finger 
1488f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE)
1489f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->EIFS_8187SE, hw_eifs);
1490f1d2b4d3SLarry Finger 	else if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8185) {
1491f1d2b4d3SLarry Finger 		/* rtl8187/rtl8185 HW bug. After EIFS is elapsed,
1492f1d2b4d3SLarry Finger 		 * the HW still wait for DIFS.
1493f1d2b4d3SLarry Finger 		 * HW uses 4uS units for EIFS.
1494f1d2b4d3SLarry Finger 		 */
1495f1d2b4d3SLarry Finger 		hw_eifs = DIV_ROUND_UP(eifs - difs, 4);
1496f1d2b4d3SLarry Finger 
1497f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->EIFS, hw_eifs);
1498f1d2b4d3SLarry Finger 	}
1499f1d2b4d3SLarry Finger }
1500f1d2b4d3SLarry Finger 
rtl8180_bss_info_changed(struct ieee80211_hw * dev,struct ieee80211_vif * vif,struct ieee80211_bss_conf * info,u64 changed)1501f1d2b4d3SLarry Finger static void rtl8180_bss_info_changed(struct ieee80211_hw *dev,
1502f1d2b4d3SLarry Finger 				     struct ieee80211_vif *vif,
1503f1d2b4d3SLarry Finger 				     struct ieee80211_bss_conf *info,
15047b7090b4SJohannes Berg 				     u64 changed)
1505f1d2b4d3SLarry Finger {
1506f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
1507f1d2b4d3SLarry Finger 	struct rtl8180_vif *vif_priv;
1508f1d2b4d3SLarry Finger 	int i;
1509f1d2b4d3SLarry Finger 	u8 reg;
1510f1d2b4d3SLarry Finger 
1511f1d2b4d3SLarry Finger 	vif_priv = (struct rtl8180_vif *)&vif->drv_priv;
1512f1d2b4d3SLarry Finger 
1513f1d2b4d3SLarry Finger 	if (changed & BSS_CHANGED_BSSID) {
1514f1d2b4d3SLarry Finger 		rtl818x_iowrite16(priv, (__le16 __iomem *)&priv->map->BSSID[0],
1515f1d2b4d3SLarry Finger 				  le16_to_cpu(*(__le16 *)info->bssid));
1516f1d2b4d3SLarry Finger 		rtl818x_iowrite32(priv, (__le32 __iomem *)&priv->map->BSSID[2],
1517f1d2b4d3SLarry Finger 				  le32_to_cpu(*(__le32 *)(info->bssid + 2)));
1518f1d2b4d3SLarry Finger 
1519f1d2b4d3SLarry Finger 		if (is_valid_ether_addr(info->bssid)) {
1520f1d2b4d3SLarry Finger 			if (vif->type == NL80211_IFTYPE_ADHOC)
1521f1d2b4d3SLarry Finger 				reg = RTL818X_MSR_ADHOC;
1522f1d2b4d3SLarry Finger 			else
1523f1d2b4d3SLarry Finger 				reg = RTL818X_MSR_INFRA;
1524f1d2b4d3SLarry Finger 		} else
1525f1d2b4d3SLarry Finger 			reg = RTL818X_MSR_NO_LINK;
1526f1d2b4d3SLarry Finger 
1527f1d2b4d3SLarry Finger 		if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE)
1528f1d2b4d3SLarry Finger 			reg |= RTL818X_MSR_ENEDCA;
1529f1d2b4d3SLarry Finger 
1530f1d2b4d3SLarry Finger 		rtl818x_iowrite8(priv, &priv->map->MSR, reg);
1531f1d2b4d3SLarry Finger 	}
1532f1d2b4d3SLarry Finger 
1533f1d2b4d3SLarry Finger 	if (changed & BSS_CHANGED_BASIC_RATES)
1534f1d2b4d3SLarry Finger 		rtl8180_conf_basic_rates(dev, info->basic_rates);
1535f1d2b4d3SLarry Finger 
1536f1d2b4d3SLarry Finger 	if (changed & (BSS_CHANGED_ERP_SLOT | BSS_CHANGED_ERP_PREAMBLE)) {
1537f1d2b4d3SLarry Finger 
1538f1d2b4d3SLarry Finger 		/* when preamble changes, acktime duration changes, and erp must
1539f1d2b4d3SLarry Finger 		 * be recalculated. ACK time is calculated at lowest rate.
1540f1d2b4d3SLarry Finger 		 * Since mac80211 include SIFS time we remove it (-10)
1541f1d2b4d3SLarry Finger 		 */
1542f1d2b4d3SLarry Finger 		priv->ack_time =
1543f1d2b4d3SLarry Finger 			le16_to_cpu(ieee80211_generic_frame_duration(dev,
1544f1d2b4d3SLarry Finger 					priv->vif,
154557fbcce3SJohannes Berg 					NL80211_BAND_2GHZ, 10,
1546f1d2b4d3SLarry Finger 					&priv->rates[0])) - 10;
1547f1d2b4d3SLarry Finger 
1548f1d2b4d3SLarry Finger 		rtl8180_conf_erp(dev, info);
1549f1d2b4d3SLarry Finger 
1550f1d2b4d3SLarry Finger 		/* mac80211 supplies aifs_n to driver and calls
1551f1d2b4d3SLarry Finger 		 * conf_tx callback whether aifs_n changes, NOT
1552f1d2b4d3SLarry Finger 		 * when aifs changes.
1553f1d2b4d3SLarry Finger 		 * Aifs should be recalculated if slot changes.
1554f1d2b4d3SLarry Finger 		 */
1555f1d2b4d3SLarry Finger 		if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) {
1556f1d2b4d3SLarry Finger 			for (i = 0; i < 4; i++)
1557f1d2b4d3SLarry Finger 				rtl8187se_conf_ac_parm(dev, i);
1558f1d2b4d3SLarry Finger 		}
1559f1d2b4d3SLarry Finger 	}
1560f1d2b4d3SLarry Finger 
1561f1d2b4d3SLarry Finger 	if (changed & BSS_CHANGED_BEACON_ENABLED)
1562f1d2b4d3SLarry Finger 		vif_priv->enable_beacon = info->enable_beacon;
1563f1d2b4d3SLarry Finger 
1564f1d2b4d3SLarry Finger 	if (changed & (BSS_CHANGED_BEACON_ENABLED | BSS_CHANGED_BEACON)) {
1565f1d2b4d3SLarry Finger 		cancel_delayed_work_sync(&vif_priv->beacon_work);
1566f1d2b4d3SLarry Finger 		if (vif_priv->enable_beacon)
1567f1d2b4d3SLarry Finger 			schedule_work(&vif_priv->beacon_work.work);
1568f1d2b4d3SLarry Finger 	}
1569f1d2b4d3SLarry Finger }
1570f1d2b4d3SLarry Finger 
rtl8180_prepare_multicast(struct ieee80211_hw * dev,struct netdev_hw_addr_list * mc_list)1571f1d2b4d3SLarry Finger static u64 rtl8180_prepare_multicast(struct ieee80211_hw *dev,
1572f1d2b4d3SLarry Finger 				     struct netdev_hw_addr_list *mc_list)
1573f1d2b4d3SLarry Finger {
1574f1d2b4d3SLarry Finger 	return netdev_hw_addr_list_count(mc_list);
1575f1d2b4d3SLarry Finger }
1576f1d2b4d3SLarry Finger 
rtl8180_configure_filter(struct ieee80211_hw * dev,unsigned int changed_flags,unsigned int * total_flags,u64 multicast)1577f1d2b4d3SLarry Finger static void rtl8180_configure_filter(struct ieee80211_hw *dev,
1578f1d2b4d3SLarry Finger 				     unsigned int changed_flags,
1579f1d2b4d3SLarry Finger 				     unsigned int *total_flags,
1580f1d2b4d3SLarry Finger 				     u64 multicast)
1581f1d2b4d3SLarry Finger {
1582f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = dev->priv;
1583f1d2b4d3SLarry Finger 
1584f1d2b4d3SLarry Finger 	if (changed_flags & FIF_FCSFAIL)
1585f1d2b4d3SLarry Finger 		priv->rx_conf ^= RTL818X_RX_CONF_FCS;
1586f1d2b4d3SLarry Finger 	if (changed_flags & FIF_CONTROL)
1587f1d2b4d3SLarry Finger 		priv->rx_conf ^= RTL818X_RX_CONF_CTRL;
1588f1d2b4d3SLarry Finger 	if (changed_flags & FIF_OTHER_BSS)
1589f1d2b4d3SLarry Finger 		priv->rx_conf ^= RTL818X_RX_CONF_MONITOR;
1590f1d2b4d3SLarry Finger 	if (*total_flags & FIF_ALLMULTI || multicast > 0)
1591f1d2b4d3SLarry Finger 		priv->rx_conf |= RTL818X_RX_CONF_MULTICAST;
1592f1d2b4d3SLarry Finger 	else
1593f1d2b4d3SLarry Finger 		priv->rx_conf &= ~RTL818X_RX_CONF_MULTICAST;
1594f1d2b4d3SLarry Finger 
1595f1d2b4d3SLarry Finger 	*total_flags = 0;
1596f1d2b4d3SLarry Finger 
1597f1d2b4d3SLarry Finger 	if (priv->rx_conf & RTL818X_RX_CONF_FCS)
1598f1d2b4d3SLarry Finger 		*total_flags |= FIF_FCSFAIL;
1599f1d2b4d3SLarry Finger 	if (priv->rx_conf & RTL818X_RX_CONF_CTRL)
1600f1d2b4d3SLarry Finger 		*total_flags |= FIF_CONTROL;
1601f1d2b4d3SLarry Finger 	if (priv->rx_conf & RTL818X_RX_CONF_MONITOR)
1602f1d2b4d3SLarry Finger 		*total_flags |= FIF_OTHER_BSS;
1603f1d2b4d3SLarry Finger 	if (priv->rx_conf & RTL818X_RX_CONF_MULTICAST)
1604f1d2b4d3SLarry Finger 		*total_flags |= FIF_ALLMULTI;
1605f1d2b4d3SLarry Finger 
1606f1d2b4d3SLarry Finger 	rtl818x_iowrite32(priv, &priv->map->RX_CONF, priv->rx_conf);
1607f1d2b4d3SLarry Finger }
1608f1d2b4d3SLarry Finger 
1609f1d2b4d3SLarry Finger static const struct ieee80211_ops rtl8180_ops = {
1610f1d2b4d3SLarry Finger 	.tx			= rtl8180_tx,
1611*a790cc3aSAlexander Wetzel 	.wake_tx_queue		= ieee80211_handle_wake_tx_queue,
1612f1d2b4d3SLarry Finger 	.start			= rtl8180_start,
1613f1d2b4d3SLarry Finger 	.stop			= rtl8180_stop,
1614f1d2b4d3SLarry Finger 	.add_interface		= rtl8180_add_interface,
1615f1d2b4d3SLarry Finger 	.remove_interface	= rtl8180_remove_interface,
1616f1d2b4d3SLarry Finger 	.config			= rtl8180_config,
1617f1d2b4d3SLarry Finger 	.bss_info_changed	= rtl8180_bss_info_changed,
1618f1d2b4d3SLarry Finger 	.conf_tx		= rtl8180_conf_tx,
1619f1d2b4d3SLarry Finger 	.prepare_multicast	= rtl8180_prepare_multicast,
1620f1d2b4d3SLarry Finger 	.configure_filter	= rtl8180_configure_filter,
1621f1d2b4d3SLarry Finger 	.get_tsf		= rtl8180_get_tsf,
1622f1d2b4d3SLarry Finger };
1623f1d2b4d3SLarry Finger 
rtl8180_eeprom_register_read(struct eeprom_93cx6 * eeprom)1624f1d2b4d3SLarry Finger static void rtl8180_eeprom_register_read(struct eeprom_93cx6 *eeprom)
1625f1d2b4d3SLarry Finger {
1626f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = eeprom->data;
1627f1d2b4d3SLarry Finger 	u8 reg = rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
1628f1d2b4d3SLarry Finger 
1629f1d2b4d3SLarry Finger 	eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE;
1630f1d2b4d3SLarry Finger 	eeprom->reg_data_out = reg & RTL818X_EEPROM_CMD_READ;
1631f1d2b4d3SLarry Finger 	eeprom->reg_data_clock = reg & RTL818X_EEPROM_CMD_CK;
1632f1d2b4d3SLarry Finger 	eeprom->reg_chip_select = reg & RTL818X_EEPROM_CMD_CS;
1633f1d2b4d3SLarry Finger }
1634f1d2b4d3SLarry Finger 
rtl8180_eeprom_register_write(struct eeprom_93cx6 * eeprom)1635f1d2b4d3SLarry Finger static void rtl8180_eeprom_register_write(struct eeprom_93cx6 *eeprom)
1636f1d2b4d3SLarry Finger {
1637f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv = eeprom->data;
1638f1d2b4d3SLarry Finger 	u8 reg = 2 << 6;
1639f1d2b4d3SLarry Finger 
1640f1d2b4d3SLarry Finger 	if (eeprom->reg_data_in)
1641f1d2b4d3SLarry Finger 		reg |= RTL818X_EEPROM_CMD_WRITE;
1642f1d2b4d3SLarry Finger 	if (eeprom->reg_data_out)
1643f1d2b4d3SLarry Finger 		reg |= RTL818X_EEPROM_CMD_READ;
1644f1d2b4d3SLarry Finger 	if (eeprom->reg_data_clock)
1645f1d2b4d3SLarry Finger 		reg |= RTL818X_EEPROM_CMD_CK;
1646f1d2b4d3SLarry Finger 	if (eeprom->reg_chip_select)
1647f1d2b4d3SLarry Finger 		reg |= RTL818X_EEPROM_CMD_CS;
1648f1d2b4d3SLarry Finger 
1649f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, reg);
1650f1d2b4d3SLarry Finger 	rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
1651f1d2b4d3SLarry Finger 	udelay(10);
1652f1d2b4d3SLarry Finger }
1653f1d2b4d3SLarry Finger 
rtl8180_eeprom_read(struct rtl8180_priv * priv)1654f1d2b4d3SLarry Finger static void rtl8180_eeprom_read(struct rtl8180_priv *priv)
1655f1d2b4d3SLarry Finger {
1656f1d2b4d3SLarry Finger 	struct eeprom_93cx6 eeprom;
1657f1d2b4d3SLarry Finger 	int eeprom_cck_table_adr;
1658f1d2b4d3SLarry Finger 	u16 eeprom_val;
1659f1d2b4d3SLarry Finger 	int i;
1660f1d2b4d3SLarry Finger 
1661f1d2b4d3SLarry Finger 	eeprom.data = priv;
1662f1d2b4d3SLarry Finger 	eeprom.register_read = rtl8180_eeprom_register_read;
1663f1d2b4d3SLarry Finger 	eeprom.register_write = rtl8180_eeprom_register_write;
1664f1d2b4d3SLarry Finger 	if (rtl818x_ioread32(priv, &priv->map->RX_CONF) & (1 << 6))
1665f1d2b4d3SLarry Finger 		eeprom.width = PCI_EEPROM_WIDTH_93C66;
1666f1d2b4d3SLarry Finger 	else
1667f1d2b4d3SLarry Finger 		eeprom.width = PCI_EEPROM_WIDTH_93C46;
1668f1d2b4d3SLarry Finger 
1669f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
1670f1d2b4d3SLarry Finger 			RTL818X_EEPROM_CMD_PROGRAM);
1671f1d2b4d3SLarry Finger 	rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
1672f1d2b4d3SLarry Finger 	udelay(10);
1673f1d2b4d3SLarry Finger 
1674f1d2b4d3SLarry Finger 	eeprom_93cx6_read(&eeprom, 0x06, &eeprom_val);
1675f1d2b4d3SLarry Finger 	eeprom_val &= 0xFF;
1676f1d2b4d3SLarry Finger 	priv->rf_type = eeprom_val;
1677f1d2b4d3SLarry Finger 
1678f1d2b4d3SLarry Finger 	eeprom_93cx6_read(&eeprom, 0x17, &eeprom_val);
1679f1d2b4d3SLarry Finger 	priv->csthreshold = eeprom_val >> 8;
1680f1d2b4d3SLarry Finger 
1681f1d2b4d3SLarry Finger 	eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)priv->mac_addr, 3);
1682f1d2b4d3SLarry Finger 
1683f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE)
1684f1d2b4d3SLarry Finger 		eeprom_cck_table_adr = 0x30;
1685f1d2b4d3SLarry Finger 	else
1686f1d2b4d3SLarry Finger 		eeprom_cck_table_adr = 0x10;
1687f1d2b4d3SLarry Finger 
1688f1d2b4d3SLarry Finger 	/* CCK TX power */
1689f1d2b4d3SLarry Finger 	for (i = 0; i < 14; i += 2) {
1690f1d2b4d3SLarry Finger 		u16 txpwr;
1691f1d2b4d3SLarry Finger 		eeprom_93cx6_read(&eeprom, eeprom_cck_table_adr + (i >> 1),
1692f1d2b4d3SLarry Finger 				&txpwr);
1693f1d2b4d3SLarry Finger 		priv->channels[i].hw_value = txpwr & 0xFF;
1694f1d2b4d3SLarry Finger 		priv->channels[i + 1].hw_value = txpwr >> 8;
1695f1d2b4d3SLarry Finger 	}
1696f1d2b4d3SLarry Finger 
1697f1d2b4d3SLarry Finger 	/* OFDM TX power */
1698f1d2b4d3SLarry Finger 	if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) {
1699f1d2b4d3SLarry Finger 		for (i = 0; i < 14; i += 2) {
1700f1d2b4d3SLarry Finger 			u16 txpwr;
1701f1d2b4d3SLarry Finger 			eeprom_93cx6_read(&eeprom, 0x20 + (i >> 1), &txpwr);
1702f1d2b4d3SLarry Finger 			priv->channels[i].hw_value |= (txpwr & 0xFF) << 8;
1703f1d2b4d3SLarry Finger 			priv->channels[i + 1].hw_value |= txpwr & 0xFF00;
1704f1d2b4d3SLarry Finger 		}
1705f1d2b4d3SLarry Finger 	}
1706f1d2b4d3SLarry Finger 
1707f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8180) {
1708f1d2b4d3SLarry Finger 		__le32 anaparam;
1709f1d2b4d3SLarry Finger 		eeprom_93cx6_multiread(&eeprom, 0xD, (__le16 *)&anaparam, 2);
1710f1d2b4d3SLarry Finger 		priv->anaparam = le32_to_cpu(anaparam);
1711f1d2b4d3SLarry Finger 		eeprom_93cx6_read(&eeprom, 0x19, &priv->rfparam);
1712f1d2b4d3SLarry Finger 	}
1713f1d2b4d3SLarry Finger 
1714f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE) {
1715f1d2b4d3SLarry Finger 		eeprom_93cx6_read(&eeprom, 0x3F, &eeprom_val);
1716f1d2b4d3SLarry Finger 		priv->antenna_diversity_en = !!(eeprom_val & 0x100);
1717f1d2b4d3SLarry Finger 		priv->antenna_diversity_default = (eeprom_val & 0xC00) == 0x400;
1718f1d2b4d3SLarry Finger 
1719f1d2b4d3SLarry Finger 		eeprom_93cx6_read(&eeprom, 0x7C, &eeprom_val);
1720f1d2b4d3SLarry Finger 		priv->xtal_out = eeprom_val & 0xF;
1721f1d2b4d3SLarry Finger 		priv->xtal_in = (eeprom_val & 0xF0) >> 4;
1722f1d2b4d3SLarry Finger 		priv->xtal_cal = !!(eeprom_val & 0x1000);
1723f1d2b4d3SLarry Finger 		priv->thermal_meter_val = (eeprom_val & 0xF00) >> 8;
1724f1d2b4d3SLarry Finger 		priv->thermal_meter_en = !!(eeprom_val & 0x2000);
1725f1d2b4d3SLarry Finger 	}
1726f1d2b4d3SLarry Finger 
1727f1d2b4d3SLarry Finger 	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD,
1728f1d2b4d3SLarry Finger 			RTL818X_EEPROM_CMD_NORMAL);
1729f1d2b4d3SLarry Finger }
1730f1d2b4d3SLarry Finger 
rtl8180_probe(struct pci_dev * pdev,const struct pci_device_id * id)1731f1d2b4d3SLarry Finger static int rtl8180_probe(struct pci_dev *pdev,
1732f1d2b4d3SLarry Finger 				   const struct pci_device_id *id)
1733f1d2b4d3SLarry Finger {
1734f1d2b4d3SLarry Finger 	struct ieee80211_hw *dev;
1735f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv;
1736b9b81d15SYueHaibing 	unsigned long mem_len;
1737b9b81d15SYueHaibing 	unsigned int io_len;
1738f1d2b4d3SLarry Finger 	int err;
1739f1d2b4d3SLarry Finger 	const char *chip_name, *rf_name = NULL;
1740f1d2b4d3SLarry Finger 	u32 reg;
1741f1d2b4d3SLarry Finger 
1742f1d2b4d3SLarry Finger 	err = pci_enable_device(pdev);
1743f1d2b4d3SLarry Finger 	if (err) {
1744f1d2b4d3SLarry Finger 		printk(KERN_ERR "%s (rtl8180): Cannot enable new PCI device\n",
1745f1d2b4d3SLarry Finger 		       pci_name(pdev));
1746f1d2b4d3SLarry Finger 		return err;
1747f1d2b4d3SLarry Finger 	}
1748f1d2b4d3SLarry Finger 
1749f1d2b4d3SLarry Finger 	err = pci_request_regions(pdev, KBUILD_MODNAME);
1750f1d2b4d3SLarry Finger 	if (err) {
1751f1d2b4d3SLarry Finger 		printk(KERN_ERR "%s (rtl8180): Cannot obtain PCI resources\n",
1752f1d2b4d3SLarry Finger 		       pci_name(pdev));
17531c76b490SJia-Ju Bai 		goto err_disable_dev;
1754f1d2b4d3SLarry Finger 	}
1755f1d2b4d3SLarry Finger 
1756f1d2b4d3SLarry Finger 	io_len = pci_resource_len(pdev, 0);
1757f1d2b4d3SLarry Finger 	mem_len = pci_resource_len(pdev, 1);
1758f1d2b4d3SLarry Finger 
1759f1d2b4d3SLarry Finger 	if (mem_len < sizeof(struct rtl818x_csr) ||
1760f1d2b4d3SLarry Finger 	    io_len < sizeof(struct rtl818x_csr)) {
1761f1d2b4d3SLarry Finger 		printk(KERN_ERR "%s (rtl8180): Too short PCI resources\n",
1762f1d2b4d3SLarry Finger 		       pci_name(pdev));
1763f1d2b4d3SLarry Finger 		err = -ENOMEM;
1764f1d2b4d3SLarry Finger 		goto err_free_reg;
1765f1d2b4d3SLarry Finger 	}
1766f1d2b4d3SLarry Finger 
1767f4ce4bf6SChristophe JAILLET 	if ((err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) ||
1768f4ce4bf6SChristophe JAILLET 	    (err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)))) {
1769f1d2b4d3SLarry Finger 		printk(KERN_ERR "%s (rtl8180): No suitable DMA available\n",
1770f1d2b4d3SLarry Finger 		       pci_name(pdev));
1771f1d2b4d3SLarry Finger 		goto err_free_reg;
1772f1d2b4d3SLarry Finger 	}
1773f1d2b4d3SLarry Finger 
1774f1d2b4d3SLarry Finger 	pci_set_master(pdev);
1775f1d2b4d3SLarry Finger 
1776f1d2b4d3SLarry Finger 	dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8180_ops);
1777f1d2b4d3SLarry Finger 	if (!dev) {
1778f1d2b4d3SLarry Finger 		printk(KERN_ERR "%s (rtl8180): ieee80211 alloc failed\n",
1779f1d2b4d3SLarry Finger 		       pci_name(pdev));
1780f1d2b4d3SLarry Finger 		err = -ENOMEM;
1781f1d2b4d3SLarry Finger 		goto err_free_reg;
1782f1d2b4d3SLarry Finger 	}
1783f1d2b4d3SLarry Finger 
1784f1d2b4d3SLarry Finger 	priv = dev->priv;
1785f1d2b4d3SLarry Finger 	priv->pdev = pdev;
1786f1d2b4d3SLarry Finger 
1787f1d2b4d3SLarry Finger 	dev->max_rates = 1;
1788f1d2b4d3SLarry Finger 	SET_IEEE80211_DEV(dev, &pdev->dev);
1789f1d2b4d3SLarry Finger 	pci_set_drvdata(pdev, dev);
1790f1d2b4d3SLarry Finger 
1791f1d2b4d3SLarry Finger 	priv->map_pio = false;
1792f1d2b4d3SLarry Finger 	priv->map = pci_iomap(pdev, 1, mem_len);
1793f1d2b4d3SLarry Finger 	if (!priv->map) {
1794f1d2b4d3SLarry Finger 		priv->map = pci_iomap(pdev, 0, io_len);
1795f1d2b4d3SLarry Finger 		priv->map_pio = true;
1796f1d2b4d3SLarry Finger 	}
1797f1d2b4d3SLarry Finger 
1798f1d2b4d3SLarry Finger 	if (!priv->map) {
1799f1d2b4d3SLarry Finger 		dev_err(&pdev->dev, "Cannot map device memory/PIO\n");
1800f1d2b4d3SLarry Finger 		err = -ENOMEM;
1801f1d2b4d3SLarry Finger 		goto err_free_dev;
1802f1d2b4d3SLarry Finger 	}
1803f1d2b4d3SLarry Finger 
1804f1d2b4d3SLarry Finger 	BUILD_BUG_ON(sizeof(priv->channels) != sizeof(rtl818x_channels));
1805f1d2b4d3SLarry Finger 	BUILD_BUG_ON(sizeof(priv->rates) != sizeof(rtl818x_rates));
1806f1d2b4d3SLarry Finger 
1807f1d2b4d3SLarry Finger 	memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels));
1808f1d2b4d3SLarry Finger 	memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates));
1809f1d2b4d3SLarry Finger 
181057fbcce3SJohannes Berg 	priv->band.band = NL80211_BAND_2GHZ;
1811f1d2b4d3SLarry Finger 	priv->band.channels = priv->channels;
1812f1d2b4d3SLarry Finger 	priv->band.n_channels = ARRAY_SIZE(rtl818x_channels);
1813f1d2b4d3SLarry Finger 	priv->band.bitrates = priv->rates;
1814f1d2b4d3SLarry Finger 	priv->band.n_bitrates = 4;
181557fbcce3SJohannes Berg 	dev->wiphy->bands[NL80211_BAND_2GHZ] = &priv->band;
1816f1d2b4d3SLarry Finger 
1817f1d2b4d3SLarry Finger 	ieee80211_hw_set(dev, HOST_BROADCAST_PS_BUFFERING);
1818f1d2b4d3SLarry Finger 	ieee80211_hw_set(dev, RX_INCLUDES_FCS);
1819f1d2b4d3SLarry Finger 
1820f1d2b4d3SLarry Finger 	dev->vif_data_size = sizeof(struct rtl8180_vif);
1821f1d2b4d3SLarry Finger 	dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1822f1d2b4d3SLarry Finger 					BIT(NL80211_IFTYPE_ADHOC);
1823f1d2b4d3SLarry Finger 	dev->max_signal = 65;
1824f1d2b4d3SLarry Finger 
1825f1d2b4d3SLarry Finger 	reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
1826f1d2b4d3SLarry Finger 	reg &= RTL818X_TX_CONF_HWVER_MASK;
1827f1d2b4d3SLarry Finger 	switch (reg) {
1828f1d2b4d3SLarry Finger 	case RTL818X_TX_CONF_R8180_ABCD:
1829f1d2b4d3SLarry Finger 		chip_name = "RTL8180";
1830f1d2b4d3SLarry Finger 		priv->chip_family = RTL818X_CHIP_FAMILY_RTL8180;
1831f1d2b4d3SLarry Finger 		break;
1832f1d2b4d3SLarry Finger 
1833f1d2b4d3SLarry Finger 	case RTL818X_TX_CONF_R8180_F:
1834f1d2b4d3SLarry Finger 		chip_name = "RTL8180vF";
1835f1d2b4d3SLarry Finger 		priv->chip_family = RTL818X_CHIP_FAMILY_RTL8180;
1836f1d2b4d3SLarry Finger 		break;
1837f1d2b4d3SLarry Finger 
1838f1d2b4d3SLarry Finger 	case RTL818X_TX_CONF_R8185_ABC:
1839f1d2b4d3SLarry Finger 		chip_name = "RTL8185";
1840f1d2b4d3SLarry Finger 		priv->chip_family = RTL818X_CHIP_FAMILY_RTL8185;
1841f1d2b4d3SLarry Finger 		break;
1842f1d2b4d3SLarry Finger 
1843f1d2b4d3SLarry Finger 	case RTL818X_TX_CONF_R8185_D:
1844f1d2b4d3SLarry Finger 		chip_name = "RTL8185vD";
1845f1d2b4d3SLarry Finger 		priv->chip_family = RTL818X_CHIP_FAMILY_RTL8185;
1846f1d2b4d3SLarry Finger 		break;
1847f1d2b4d3SLarry Finger 
1848f1d2b4d3SLarry Finger 	case RTL818X_TX_CONF_RTL8187SE:
1849f1d2b4d3SLarry Finger 		chip_name = "RTL8187SE";
1850f1d2b4d3SLarry Finger 		if (priv->map_pio) {
1851f1d2b4d3SLarry Finger 			dev_err(&pdev->dev,
1852f1d2b4d3SLarry Finger 				"MMIO failed. PIO not supported on RTL8187SE\n");
1853f1d2b4d3SLarry Finger 			err = -ENOMEM;
1854f1d2b4d3SLarry Finger 			goto err_iounmap;
1855f1d2b4d3SLarry Finger 		}
1856f1d2b4d3SLarry Finger 		priv->chip_family = RTL818X_CHIP_FAMILY_RTL8187SE;
1857f1d2b4d3SLarry Finger 		break;
1858f1d2b4d3SLarry Finger 
1859f1d2b4d3SLarry Finger 	default:
1860f1d2b4d3SLarry Finger 		printk(KERN_ERR "%s (rtl8180): Unknown chip! (0x%x)\n",
1861f1d2b4d3SLarry Finger 		       pci_name(pdev), reg >> 25);
1862f1d2b4d3SLarry Finger 		err = -ENODEV;
1863f1d2b4d3SLarry Finger 		goto err_iounmap;
1864f1d2b4d3SLarry Finger 	}
1865f1d2b4d3SLarry Finger 
1866f1d2b4d3SLarry Finger 	/* we declare to MAC80211 all the queues except for beacon queue
1867f1d2b4d3SLarry Finger 	 * that will be eventually handled by DRV.
1868f1d2b4d3SLarry Finger 	 * TX rings are arranged in such a way that lower is the IDX,
1869f1d2b4d3SLarry Finger 	 * higher is the priority, in order to achieve direct mapping
1870f1d2b4d3SLarry Finger 	 * with mac80211, however the beacon queue is an exception and it
1871f1d2b4d3SLarry Finger 	 * is mapped on the highst tx ring IDX.
1872f1d2b4d3SLarry Finger 	 */
1873f1d2b4d3SLarry Finger 	if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE)
1874f1d2b4d3SLarry Finger 		dev->queues = RTL8187SE_NR_TX_QUEUES - 1;
1875f1d2b4d3SLarry Finger 	else
1876f1d2b4d3SLarry Finger 		dev->queues = RTL8180_NR_TX_QUEUES - 1;
1877f1d2b4d3SLarry Finger 
1878f1d2b4d3SLarry Finger 	if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180) {
1879f1d2b4d3SLarry Finger 		priv->band.n_bitrates = ARRAY_SIZE(rtl818x_rates);
1880f1d2b4d3SLarry Finger 		pci_try_set_mwi(pdev);
1881f1d2b4d3SLarry Finger 	}
1882f1d2b4d3SLarry Finger 
1883f1d2b4d3SLarry Finger 	if (priv->chip_family != RTL818X_CHIP_FAMILY_RTL8180)
1884f1d2b4d3SLarry Finger 		ieee80211_hw_set(dev, SIGNAL_DBM);
1885f1d2b4d3SLarry Finger 	else
1886f1d2b4d3SLarry Finger 		ieee80211_hw_set(dev, SIGNAL_UNSPEC);
1887f1d2b4d3SLarry Finger 
1888ae44b502SAndrew Zaborowski 	wiphy_ext_feature_set(dev->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
1889ae44b502SAndrew Zaborowski 
1890f1d2b4d3SLarry Finger 	rtl8180_eeprom_read(priv);
1891f1d2b4d3SLarry Finger 
1892f1d2b4d3SLarry Finger 	switch (priv->rf_type) {
1893f1d2b4d3SLarry Finger 	case 1:	rf_name = "Intersil";
1894f1d2b4d3SLarry Finger 		break;
1895f1d2b4d3SLarry Finger 	case 2:	rf_name = "RFMD";
1896f1d2b4d3SLarry Finger 		break;
1897f1d2b4d3SLarry Finger 	case 3:	priv->rf = &sa2400_rf_ops;
1898f1d2b4d3SLarry Finger 		break;
1899f1d2b4d3SLarry Finger 	case 4:	priv->rf = &max2820_rf_ops;
1900f1d2b4d3SLarry Finger 		break;
1901f1d2b4d3SLarry Finger 	case 5:	priv->rf = &grf5101_rf_ops;
1902f1d2b4d3SLarry Finger 		break;
1903f1d2b4d3SLarry Finger 	case 9:
1904f1d2b4d3SLarry Finger 		if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8187SE)
1905f1d2b4d3SLarry Finger 			priv->rf = rtl8187se_detect_rf(dev);
1906f1d2b4d3SLarry Finger 		else
1907f1d2b4d3SLarry Finger 			priv->rf = rtl8180_detect_rf(dev);
1908f1d2b4d3SLarry Finger 		break;
1909f1d2b4d3SLarry Finger 	case 10:
1910f1d2b4d3SLarry Finger 		rf_name = "RTL8255";
1911f1d2b4d3SLarry Finger 		break;
1912f1d2b4d3SLarry Finger 	default:
1913f1d2b4d3SLarry Finger 		printk(KERN_ERR "%s (rtl8180): Unknown RF! (0x%x)\n",
1914f1d2b4d3SLarry Finger 		       pci_name(pdev), priv->rf_type);
1915f1d2b4d3SLarry Finger 		err = -ENODEV;
1916f1d2b4d3SLarry Finger 		goto err_iounmap;
1917f1d2b4d3SLarry Finger 	}
1918f1d2b4d3SLarry Finger 
1919f1d2b4d3SLarry Finger 	if (!priv->rf) {
1920f1d2b4d3SLarry Finger 		printk(KERN_ERR "%s (rtl8180): %s RF frontend not supported!\n",
1921f1d2b4d3SLarry Finger 		       pci_name(pdev), rf_name);
1922f1d2b4d3SLarry Finger 		err = -ENODEV;
1923f1d2b4d3SLarry Finger 		goto err_iounmap;
1924f1d2b4d3SLarry Finger 	}
1925f1d2b4d3SLarry Finger 
1926f1d2b4d3SLarry Finger 	if (!is_valid_ether_addr(priv->mac_addr)) {
1927f1d2b4d3SLarry Finger 		printk(KERN_WARNING "%s (rtl8180): Invalid hwaddr! Using"
1928f1d2b4d3SLarry Finger 		       " randomly generated MAC addr\n", pci_name(pdev));
1929f1d2b4d3SLarry Finger 		eth_random_addr(priv->mac_addr);
1930f1d2b4d3SLarry Finger 	}
1931f1d2b4d3SLarry Finger 	SET_IEEE80211_PERM_ADDR(dev, priv->mac_addr);
1932f1d2b4d3SLarry Finger 
1933f1d2b4d3SLarry Finger 	spin_lock_init(&priv->lock);
1934f1d2b4d3SLarry Finger 
1935f1d2b4d3SLarry Finger 	err = ieee80211_register_hw(dev);
1936f1d2b4d3SLarry Finger 	if (err) {
1937f1d2b4d3SLarry Finger 		printk(KERN_ERR "%s (rtl8180): Cannot register device\n",
1938f1d2b4d3SLarry Finger 		       pci_name(pdev));
1939f1d2b4d3SLarry Finger 		goto err_iounmap;
1940f1d2b4d3SLarry Finger 	}
1941f1d2b4d3SLarry Finger 
1942f1d2b4d3SLarry Finger 	wiphy_info(dev->wiphy, "hwaddr %pm, %s + %s\n",
1943f1d2b4d3SLarry Finger 		   priv->mac_addr, chip_name, priv->rf->name);
1944f1d2b4d3SLarry Finger 
1945f1d2b4d3SLarry Finger 	return 0;
1946f1d2b4d3SLarry Finger 
1947f1d2b4d3SLarry Finger  err_iounmap:
1948f1d2b4d3SLarry Finger 	pci_iounmap(pdev, priv->map);
1949f1d2b4d3SLarry Finger 
1950f1d2b4d3SLarry Finger  err_free_dev:
1951f1d2b4d3SLarry Finger 	ieee80211_free_hw(dev);
1952f1d2b4d3SLarry Finger 
1953f1d2b4d3SLarry Finger  err_free_reg:
1954f1d2b4d3SLarry Finger 	pci_release_regions(pdev);
19551c76b490SJia-Ju Bai 
19561c76b490SJia-Ju Bai  err_disable_dev:
1957f1d2b4d3SLarry Finger 	pci_disable_device(pdev);
1958f1d2b4d3SLarry Finger 	return err;
1959f1d2b4d3SLarry Finger }
1960f1d2b4d3SLarry Finger 
rtl8180_remove(struct pci_dev * pdev)1961f1d2b4d3SLarry Finger static void rtl8180_remove(struct pci_dev *pdev)
1962f1d2b4d3SLarry Finger {
1963f1d2b4d3SLarry Finger 	struct ieee80211_hw *dev = pci_get_drvdata(pdev);
1964f1d2b4d3SLarry Finger 	struct rtl8180_priv *priv;
1965f1d2b4d3SLarry Finger 
1966f1d2b4d3SLarry Finger 	if (!dev)
1967f1d2b4d3SLarry Finger 		return;
1968f1d2b4d3SLarry Finger 
1969f1d2b4d3SLarry Finger 	ieee80211_unregister_hw(dev);
1970f1d2b4d3SLarry Finger 
1971f1d2b4d3SLarry Finger 	priv = dev->priv;
1972f1d2b4d3SLarry Finger 
1973f1d2b4d3SLarry Finger 	pci_iounmap(pdev, priv->map);
1974f1d2b4d3SLarry Finger 	pci_release_regions(pdev);
1975f1d2b4d3SLarry Finger 	pci_disable_device(pdev);
1976f1d2b4d3SLarry Finger 	ieee80211_free_hw(dev);
1977f1d2b4d3SLarry Finger }
1978f1d2b4d3SLarry Finger 
1979ef642510SVaibhav Gupta #define rtl8180_suspend NULL
1980ef642510SVaibhav Gupta #define rtl8180_resume NULL
1981f1d2b4d3SLarry Finger 
1982ef642510SVaibhav Gupta static SIMPLE_DEV_PM_OPS(rtl8180_pm_ops, rtl8180_suspend, rtl8180_resume);
1983f1d2b4d3SLarry Finger 
1984f1d2b4d3SLarry Finger static struct pci_driver rtl8180_driver = {
1985f1d2b4d3SLarry Finger 	.name		= KBUILD_MODNAME,
1986f1d2b4d3SLarry Finger 	.id_table	= rtl8180_table,
1987f1d2b4d3SLarry Finger 	.probe		= rtl8180_probe,
1988f1d2b4d3SLarry Finger 	.remove		= rtl8180_remove,
1989ef642510SVaibhav Gupta 	.driver.pm	= &rtl8180_pm_ops,
1990f1d2b4d3SLarry Finger };
1991f1d2b4d3SLarry Finger 
1992f1d2b4d3SLarry Finger module_pci_driver(rtl8180_driver);
1993