diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2400pci.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2400pci.c | 108 |
1 files changed, 70 insertions, 38 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index 42bd38ac7a1d..78fca1bcc544 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -69,14 +69,14 @@ static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev, | |||
69 | { | 69 | { |
70 | u32 reg; | 70 | u32 reg; |
71 | 71 | ||
72 | mutex_lock(&rt2x00dev->csr_mutex); | ||
73 | |||
72 | /* | 74 | /* |
73 | * Wait until the BBP becomes ready. | 75 | * Wait until the BBP becomes ready. |
74 | */ | 76 | */ |
75 | reg = rt2400pci_bbp_check(rt2x00dev); | 77 | reg = rt2400pci_bbp_check(rt2x00dev); |
76 | if (rt2x00_get_field32(reg, BBPCSR_BUSY)) { | 78 | if (rt2x00_get_field32(reg, BBPCSR_BUSY)) |
77 | ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n"); | 79 | goto exit_fail; |
78 | return; | ||
79 | } | ||
80 | 80 | ||
81 | /* | 81 | /* |
82 | * Write the data into the BBP. | 82 | * Write the data into the BBP. |
@@ -88,6 +88,15 @@ static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev, | |||
88 | rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 1); | 88 | rt2x00_set_field32(®, BBPCSR_WRITE_CONTROL, 1); |
89 | 89 | ||
90 | rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); | 90 | rt2x00pci_register_write(rt2x00dev, BBPCSR, reg); |
91 | |||
92 | mutex_unlock(&rt2x00dev->csr_mutex); | ||
93 | |||
94 | return; | ||
95 | |||
96 | exit_fail: | ||
97 | mutex_unlock(&rt2x00dev->csr_mutex); | ||
98 | |||
99 | ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n"); | ||
91 | } | 100 | } |
92 | 101 | ||
93 | static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev, | 102 | static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev, |
@@ -95,14 +104,14 @@ static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev, | |||
95 | { | 104 | { |
96 | u32 reg; | 105 | u32 reg; |
97 | 106 | ||
107 | mutex_lock(&rt2x00dev->csr_mutex); | ||
108 | |||
98 | /* | 109 | /* |
99 | * Wait until the BBP becomes ready. | 110 | * Wait until the BBP becomes ready. |
100 | */ | 111 | */ |
101 | reg = rt2400pci_bbp_check(rt2x00dev); | 112 | reg = rt2400pci_bbp_check(rt2x00dev); |
102 | if (rt2x00_get_field32(reg, BBPCSR_BUSY)) { | 113 | if (rt2x00_get_field32(reg, BBPCSR_BUSY)) |
103 | ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n"); | 114 | goto exit_fail; |
104 | return; | ||
105 | } | ||
106 | 115 | ||
107 | /* | 116 | /* |
108 | * Write the request into the BBP. | 117 | * Write the request into the BBP. |
@@ -118,13 +127,20 @@ static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev, | |||
118 | * Wait until the BBP becomes ready. | 127 | * Wait until the BBP becomes ready. |
119 | */ | 128 | */ |
120 | reg = rt2400pci_bbp_check(rt2x00dev); | 129 | reg = rt2400pci_bbp_check(rt2x00dev); |
121 | if (rt2x00_get_field32(reg, BBPCSR_BUSY)) { | 130 | if (rt2x00_get_field32(reg, BBPCSR_BUSY)) |
122 | ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n"); | 131 | goto exit_fail; |
123 | *value = 0xff; | ||
124 | return; | ||
125 | } | ||
126 | 132 | ||
127 | *value = rt2x00_get_field32(reg, BBPCSR_VALUE); | 133 | *value = rt2x00_get_field32(reg, BBPCSR_VALUE); |
134 | |||
135 | 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; | ||
128 | } | 144 | } |
129 | 145 | ||
130 | static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev, | 146 | static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev, |
@@ -136,6 +152,8 @@ static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev, | |||
136 | if (!word) | 152 | if (!word) |
137 | return; | 153 | return; |
138 | 154 | ||
155 | mutex_lock(&rt2x00dev->csr_mutex); | ||
156 | |||
139 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 157 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { |
140 | rt2x00pci_register_read(rt2x00dev, RFCSR, ®); | 158 | rt2x00pci_register_read(rt2x00dev, RFCSR, ®); |
141 | if (!rt2x00_get_field32(reg, RFCSR_BUSY)) | 159 | if (!rt2x00_get_field32(reg, RFCSR_BUSY)) |
@@ -143,6 +161,7 @@ static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev, | |||
143 | udelay(REGISTER_BUSY_DELAY); | 161 | udelay(REGISTER_BUSY_DELAY); |
144 | } | 162 | } |
145 | 163 | ||
164 | mutex_unlock(&rt2x00dev->csr_mutex); | ||
146 | ERROR(rt2x00dev, "RFCSR register busy. Write failed.\n"); | 165 | ERROR(rt2x00dev, "RFCSR register busy. Write failed.\n"); |
147 | return; | 166 | return; |
148 | 167 | ||
@@ -155,6 +174,8 @@ rf_write: | |||
155 | 174 | ||
156 | rt2x00pci_register_write(rt2x00dev, RFCSR, reg); | 175 | rt2x00pci_register_write(rt2x00dev, RFCSR, reg); |
157 | rt2x00_rf_write(rt2x00dev, word, value); | 176 | rt2x00_rf_write(rt2x00dev, word, value); |
177 | |||
178 | mutex_unlock(&rt2x00dev->csr_mutex); | ||
158 | } | 179 | } |
159 | 180 | ||
160 | static void rt2400pci_eepromregister_read(struct eeprom_93cx6 *eeprom) | 181 | static void rt2400pci_eepromregister_read(struct eeprom_93cx6 *eeprom) |
@@ -322,7 +343,7 @@ static void rt2400pci_config_intf(struct rt2x00_dev *rt2x00dev, | |||
322 | /* | 343 | /* |
323 | * Enable beacon config | 344 | * Enable beacon config |
324 | */ | 345 | */ |
325 | bcn_preload = PREAMBLE + get_duration(IEEE80211_HEADER, 20); | 346 | bcn_preload = PREAMBLE + GET_DURATION(IEEE80211_HEADER, 20); |
326 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); | 347 | rt2x00pci_register_read(rt2x00dev, BCNCSR1, ®); |
327 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload); | 348 | rt2x00_set_field32(®, BCNCSR1_PRELOAD, bcn_preload); |
328 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); | 349 | rt2x00pci_register_write(rt2x00dev, BCNCSR1, reg); |
@@ -367,25 +388,25 @@ static void rt2400pci_config_erp(struct rt2x00_dev *rt2x00dev, | |||
367 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); | 388 | rt2x00pci_register_read(rt2x00dev, ARCSR2, ®); |
368 | rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); | 389 | rt2x00_set_field32(®, ARCSR2_SIGNAL, 0x00); |
369 | rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); | 390 | rt2x00_set_field32(®, ARCSR2_SERVICE, 0x04); |
370 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 10)); | 391 | rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 10)); |
371 | rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); | 392 | rt2x00pci_register_write(rt2x00dev, ARCSR2, reg); |
372 | 393 | ||
373 | rt2x00pci_register_read(rt2x00dev, ARCSR3, ®); | 394 | rt2x00pci_register_read(rt2x00dev, ARCSR3, ®); |
374 | rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask); | 395 | rt2x00_set_field32(®, ARCSR3_SIGNAL, 0x01 | preamble_mask); |
375 | rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); | 396 | rt2x00_set_field32(®, ARCSR3_SERVICE, 0x04); |
376 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 20)); | 397 | rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 20)); |
377 | rt2x00pci_register_write(rt2x00dev, ARCSR3, reg); | 398 | rt2x00pci_register_write(rt2x00dev, ARCSR3, reg); |
378 | 399 | ||
379 | rt2x00pci_register_read(rt2x00dev, ARCSR4, ®); | 400 | rt2x00pci_register_read(rt2x00dev, ARCSR4, ®); |
380 | rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask); | 401 | rt2x00_set_field32(®, ARCSR4_SIGNAL, 0x02 | preamble_mask); |
381 | rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); | 402 | rt2x00_set_field32(®, ARCSR4_SERVICE, 0x04); |
382 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 55)); | 403 | rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 55)); |
383 | rt2x00pci_register_write(rt2x00dev, ARCSR4, reg); | 404 | rt2x00pci_register_write(rt2x00dev, ARCSR4, reg); |
384 | 405 | ||
385 | rt2x00pci_register_read(rt2x00dev, ARCSR5, ®); | 406 | rt2x00pci_register_read(rt2x00dev, ARCSR5, ®); |
386 | rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask); | 407 | rt2x00_set_field32(®, ARCSR5_SIGNAL, 0x03 | preamble_mask); |
387 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); | 408 | rt2x00_set_field32(®, ARCSR5_SERVICE, 0x84); |
388 | rt2x00_set_field32(®, ARCSR2_LENGTH, get_duration(ACK_SIZE, 110)); | 409 | rt2x00_set_field32(®, ARCSR2_LENGTH, GET_DURATION(ACK_SIZE, 110)); |
389 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); | 410 | rt2x00pci_register_write(rt2x00dev, ARCSR5, reg); |
390 | 411 | ||
391 | rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates); | 412 | rt2x00pci_register_write(rt2x00dev, ARCSR1, erp->basic_rates); |
@@ -626,36 +647,47 @@ static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev) | |||
626 | /* | 647 | /* |
627 | * Initialization functions. | 648 | * Initialization functions. |
628 | */ | 649 | */ |
629 | static void rt2400pci_init_rxentry(struct rt2x00_dev *rt2x00dev, | 650 | static bool rt2400pci_get_entry_state(struct queue_entry *entry) |
630 | struct queue_entry *entry) | ||
631 | { | 651 | { |
632 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 652 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
633 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
634 | u32 word; | 653 | u32 word; |
635 | 654 | ||
636 | rt2x00_desc_read(entry_priv->desc, 2, &word); | 655 | if (entry->queue->qid == QID_RX) { |
637 | rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->skb->len); | 656 | rt2x00_desc_read(entry_priv->desc, 0, &word); |
638 | rt2x00_desc_write(entry_priv->desc, 2, word); | ||
639 | 657 | ||
640 | rt2x00_desc_read(entry_priv->desc, 1, &word); | 658 | return rt2x00_get_field32(word, RXD_W0_OWNER_NIC); |
641 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); | 659 | } else { |
642 | rt2x00_desc_write(entry_priv->desc, 1, word); | 660 | rt2x00_desc_read(entry_priv->desc, 0, &word); |
643 | 661 | ||
644 | rt2x00_desc_read(entry_priv->desc, 0, &word); | 662 | return (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || |
645 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); | 663 | rt2x00_get_field32(word, TXD_W0_VALID)); |
646 | rt2x00_desc_write(entry_priv->desc, 0, word); | 664 | } |
647 | } | 665 | } |
648 | 666 | ||
649 | static void rt2400pci_init_txentry(struct rt2x00_dev *rt2x00dev, | 667 | static void rt2400pci_clear_entry(struct queue_entry *entry) |
650 | struct queue_entry *entry) | ||
651 | { | 668 | { |
652 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 669 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
670 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
653 | u32 word; | 671 | u32 word; |
654 | 672 | ||
655 | rt2x00_desc_read(entry_priv->desc, 0, &word); | 673 | if (entry->queue->qid == QID_RX) { |
656 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); | 674 | rt2x00_desc_read(entry_priv->desc, 2, &word); |
657 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); | 675 | rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->skb->len); |
658 | rt2x00_desc_write(entry_priv->desc, 0, word); | 676 | rt2x00_desc_write(entry_priv->desc, 2, word); |
677 | |||
678 | rt2x00_desc_read(entry_priv->desc, 1, &word); | ||
679 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); | ||
680 | rt2x00_desc_write(entry_priv->desc, 1, word); | ||
681 | |||
682 | rt2x00_desc_read(entry_priv->desc, 0, &word); | ||
683 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); | ||
684 | rt2x00_desc_write(entry_priv->desc, 0, word); | ||
685 | } else { | ||
686 | rt2x00_desc_read(entry_priv->desc, 0, &word); | ||
687 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); | ||
688 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); | ||
689 | rt2x00_desc_write(entry_priv->desc, 0, word); | ||
690 | } | ||
659 | } | 691 | } |
660 | 692 | ||
661 | static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev) | 693 | static int rt2400pci_init_queues(struct rt2x00_dev *rt2x00dev) |
@@ -1570,8 +1602,8 @@ static const struct rt2x00lib_ops rt2400pci_rt2x00_ops = { | |||
1570 | .probe_hw = rt2400pci_probe_hw, | 1602 | .probe_hw = rt2400pci_probe_hw, |
1571 | .initialize = rt2x00pci_initialize, | 1603 | .initialize = rt2x00pci_initialize, |
1572 | .uninitialize = rt2x00pci_uninitialize, | 1604 | .uninitialize = rt2x00pci_uninitialize, |
1573 | .init_rxentry = rt2400pci_init_rxentry, | 1605 | .get_entry_state = rt2400pci_get_entry_state, |
1574 | .init_txentry = rt2400pci_init_txentry, | 1606 | .clear_entry = rt2400pci_clear_entry, |
1575 | .set_device_state = rt2400pci_set_device_state, | 1607 | .set_device_state = rt2400pci_set_device_state, |
1576 | .rfkill_poll = rt2400pci_rfkill_poll, | 1608 | .rfkill_poll = rt2400pci_rfkill_poll, |
1577 | .link_stats = rt2400pci_link_stats, | 1609 | .link_stats = rt2400pci_link_stats, |