diff options
author | Ivo van Doorn <ivdoorn@gmail.com> | 2008-11-10 13:41:40 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-11-25 16:32:53 -0500 |
commit | c9c3b1a5deac4297503145840fffcd122b253db5 (patch) | |
tree | 7d5e0cf6510c1687ef6b18d32ba9009a5692fbfd | |
parent | 9764f3f9c3700620f9f8a1f9af57f58758e835da (diff) |
rt2x00: Cleanup indirect register access
All code which accessed indirect registers was similar
in respect to the for-loop, the given timeout, etc.
Move it into a seperate function, which for PCI drivers
can be moved into rt2x00pci.
This allows us to cleanup the cleanup the code further
by removing the goto statementsand making the codepath
look a bit nicer.
Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2400pci.c | 125 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500pci.c | 125 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500usb.c | 140 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00pci.c | 25 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00pci.h | 18 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.c | 161 | ||||
-rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 147 |
7 files changed, 310 insertions, 431 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 78fca1bcc544..6a977679124d 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -49,20 +49,10 @@ | |||
49 | * the access attempt is considered to have failed, | 49 | * the access attempt is considered to have failed, |
50 | * and we will print an error. | 50 | * and we will print an error. |
51 | */ | 51 | */ |
52 | static u32 rt2400pci_bbp_check(struct rt2x00_dev *rt2x00dev) | 52 | #define WAIT_FOR_BBP(__dev, __reg) \ |
53 | { | 53 | rt2x00pci_regbusy_read((__dev), BBPCSR, BBPCSR_BUSY, (__reg)) |
54 | u32 reg; | 54 | #define WAIT_FOR_RF(__dev, __reg) \ |
55 | unsigned int i; | 55 | rt2x00pci_regbusy_read((__dev), RFCSR, RFCSR_BUSY, (__reg)) |
56 | |||
57 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
58 | rt2x00pci_register_read(rt2x00dev, BBPCSR, ®); | ||
59 | if (!rt2x00_get_field32(reg, BBPCSR_BUSY)) | ||
60 | break; | ||
61 | udelay(REGISTER_BUSY_DELAY); | ||
62 | } | ||
63 | |||
64 | return reg; | ||
65 | } | ||
66 | 56 | ||
67 | static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev, | 57 | static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev, |
68 | const unsigned int word, const u8 value) | 58 | const unsigned int word, const u8 value) |
@@ -72,31 +62,20 @@ static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev, | |||
72 | mutex_lock(&rt2x00dev->csr_mutex); | 62 | mutex_lock(&rt2x00dev->csr_mutex); |
73 | 63 | ||
74 | /* | 64 | /* |
75 | * Wait until the BBP becomes ready. | 65 | * Wait until the BBP becomes available, afterwards we |
66 | * can safely write the new data into the register. | ||
76 | */ | 67 | */ |
77 | reg = rt2400pci_bbp_check(rt2x00dev); | 68 | if (WAIT_FOR_BBP(rt2x00dev, ®)) { |
78 | if (rt2x00_get_field32(reg, BBPCSR_BUSY)) | 69 | reg = 0; |
79 | goto exit_fail; | 70 | rt2x00_set_field32(®, BBPCSR_VALUE, value); |
80 | 71 | rt2x00_set_field32(®, BBPCSR_REGNUM, word); | |
81 | /* | 72 | rt2x00_set_field32(®, BBPCSR_BUSY, 1); |
82 | * Write the data into the BBP. | 73 | rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 1); |
83 | */ | 74 | |
84 | reg = 0; | 75 | rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); |
85 | rt2x00_set_field32(®, BBPCSR_VALUE, value); | 76 | } |
86 | rt2x00_set_field32(®, BBPCSR_REGNUM, word); | ||
87 | rt2x00_set_field32(®, BBPCSR_BUSY, 1); | ||
88 | rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 1); | ||
89 | |||
90 | rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); | ||
91 | |||
92 | mutex_unlock(&rt2x00dev->csr_mutex); | ||
93 | |||
94 | return; | ||
95 | 77 | ||
96 | exit_fail: | ||
97 | mutex_unlock(&rt2x00dev->csr_mutex); | 78 | mutex_unlock(&rt2x00dev->csr_mutex); |
98 | |||
99 | ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n"); | ||
100 | } | 79 | } |
101 | 80 | ||
102 | static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev, | 81 | static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev, |
@@ -107,75 +86,55 @@ static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev, | |||
107 | mutex_lock(&rt2x00dev->csr_mutex); | 86 | mutex_lock(&rt2x00dev->csr_mutex); |
108 | 87 | ||
109 | /* | 88 | /* |
110 | * Wait until the BBP becomes ready. | 89 | * Wait until the BBP becomes available, afterwards we |
90 | * can safely write the read request into the register. | ||
91 | * After the data has been written, we wait until hardware | ||
92 | * returns the correct value, if at any time the register | ||
93 | * doesn't become available in time, reg will be 0xffffffff | ||
94 | * which means we return 0xff to the caller. | ||
111 | */ | 95 | */ |
112 | reg = rt2400pci_bbp_check(rt2x00dev); | 96 | if (WAIT_FOR_BBP(rt2x00dev, ®)) { |
113 | if (rt2x00_get_field32(reg, BBPCSR_BUSY)) | 97 | reg = 0; |
114 | goto exit_fail; | 98 | rt2x00_set_field32(®, BBPCSR_REGNUM, word); |
99 | rt2x00_set_field32(®, BBPCSR_BUSY, 1); | ||
100 | rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 0); | ||
115 | 101 | ||
116 | /* | 102 | rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); |
117 | * Write the request into the BBP. | ||
118 | */ | ||
119 | reg = 0; | ||
120 | rt2x00_set_field32(®, BBPCSR_REGNUM, word); | ||
121 | rt2x00_set_field32(®, BBPCSR_BUSY, 1); | ||
122 | rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 0); | ||
123 | 103 | ||
124 | rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); | 104 | WAIT_FOR_BBP(rt2x00dev, ®); |
125 | 105 | } | |
126 | /* | ||
127 | * Wait until the BBP becomes ready. | ||
128 | */ | ||
129 | reg = rt2400pci_bbp_check(rt2x00dev); | ||
130 | if (rt2x00_get_field32(reg, BBPCSR_BUSY)) | ||
131 | goto exit_fail; | ||
132 | 106 | ||
133 | *value = rt2x00_get_field32(reg, BBPCSR_VALUE); | 107 | *value = rt2x00_get_field32(reg, BBPCSR_VALUE); |
134 | 108 | ||
135 | mutex_unlock(&rt2x00dev->csr_mutex); | 109 | mutex_unlock(&rt2x00dev->csr_mutex); |
136 | |||
137 | return; | ||
138 | |||
139 | exit_fail: | ||
140 | mutex_unlock(&rt2x00dev->csr_mutex); | ||
141 | |||
142 | ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n"); | ||
143 | *value = 0xff; | ||
144 | } | 110 | } |
145 | 111 | ||
146 | static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev, | 112 | static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev, |
147 | const unsigned int word, const u32 value) | 113 | const unsigned int word, const u32 value) |
148 | { | 114 | { |
149 | u32 reg; | 115 | u32 reg; |
150 | unsigned int i; | ||
151 | 116 | ||
152 | if (!word) | 117 | if (!word) |
153 | return; | 118 | return; |
154 | 119 | ||
155 | mutex_lock(&rt2x00dev->csr_mutex); | 120 | mutex_lock(&rt2x00dev->csr_mutex); |
156 | 121 | ||
157 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 122 | /* |
158 | rt2x00pci_register_read(rt2x00dev, RFCSR, ®); | 123 | * Wait until the RF becomes available, afterwards we |
159 | if (!rt2x00_get_field32(reg, RFCSR_BUSY)) | 124 | * can safely write the new data into the register. |
160 | goto rf_write; | 125 | */ |
161 | udelay(REGISTER_BUSY_DELAY); | 126 | if (WAIT_FOR_RF(rt2x00dev, ®)) { |
127 | reg = 0; | ||
128 | rt2x00_set_field32(®, RFCSR_VALUE, value); | ||
129 | rt2x00_set_field32(®, RFCSR_NUMBER_OF_BITS, 20); | ||
130 | rt2x00_set_field32(®, RFCSR_IF_SELECT, 0); | ||
131 | rt2x00_set_field32(®, RFCSR_BUSY, 1); | ||
132 | |||
133 | rt2x00pci_register_write(rt2x00dev, RFCSR, reg); | ||
134 | rt2x00_rf_write(rt2x00dev, word, value); | ||
162 | } | 135 | } |
163 | 136 | ||
164 | mutex_unlock(&rt2x00dev->csr_mutex); | 137 | mutex_unlock(&rt2x00dev->csr_mutex); |
165 | ERROR(rt2x00dev, "RFCSR register busy. Write failed.\n"); | ||
166 | return; | ||
167 | |||
168 | rf_write: | ||
169 | reg = 0; | ||
170 | rt2x00_set_field32(®, RFCSR_VALUE, value); | ||
171 | rt2x00_set_field32(®, RFCSR_NUMBER_OF_BITS, 20); | ||
172 | rt2x00_set_field32(®, RFCSR_IF_SELECT, 0); | ||
173 | rt2x00_set_field32(®, RFCSR_BUSY, 1); | ||
174 | |||
175 | rt2x00pci_register_write(rt2x00dev, RFCSR, reg); | ||
176 | rt2x00_rf_write(rt2x00dev, word, value); | ||
177 | |||
178 | mutex_unlock(&rt2x00dev->csr_mutex); | ||
179 | } | 138 | } |
180 | 139 | ||
181 | static void rt2400pci_eepromregister_read(struct eeprom_93cx6 *eeprom) | 140 | static void rt2400pci_eepromregister_read(struct eeprom_93cx6 *eeprom) |
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 972b5a5c3864..d3bc218ec85c 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -49,20 +49,10 @@ | |||
49 | * the access attempt is considered to have failed, | 49 | * the access attempt is considered to have failed, |
50 | * and we will print an error. | 50 | * and we will print an error. |
51 | */ | 51 | */ |
52 | static u32 rt2500pci_bbp_check(struct rt2x00_dev *rt2x00dev) | 52 | #define WAIT_FOR_BBP(__dev, __reg) \ |
53 | { | 53 | rt2x00pci_regbusy_read((__dev), BBPCSR, BBPCSR_BUSY, (__reg)) |
54 | u32 reg; | 54 | #define WAIT_FOR_RF(__dev, __reg) \ |
55 | unsigned int i; | 55 | rt2x00pci_regbusy_read((__dev), RFCSR, RFCSR_BUSY, (__reg)) |
56 | |||
57 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
58 | rt2x00pci_register_read(rt2x00dev, BBPCSR, ®); | ||
59 | if (!rt2x00_get_field32(reg, BBPCSR_BUSY)) | ||
60 | break; | ||
61 | udelay(REGISTER_BUSY_DELAY); | ||
62 | } | ||
63 | |||
64 | return reg; | ||
65 | } | ||
66 | 56 | ||
67 | static void rt2500pci_bbp_write(struct rt2x00_dev *rt2x00dev, | 57 | static void rt2500pci_bbp_write(struct rt2x00_dev *rt2x00dev, |
68 | const unsigned int word, const u8 value) | 58 | const unsigned int word, const u8 value) |
@@ -72,31 +62,20 @@ static void rt2500pci_bbp_write(struct rt2x00_dev *rt2x00dev, | |||
72 | mutex_lock(&rt2x00dev->csr_mutex); | 62 | mutex_lock(&rt2x00dev->csr_mutex); |
73 | 63 | ||
74 | /* | 64 | /* |
75 | * Wait until the BBP becomes ready. | 65 | * Wait until the BBP becomes available, afterwards we |
66 | * can safely write the new data into the register. | ||
76 | */ | 67 | */ |
77 | reg = rt2500pci_bbp_check(rt2x00dev); | 68 | if (WAIT_FOR_BBP(rt2x00dev, ®)) { |
78 | if (rt2x00_get_field32(reg, BBPCSR_BUSY)) | 69 | reg = 0; |
79 | goto exit_fail; | 70 | rt2x00_set_field32(®, BBPCSR_VALUE, value); |
80 | 71 | rt2x00_set_field32(®, BBPCSR_REGNUM, word); | |
81 | /* | 72 | rt2x00_set_field32(®, BBPCSR_BUSY, 1); |
82 | * Write the data into the BBP. | 73 | rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 1); |
83 | */ | 74 | |
84 | reg = 0; | 75 | rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); |
85 | rt2x00_set_field32(®, BBPCSR_VALUE, value); | 76 | } |
86 | rt2x00_set_field32(®, BBPCSR_REGNUM, word); | ||
87 | rt2x00_set_field32(®, BBPCSR_BUSY, 1); | ||
88 | rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 1); | ||
89 | |||
90 | rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); | ||
91 | |||
92 | mutex_unlock(&rt2x00dev->csr_mutex); | ||
93 | |||
94 | return; | ||
95 | 77 | ||
96 | exit_fail: | ||
97 | mutex_unlock(&rt2x00dev->csr_mutex); | 78 | mutex_unlock(&rt2x00dev->csr_mutex); |
98 | |||
99 | ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n"); | ||
100 | } | 79 | } |
101 | 80 | ||
102 | static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev, | 81 | static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev, |
@@ -107,75 +86,55 @@ static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev, | |||
107 | mutex_lock(&rt2x00dev->csr_mutex); | 86 | mutex_lock(&rt2x00dev->csr_mutex); |
108 | 87 | ||
109 | /* | 88 | /* |
110 | * Wait until the BBP becomes ready. | 89 | * Wait until the BBP becomes available, afterwards we |
90 | * can safely write the read request into the register. | ||
91 | * After the data has been written, we wait until hardware | ||
92 | * returns the correct value, if at any time the register | ||
93 | * doesn't become available in time, reg will be 0xffffffff | ||
94 | * which means we return 0xff to the caller. | ||
111 | */ | 95 | */ |
112 | reg = rt2500pci_bbp_check(rt2x00dev); | 96 | if (WAIT_FOR_BBP(rt2x00dev, ®)) { |
113 | if (rt2x00_get_field32(reg, BBPCSR_BUSY)) | 97 | reg = 0; |
114 | goto exit_fail; | 98 | rt2x00_set_field32(®, BBPCSR_REGNUM, word); |
99 | rt2x00_set_field32(®, BBPCSR_BUSY, 1); | ||
100 | rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 0); | ||
115 | 101 | ||
116 | /* | 102 | rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); |
117 | * Write the request into the BBP. | ||
118 | */ | ||
119 | reg = 0; | ||
120 | rt2x00_set_field32(®, BBPCSR_REGNUM, word); | ||
121 | rt2x00_set_field32(®, BBPCSR_BUSY, 1); | ||
122 | rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 0); | ||
123 | 103 | ||
124 | rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); | 104 | WAIT_FOR_BBP(rt2x00dev, ®); |
125 | 105 | } | |
126 | /* | ||
127 | * Wait until the BBP becomes ready. | ||
128 | */ | ||
129 | reg = rt2500pci_bbp_check(rt2x00dev); | ||
130 | if (rt2x00_get_field32(reg, BBPCSR_BUSY)) | ||
131 | goto exit_fail; | ||
132 | 106 | ||
133 | *value = rt2x00_get_field32(reg, BBPCSR_VALUE); | 107 | *value = rt2x00_get_field32(reg, BBPCSR_VALUE); |
134 | 108 | ||
135 | mutex_unlock(&rt2x00dev->csr_mutex); | 109 | mutex_unlock(&rt2x00dev->csr_mutex); |
136 | |||
137 | return; | ||
138 | |||
139 | exit_fail: | ||
140 | mutex_unlock(&rt2x00dev->csr_mutex); | ||
141 | |||
142 | ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n"); | ||
143 | *value = 0xff; | ||
144 | } | 110 | } |
145 | 111 | ||
146 | static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev, | 112 | static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev, |
147 | const unsigned int word, const u32 value) | 113 | const unsigned int word, const u32 value) |
148 | { | 114 | { |
149 | u32 reg; | 115 | u32 reg; |
150 | unsigned int i; | ||
151 | 116 | ||
152 | if (!word) | 117 | if (!word) |
153 | return; | 118 | return; |
154 | 119 | ||
155 | mutex_lock(&rt2x00dev->csr_mutex); | 120 | mutex_lock(&rt2x00dev->csr_mutex); |
156 | 121 | ||
157 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 122 | /* |
158 | rt2x00pci_register_read(rt2x00dev, RFCSR, ®); | 123 | * Wait until the RF becomes available, afterwards we |
159 | if (!rt2x00_get_field32(reg, RFCSR_BUSY)) | 124 | * can safely write the new data into the register. |
160 | goto rf_write; | 125 | */ |
161 | udelay(REGISTER_BUSY_DELAY); | 126 | if (WAIT_FOR_RF(rt2x00dev, ®)) { |
127 | reg = 0; | ||
128 | rt2x00_set_field32(®, RFCSR_VALUE, value); | ||
129 | rt2x00_set_field32(®, RFCSR_NUMBER_OF_BITS, 20); | ||
130 | rt2x00_set_field32(®, RFCSR_IF_SELECT, 0); | ||
131 | rt2x00_set_field32(®, RFCSR_BUSY, 1); | ||
132 | |||
133 | rt2x00pci_register_write(rt2x00dev, RFCSR, reg); | ||
134 | rt2x00_rf_write(rt2x00dev, word, value); | ||
162 | } | 135 | } |
163 | 136 | ||
164 | mutex_unlock(&rt2x00dev->csr_mutex); | 137 | mutex_unlock(&rt2x00dev->csr_mutex); |
165 | ERROR(rt2x00dev, "RFCSR register busy. Write failed.\n"); | ||
166 | return; | ||
167 | |||
168 | rf_write: | ||
169 | reg = 0; | ||
170 | rt2x00_set_field32(®, RFCSR_VALUE, value); | ||
171 | rt2x00_set_field32(®, RFCSR_NUMBER_OF_BITS, 20); | ||
172 | rt2x00_set_field32(®, RFCSR_IF_SELECT, 0); | ||
173 | rt2x00_set_field32(®, RFCSR_BUSY, 1); | ||
174 | |||
175 | rt2x00pci_register_write(rt2x00dev, RFCSR, reg); | ||
176 | rt2x00_rf_write(rt2x00dev, word, value); | ||
177 | |||
178 | mutex_unlock(&rt2x00dev->csr_mutex); | ||
179 | } | 138 | } |
180 | 139 | ||
181 | static void rt2500pci_eepromregister_read(struct eeprom_93cx6 *eeprom) | 140 | static void rt2500pci_eepromregister_read(struct eeprom_93cx6 *eeprom) |
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index e6bae4ae4c47..40eb64358821 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -57,7 +57,7 @@ static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev, | |||
57 | __le16 reg; | 57 | __le16 reg; |
58 | rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ, | 58 | rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ, |
59 | USB_VENDOR_REQUEST_IN, offset, | 59 | USB_VENDOR_REQUEST_IN, offset, |
60 | ®, sizeof(u16), REGISTER_TIMEOUT); | 60 | ®, sizeof(reg), REGISTER_TIMEOUT); |
61 | *value = le16_to_cpu(reg); | 61 | *value = le16_to_cpu(reg); |
62 | } | 62 | } |
63 | 63 | ||
@@ -68,7 +68,7 @@ static inline void rt2500usb_register_read_lock(struct rt2x00_dev *rt2x00dev, | |||
68 | __le16 reg; | 68 | __le16 reg; |
69 | rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_READ, | 69 | rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_READ, |
70 | USB_VENDOR_REQUEST_IN, offset, | 70 | USB_VENDOR_REQUEST_IN, offset, |
71 | ®, sizeof(u16), REGISTER_TIMEOUT); | 71 | ®, sizeof(reg), REGISTER_TIMEOUT); |
72 | *value = le16_to_cpu(reg); | 72 | *value = le16_to_cpu(reg); |
73 | } | 73 | } |
74 | 74 | ||
@@ -89,7 +89,7 @@ static inline void rt2500usb_register_write(struct rt2x00_dev *rt2x00dev, | |||
89 | __le16 reg = cpu_to_le16(value); | 89 | __le16 reg = cpu_to_le16(value); |
90 | rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_WRITE, | 90 | rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_WRITE, |
91 | USB_VENDOR_REQUEST_OUT, offset, | 91 | USB_VENDOR_REQUEST_OUT, offset, |
92 | ®, sizeof(u16), REGISTER_TIMEOUT); | 92 | ®, sizeof(reg), REGISTER_TIMEOUT); |
93 | } | 93 | } |
94 | 94 | ||
95 | static inline void rt2500usb_register_write_lock(struct rt2x00_dev *rt2x00dev, | 95 | static inline void rt2500usb_register_write_lock(struct rt2x00_dev *rt2x00dev, |
@@ -99,7 +99,7 @@ static inline void rt2500usb_register_write_lock(struct rt2x00_dev *rt2x00dev, | |||
99 | __le16 reg = cpu_to_le16(value); | 99 | __le16 reg = cpu_to_le16(value); |
100 | rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_WRITE, | 100 | rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_WRITE, |
101 | USB_VENDOR_REQUEST_OUT, offset, | 101 | USB_VENDOR_REQUEST_OUT, offset, |
102 | ®, sizeof(u16), REGISTER_TIMEOUT); | 102 | ®, sizeof(reg), REGISTER_TIMEOUT); |
103 | } | 103 | } |
104 | 104 | ||
105 | static inline void rt2500usb_register_multiwrite(struct rt2x00_dev *rt2x00dev, | 105 | static inline void rt2500usb_register_multiwrite(struct rt2x00_dev *rt2x00dev, |
@@ -112,21 +112,32 @@ static inline void rt2500usb_register_multiwrite(struct rt2x00_dev *rt2x00dev, | |||
112 | REGISTER_TIMEOUT16(length)); | 112 | REGISTER_TIMEOUT16(length)); |
113 | } | 113 | } |
114 | 114 | ||
115 | static u16 rt2500usb_bbp_check(struct rt2x00_dev *rt2x00dev) | 115 | static int rt2500usb_regbusy_read(struct rt2x00_dev *rt2x00dev, |
116 | const unsigned int offset, | ||
117 | struct rt2x00_field16 field, | ||
118 | u16 *reg) | ||
116 | { | 119 | { |
117 | u16 reg; | ||
118 | unsigned int i; | 120 | unsigned int i; |
119 | 121 | ||
120 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 122 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { |
121 | rt2500usb_register_read_lock(rt2x00dev, PHY_CSR8, ®); | 123 | rt2500usb_register_read_lock(rt2x00dev, offset, reg); |
122 | if (!rt2x00_get_field16(reg, PHY_CSR8_BUSY)) | 124 | if (!rt2x00_get_field16(*reg, field)) |
123 | break; | 125 | return 1; |
124 | udelay(REGISTER_BUSY_DELAY); | 126 | udelay(REGISTER_BUSY_DELAY); |
125 | } | 127 | } |
126 | 128 | ||
127 | return reg; | 129 | ERROR(rt2x00dev, "Indirect register access failed: " |
130 | "offset=0x%.08x, value=0x%.08x\n", offset, *reg); | ||
131 | *reg = ~0; | ||
132 | |||
133 | return 0; | ||
128 | } | 134 | } |
129 | 135 | ||
136 | #define WAIT_FOR_BBP(__dev, __reg) \ | ||
137 | rt2500usb_regbusy_read((__dev), PHY_CSR8, PHY_CSR8_BUSY, (__reg)) | ||
138 | #define WAIT_FOR_RF(__dev, __reg) \ | ||
139 | rt2500usb_regbusy_read((__dev), PHY_CSR10, PHY_CSR10_RF_BUSY, (__reg)) | ||
140 | |||
130 | static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev, | 141 | static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev, |
131 | const unsigned int word, const u8 value) | 142 | const unsigned int word, const u8 value) |
132 | { | 143 | { |
@@ -135,30 +146,19 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev, | |||
135 | mutex_lock(&rt2x00dev->csr_mutex); | 146 | mutex_lock(&rt2x00dev->csr_mutex); |
136 | 147 | ||
137 | /* | 148 | /* |
138 | * Wait until the BBP becomes ready. | 149 | * Wait until the BBP becomes available, afterwards we |
139 | */ | 150 | * can safely write the new data into the register. |
140 | reg = rt2500usb_bbp_check(rt2x00dev); | ||
141 | if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) | ||
142 | goto exit_fail; | ||
143 | |||
144 | /* | ||
145 | * Write the data into the BBP. | ||
146 | */ | 151 | */ |
147 | reg = 0; | 152 | if (WAIT_FOR_BBP(rt2x00dev, ®)) { |
148 | rt2x00_set_field16(®, PHY_CSR7_DATA, value); | 153 | reg = 0; |
149 | rt2x00_set_field16(®, PHY_CSR7_REG_ID, word); | 154 | rt2x00_set_field16(®, PHY_CSR7_DATA, value); |
150 | rt2x00_set_field16(®, PHY_CSR7_READ_CONTROL, 0); | 155 | rt2x00_set_field16(®, PHY_CSR7_REG_ID, word); |
151 | 156 | rt2x00_set_field16(®, PHY_CSR7_READ_CONTROL, 0); | |
152 | rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg); | ||
153 | |||
154 | mutex_unlock(&rt2x00dev->csr_mutex); | ||
155 | 157 | ||
156 | return; | 158 | rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg); |
159 | } | ||
157 | 160 | ||
158 | exit_fail: | ||
159 | mutex_unlock(&rt2x00dev->csr_mutex); | 161 | mutex_unlock(&rt2x00dev->csr_mutex); |
160 | |||
161 | ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n"); | ||
162 | } | 162 | } |
163 | 163 | ||
164 | static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev, | 164 | static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev, |
@@ -169,77 +169,57 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev, | |||
169 | mutex_lock(&rt2x00dev->csr_mutex); | 169 | mutex_lock(&rt2x00dev->csr_mutex); |
170 | 170 | ||
171 | /* | 171 | /* |
172 | * Wait until the BBP becomes ready. | 172 | * Wait until the BBP becomes available, afterwards we |
173 | */ | 173 | * can safely write the read request into the register. |
174 | reg = rt2500usb_bbp_check(rt2x00dev); | 174 | * After the data has been written, we wait until hardware |
175 | if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) | 175 | * returns the correct value, if at any time the register |
176 | goto exit_fail; | 176 | * doesn't become available in time, reg will be 0xffffffff |
177 | 177 | * which means we return 0xff to the caller. | |
178 | /* | ||
179 | * Write the request into the BBP. | ||
180 | */ | 178 | */ |
181 | reg = 0; | 179 | if (WAIT_FOR_BBP(rt2x00dev, ®)) { |
182 | rt2x00_set_field16(®, PHY_CSR7_REG_ID, word); | 180 | reg = 0; |
183 | rt2x00_set_field16(®, PHY_CSR7_READ_CONTROL, 1); | 181 | rt2x00_set_field16(®, PHY_CSR7_REG_ID, word); |
182 | rt2x00_set_field16(®, PHY_CSR7_READ_CONTROL, 1); | ||
184 | 183 | ||
185 | rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg); | 184 | rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg); |
186 | 185 | ||
187 | /* | 186 | if (WAIT_FOR_BBP(rt2x00dev, ®)) |
188 | * Wait until the BBP becomes ready. | 187 | rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, ®); |
189 | */ | 188 | } |
190 | reg = rt2500usb_bbp_check(rt2x00dev); | ||
191 | if (rt2x00_get_field16(reg, PHY_CSR8_BUSY)) | ||
192 | goto exit_fail; | ||
193 | 189 | ||
194 | rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, ®); | ||
195 | *value = rt2x00_get_field16(reg, PHY_CSR7_DATA); | 190 | *value = rt2x00_get_field16(reg, PHY_CSR7_DATA); |
196 | 191 | ||
197 | mutex_unlock(&rt2x00dev->csr_mutex); | 192 | mutex_unlock(&rt2x00dev->csr_mutex); |
198 | |||
199 | return; | ||
200 | |||
201 | exit_fail: | ||
202 | mutex_unlock(&rt2x00dev->csr_mutex); | ||
203 | |||
204 | ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n"); | ||
205 | *value = 0xff; | ||
206 | } | 193 | } |
207 | 194 | ||
208 | static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev, | 195 | static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev, |
209 | const unsigned int word, const u32 value) | 196 | const unsigned int word, const u32 value) |
210 | { | 197 | { |
211 | u16 reg; | 198 | u16 reg; |
212 | unsigned int i; | ||
213 | 199 | ||
214 | if (!word) | 200 | if (!word) |
215 | return; | 201 | return; |
216 | 202 | ||
217 | mutex_lock(&rt2x00dev->csr_mutex); | 203 | mutex_lock(&rt2x00dev->csr_mutex); |
218 | 204 | ||
219 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 205 | /* |
220 | rt2500usb_register_read_lock(rt2x00dev, PHY_CSR10, ®); | 206 | * Wait until the RF becomes available, afterwards we |
221 | if (!rt2x00_get_field16(reg, PHY_CSR10_RF_BUSY)) | 207 | * can safely write the new data into the register. |
222 | goto rf_write; | 208 | */ |
223 | udelay(REGISTER_BUSY_DELAY); | 209 | if (WAIT_FOR_RF(rt2x00dev, ®)) { |
224 | } | 210 | reg = 0; |
225 | 211 | rt2x00_set_field16(®, PHY_CSR9_RF_VALUE, value); | |
226 | mutex_unlock(&rt2x00dev->csr_mutex); | 212 | rt2500usb_register_write_lock(rt2x00dev, PHY_CSR9, reg); |
227 | ERROR(rt2x00dev, "PHY_CSR10 register busy. Write failed.\n"); | ||
228 | return; | ||
229 | |||
230 | rf_write: | ||
231 | reg = 0; | ||
232 | rt2x00_set_field16(®, PHY_CSR9_RF_VALUE, value); | ||
233 | rt2500usb_register_write_lock(rt2x00dev, PHY_CSR9, reg); | ||
234 | 213 | ||
235 | reg = 0; | 214 | reg = 0; |
236 | rt2x00_set_field16(®, PHY_CSR10_RF_VALUE, value >> 16); | 215 | rt2x00_set_field16(®, PHY_CSR10_RF_VALUE, value >> 16); |
237 | rt2x00_set_field16(®, PHY_CSR10_RF_NUMBER_OF_BITS, 20); | 216 | rt2x00_set_field16(®, PHY_CSR10_RF_NUMBER_OF_BITS, 20); |
238 | rt2x00_set_field16(®, PHY_CSR10_RF_IF_SELECT, 0); | 217 | rt2x00_set_field16(®, PHY_CSR10_RF_IF_SELECT, 0); |
239 | rt2x00_set_field16(®, PHY_CSR10_RF_BUSY, 1); | 218 | rt2x00_set_field16(®, PHY_CSR10_RF_BUSY, 1); |
240 | 219 | ||
241 | rt2500usb_register_write_lock(rt2x00dev, PHY_CSR10, reg); | 220 | rt2500usb_register_write_lock(rt2x00dev, PHY_CSR10, reg); |
242 | rt2x00_rf_write(rt2x00dev, word, value); | 221 | rt2x00_rf_write(rt2x00dev, word, value); |
222 | } | ||
243 | 223 | ||
244 | mutex_unlock(&rt2x00dev->csr_mutex); | 224 | mutex_unlock(&rt2x00dev->csr_mutex); |
245 | } | 225 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index e33bd0f150c5..d52b22b82d1f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c | |||
@@ -32,6 +32,31 @@ | |||
32 | #include "rt2x00pci.h" | 32 | #include "rt2x00pci.h" |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * Register access. | ||
36 | */ | ||
37 | int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, | ||
38 | const unsigned int offset, | ||
39 | const struct rt2x00_field32 field, | ||
40 | u32 *reg) | ||
41 | { | ||
42 | unsigned int i; | ||
43 | |||
44 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
45 | rt2x00pci_register_read(rt2x00dev, offset, reg); | ||
46 | if (!rt2x00_get_field32(*reg, field)) | ||
47 | return 1; | ||
48 | udelay(REGISTER_BUSY_DELAY); | ||
49 | } | ||
50 | |||
51 | ERROR(rt2x00dev, "Indirect register access failed: " | ||
52 | "offset=0x%.08x, value=0x%.08x\n", offset, *reg); | ||
53 | *reg = ~0; | ||
54 | |||
55 | return 0; | ||
56 | } | ||
57 | EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read); | ||
58 | |||
59 | /* | ||
35 | * TX data handlers. | 60 | * TX data handlers. |
36 | */ | 61 | */ |
37 | int rt2x00pci_write_tx_data(struct queue_entry *entry) | 62 | int rt2x00pci_write_tx_data(struct queue_entry *entry) |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h index 96a2082a3532..9c0a4d77bc1b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.h +++ b/drivers/net/wireless/rt2x00/rt2x00pci.h | |||
@@ -77,6 +77,24 @@ rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev, | |||
77 | } | 77 | } |
78 | 78 | ||
79 | /** | 79 | /** |
80 | * rt2x00pci_regbusy_read - Read from register with busy check | ||
81 | * @rt2x00dev: Device pointer, see &struct rt2x00_dev. | ||
82 | * @offset: Register offset | ||
83 | * @field: Field to check if register is busy | ||
84 | * @reg: Pointer to where register contents should be stored | ||
85 | * | ||
86 | * This function will read the given register, and checks if the | ||
87 | * register is busy. If it is, it will sleep for a couple of | ||
88 | * microseconds before reading the register again. If the register | ||
89 | * is not read after a certain timeout, this function will return | ||
90 | * FALSE. | ||
91 | */ | ||
92 | int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev, | ||
93 | const unsigned int offset, | ||
94 | const struct rt2x00_field32 field, | ||
95 | u32 *reg); | ||
96 | |||
97 | /** | ||
80 | * rt2x00pci_write_tx_data - Initialize data for TX operation | 98 | * rt2x00pci_write_tx_data - Initialize data for TX operation |
81 | * @entry: The entry where the frame is located | 99 | * @entry: The entry where the frame is located |
82 | * | 100 | * |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 89ac34fbadf2..d54443c25fe3 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -55,20 +55,13 @@ MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | |||
55 | * the access attempt is considered to have failed, | 55 | * the access attempt is considered to have failed, |
56 | * and we will print an error. | 56 | * and we will print an error. |
57 | */ | 57 | */ |
58 | static u32 rt61pci_bbp_check(struct rt2x00_dev *rt2x00dev) | 58 | #define WAIT_FOR_BBP(__dev, __reg) \ |
59 | { | 59 | rt2x00pci_regbusy_read((__dev), PHY_CSR3, PHY_CSR3_BUSY, (__reg)) |
60 | u32 reg; | 60 | #define WAIT_FOR_RF(__dev, __reg) \ |
61 | unsigned int i; | 61 | rt2x00pci_regbusy_read((__dev), PHY_CSR4, PHY_CSR4_BUSY, (__reg)) |
62 | 62 | #define WAIT_FOR_MCU(__dev, __reg) \ | |
63 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 63 | rt2x00pci_regbusy_read((__dev), H2M_MAILBOX_CSR, \ |
64 | rt2x00pci_register_read(rt2x00dev, PHY_CSR3, ®); | 64 | H2M_MAILBOX_CSR_OWNER, (__reg)) |
65 | if (!rt2x00_get_field32(reg, PHY_CSR3_BUSY)) | ||
66 | break; | ||
67 | udelay(REGISTER_BUSY_DELAY); | ||
68 | } | ||
69 | |||
70 | return reg; | ||
71 | } | ||
72 | 65 | ||
73 | static void rt61pci_bbp_write(struct rt2x00_dev *rt2x00dev, | 66 | static void rt61pci_bbp_write(struct rt2x00_dev *rt2x00dev, |
74 | const unsigned int word, const u8 value) | 67 | const unsigned int word, const u8 value) |
@@ -78,30 +71,20 @@ static void rt61pci_bbp_write(struct rt2x00_dev *rt2x00dev, | |||
78 | mutex_lock(&rt2x00dev->csr_mutex); | 71 | mutex_lock(&rt2x00dev->csr_mutex); |
79 | 72 | ||
80 | /* | 73 | /* |
81 | * Wait until the BBP becomes ready. | 74 | * Wait until the BBP becomes available, afterwards we |
82 | */ | 75 | * can safely write the new data into the register. |
83 | reg = rt61pci_bbp_check(rt2x00dev); | ||
84 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) | ||
85 | goto exit_fail; | ||
86 | |||
87 | /* | ||
88 | * Write the data into the BBP. | ||
89 | */ | 76 | */ |
90 | reg = 0; | 77 | if (WAIT_FOR_BBP(rt2x00dev, ®)) { |
91 | rt2x00_set_field32(®, PHY_CSR3_VALUE, value); | 78 | reg = 0; |
92 | rt2x00_set_field32(®, PHY_CSR3_REGNUM, word); | 79 | rt2x00_set_field32(®, PHY_CSR3_VALUE, value); |
93 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); | 80 | rt2x00_set_field32(®, PHY_CSR3_REGNUM, word); |
94 | rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 0); | 81 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); |
95 | 82 | rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 0); | |
96 | rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg); | ||
97 | mutex_unlock(&rt2x00dev->csr_mutex); | ||
98 | 83 | ||
99 | return; | 84 | rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg); |
85 | } | ||
100 | 86 | ||
101 | exit_fail: | ||
102 | mutex_unlock(&rt2x00dev->csr_mutex); | 87 | mutex_unlock(&rt2x00dev->csr_mutex); |
103 | |||
104 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n"); | ||
105 | } | 88 | } |
106 | 89 | ||
107 | static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev, | 90 | static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev, |
@@ -112,72 +95,53 @@ static void rt61pci_bbp_read(struct rt2x00_dev *rt2x00dev, | |||
112 | mutex_lock(&rt2x00dev->csr_mutex); | 95 | mutex_lock(&rt2x00dev->csr_mutex); |
113 | 96 | ||
114 | /* | 97 | /* |
115 | * Wait until the BBP becomes ready. | 98 | * Wait until the BBP becomes available, afterwards we |
99 | * can safely write the read request into the register. | ||
100 | * After the data has been written, we wait until hardware | ||
101 | * returns the correct value, if at any time the register | ||
102 | * doesn't become available in time, reg will be 0xffffffff | ||
103 | * which means we return 0xff to the caller. | ||
116 | */ | 104 | */ |
117 | reg = rt61pci_bbp_check(rt2x00dev); | 105 | if (WAIT_FOR_BBP(rt2x00dev, ®)) { |
118 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) | 106 | reg = 0; |
119 | goto exit_fail; | 107 | rt2x00_set_field32(®, PHY_CSR3_REGNUM, word); |
108 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); | ||
109 | rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 1); | ||
120 | 110 | ||
121 | /* | 111 | rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg); |
122 | * Write the request into the BBP. | ||
123 | */ | ||
124 | reg = 0; | ||
125 | rt2x00_set_field32(®, PHY_CSR3_REGNUM, word); | ||
126 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); | ||
127 | rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 1); | ||
128 | 112 | ||
129 | rt2x00pci_register_write(rt2x00dev, PHY_CSR3, reg); | 113 | WAIT_FOR_BBP(rt2x00dev, ®); |
130 | 114 | } | |
131 | /* | ||
132 | * Wait until the BBP becomes ready. | ||
133 | */ | ||
134 | reg = rt61pci_bbp_check(rt2x00dev); | ||
135 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) | ||
136 | goto exit_fail; | ||
137 | 115 | ||
138 | *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE); | 116 | *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE); |
139 | mutex_unlock(&rt2x00dev->csr_mutex); | ||
140 | |||
141 | return; | ||
142 | 117 | ||
143 | exit_fail: | ||
144 | mutex_unlock(&rt2x00dev->csr_mutex); | 118 | mutex_unlock(&rt2x00dev->csr_mutex); |
145 | |||
146 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); | ||
147 | *value = 0xff; | ||
148 | } | 119 | } |
149 | 120 | ||
150 | static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev, | 121 | static void rt61pci_rf_write(struct rt2x00_dev *rt2x00dev, |
151 | const unsigned int word, const u32 value) | 122 | const unsigned int word, const u32 value) |
152 | { | 123 | { |
153 | u32 reg; | 124 | u32 reg; |
154 | unsigned int i; | ||
155 | 125 | ||
156 | if (!word) | 126 | if (!word) |
157 | return; | 127 | return; |
158 | 128 | ||
159 | mutex_lock(&rt2x00dev->csr_mutex); | 129 | mutex_lock(&rt2x00dev->csr_mutex); |
160 | 130 | ||
161 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 131 | /* |
162 | rt2x00pci_register_read(rt2x00dev, PHY_CSR4, ®); | 132 | * Wait until the RF becomes available, afterwards we |
163 | if (!rt2x00_get_field32(reg, PHY_CSR4_BUSY)) | 133 | * can safely write the new data into the register. |
164 | goto rf_write; | 134 | */ |
165 | udelay(REGISTER_BUSY_DELAY); | 135 | if (WAIT_FOR_RF(rt2x00dev, ®)) { |
166 | } | 136 | reg = 0; |
167 | 137 | rt2x00_set_field32(®, PHY_CSR4_VALUE, value); | |
168 | mutex_unlock(&rt2x00dev->csr_mutex); | 138 | rt2x00_set_field32(®, PHY_CSR4_NUMBER_OF_BITS, 21); |
169 | ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n"); | 139 | rt2x00_set_field32(®, PHY_CSR4_IF_SELECT, 0); |
170 | return; | 140 | rt2x00_set_field32(®, PHY_CSR4_BUSY, 1); |
171 | |||
172 | rf_write: | ||
173 | reg = 0; | ||
174 | rt2x00_set_field32(®, PHY_CSR4_VALUE, value); | ||
175 | rt2x00_set_field32(®, PHY_CSR4_NUMBER_OF_BITS, 21); | ||
176 | rt2x00_set_field32(®, PHY_CSR4_IF_SELECT, 0); | ||
177 | rt2x00_set_field32(®, PHY_CSR4_BUSY, 1); | ||
178 | 141 | ||
179 | rt2x00pci_register_write(rt2x00dev, PHY_CSR4, reg); | 142 | rt2x00pci_register_write(rt2x00dev, PHY_CSR4, reg); |
180 | rt2x00_rf_write(rt2x00dev, word, value); | 143 | rt2x00_rf_write(rt2x00dev, word, value); |
144 | } | ||
181 | 145 | ||
182 | mutex_unlock(&rt2x00dev->csr_mutex); | 146 | mutex_unlock(&rt2x00dev->csr_mutex); |
183 | } | 147 | } |
@@ -196,32 +160,25 @@ static void rt61pci_mcu_request(struct rt2x00_dev *rt2x00dev, | |||
196 | 160 | ||
197 | mutex_lock(&rt2x00dev->csr_mutex); | 161 | mutex_lock(&rt2x00dev->csr_mutex); |
198 | 162 | ||
199 | rt2x00pci_register_read(rt2x00dev, H2M_MAILBOX_CSR, ®); | 163 | /* |
200 | 164 | * Wait until the MCU becomes available, afterwards we | |
201 | if (rt2x00_get_field32(reg, H2M_MAILBOX_CSR_OWNER)) | 165 | * can safely write the new data into the register. |
202 | goto exit_fail; | 166 | */ |
203 | 167 | if (WAIT_FOR_MCU(rt2x00dev, ®)) { | |
204 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_OWNER, 1); | 168 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_OWNER, 1); |
205 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_CMD_TOKEN, token); | 169 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_CMD_TOKEN, token); |
206 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG0, arg0); | 170 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG0, arg0); |
207 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG1, arg1); | 171 | rt2x00_set_field32(®, H2M_MAILBOX_CSR_ARG1, arg1); |
208 | rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CSR, reg); | 172 | rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CSR, reg); |
209 | |||
210 | rt2x00pci_register_read(rt2x00dev, HOST_CMD_CSR, ®); | ||
211 | rt2x00_set_field32(®, HOST_CMD_CSR_HOST_COMMAND, command); | ||
212 | rt2x00_set_field32(®, HOST_CMD_CSR_INTERRUPT_MCU, 1); | ||
213 | rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg); | ||
214 | |||
215 | mutex_unlock(&rt2x00dev->csr_mutex); | ||
216 | 173 | ||
217 | return; | 174 | rt2x00pci_register_read(rt2x00dev, HOST_CMD_CSR, ®); |
175 | rt2x00_set_field32(®, HOST_CMD_CSR_HOST_COMMAND, command); | ||
176 | rt2x00_set_field32(®, HOST_CMD_CSR_INTERRUPT_MCU, 1); | ||
177 | rt2x00pci_register_write(rt2x00dev, HOST_CMD_CSR, reg); | ||
178 | } | ||
218 | 179 | ||
219 | exit_fail: | ||
220 | mutex_unlock(&rt2x00dev->csr_mutex); | 180 | mutex_unlock(&rt2x00dev->csr_mutex); |
221 | 181 | ||
222 | ERROR(rt2x00dev, | ||
223 | "mcu request error. Request 0x%02x failed for token 0x%02x.\n", | ||
224 | command, token); | ||
225 | } | 182 | } |
226 | #endif /* CONFIG_RT2X00_LIB_LEDS */ | 183 | #endif /* CONFIG_RT2X00_LIB_LEDS */ |
227 | 184 | ||
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index d1a63e0017da..b4ca8488beff 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -63,7 +63,7 @@ static inline void rt73usb_register_read(struct rt2x00_dev *rt2x00dev, | |||
63 | __le32 reg; | 63 | __le32 reg; |
64 | rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ, | 64 | rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ, |
65 | USB_VENDOR_REQUEST_IN, offset, | 65 | USB_VENDOR_REQUEST_IN, offset, |
66 | ®, sizeof(u32), REGISTER_TIMEOUT); | 66 | ®, sizeof(reg), REGISTER_TIMEOUT); |
67 | *value = le32_to_cpu(reg); | 67 | *value = le32_to_cpu(reg); |
68 | } | 68 | } |
69 | 69 | ||
@@ -73,7 +73,7 @@ static inline void rt73usb_register_read_lock(struct rt2x00_dev *rt2x00dev, | |||
73 | __le32 reg; | 73 | __le32 reg; |
74 | rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_READ, | 74 | rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_READ, |
75 | USB_VENDOR_REQUEST_IN, offset, | 75 | USB_VENDOR_REQUEST_IN, offset, |
76 | ®, sizeof(u32), REGISTER_TIMEOUT); | 76 | ®, sizeof(reg), REGISTER_TIMEOUT); |
77 | *value = le32_to_cpu(reg); | 77 | *value = le32_to_cpu(reg); |
78 | } | 78 | } |
79 | 79 | ||
@@ -93,7 +93,7 @@ static inline void rt73usb_register_write(struct rt2x00_dev *rt2x00dev, | |||
93 | __le32 reg = cpu_to_le32(value); | 93 | __le32 reg = cpu_to_le32(value); |
94 | rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_WRITE, | 94 | rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_WRITE, |
95 | USB_VENDOR_REQUEST_OUT, offset, | 95 | USB_VENDOR_REQUEST_OUT, offset, |
96 | ®, sizeof(u32), REGISTER_TIMEOUT); | 96 | ®, sizeof(reg), REGISTER_TIMEOUT); |
97 | } | 97 | } |
98 | 98 | ||
99 | static inline void rt73usb_register_write_lock(struct rt2x00_dev *rt2x00dev, | 99 | static inline void rt73usb_register_write_lock(struct rt2x00_dev *rt2x00dev, |
@@ -102,7 +102,7 @@ static inline void rt73usb_register_write_lock(struct rt2x00_dev *rt2x00dev, | |||
102 | __le32 reg = cpu_to_le32(value); | 102 | __le32 reg = cpu_to_le32(value); |
103 | rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_WRITE, | 103 | rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_WRITE, |
104 | USB_VENDOR_REQUEST_OUT, offset, | 104 | USB_VENDOR_REQUEST_OUT, offset, |
105 | ®, sizeof(u32), REGISTER_TIMEOUT); | 105 | ®, sizeof(reg), REGISTER_TIMEOUT); |
106 | } | 106 | } |
107 | 107 | ||
108 | static inline void rt73usb_register_multiwrite(struct rt2x00_dev *rt2x00dev, | 108 | static inline void rt73usb_register_multiwrite(struct rt2x00_dev *rt2x00dev, |
@@ -115,21 +115,32 @@ static inline void rt73usb_register_multiwrite(struct rt2x00_dev *rt2x00dev, | |||
115 | REGISTER_TIMEOUT32(length)); | 115 | REGISTER_TIMEOUT32(length)); |
116 | } | 116 | } |
117 | 117 | ||
118 | static u32 rt73usb_bbp_check(struct rt2x00_dev *rt2x00dev) | 118 | static int rt73usb_regbusy_read(struct rt2x00_dev *rt2x00dev, |
119 | const unsigned int offset, | ||
120 | struct rt2x00_field32 field, | ||
121 | u32 *reg) | ||
119 | { | 122 | { |
120 | u32 reg; | ||
121 | unsigned int i; | 123 | unsigned int i; |
122 | 124 | ||
123 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 125 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { |
124 | rt73usb_register_read_lock(rt2x00dev, PHY_CSR3, ®); | 126 | rt73usb_register_read_lock(rt2x00dev, offset, reg); |
125 | if (!rt2x00_get_field32(reg, PHY_CSR3_BUSY)) | 127 | if (!rt2x00_get_field32(*reg, field)) |
126 | break; | 128 | return 1; |
127 | udelay(REGISTER_BUSY_DELAY); | 129 | udelay(REGISTER_BUSY_DELAY); |
128 | } | 130 | } |
129 | 131 | ||
130 | return reg; | 132 | ERROR(rt2x00dev, "Indirect register access failed: " |
133 | "offset=0x%.08x, value=0x%.08x\n", offset, *reg); | ||
134 | *reg = ~0; | ||
135 | |||
136 | return 0; | ||
131 | } | 137 | } |
132 | 138 | ||
139 | #define WAIT_FOR_BBP(__dev, __reg) \ | ||
140 | rt73usb_regbusy_read((__dev), PHY_CSR3, PHY_CSR3_BUSY, (__reg)) | ||
141 | #define WAIT_FOR_RF(__dev, __reg) \ | ||
142 | rt73usb_regbusy_read((__dev), PHY_CSR4, PHY_CSR4_BUSY, (__reg)) | ||
143 | |||
133 | static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev, | 144 | static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev, |
134 | const unsigned int word, const u8 value) | 145 | const unsigned int word, const u8 value) |
135 | { | 146 | { |
@@ -138,30 +149,20 @@ static void rt73usb_bbp_write(struct rt2x00_dev *rt2x00dev, | |||
138 | mutex_lock(&rt2x00dev->csr_mutex); | 149 | mutex_lock(&rt2x00dev->csr_mutex); |
139 | 150 | ||
140 | /* | 151 | /* |
141 | * Wait until the BBP becomes ready. | 152 | * Wait until the BBP becomes available, afterwards we |
153 | * can safely write the new data into the register. | ||
142 | */ | 154 | */ |
143 | reg = rt73usb_bbp_check(rt2x00dev); | 155 | if (WAIT_FOR_BBP(rt2x00dev, ®)) { |
144 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) | 156 | reg = 0; |
145 | goto exit_fail; | 157 | rt2x00_set_field32(®, PHY_CSR3_VALUE, value); |
146 | 158 | rt2x00_set_field32(®, PHY_CSR3_REGNUM, word); | |
147 | /* | 159 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); |
148 | * Write the data into the BBP. | 160 | rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 0); |
149 | */ | 161 | |
150 | reg = 0; | 162 | rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg); |
151 | rt2x00_set_field32(®, PHY_CSR3_VALUE, value); | 163 | } |
152 | rt2x00_set_field32(®, PHY_CSR3_REGNUM, word); | ||
153 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); | ||
154 | rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 0); | ||
155 | |||
156 | rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg); | ||
157 | mutex_unlock(&rt2x00dev->csr_mutex); | ||
158 | |||
159 | return; | ||
160 | 164 | ||
161 | exit_fail: | ||
162 | mutex_unlock(&rt2x00dev->csr_mutex); | 165 | mutex_unlock(&rt2x00dev->csr_mutex); |
163 | |||
164 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Write failed.\n"); | ||
165 | } | 166 | } |
166 | 167 | ||
167 | static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev, | 168 | static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev, |
@@ -172,79 +173,59 @@ static void rt73usb_bbp_read(struct rt2x00_dev *rt2x00dev, | |||
172 | mutex_lock(&rt2x00dev->csr_mutex); | 173 | mutex_lock(&rt2x00dev->csr_mutex); |
173 | 174 | ||
174 | /* | 175 | /* |
175 | * Wait until the BBP becomes ready. | 176 | * Wait until the BBP becomes available, afterwards we |
177 | * can safely write the read request into the register. | ||
178 | * After the data has been written, we wait until hardware | ||
179 | * returns the correct value, if at any time the register | ||
180 | * doesn't become available in time, reg will be 0xffffffff | ||
181 | * which means we return 0xff to the caller. | ||
176 | */ | 182 | */ |
177 | reg = rt73usb_bbp_check(rt2x00dev); | 183 | if (WAIT_FOR_BBP(rt2x00dev, ®)) { |
178 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) | 184 | reg = 0; |
179 | goto exit_fail; | 185 | rt2x00_set_field32(®, PHY_CSR3_REGNUM, word); |
186 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); | ||
187 | rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 1); | ||
180 | 188 | ||
181 | /* | 189 | rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg); |
182 | * Write the request into the BBP. | ||
183 | */ | ||
184 | reg = 0; | ||
185 | rt2x00_set_field32(®, PHY_CSR3_REGNUM, word); | ||
186 | rt2x00_set_field32(®, PHY_CSR3_BUSY, 1); | ||
187 | rt2x00_set_field32(®, PHY_CSR3_READ_CONTROL, 1); | ||
188 | 190 | ||
189 | rt73usb_register_write_lock(rt2x00dev, PHY_CSR3, reg); | 191 | WAIT_FOR_BBP(rt2x00dev, ®); |
190 | 192 | } | |
191 | /* | ||
192 | * Wait until the BBP becomes ready. | ||
193 | */ | ||
194 | reg = rt73usb_bbp_check(rt2x00dev); | ||
195 | if (rt2x00_get_field32(reg, PHY_CSR3_BUSY)) | ||
196 | goto exit_fail; | ||
197 | 193 | ||
198 | *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE); | 194 | *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE); |
199 | mutex_unlock(&rt2x00dev->csr_mutex); | ||
200 | |||
201 | return; | ||
202 | 195 | ||
203 | exit_fail: | ||
204 | mutex_unlock(&rt2x00dev->csr_mutex); | 196 | mutex_unlock(&rt2x00dev->csr_mutex); |
205 | |||
206 | ERROR(rt2x00dev, "PHY_CSR3 register busy. Read failed.\n"); | ||
207 | *value = 0xff; | ||
208 | } | 197 | } |
209 | 198 | ||
210 | static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev, | 199 | static void rt73usb_rf_write(struct rt2x00_dev *rt2x00dev, |
211 | const unsigned int word, const u32 value) | 200 | const unsigned int word, const u32 value) |
212 | { | 201 | { |
213 | u32 reg; | 202 | u32 reg; |
214 | unsigned int i; | ||
215 | 203 | ||
216 | if (!word) | 204 | if (!word) |
217 | return; | 205 | return; |
218 | 206 | ||
219 | mutex_lock(&rt2x00dev->csr_mutex); | 207 | mutex_lock(&rt2x00dev->csr_mutex); |
220 | 208 | ||
221 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
222 | rt73usb_register_read_lock(rt2x00dev, PHY_CSR4, ®); | ||
223 | if (!rt2x00_get_field32(reg, PHY_CSR4_BUSY)) | ||
224 | goto rf_write; | ||
225 | udelay(REGISTER_BUSY_DELAY); | ||
226 | } | ||
227 | |||
228 | mutex_unlock(&rt2x00dev->csr_mutex); | ||
229 | ERROR(rt2x00dev, "PHY_CSR4 register busy. Write failed.\n"); | ||
230 | return; | ||
231 | |||
232 | rf_write: | ||
233 | reg = 0; | ||
234 | rt2x00_set_field32(®, PHY_CSR4_VALUE, value); | ||
235 | |||
236 | /* | 209 | /* |
237 | * RF5225 and RF2527 contain 21 bits per RF register value, | 210 | * Wait until the RF becomes available, afterwards we |
238 | * all others contain 20 bits. | 211 | * can safely write the new data into the register. |
239 | */ | 212 | */ |
240 | rt2x00_set_field32(®, PHY_CSR4_NUMBER_OF_BITS, | 213 | if (WAIT_FOR_RF(rt2x00dev, ®)) { |
241 | 20 + (rt2x00_rf(&rt2x00dev->chip, RF5225) || | 214 | reg = 0; |
242 | rt2x00_rf(&rt2x00dev->chip, RF2527))); | 215 | rt2x00_set_field32(®, PHY_CSR4_VALUE, value); |
243 | rt2x00_set_field32(®, PHY_CSR4_IF_SELECT, 0); | 216 | /* |
244 | rt2x00_set_field32(®, PHY_CSR4_BUSY, 1); | 217 | * RF5225 and RF2527 contain 21 bits per RF register value, |
245 | 218 | * all others contain 20 bits. | |
246 | rt73usb_register_write_lock(rt2x00dev, PHY_CSR4, reg); | 219 | */ |
247 | rt2x00_rf_write(rt2x00dev, word, value); | 220 | rt2x00_set_field32(®, PHY_CSR4_NUMBER_OF_BITS, |
221 | 20 + (rt2x00_rf(&rt2x00dev->chip, RF5225) || | ||
222 | rt2x00_rf(&rt2x00dev->chip, RF2527))); | ||
223 | rt2x00_set_field32(®, PHY_CSR4_IF_SELECT, 0); | ||
224 | rt2x00_set_field32(®, PHY_CSR4_BUSY, 1); | ||
225 | |||
226 | rt73usb_register_write_lock(rt2x00dev, PHY_CSR4, reg); | ||
227 | rt2x00_rf_write(rt2x00dev, word, value); | ||
228 | } | ||
248 | 229 | ||
249 | mutex_unlock(&rt2x00dev->csr_mutex); | 230 | mutex_unlock(&rt2x00dev->csr_mutex); |
250 | } | 231 | } |