diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt73usb.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 270 |
1 files changed, 116 insertions, 154 deletions
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 6a62d6bb96fe..d383735ab8f2 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -74,10 +74,10 @@ static inline void rt73usb_register_multiread(struct rt2x00_dev *rt2x00dev, | |||
74 | const unsigned int offset, | 74 | const unsigned int offset, |
75 | void *value, const u32 length) | 75 | void *value, const u32 length) |
76 | { | 76 | { |
77 | int timeout = REGISTER_TIMEOUT * (length / sizeof(u32)); | ||
78 | rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ, | 77 | rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ, |
79 | USB_VENDOR_REQUEST_IN, offset, | 78 | USB_VENDOR_REQUEST_IN, offset, |
80 | value, length, timeout); | 79 | value, length, |
80 | REGISTER_TIMEOUT32(length)); | ||
81 | } | 81 | } |
82 | 82 | ||
83 | static inline void rt73usb_register_write(struct rt2x00_dev *rt2x00dev, | 83 | static inline void rt73usb_register_write(struct rt2x00_dev *rt2x00dev, |
@@ -102,10 +102,10 @@ static inline void rt73usb_register_multiwrite(struct rt2x00_dev *rt2x00dev, | |||
102 | const unsigned int offset, | 102 | const unsigned int offset, |
103 | void *value, const u32 length) | 103 | void *value, const u32 length) |
104 | { | 104 | { |
105 | int timeout = REGISTER_TIMEOUT * (length / sizeof(u32)); | ||
106 | rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_WRITE, | 105 | rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_WRITE, |
107 | USB_VENDOR_REQUEST_OUT, offset, | 106 | USB_VENDOR_REQUEST_OUT, offset, |
108 | value, length, timeout); | 107 | value, length, |
108 | REGISTER_TIMEOUT32(length)); | ||
109 | } | 109 | } |
110 | 110 | ||
111 | static u32 rt73usb_bbp_check(struct rt2x00_dev *rt2x00dev) | 111 | static u32 rt73usb_bbp_check(struct rt2x00_dev *rt2x00dev) |
@@ -341,6 +341,17 @@ static int rt73usb_blink_set(struct led_classdev *led_cdev, | |||
341 | 341 | ||
342 | return 0; | 342 | return 0; |
343 | } | 343 | } |
344 | |||
345 | static void rt73usb_init_led(struct rt2x00_dev *rt2x00dev, | ||
346 | struct rt2x00_led *led, | ||
347 | enum led_type type) | ||
348 | { | ||
349 | led->rt2x00dev = rt2x00dev; | ||
350 | led->type = type; | ||
351 | led->led_dev.brightness_set = rt73usb_brightness_set; | ||
352 | led->led_dev.blink_set = rt73usb_blink_set; | ||
353 | led->flags = LED_INITIALIZED; | ||
354 | } | ||
344 | #endif /* CONFIG_RT73USB_LEDS */ | 355 | #endif /* CONFIG_RT73USB_LEDS */ |
345 | 356 | ||
346 | /* | 357 | /* |
@@ -882,7 +893,6 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data, | |||
882 | const char *ptr = data; | 893 | const char *ptr = data; |
883 | char *cache; | 894 | char *cache; |
884 | int buflen; | 895 | int buflen; |
885 | int timeout; | ||
886 | 896 | ||
887 | /* | 897 | /* |
888 | * Wait for stable hardware. | 898 | * Wait for stable hardware. |
@@ -913,14 +923,14 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data, | |||
913 | 923 | ||
914 | for (i = 0; i < len; i += CSR_CACHE_SIZE_FIRMWARE) { | 924 | for (i = 0; i < len; i += CSR_CACHE_SIZE_FIRMWARE) { |
915 | buflen = min_t(int, len - i, CSR_CACHE_SIZE_FIRMWARE); | 925 | buflen = min_t(int, len - i, CSR_CACHE_SIZE_FIRMWARE); |
916 | timeout = REGISTER_TIMEOUT * (buflen / sizeof(u32)); | ||
917 | 926 | ||
918 | memcpy(cache, ptr, buflen); | 927 | memcpy(cache, ptr, buflen); |
919 | 928 | ||
920 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, | 929 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, |
921 | USB_VENDOR_REQUEST_OUT, | 930 | USB_VENDOR_REQUEST_OUT, |
922 | FIRMWARE_IMAGE_BASE + i, 0, | 931 | FIRMWARE_IMAGE_BASE + i, 0, |
923 | cache, buflen, timeout); | 932 | cache, buflen, |
933 | REGISTER_TIMEOUT32(buflen)); | ||
924 | 934 | ||
925 | ptr += buflen; | 935 | ptr += buflen; |
926 | } | 936 | } |
@@ -1100,25 +1110,32 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1100 | return 0; | 1110 | return 0; |
1101 | } | 1111 | } |
1102 | 1112 | ||
1103 | static int rt73usb_init_bbp(struct rt2x00_dev *rt2x00dev) | 1113 | static int rt73usb_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) |
1104 | { | 1114 | { |
1105 | unsigned int i; | 1115 | unsigned int i; |
1106 | u16 eeprom; | ||
1107 | u8 reg_id; | ||
1108 | u8 value; | 1116 | u8 value; |
1109 | 1117 | ||
1110 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 1118 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { |
1111 | rt73usb_bbp_read(rt2x00dev, 0, &value); | 1119 | rt73usb_bbp_read(rt2x00dev, 0, &value); |
1112 | if ((value != 0xff) && (value != 0x00)) | 1120 | if ((value != 0xff) && (value != 0x00)) |
1113 | goto continue_csr_init; | 1121 | return 0; |
1114 | NOTICE(rt2x00dev, "Waiting for BBP register.\n"); | ||
1115 | udelay(REGISTER_BUSY_DELAY); | 1122 | udelay(REGISTER_BUSY_DELAY); |
1116 | } | 1123 | } |
1117 | 1124 | ||
1118 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); | 1125 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); |
1119 | return -EACCES; | 1126 | return -EACCES; |
1127 | } | ||
1128 | |||
1129 | static int rt73usb_init_bbp(struct rt2x00_dev *rt2x00dev) | ||
1130 | { | ||
1131 | unsigned int i; | ||
1132 | u16 eeprom; | ||
1133 | u8 reg_id; | ||
1134 | u8 value; | ||
1135 | |||
1136 | if (unlikely(rt73usb_wait_bbp_ready(rt2x00dev))) | ||
1137 | return -EACCES; | ||
1120 | 1138 | ||
1121 | continue_csr_init: | ||
1122 | rt73usb_bbp_write(rt2x00dev, 3, 0x80); | 1139 | rt73usb_bbp_write(rt2x00dev, 3, 0x80); |
1123 | rt73usb_bbp_write(rt2x00dev, 15, 0x30); | 1140 | rt73usb_bbp_write(rt2x00dev, 15, 0x30); |
1124 | rt73usb_bbp_write(rt2x00dev, 21, 0xc8); | 1141 | rt73usb_bbp_write(rt2x00dev, 21, 0xc8); |
@@ -1168,7 +1185,8 @@ static void rt73usb_toggle_rx(struct rt2x00_dev *rt2x00dev, | |||
1168 | 1185 | ||
1169 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); | 1186 | rt73usb_register_read(rt2x00dev, TXRX_CSR0, ®); |
1170 | rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, | 1187 | rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, |
1171 | state == STATE_RADIO_RX_OFF); | 1188 | (state == STATE_RADIO_RX_OFF) || |
1189 | (state == STATE_RADIO_RX_OFF_LINK)); | ||
1172 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); | 1190 | rt73usb_register_write(rt2x00dev, TXRX_CSR0, reg); |
1173 | } | 1191 | } |
1174 | 1192 | ||
@@ -1177,11 +1195,9 @@ static int rt73usb_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1177 | /* | 1195 | /* |
1178 | * Initialize all registers. | 1196 | * Initialize all registers. |
1179 | */ | 1197 | */ |
1180 | if (rt73usb_init_registers(rt2x00dev) || | 1198 | if (unlikely(rt73usb_init_registers(rt2x00dev) || |
1181 | rt73usb_init_bbp(rt2x00dev)) { | 1199 | rt73usb_init_bbp(rt2x00dev))) |
1182 | ERROR(rt2x00dev, "Register initialization failed.\n"); | ||
1183 | return -EIO; | 1200 | return -EIO; |
1184 | } | ||
1185 | 1201 | ||
1186 | return 0; | 1202 | return 0; |
1187 | } | 1203 | } |
@@ -1203,7 +1219,6 @@ static int rt73usb_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) | |||
1203 | u32 reg; | 1219 | u32 reg; |
1204 | unsigned int i; | 1220 | unsigned int i; |
1205 | char put_to_sleep; | 1221 | char put_to_sleep; |
1206 | char current_state; | ||
1207 | 1222 | ||
1208 | put_to_sleep = (state != STATE_AWAKE); | 1223 | put_to_sleep = (state != STATE_AWAKE); |
1209 | 1224 | ||
@@ -1219,16 +1234,12 @@ static int rt73usb_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) | |||
1219 | */ | 1234 | */ |
1220 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 1235 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { |
1221 | rt73usb_register_read(rt2x00dev, MAC_CSR12, ®); | 1236 | rt73usb_register_read(rt2x00dev, MAC_CSR12, ®); |
1222 | current_state = | 1237 | state = rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE); |
1223 | rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE); | 1238 | if (state == !put_to_sleep) |
1224 | if (current_state == !put_to_sleep) | ||
1225 | return 0; | 1239 | return 0; |
1226 | msleep(10); | 1240 | msleep(10); |
1227 | } | 1241 | } |
1228 | 1242 | ||
1229 | NOTICE(rt2x00dev, "Device failed to enter state %d, " | ||
1230 | "current device state %d.\n", !put_to_sleep, current_state); | ||
1231 | |||
1232 | return -EBUSY; | 1243 | return -EBUSY; |
1233 | } | 1244 | } |
1234 | 1245 | ||
@@ -1246,11 +1257,13 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1246 | break; | 1257 | break; |
1247 | case STATE_RADIO_RX_ON: | 1258 | case STATE_RADIO_RX_ON: |
1248 | case STATE_RADIO_RX_ON_LINK: | 1259 | case STATE_RADIO_RX_ON_LINK: |
1249 | rt73usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); | ||
1250 | break; | ||
1251 | case STATE_RADIO_RX_OFF: | 1260 | case STATE_RADIO_RX_OFF: |
1252 | case STATE_RADIO_RX_OFF_LINK: | 1261 | case STATE_RADIO_RX_OFF_LINK: |
1253 | rt73usb_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); | 1262 | rt73usb_toggle_rx(rt2x00dev, state); |
1263 | break; | ||
1264 | case STATE_RADIO_IRQ_ON: | ||
1265 | case STATE_RADIO_IRQ_OFF: | ||
1266 | /* No support, but no error either */ | ||
1254 | break; | 1267 | break; |
1255 | case STATE_DEEP_SLEEP: | 1268 | case STATE_DEEP_SLEEP: |
1256 | case STATE_SLEEP: | 1269 | case STATE_SLEEP: |
@@ -1263,6 +1276,10 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1263 | break; | 1276 | break; |
1264 | } | 1277 | } |
1265 | 1278 | ||
1279 | if (unlikely(retval)) | ||
1280 | ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", | ||
1281 | state, retval); | ||
1282 | |||
1266 | return retval; | 1283 | return retval; |
1267 | } | 1284 | } |
1268 | 1285 | ||
@@ -1271,8 +1288,7 @@ static int rt73usb_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1271 | */ | 1288 | */ |
1272 | static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1289 | static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
1273 | struct sk_buff *skb, | 1290 | struct sk_buff *skb, |
1274 | struct txentry_desc *txdesc, | 1291 | struct txentry_desc *txdesc) |
1275 | struct ieee80211_tx_control *control) | ||
1276 | { | 1292 | { |
1277 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 1293 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1278 | __le32 *txd = skbdesc->desc; | 1294 | __le32 *txd = skbdesc->desc; |
@@ -1317,16 +1333,59 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1317 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); | 1333 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); |
1318 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); | 1334 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1319 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1335 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1320 | !!(control->flags & | 1336 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); |
1321 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | ||
1322 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); | 1337 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); |
1323 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); | 1338 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, |
1339 | skb->len - skbdesc->desc_len); | ||
1324 | rt2x00_set_field32(&word, TXD_W0_BURST2, | 1340 | rt2x00_set_field32(&word, TXD_W0_BURST2, |
1325 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); | 1341 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); |
1326 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); | 1342 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); |
1327 | rt2x00_desc_write(txd, 0, word); | 1343 | rt2x00_desc_write(txd, 0, word); |
1328 | } | 1344 | } |
1329 | 1345 | ||
1346 | /* | ||
1347 | * TX data initialization | ||
1348 | */ | ||
1349 | static void rt73usb_write_beacon(struct queue_entry *entry) | ||
1350 | { | ||
1351 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
1352 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
1353 | unsigned int beacon_base; | ||
1354 | u32 reg; | ||
1355 | |||
1356 | /* | ||
1357 | * Add the descriptor in front of the skb. | ||
1358 | */ | ||
1359 | skb_push(entry->skb, entry->queue->desc_size); | ||
1360 | memcpy(entry->skb->data, skbdesc->desc, skbdesc->desc_len); | ||
1361 | skbdesc->desc = entry->skb->data; | ||
1362 | |||
1363 | /* | ||
1364 | * Disable beaconing while we are reloading the beacon data, | ||
1365 | * otherwise we might be sending out invalid data. | ||
1366 | */ | ||
1367 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
1368 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
1369 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
1370 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
1371 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
1372 | |||
1373 | /* | ||
1374 | * Write entire beacon with descriptor to register. | ||
1375 | */ | ||
1376 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); | ||
1377 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, | ||
1378 | USB_VENDOR_REQUEST_OUT, beacon_base, 0, | ||
1379 | entry->skb->data, entry->skb->len, | ||
1380 | REGISTER_TIMEOUT32(entry->skb->len)); | ||
1381 | |||
1382 | /* | ||
1383 | * Clean up the beacon skb. | ||
1384 | */ | ||
1385 | dev_kfree_skb(entry->skb); | ||
1386 | entry->skb = NULL; | ||
1387 | } | ||
1388 | |||
1330 | static int rt73usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, | 1389 | static int rt73usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, |
1331 | struct sk_buff *skb) | 1390 | struct sk_buff *skb) |
1332 | { | 1391 | { |
@@ -1342,16 +1401,15 @@ static int rt73usb_get_tx_data_len(struct rt2x00_dev *rt2x00dev, | |||
1342 | return length; | 1401 | return length; |
1343 | } | 1402 | } |
1344 | 1403 | ||
1345 | /* | ||
1346 | * TX data initialization | ||
1347 | */ | ||
1348 | static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1404 | static void rt73usb_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1349 | const unsigned int queue) | 1405 | const enum data_queue_qid queue) |
1350 | { | 1406 | { |
1351 | u32 reg; | 1407 | u32 reg; |
1352 | 1408 | ||
1353 | if (queue != RT2X00_BCN_QUEUE_BEACON) | 1409 | if (queue != QID_BEACON) { |
1410 | rt2x00usb_kick_tx_queue(rt2x00dev, queue); | ||
1354 | return; | 1411 | return; |
1412 | } | ||
1355 | 1413 | ||
1356 | /* | 1414 | /* |
1357 | * For Wi-Fi faily generated beacons between participating stations. | 1415 | * For Wi-Fi faily generated beacons between participating stations. |
@@ -1421,25 +1479,22 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry, | |||
1421 | { | 1479 | { |
1422 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | 1480 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1423 | __le32 *rxd = (__le32 *)entry->skb->data; | 1481 | __le32 *rxd = (__le32 *)entry->skb->data; |
1424 | unsigned int offset = entry->queue->desc_size + 2; | ||
1425 | u32 word0; | 1482 | u32 word0; |
1426 | u32 word1; | 1483 | u32 word1; |
1427 | 1484 | ||
1428 | /* | 1485 | /* |
1429 | * Copy descriptor to the available headroom inside the skbuffer. | 1486 | * Copy descriptor to the skbdesc->desc buffer, making it safe from moving of |
1487 | * frame data in rt2x00usb. | ||
1430 | */ | 1488 | */ |
1431 | skb_push(entry->skb, offset); | 1489 | memcpy(skbdesc->desc, rxd, skbdesc->desc_len); |
1432 | memcpy(entry->skb->data, rxd, entry->queue->desc_size); | 1490 | rxd = (__le32 *)skbdesc->desc; |
1433 | rxd = (__le32 *)entry->skb->data; | ||
1434 | 1491 | ||
1435 | /* | 1492 | /* |
1436 | * The descriptor is now aligned to 4 bytes and thus it is | 1493 | * It is now safe to read the descriptor on all architectures. |
1437 | * now safe to read it on all architectures. | ||
1438 | */ | 1494 | */ |
1439 | rt2x00_desc_read(rxd, 0, &word0); | 1495 | rt2x00_desc_read(rxd, 0, &word0); |
1440 | rt2x00_desc_read(rxd, 1, &word1); | 1496 | rt2x00_desc_read(rxd, 1, &word1); |
1441 | 1497 | ||
1442 | rxdesc->flags = 0; | ||
1443 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1498 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1444 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1499 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1445 | 1500 | ||
@@ -1453,25 +1508,16 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry, | |||
1453 | rxdesc->rssi = rt73usb_agc_to_rssi(entry->queue->rt2x00dev, word1); | 1508 | rxdesc->rssi = rt73usb_agc_to_rssi(entry->queue->rt2x00dev, word1); |
1454 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1509 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); |
1455 | 1510 | ||
1456 | rxdesc->dev_flags = 0; | ||
1457 | if (rt2x00_get_field32(word0, RXD_W0_OFDM)) | 1511 | if (rt2x00_get_field32(word0, RXD_W0_OFDM)) |
1458 | rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP; | 1512 | rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP; |
1459 | if (rt2x00_get_field32(word0, RXD_W0_MY_BSS)) | 1513 | if (rt2x00_get_field32(word0, RXD_W0_MY_BSS)) |
1460 | rxdesc->dev_flags |= RXDONE_MY_BSS; | 1514 | rxdesc->dev_flags |= RXDONE_MY_BSS; |
1461 | 1515 | ||
1462 | /* | 1516 | /* |
1463 | * Adjust the skb memory window to the frame boundaries. | 1517 | * Set skb pointers, and update frame information. |
1464 | */ | 1518 | */ |
1465 | skb_pull(entry->skb, offset + entry->queue->desc_size); | 1519 | skb_pull(entry->skb, entry->queue->desc_size); |
1466 | skb_trim(entry->skb, rxdesc->size); | 1520 | skb_trim(entry->skb, rxdesc->size); |
1467 | |||
1468 | /* | ||
1469 | * Set descriptor and data pointer. | ||
1470 | */ | ||
1471 | skbdesc->data = entry->skb->data; | ||
1472 | skbdesc->data_len = rxdesc->size; | ||
1473 | skbdesc->desc = rxd; | ||
1474 | skbdesc->desc_len = entry->queue->desc_size; | ||
1475 | } | 1521 | } |
1476 | 1522 | ||
1477 | /* | 1523 | /* |
@@ -1644,31 +1690,11 @@ static int rt73usb_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1644 | #ifdef CONFIG_RT73USB_LEDS | 1690 | #ifdef CONFIG_RT73USB_LEDS |
1645 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); | 1691 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); |
1646 | 1692 | ||
1647 | rt2x00dev->led_radio.rt2x00dev = rt2x00dev; | 1693 | rt73usb_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); |
1648 | rt2x00dev->led_radio.type = LED_TYPE_RADIO; | 1694 | rt73usb_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); |
1649 | rt2x00dev->led_radio.led_dev.brightness_set = | 1695 | if (value == LED_MODE_SIGNAL_STRENGTH) |
1650 | rt73usb_brightness_set; | 1696 | rt73usb_init_led(rt2x00dev, &rt2x00dev->led_qual, |
1651 | rt2x00dev->led_radio.led_dev.blink_set = | 1697 | LED_TYPE_QUALITY); |
1652 | rt73usb_blink_set; | ||
1653 | rt2x00dev->led_radio.flags = LED_INITIALIZED; | ||
1654 | |||
1655 | rt2x00dev->led_assoc.rt2x00dev = rt2x00dev; | ||
1656 | rt2x00dev->led_assoc.type = LED_TYPE_ASSOC; | ||
1657 | rt2x00dev->led_assoc.led_dev.brightness_set = | ||
1658 | rt73usb_brightness_set; | ||
1659 | rt2x00dev->led_assoc.led_dev.blink_set = | ||
1660 | rt73usb_blink_set; | ||
1661 | rt2x00dev->led_assoc.flags = LED_INITIALIZED; | ||
1662 | |||
1663 | if (value == LED_MODE_SIGNAL_STRENGTH) { | ||
1664 | rt2x00dev->led_qual.rt2x00dev = rt2x00dev; | ||
1665 | rt2x00dev->led_qual.type = LED_TYPE_QUALITY; | ||
1666 | rt2x00dev->led_qual.led_dev.brightness_set = | ||
1667 | rt73usb_brightness_set; | ||
1668 | rt2x00dev->led_qual.led_dev.blink_set = | ||
1669 | rt73usb_blink_set; | ||
1670 | rt2x00dev->led_qual.flags = LED_INITIALIZED; | ||
1671 | } | ||
1672 | 1698 | ||
1673 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value); | 1699 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value); |
1674 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0, | 1700 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0, |
@@ -1846,13 +1872,11 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1846 | */ | 1872 | */ |
1847 | rt2x00dev->hw->flags = | 1873 | rt2x00dev->hw->flags = |
1848 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | | 1874 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | |
1849 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; | 1875 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
1876 | IEEE80211_HW_SIGNAL_DBM; | ||
1850 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; | 1877 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; |
1851 | rt2x00dev->hw->max_signal = MAX_SIGNAL; | ||
1852 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; | ||
1853 | rt2x00dev->hw->queues = 4; | ||
1854 | 1878 | ||
1855 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); | 1879 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); |
1856 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | 1880 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, |
1857 | rt2x00_eeprom_addr(rt2x00dev, | 1881 | rt2x00_eeprom_addr(rt2x00dev, |
1858 | EEPROM_MAC_ADDR_0)); | 1882 | EEPROM_MAC_ADDR_0)); |
@@ -1974,69 +1998,6 @@ static u64 rt73usb_get_tsf(struct ieee80211_hw *hw) | |||
1974 | #define rt73usb_get_tsf NULL | 1998 | #define rt73usb_get_tsf NULL |
1975 | #endif | 1999 | #endif |
1976 | 2000 | ||
1977 | static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
1978 | struct ieee80211_tx_control *control) | ||
1979 | { | ||
1980 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
1981 | struct rt2x00_intf *intf = vif_to_intf(control->vif); | ||
1982 | struct skb_frame_desc *skbdesc; | ||
1983 | unsigned int beacon_base; | ||
1984 | unsigned int timeout; | ||
1985 | u32 reg; | ||
1986 | |||
1987 | if (unlikely(!intf->beacon)) | ||
1988 | return -ENOBUFS; | ||
1989 | |||
1990 | /* | ||
1991 | * Add the descriptor in front of the skb. | ||
1992 | */ | ||
1993 | skb_push(skb, intf->beacon->queue->desc_size); | ||
1994 | memset(skb->data, 0, intf->beacon->queue->desc_size); | ||
1995 | |||
1996 | /* | ||
1997 | * Fill in skb descriptor | ||
1998 | */ | ||
1999 | skbdesc = get_skb_frame_desc(skb); | ||
2000 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
2001 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; | ||
2002 | skbdesc->data = skb->data + intf->beacon->queue->desc_size; | ||
2003 | skbdesc->data_len = skb->len - intf->beacon->queue->desc_size; | ||
2004 | skbdesc->desc = skb->data; | ||
2005 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
2006 | skbdesc->entry = intf->beacon; | ||
2007 | |||
2008 | /* | ||
2009 | * Disable beaconing while we are reloading the beacon data, | ||
2010 | * otherwise we might be sending out invalid data. | ||
2011 | */ | ||
2012 | rt73usb_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
2013 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
2014 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
2015 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
2016 | rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
2017 | |||
2018 | /* | ||
2019 | * mac80211 doesn't provide the control->queue variable | ||
2020 | * for beacons. Set our own queue identification so | ||
2021 | * it can be used during descriptor initialization. | ||
2022 | */ | ||
2023 | control->queue = RT2X00_BCN_QUEUE_BEACON; | ||
2024 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | ||
2025 | |||
2026 | /* | ||
2027 | * Write entire beacon with descriptor to register, | ||
2028 | * and kick the beacon generator. | ||
2029 | */ | ||
2030 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
2031 | timeout = REGISTER_TIMEOUT * (skb->len / sizeof(u32)); | ||
2032 | rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE, | ||
2033 | USB_VENDOR_REQUEST_OUT, beacon_base, 0, | ||
2034 | skb->data, skb->len, timeout); | ||
2035 | rt73usb_kick_tx_queue(rt2x00dev, control->queue); | ||
2036 | |||
2037 | return 0; | ||
2038 | } | ||
2039 | |||
2040 | static const struct ieee80211_ops rt73usb_mac80211_ops = { | 2001 | static const struct ieee80211_ops rt73usb_mac80211_ops = { |
2041 | .tx = rt2x00mac_tx, | 2002 | .tx = rt2x00mac_tx, |
2042 | .start = rt2x00mac_start, | 2003 | .start = rt2x00mac_start, |
@@ -2052,7 +2013,6 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = { | |||
2052 | .conf_tx = rt2x00mac_conf_tx, | 2013 | .conf_tx = rt2x00mac_conf_tx, |
2053 | .get_tx_stats = rt2x00mac_get_tx_stats, | 2014 | .get_tx_stats = rt2x00mac_get_tx_stats, |
2054 | .get_tsf = rt73usb_get_tsf, | 2015 | .get_tsf = rt73usb_get_tsf, |
2055 | .beacon_update = rt73usb_beacon_update, | ||
2056 | }; | 2016 | }; |
2057 | 2017 | ||
2058 | static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { | 2018 | static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { |
@@ -2070,6 +2030,7 @@ static const struct rt2x00lib_ops rt73usb_rt2x00_ops = { | |||
2070 | .link_tuner = rt73usb_link_tuner, | 2030 | .link_tuner = rt73usb_link_tuner, |
2071 | .write_tx_desc = rt73usb_write_tx_desc, | 2031 | .write_tx_desc = rt73usb_write_tx_desc, |
2072 | .write_tx_data = rt2x00usb_write_tx_data, | 2032 | .write_tx_data = rt2x00usb_write_tx_data, |
2033 | .write_beacon = rt73usb_write_beacon, | ||
2073 | .get_tx_data_len = rt73usb_get_tx_data_len, | 2034 | .get_tx_data_len = rt73usb_get_tx_data_len, |
2074 | .kick_tx_queue = rt73usb_kick_tx_queue, | 2035 | .kick_tx_queue = rt73usb_kick_tx_queue, |
2075 | .fill_rxdone = rt73usb_fill_rxdone, | 2036 | .fill_rxdone = rt73usb_fill_rxdone, |
@@ -2083,21 +2044,21 @@ static const struct data_queue_desc rt73usb_queue_rx = { | |||
2083 | .entry_num = RX_ENTRIES, | 2044 | .entry_num = RX_ENTRIES, |
2084 | .data_size = DATA_FRAME_SIZE, | 2045 | .data_size = DATA_FRAME_SIZE, |
2085 | .desc_size = RXD_DESC_SIZE, | 2046 | .desc_size = RXD_DESC_SIZE, |
2086 | .priv_size = sizeof(struct queue_entry_priv_usb_rx), | 2047 | .priv_size = sizeof(struct queue_entry_priv_usb), |
2087 | }; | 2048 | }; |
2088 | 2049 | ||
2089 | static const struct data_queue_desc rt73usb_queue_tx = { | 2050 | static const struct data_queue_desc rt73usb_queue_tx = { |
2090 | .entry_num = TX_ENTRIES, | 2051 | .entry_num = TX_ENTRIES, |
2091 | .data_size = DATA_FRAME_SIZE, | 2052 | .data_size = DATA_FRAME_SIZE, |
2092 | .desc_size = TXD_DESC_SIZE, | 2053 | .desc_size = TXD_DESC_SIZE, |
2093 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | 2054 | .priv_size = sizeof(struct queue_entry_priv_usb), |
2094 | }; | 2055 | }; |
2095 | 2056 | ||
2096 | static const struct data_queue_desc rt73usb_queue_bcn = { | 2057 | static const struct data_queue_desc rt73usb_queue_bcn = { |
2097 | .entry_num = 4 * BEACON_ENTRIES, | 2058 | .entry_num = 4 * BEACON_ENTRIES, |
2098 | .data_size = MGMT_FRAME_SIZE, | 2059 | .data_size = MGMT_FRAME_SIZE, |
2099 | .desc_size = TXINFO_SIZE, | 2060 | .desc_size = TXINFO_SIZE, |
2100 | .priv_size = sizeof(struct queue_entry_priv_usb_tx), | 2061 | .priv_size = sizeof(struct queue_entry_priv_usb), |
2101 | }; | 2062 | }; |
2102 | 2063 | ||
2103 | static const struct rt2x00_ops rt73usb_ops = { | 2064 | static const struct rt2x00_ops rt73usb_ops = { |
@@ -2106,6 +2067,7 @@ static const struct rt2x00_ops rt73usb_ops = { | |||
2106 | .max_ap_intf = 4, | 2067 | .max_ap_intf = 4, |
2107 | .eeprom_size = EEPROM_SIZE, | 2068 | .eeprom_size = EEPROM_SIZE, |
2108 | .rf_size = RF_SIZE, | 2069 | .rf_size = RF_SIZE, |
2070 | .tx_queues = NUM_TX_QUEUES, | ||
2109 | .rx = &rt73usb_queue_rx, | 2071 | .rx = &rt73usb_queue_rx, |
2110 | .tx = &rt73usb_queue_tx, | 2072 | .tx = &rt73usb_queue_tx, |
2111 | .bcn = &rt73usb_queue_bcn, | 2073 | .bcn = &rt73usb_queue_bcn, |