diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00')
26 files changed, 485 insertions, 422 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index ad2c98af7e9d..1eb882e15fb4 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -1076,9 +1076,6 @@ static void rt2400pci_write_beacon(struct queue_entry *entry, | |||
1076 | struct txentry_desc *txdesc) | 1076 | struct txentry_desc *txdesc) |
1077 | { | 1077 | { |
1078 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 1078 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
1079 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | ||
1080 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
1081 | u32 word; | ||
1082 | u32 reg; | 1079 | u32 reg; |
1083 | 1080 | ||
1084 | /* | 1081 | /* |
@@ -1091,9 +1088,15 @@ static void rt2400pci_write_beacon(struct queue_entry *entry, | |||
1091 | 1088 | ||
1092 | rt2x00queue_map_txskb(rt2x00dev, entry->skb); | 1089 | rt2x00queue_map_txskb(rt2x00dev, entry->skb); |
1093 | 1090 | ||
1094 | rt2x00_desc_read(entry_priv->desc, 1, &word); | 1091 | /* |
1095 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); | 1092 | * Write the TX descriptor for the beacon. |
1096 | rt2x00_desc_write(entry_priv->desc, 1, word); | 1093 | */ |
1094 | rt2400pci_write_tx_desc(rt2x00dev, entry->skb, txdesc); | ||
1095 | |||
1096 | /* | ||
1097 | * Dump beacon to userspace through debugfs. | ||
1098 | */ | ||
1099 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); | ||
1097 | 1100 | ||
1098 | /* | 1101 | /* |
1099 | * Enable beaconing again. | 1102 | * Enable beaconing again. |
@@ -1226,7 +1229,7 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, | |||
1226 | } | 1229 | } |
1227 | txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); | 1230 | txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); |
1228 | 1231 | ||
1229 | rt2x00lib_txdone(entry, &txdesc); | 1232 | rt2x00pci_txdone(entry, &txdesc); |
1230 | } | 1233 | } |
1231 | } | 1234 | } |
1232 | 1235 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 41da3d218c65..a29cb212f89a 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -1233,9 +1233,6 @@ static void rt2500pci_write_beacon(struct queue_entry *entry, | |||
1233 | struct txentry_desc *txdesc) | 1233 | struct txentry_desc *txdesc) |
1234 | { | 1234 | { |
1235 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 1235 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
1236 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | ||
1237 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
1238 | u32 word; | ||
1239 | u32 reg; | 1236 | u32 reg; |
1240 | 1237 | ||
1241 | /* | 1238 | /* |
@@ -1248,9 +1245,15 @@ static void rt2500pci_write_beacon(struct queue_entry *entry, | |||
1248 | 1245 | ||
1249 | rt2x00queue_map_txskb(rt2x00dev, entry->skb); | 1246 | rt2x00queue_map_txskb(rt2x00dev, entry->skb); |
1250 | 1247 | ||
1251 | rt2x00_desc_read(entry_priv->desc, 1, &word); | 1248 | /* |
1252 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); | 1249 | * Write the TX descriptor for the beacon. |
1253 | rt2x00_desc_write(entry_priv->desc, 1, word); | 1250 | */ |
1251 | rt2500pci_write_tx_desc(rt2x00dev, entry->skb, txdesc); | ||
1252 | |||
1253 | /* | ||
1254 | * Dump beacon to userspace through debugfs. | ||
1255 | */ | ||
1256 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); | ||
1254 | 1257 | ||
1255 | /* | 1258 | /* |
1256 | * Enable beaconing again. | 1259 | * Enable beaconing again. |
@@ -1362,7 +1365,7 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, | |||
1362 | } | 1365 | } |
1363 | txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); | 1366 | txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); |
1364 | 1367 | ||
1365 | rt2x00lib_txdone(entry, &txdesc); | 1368 | rt2x00pci_txdone(entry, &txdesc); |
1366 | } | 1369 | } |
1367 | } | 1370 | } |
1368 | 1371 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 9ae96a626e6d..002db646ae0b 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -345,7 +345,6 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev, | |||
345 | struct rt2x00lib_crypto *crypto, | 345 | struct rt2x00lib_crypto *crypto, |
346 | struct ieee80211_key_conf *key) | 346 | struct ieee80211_key_conf *key) |
347 | { | 347 | { |
348 | int timeout; | ||
349 | u32 mask; | 348 | u32 mask; |
350 | u16 reg; | 349 | u16 reg; |
351 | 350 | ||
@@ -367,18 +366,8 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev, | |||
367 | 366 | ||
368 | key->hw_key_idx += reg ? ffz(reg) : 0; | 367 | key->hw_key_idx += reg ? ffz(reg) : 0; |
369 | 368 | ||
370 | /* | 369 | rt2500usb_register_multiwrite(rt2x00dev, reg, |
371 | * The encryption key doesn't fit within the CSR cache, | 370 | crypto->key, sizeof(crypto->key)); |
372 | * this means we should allocate it separately and use | ||
373 | * rt2x00usb_vendor_request() to send the key to the hardware. | ||
374 | */ | ||
375 | reg = KEY_ENTRY(key->hw_key_idx); | ||
376 | timeout = REGISTER_TIMEOUT32(sizeof(crypto->key)); | ||
377 | rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, | ||
378 | USB_VENDOR_REQUEST_OUT, reg, | ||
379 | crypto->key, | ||
380 | sizeof(crypto->key), | ||
381 | timeout); | ||
382 | 371 | ||
383 | /* | 372 | /* |
384 | * The driver does not support the IV/EIV generation | 373 | * The driver does not support the IV/EIV generation |
@@ -1034,7 +1023,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1034 | struct txentry_desc *txdesc) | 1023 | struct txentry_desc *txdesc) |
1035 | { | 1024 | { |
1036 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 1025 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1037 | __le32 *txd = (__le32 *)(skb->data - TXD_DESC_SIZE); | 1026 | __le32 *txd = (__le32 *) skb->data; |
1038 | u32 word; | 1027 | u32 word; |
1039 | 1028 | ||
1040 | /* | 1029 | /* |
@@ -1080,6 +1069,7 @@ static void rt2500usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1080 | /* | 1069 | /* |
1081 | * Register descriptor details in skb frame descriptor. | 1070 | * Register descriptor details in skb frame descriptor. |
1082 | */ | 1071 | */ |
1072 | skbdesc->flags |= SKBDESC_DESC_IN_SKB; | ||
1083 | skbdesc->desc = txd; | 1073 | skbdesc->desc = txd; |
1084 | skbdesc->desc_len = TXD_DESC_SIZE; | 1074 | skbdesc->desc_len = TXD_DESC_SIZE; |
1085 | } | 1075 | } |
@@ -1108,9 +1098,20 @@ static void rt2500usb_write_beacon(struct queue_entry *entry, | |||
1108 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); | 1098 | rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg); |
1109 | 1099 | ||
1110 | /* | 1100 | /* |
1111 | * Take the descriptor in front of the skb into account. | 1101 | * Add space for the descriptor in front of the skb. |
1112 | */ | 1102 | */ |
1113 | skb_push(entry->skb, TXD_DESC_SIZE); | 1103 | skb_push(entry->skb, TXD_DESC_SIZE); |
1104 | memset(entry->skb->data, 0, TXD_DESC_SIZE); | ||
1105 | |||
1106 | /* | ||
1107 | * Write the TX descriptor for the beacon. | ||
1108 | */ | ||
1109 | rt2500usb_write_tx_desc(rt2x00dev, entry->skb, txdesc); | ||
1110 | |||
1111 | /* | ||
1112 | * Dump beacon to userspace through debugfs. | ||
1113 | */ | ||
1114 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); | ||
1114 | 1115 | ||
1115 | /* | 1116 | /* |
1116 | * USB devices cannot blindly pass the skb->len as the | 1117 | * USB devices cannot blindly pass the skb->len as the |
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h index 2aa03751c341..317b7807175e 100644 --- a/drivers/net/wireless/rt2x00/rt2800.h +++ b/drivers/net/wireless/rt2x00/rt2800.h | |||
@@ -63,7 +63,6 @@ | |||
63 | */ | 63 | */ |
64 | #define REV_RT2860C 0x0100 | 64 | #define REV_RT2860C 0x0100 |
65 | #define REV_RT2860D 0x0101 | 65 | #define REV_RT2860D 0x0101 |
66 | #define REV_RT2870D 0x0101 | ||
67 | #define REV_RT2872E 0x0200 | 66 | #define REV_RT2872E 0x0200 |
68 | #define REV_RT3070E 0x0200 | 67 | #define REV_RT3070E 0x0200 |
69 | #define REV_RT3070F 0x0201 | 68 | #define REV_RT3070F 0x0201 |
@@ -99,6 +98,21 @@ | |||
99 | */ | 98 | */ |
100 | 99 | ||
101 | /* | 100 | /* |
101 | * E2PROM_CSR: PCI EEPROM control register. | ||
102 | * RELOAD: Write 1 to reload eeprom content. | ||
103 | * TYPE: 0: 93c46, 1:93c66. | ||
104 | * LOAD_STATUS: 1:loading, 0:done. | ||
105 | */ | ||
106 | #define E2PROM_CSR 0x0004 | ||
107 | #define E2PROM_CSR_DATA_CLOCK FIELD32(0x00000001) | ||
108 | #define E2PROM_CSR_CHIP_SELECT FIELD32(0x00000002) | ||
109 | #define E2PROM_CSR_DATA_IN FIELD32(0x00000004) | ||
110 | #define E2PROM_CSR_DATA_OUT FIELD32(0x00000008) | ||
111 | #define E2PROM_CSR_TYPE FIELD32(0x00000030) | ||
112 | #define E2PROM_CSR_LOAD_STATUS FIELD32(0x00000040) | ||
113 | #define E2PROM_CSR_RELOAD FIELD32(0x00000080) | ||
114 | |||
115 | /* | ||
102 | * OPT_14: Unknown register used by rt3xxx devices. | 116 | * OPT_14: Unknown register used by rt3xxx devices. |
103 | */ | 117 | */ |
104 | #define OPT_14_CSR 0x0114 | 118 | #define OPT_14_CSR 0x0114 |
@@ -322,6 +336,39 @@ | |||
322 | #define RX_DRX_IDX 0x029c | 336 | #define RX_DRX_IDX 0x029c |
323 | 337 | ||
324 | /* | 338 | /* |
339 | * USB_DMA_CFG | ||
340 | * RX_BULK_AGG_TIMEOUT: Rx Bulk Aggregation TimeOut in unit of 33ns. | ||
341 | * RX_BULK_AGG_LIMIT: Rx Bulk Aggregation Limit in unit of 256 bytes. | ||
342 | * PHY_CLEAR: phy watch dog enable. | ||
343 | * TX_CLEAR: Clear USB DMA TX path. | ||
344 | * TXOP_HALT: Halt TXOP count down when TX buffer is full. | ||
345 | * RX_BULK_AGG_EN: Enable Rx Bulk Aggregation. | ||
346 | * RX_BULK_EN: Enable USB DMA Rx. | ||
347 | * TX_BULK_EN: Enable USB DMA Tx. | ||
348 | * EP_OUT_VALID: OUT endpoint data valid. | ||
349 | * RX_BUSY: USB DMA RX FSM busy. | ||
350 | * TX_BUSY: USB DMA TX FSM busy. | ||
351 | */ | ||
352 | #define USB_DMA_CFG 0x02a0 | ||
353 | #define USB_DMA_CFG_RX_BULK_AGG_TIMEOUT FIELD32(0x000000ff) | ||
354 | #define USB_DMA_CFG_RX_BULK_AGG_LIMIT FIELD32(0x0000ff00) | ||
355 | #define USB_DMA_CFG_PHY_CLEAR FIELD32(0x00010000) | ||
356 | #define USB_DMA_CFG_TX_CLEAR FIELD32(0x00080000) | ||
357 | #define USB_DMA_CFG_TXOP_HALT FIELD32(0x00100000) | ||
358 | #define USB_DMA_CFG_RX_BULK_AGG_EN FIELD32(0x00200000) | ||
359 | #define USB_DMA_CFG_RX_BULK_EN FIELD32(0x00400000) | ||
360 | #define USB_DMA_CFG_TX_BULK_EN FIELD32(0x00800000) | ||
361 | #define USB_DMA_CFG_EP_OUT_VALID FIELD32(0x3f000000) | ||
362 | #define USB_DMA_CFG_RX_BUSY FIELD32(0x40000000) | ||
363 | #define USB_DMA_CFG_TX_BUSY FIELD32(0x80000000) | ||
364 | |||
365 | /* | ||
366 | * US_CYC_CNT | ||
367 | */ | ||
368 | #define US_CYC_CNT 0x02a4 | ||
369 | #define US_CYC_CNT_CLOCK_CYCLE FIELD32(0x000000ff) | ||
370 | |||
371 | /* | ||
325 | * PBF_SYS_CTRL | 372 | * PBF_SYS_CTRL |
326 | * HOST_RAM_WRITE: enable Host program ram write selection | 373 | * HOST_RAM_WRITE: enable Host program ram write selection |
327 | */ | 374 | */ |
@@ -1370,17 +1417,17 @@ | |||
1370 | struct mac_wcid_entry { | 1417 | struct mac_wcid_entry { |
1371 | u8 mac[6]; | 1418 | u8 mac[6]; |
1372 | u8 reserved[2]; | 1419 | u8 reserved[2]; |
1373 | } __attribute__ ((packed)); | 1420 | } __packed; |
1374 | 1421 | ||
1375 | struct hw_key_entry { | 1422 | struct hw_key_entry { |
1376 | u8 key[16]; | 1423 | u8 key[16]; |
1377 | u8 tx_mic[8]; | 1424 | u8 tx_mic[8]; |
1378 | u8 rx_mic[8]; | 1425 | u8 rx_mic[8]; |
1379 | } __attribute__ ((packed)); | 1426 | } __packed; |
1380 | 1427 | ||
1381 | struct mac_iveiv_entry { | 1428 | struct mac_iveiv_entry { |
1382 | u8 iv[8]; | 1429 | u8 iv[8]; |
1383 | } __attribute__ ((packed)); | 1430 | } __packed; |
1384 | 1431 | ||
1385 | /* | 1432 | /* |
1386 | * MAC_WCID_ATTRIBUTE: | 1433 | * MAC_WCID_ATTRIBUTE: |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index db4250d1c8b3..ae20e6728b1e 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c | |||
@@ -38,12 +38,8 @@ | |||
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | 39 | ||
40 | #include "rt2x00.h" | 40 | #include "rt2x00.h" |
41 | #if defined(CONFIG_RT2X00_LIB_USB) || defined(CONFIG_RT2X00_LIB_USB_MODULE) | ||
42 | #include "rt2x00usb.h" | ||
43 | #endif | ||
44 | #include "rt2800lib.h" | 41 | #include "rt2800lib.h" |
45 | #include "rt2800.h" | 42 | #include "rt2800.h" |
46 | #include "rt2800usb.h" | ||
47 | 43 | ||
48 | MODULE_AUTHOR("Bartlomiej Zolnierkiewicz"); | 44 | MODULE_AUTHOR("Bartlomiej Zolnierkiewicz"); |
49 | MODULE_DESCRIPTION("rt2800 library"); | 45 | MODULE_DESCRIPTION("rt2800 library"); |
@@ -282,9 +278,8 @@ int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev) | |||
282 | } | 278 | } |
283 | EXPORT_SYMBOL_GPL(rt2800_wait_wpdma_ready); | 279 | EXPORT_SYMBOL_GPL(rt2800_wait_wpdma_ready); |
284 | 280 | ||
285 | void rt2800_write_txwi(struct sk_buff *skb, struct txentry_desc *txdesc) | 281 | void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc) |
286 | { | 282 | { |
287 | __le32 *txwi = (__le32 *)(skb->data - TXWI_DESC_SIZE); | ||
288 | u32 word; | 283 | u32 word; |
289 | 284 | ||
290 | /* | 285 | /* |
@@ -380,6 +375,67 @@ void rt2800_process_rxwi(struct sk_buff *skb, struct rxdone_entry_desc *rxdesc) | |||
380 | } | 375 | } |
381 | EXPORT_SYMBOL_GPL(rt2800_process_rxwi); | 376 | EXPORT_SYMBOL_GPL(rt2800_process_rxwi); |
382 | 377 | ||
378 | void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc) | ||
379 | { | ||
380 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
381 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
382 | unsigned int beacon_base; | ||
383 | u32 reg; | ||
384 | |||
385 | /* | ||
386 | * Disable beaconing while we are reloading the beacon data, | ||
387 | * otherwise we might be sending out invalid data. | ||
388 | */ | ||
389 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); | ||
390 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); | ||
391 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | ||
392 | |||
393 | /* | ||
394 | * Add space for the TXWI in front of the skb. | ||
395 | */ | ||
396 | skb_push(entry->skb, TXWI_DESC_SIZE); | ||
397 | memset(entry->skb, 0, TXWI_DESC_SIZE); | ||
398 | |||
399 | /* | ||
400 | * Register descriptor details in skb frame descriptor. | ||
401 | */ | ||
402 | skbdesc->flags |= SKBDESC_DESC_IN_SKB; | ||
403 | skbdesc->desc = entry->skb->data; | ||
404 | skbdesc->desc_len = TXWI_DESC_SIZE; | ||
405 | |||
406 | /* | ||
407 | * Add the TXWI for the beacon to the skb. | ||
408 | */ | ||
409 | rt2800_write_txwi((__le32 *)entry->skb->data, txdesc); | ||
410 | |||
411 | /* | ||
412 | * Dump beacon to userspace through debugfs. | ||
413 | */ | ||
414 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); | ||
415 | |||
416 | /* | ||
417 | * Write entire beacon with TXWI to register. | ||
418 | */ | ||
419 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); | ||
420 | rt2800_register_multiwrite(rt2x00dev, beacon_base, | ||
421 | entry->skb->data, entry->skb->len); | ||
422 | |||
423 | /* | ||
424 | * Enable beaconing again. | ||
425 | */ | ||
426 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); | ||
427 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); | ||
428 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); | ||
429 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | ||
430 | |||
431 | /* | ||
432 | * Clean up beacon skb. | ||
433 | */ | ||
434 | dev_kfree_skb_any(entry->skb); | ||
435 | entry->skb = NULL; | ||
436 | } | ||
437 | EXPORT_SYMBOL(rt2800_write_beacon); | ||
438 | |||
383 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 439 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
384 | const struct rt2x00debug rt2800_rt2x00debug = { | 440 | const struct rt2x00debug rt2800_rt2x00debug = { |
385 | .owner = THIS_MODULE, | 441 | .owner = THIS_MODULE, |
@@ -1212,6 +1268,7 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1212 | u32 reg; | 1268 | u32 reg; |
1213 | u16 eeprom; | 1269 | u16 eeprom; |
1214 | unsigned int i; | 1270 | unsigned int i; |
1271 | int ret; | ||
1215 | 1272 | ||
1216 | rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); | 1273 | rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); |
1217 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); | 1274 | rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); |
@@ -1221,59 +1278,9 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1221 | rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); | 1278 | rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); |
1222 | rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); | 1279 | rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); |
1223 | 1280 | ||
1224 | if (rt2x00_is_usb(rt2x00dev)) { | 1281 | ret = rt2800_drv_init_registers(rt2x00dev); |
1225 | /* | 1282 | if (ret) |
1226 | * Wait until BBP and RF are ready. | 1283 | return ret; |
1227 | */ | ||
1228 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
1229 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); | ||
1230 | if (reg && reg != ~0) | ||
1231 | break; | ||
1232 | msleep(1); | ||
1233 | } | ||
1234 | |||
1235 | if (i == REGISTER_BUSY_COUNT) { | ||
1236 | ERROR(rt2x00dev, "Unstable hardware.\n"); | ||
1237 | return -EBUSY; | ||
1238 | } | ||
1239 | |||
1240 | rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, ®); | ||
1241 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, | ||
1242 | reg & ~0x00002000); | ||
1243 | } else if (rt2x00_is_pci(rt2x00dev) || rt2x00_is_soc(rt2x00dev)) { | ||
1244 | /* | ||
1245 | * Reset DMA indexes | ||
1246 | */ | ||
1247 | rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, ®); | ||
1248 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, 1); | ||
1249 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, 1); | ||
1250 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, 1); | ||
1251 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX3, 1); | ||
1252 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX4, 1); | ||
1253 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX5, 1); | ||
1254 | rt2x00_set_field32(®, WPDMA_RST_IDX_DRX_IDX0, 1); | ||
1255 | rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg); | ||
1256 | |||
1257 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); | ||
1258 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); | ||
1259 | |||
1260 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); | ||
1261 | } | ||
1262 | |||
1263 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | ||
1264 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); | ||
1265 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); | ||
1266 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
1267 | |||
1268 | if (rt2x00_is_usb(rt2x00dev)) { | ||
1269 | rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000); | ||
1270 | #if defined(CONFIG_RT2X00_LIB_USB) || defined(CONFIG_RT2X00_LIB_USB_MODULE) | ||
1271 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0, | ||
1272 | USB_MODE_RESET, REGISTER_TIMEOUT); | ||
1273 | #endif | ||
1274 | } | ||
1275 | |||
1276 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); | ||
1277 | 1284 | ||
1278 | rt2800_register_read(rt2x00dev, BCN_OFFSET0, ®); | 1285 | rt2800_register_read(rt2x00dev, BCN_OFFSET0, ®); |
1279 | rt2x00_set_field32(®, BCN_OFFSET0_BCN0, 0xe0); /* 0x3800 */ | 1286 | rt2x00_set_field32(®, BCN_OFFSET0_BCN0, 0xe0); /* 0x3800 */ |
@@ -1328,7 +1335,6 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1328 | } else { | 1335 | } else { |
1329 | rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); | 1336 | rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); |
1330 | } | 1337 | } |
1331 | rt2800_register_write(rt2x00dev, TX_SW_CFG2, reg); | ||
1332 | } else if (rt2x00_rt(rt2x00dev, RT3070)) { | 1338 | } else if (rt2x00_rt(rt2x00dev, RT3070)) { |
1333 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); | 1339 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); |
1334 | 1340 | ||
@@ -1339,6 +1345,10 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1339 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); | 1345 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); |
1340 | rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); | 1346 | rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); |
1341 | } | 1347 | } |
1348 | } else if (rt2800_is_305x_soc(rt2x00dev)) { | ||
1349 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000400); | ||
1350 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); | ||
1351 | rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x0000001f); | ||
1342 | } else { | 1352 | } else { |
1343 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000); | 1353 | rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000); |
1344 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); | 1354 | rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); |
@@ -1560,9 +1570,9 @@ int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1560 | rt2800_register_write(rt2x00dev, HW_BEACON_BASE7, 0); | 1570 | rt2800_register_write(rt2x00dev, HW_BEACON_BASE7, 0); |
1561 | 1571 | ||
1562 | if (rt2x00_is_usb(rt2x00dev)) { | 1572 | if (rt2x00_is_usb(rt2x00dev)) { |
1563 | rt2800_register_read(rt2x00dev, USB_CYC_CFG, ®); | 1573 | rt2800_register_read(rt2x00dev, US_CYC_CNT, ®); |
1564 | rt2x00_set_field32(®, USB_CYC_CFG_CLOCK_CYCLE, 30); | 1574 | rt2x00_set_field32(®, US_CYC_CNT_CLOCK_CYCLE, 30); |
1565 | rt2800_register_write(rt2x00dev, USB_CYC_CFG, reg); | 1575 | rt2800_register_write(rt2x00dev, US_CYC_CNT, reg); |
1566 | } | 1576 | } |
1567 | 1577 | ||
1568 | rt2800_register_read(rt2x00dev, HT_FBK_CFG0, ®); | 1578 | rt2800_register_read(rt2x00dev, HT_FBK_CFG0, ®); |
@@ -1706,8 +1716,7 @@ int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) | |||
1706 | rt2800_bbp_write(rt2x00dev, 82, 0x62); | 1716 | rt2800_bbp_write(rt2x00dev, 82, 0x62); |
1707 | rt2800_bbp_write(rt2x00dev, 83, 0x6a); | 1717 | rt2800_bbp_write(rt2x00dev, 83, 0x6a); |
1708 | 1718 | ||
1709 | if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D) || | 1719 | if (rt2x00_rt_rev(rt2x00dev, RT2860, REV_RT2860D)) |
1710 | rt2x00_rt_rev(rt2x00dev, RT2870, REV_RT2870D)) | ||
1711 | rt2800_bbp_write(rt2x00dev, 84, 0x19); | 1720 | rt2800_bbp_write(rt2x00dev, 84, 0x19); |
1712 | else | 1721 | else |
1713 | rt2800_bbp_write(rt2x00dev, 84, 0x99); | 1722 | rt2800_bbp_write(rt2x00dev, 84, 0x99); |
@@ -2013,8 +2022,7 @@ int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) | |||
2013 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || | 2022 | if (rt2x00_rt_rev_lt(rt2x00dev, RT3071, REV_RT3071E) || |
2014 | rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || | 2023 | rt2x00_rt_rev_lt(rt2x00dev, RT3090, REV_RT3090E) || |
2015 | rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { | 2024 | rt2x00_rt_rev_lt(rt2x00dev, RT3390, REV_RT3390E)) { |
2016 | rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom); | 2025 | if (test_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags)) |
2017 | if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG)) | ||
2018 | rt2x00_set_field8(&rfcsr, RFCSR17_R, 1); | 2026 | rt2x00_set_field8(&rfcsr, RFCSR17_R, 1); |
2019 | } | 2027 | } |
2020 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom); | 2028 | rt2x00_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &eeprom); |
@@ -2147,7 +2155,6 @@ int rt2800_validate_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2147 | rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); | 2155 | rt2x00_eeprom_write(rt2x00dev, EEPROM_ANTENNA, word); |
2148 | EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); | 2156 | EEPROM(rt2x00dev, "Antenna: 0x%04x\n", word); |
2149 | } else if (rt2x00_rt(rt2x00dev, RT2860) || | 2157 | } else if (rt2x00_rt(rt2x00dev, RT2860) || |
2150 | rt2x00_rt(rt2x00dev, RT2870) || | ||
2151 | rt2x00_rt(rt2x00dev, RT2872)) { | 2158 | rt2x00_rt(rt2x00dev, RT2872)) { |
2152 | /* | 2159 | /* |
2153 | * There is a max of 2 RX streams for RT28x0 series | 2160 | * There is a max of 2 RX streams for RT28x0 series |
@@ -2251,7 +2258,6 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2251 | value, rt2x00_get_field32(reg, MAC_CSR0_REVISION)); | 2258 | value, rt2x00_get_field32(reg, MAC_CSR0_REVISION)); |
2252 | 2259 | ||
2253 | if (!rt2x00_rt(rt2x00dev, RT2860) && | 2260 | if (!rt2x00_rt(rt2x00dev, RT2860) && |
2254 | !rt2x00_rt(rt2x00dev, RT2870) && | ||
2255 | !rt2x00_rt(rt2x00dev, RT2872) && | 2261 | !rt2x00_rt(rt2x00dev, RT2872) && |
2256 | !rt2x00_rt(rt2x00dev, RT2883) && | 2262 | !rt2x00_rt(rt2x00dev, RT2883) && |
2257 | !rt2x00_rt(rt2x00dev, RT3070) && | 2263 | !rt2x00_rt(rt2x00dev, RT3070) && |
@@ -2528,16 +2534,16 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2528 | else | 2534 | else |
2529 | spec->ht.ht_supported = false; | 2535 | spec->ht.ht_supported = false; |
2530 | 2536 | ||
2531 | /* | ||
2532 | * Don't set IEEE80211_HT_CAP_SUP_WIDTH_20_40 for now as it causes | ||
2533 | * reception problems with HT40 capable 11n APs | ||
2534 | */ | ||
2535 | spec->ht.cap = | 2537 | spec->ht.cap = |
2538 | IEEE80211_HT_CAP_SUP_WIDTH_20_40 | | ||
2536 | IEEE80211_HT_CAP_GRN_FLD | | 2539 | IEEE80211_HT_CAP_GRN_FLD | |
2537 | IEEE80211_HT_CAP_SGI_20 | | 2540 | IEEE80211_HT_CAP_SGI_20 | |
2538 | IEEE80211_HT_CAP_SGI_40 | | 2541 | IEEE80211_HT_CAP_SGI_40 | |
2539 | IEEE80211_HT_CAP_TX_STBC | | ||
2540 | IEEE80211_HT_CAP_RX_STBC; | 2542 | IEEE80211_HT_CAP_RX_STBC; |
2543 | |||
2544 | if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_TXPATH) >= 2) | ||
2545 | spec->ht.cap |= IEEE80211_HT_CAP_TX_STBC; | ||
2546 | |||
2541 | spec->ht.ampdu_factor = 3; | 2547 | spec->ht.ampdu_factor = 3; |
2542 | spec->ht.ampdu_density = 4; | 2548 | spec->ht.ampdu_density = 4; |
2543 | spec->ht.mcs.tx_params = | 2549 | spec->ht.mcs.tx_params = |
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h index 94de999e2290..8313dbf441a5 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/rt2x00/rt2800lib.h | |||
@@ -40,6 +40,8 @@ struct rt2800_ops { | |||
40 | int (*regbusy_read)(struct rt2x00_dev *rt2x00dev, | 40 | int (*regbusy_read)(struct rt2x00_dev *rt2x00dev, |
41 | const unsigned int offset, | 41 | const unsigned int offset, |
42 | const struct rt2x00_field32 field, u32 *reg); | 42 | const struct rt2x00_field32 field, u32 *reg); |
43 | |||
44 | int (*drv_init_registers)(struct rt2x00_dev *rt2x00dev); | ||
43 | }; | 45 | }; |
44 | 46 | ||
45 | static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev, | 47 | static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev, |
@@ -107,13 +109,22 @@ static inline int rt2800_regbusy_read(struct rt2x00_dev *rt2x00dev, | |||
107 | return rt2800ops->regbusy_read(rt2x00dev, offset, field, reg); | 109 | return rt2800ops->regbusy_read(rt2x00dev, offset, field, reg); |
108 | } | 110 | } |
109 | 111 | ||
112 | static inline int rt2800_drv_init_registers(struct rt2x00_dev *rt2x00dev) | ||
113 | { | ||
114 | const struct rt2800_ops *rt2800ops = rt2x00dev->priv; | ||
115 | |||
116 | return rt2800ops->drv_init_registers(rt2x00dev); | ||
117 | } | ||
118 | |||
110 | void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev, | 119 | void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev, |
111 | const u8 command, const u8 token, | 120 | const u8 command, const u8 token, |
112 | const u8 arg0, const u8 arg1); | 121 | const u8 arg0, const u8 arg1); |
113 | 122 | ||
114 | void rt2800_write_txwi(struct sk_buff *skb, struct txentry_desc *txdesc); | 123 | void rt2800_write_txwi(__le32 *txwi, struct txentry_desc *txdesc); |
115 | void rt2800_process_rxwi(struct sk_buff *skb, struct rxdone_entry_desc *txdesc); | 124 | void rt2800_process_rxwi(struct sk_buff *skb, struct rxdone_entry_desc *txdesc); |
116 | 125 | ||
126 | void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); | ||
127 | |||
117 | extern const struct rt2x00debug rt2800_rt2x00debug; | 128 | extern const struct rt2x00debug rt2800_rt2x00debug; |
118 | 129 | ||
119 | int rt2800_rfkill_poll(struct rt2x00_dev *rt2x00dev); | 130 | int rt2800_rfkill_poll(struct rt2x00_dev *rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index b2f23272c3aa..b5a871eb8881 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -446,6 +446,38 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev, | |||
446 | rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); | 446 | rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); |
447 | } | 447 | } |
448 | 448 | ||
449 | static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) | ||
450 | { | ||
451 | u32 reg; | ||
452 | |||
453 | /* | ||
454 | * Reset DMA indexes | ||
455 | */ | ||
456 | rt2800_register_read(rt2x00dev, WPDMA_RST_IDX, ®); | ||
457 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX0, 1); | ||
458 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX1, 1); | ||
459 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX2, 1); | ||
460 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX3, 1); | ||
461 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX4, 1); | ||
462 | rt2x00_set_field32(®, WPDMA_RST_IDX_DTX_IDX5, 1); | ||
463 | rt2x00_set_field32(®, WPDMA_RST_IDX_DRX_IDX0, 1); | ||
464 | rt2800_register_write(rt2x00dev, WPDMA_RST_IDX, reg); | ||
465 | |||
466 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e1f); | ||
467 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); | ||
468 | |||
469 | rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); | ||
470 | |||
471 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | ||
472 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); | ||
473 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); | ||
474 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
475 | |||
476 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); | ||
477 | |||
478 | return 0; | ||
479 | } | ||
480 | |||
449 | static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) | 481 | static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) |
450 | { | 482 | { |
451 | u32 reg; | 483 | u32 reg; |
@@ -465,7 +497,7 @@ static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
465 | /* | 497 | /* |
466 | * Send signal to firmware during boot time. | 498 | * Send signal to firmware during boot time. |
467 | */ | 499 | */ |
468 | rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0xff, 0, 0); | 500 | rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); |
469 | 501 | ||
470 | /* | 502 | /* |
471 | * Enable RX. | 503 | * Enable RX. |
@@ -613,18 +645,10 @@ static int rt2800pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
613 | /* | 645 | /* |
614 | * TX descriptor initialization | 646 | * TX descriptor initialization |
615 | */ | 647 | */ |
616 | static int rt2800pci_write_tx_data(struct queue_entry* entry, | 648 | static void rt2800pci_write_tx_datadesc(struct queue_entry* entry, |
617 | struct txentry_desc *txdesc) | 649 | struct txentry_desc *txdesc) |
618 | { | 650 | { |
619 | int ret; | 651 | rt2800_write_txwi((__le32 *) entry->skb->data, txdesc); |
620 | |||
621 | ret = rt2x00pci_write_tx_data(entry, txdesc); | ||
622 | if (ret) | ||
623 | return ret; | ||
624 | |||
625 | rt2800_write_txwi(entry->skb, txdesc); | ||
626 | |||
627 | return 0; | ||
628 | } | 652 | } |
629 | 653 | ||
630 | 654 | ||
@@ -684,49 +708,6 @@ static void rt2800pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
684 | /* | 708 | /* |
685 | * TX data initialization | 709 | * TX data initialization |
686 | */ | 710 | */ |
687 | static void rt2800pci_write_beacon(struct queue_entry *entry, | ||
688 | struct txentry_desc *txdesc) | ||
689 | { | ||
690 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
691 | unsigned int beacon_base; | ||
692 | u32 reg; | ||
693 | |||
694 | /* | ||
695 | * Disable beaconing while we are reloading the beacon data, | ||
696 | * otherwise we might be sending out invalid data. | ||
697 | */ | ||
698 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); | ||
699 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); | ||
700 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | ||
701 | |||
702 | /* | ||
703 | * Add the TXWI for the beacon to the skb. | ||
704 | */ | ||
705 | rt2800_write_txwi(entry->skb, txdesc); | ||
706 | skb_push(entry->skb, TXWI_DESC_SIZE); | ||
707 | |||
708 | /* | ||
709 | * Write entire beacon with TXWI to register. | ||
710 | */ | ||
711 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); | ||
712 | rt2800_register_multiwrite(rt2x00dev, beacon_base, | ||
713 | entry->skb->data, entry->skb->len); | ||
714 | |||
715 | /* | ||
716 | * Enable beaconing again. | ||
717 | */ | ||
718 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); | ||
719 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); | ||
720 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); | ||
721 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | ||
722 | |||
723 | /* | ||
724 | * Clean up beacon skb. | ||
725 | */ | ||
726 | dev_kfree_skb_any(entry->skb); | ||
727 | entry->skb = NULL; | ||
728 | } | ||
729 | |||
730 | static void rt2800pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 711 | static void rt2800pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
731 | const enum data_queue_qid queue_idx) | 712 | const enum data_queue_qid queue_idx) |
732 | { | 713 | { |
@@ -880,8 +861,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
880 | 861 | ||
881 | /* Check if we got a match by looking at WCID/ACK/PID | 862 | /* Check if we got a match by looking at WCID/ACK/PID |
882 | * fields */ | 863 | * fields */ |
883 | txwi = (__le32 *)(entry->skb->data - | 864 | txwi = (__le32 *) entry->skb->data; |
884 | rt2x00dev->ops->extra_tx_headroom); | ||
885 | 865 | ||
886 | rt2x00_desc_read(txwi, 1, &word); | 866 | rt2x00_desc_read(txwi, 1, &word); |
887 | tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); | 867 | tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); |
@@ -926,7 +906,7 @@ static void rt2800pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
926 | __set_bit(TXDONE_FALLBACK, &txdesc.flags); | 906 | __set_bit(TXDONE_FALLBACK, &txdesc.flags); |
927 | 907 | ||
928 | 908 | ||
929 | rt2x00lib_txdone(entry, &txdesc); | 909 | rt2x00pci_txdone(entry, &txdesc); |
930 | } | 910 | } |
931 | } | 911 | } |
932 | 912 | ||
@@ -996,6 +976,8 @@ static const struct rt2800_ops rt2800pci_rt2800_ops = { | |||
996 | .register_multiwrite = rt2x00pci_register_multiwrite, | 976 | .register_multiwrite = rt2x00pci_register_multiwrite, |
997 | 977 | ||
998 | .regbusy_read = rt2x00pci_regbusy_read, | 978 | .regbusy_read = rt2x00pci_regbusy_read, |
979 | |||
980 | .drv_init_registers = rt2800pci_init_registers, | ||
999 | }; | 981 | }; |
1000 | 982 | ||
1001 | static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) | 983 | static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) |
@@ -1063,8 +1045,9 @@ static const struct rt2x00lib_ops rt2800pci_rt2x00_ops = { | |||
1063 | .reset_tuner = rt2800_reset_tuner, | 1045 | .reset_tuner = rt2800_reset_tuner, |
1064 | .link_tuner = rt2800_link_tuner, | 1046 | .link_tuner = rt2800_link_tuner, |
1065 | .write_tx_desc = rt2800pci_write_tx_desc, | 1047 | .write_tx_desc = rt2800pci_write_tx_desc, |
1066 | .write_tx_data = rt2800pci_write_tx_data, | 1048 | .write_tx_data = rt2x00pci_write_tx_data, |
1067 | .write_beacon = rt2800pci_write_beacon, | 1049 | .write_tx_datadesc = rt2800pci_write_tx_datadesc, |
1050 | .write_beacon = rt2800_write_beacon, | ||
1068 | .kick_tx_queue = rt2800pci_kick_tx_queue, | 1051 | .kick_tx_queue = rt2800pci_kick_tx_queue, |
1069 | .kill_tx_queue = rt2800pci_kill_tx_queue, | 1052 | .kill_tx_queue = rt2800pci_kill_tx_queue, |
1070 | .fill_rxdone = rt2800pci_fill_rxdone, | 1053 | .fill_rxdone = rt2800pci_fill_rxdone, |
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.h b/drivers/net/wireless/rt2x00/rt2800pci.h index afc8e7da27cb..5a8dda9b5b5a 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.h +++ b/drivers/net/wireless/rt2x00/rt2800pci.h | |||
@@ -35,25 +35,6 @@ | |||
35 | #define RT2800PCI_H | 35 | #define RT2800PCI_H |
36 | 36 | ||
37 | /* | 37 | /* |
38 | * PCI registers. | ||
39 | */ | ||
40 | |||
41 | /* | ||
42 | * E2PROM_CSR: EEPROM control register. | ||
43 | * RELOAD: Write 1 to reload eeprom content. | ||
44 | * TYPE: 0: 93c46, 1:93c66. | ||
45 | * LOAD_STATUS: 1:loading, 0:done. | ||
46 | */ | ||
47 | #define E2PROM_CSR 0x0004 | ||
48 | #define E2PROM_CSR_DATA_CLOCK FIELD32(0x00000001) | ||
49 | #define E2PROM_CSR_CHIP_SELECT FIELD32(0x00000002) | ||
50 | #define E2PROM_CSR_DATA_IN FIELD32(0x00000004) | ||
51 | #define E2PROM_CSR_DATA_OUT FIELD32(0x00000008) | ||
52 | #define E2PROM_CSR_TYPE FIELD32(0x00000030) | ||
53 | #define E2PROM_CSR_LOAD_STATUS FIELD32(0x00000040) | ||
54 | #define E2PROM_CSR_RELOAD FIELD32(0x00000080) | ||
55 | |||
56 | /* | ||
57 | * Queue register offset macros | 38 | * Queue register offset macros |
58 | */ | 39 | */ |
59 | #define TX_QUEUE_REG_OFFSET 0x10 | 40 | #define TX_QUEUE_REG_OFFSET 0x10 |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 0f8b84b7224c..c437960de3ed 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c | |||
@@ -169,11 +169,8 @@ static int rt2800usb_load_firmware(struct rt2x00_dev *rt2x00dev, | |||
169 | /* | 169 | /* |
170 | * Write firmware to device. | 170 | * Write firmware to device. |
171 | */ | 171 | */ |
172 | rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, | 172 | rt2800_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, |
173 | USB_VENDOR_REQUEST_OUT, | 173 | data + offset, length); |
174 | FIRMWARE_IMAGE_BASE, | ||
175 | data + offset, length, | ||
176 | REGISTER_TIMEOUT32(length)); | ||
177 | 174 | ||
178 | rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); | 175 | rt2800_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); |
179 | rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); | 176 | rt2800_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0); |
@@ -196,7 +193,7 @@ static int rt2800usb_load_firmware(struct rt2x00_dev *rt2x00dev, | |||
196 | /* | 193 | /* |
197 | * Send signal to firmware during boot time. | 194 | * Send signal to firmware during boot time. |
198 | */ | 195 | */ |
199 | rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0xff, 0, 0); | 196 | rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0); |
200 | 197 | ||
201 | if (rt2x00_rt(rt2x00dev, RT3070) || | 198 | if (rt2x00_rt(rt2x00dev, RT3070) || |
202 | rt2x00_rt(rt2x00dev, RT3071) || | 199 | rt2x00_rt(rt2x00dev, RT3071) || |
@@ -246,6 +243,44 @@ static void rt2800usb_toggle_rx(struct rt2x00_dev *rt2x00dev, | |||
246 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | 243 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); |
247 | } | 244 | } |
248 | 245 | ||
246 | static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) | ||
247 | { | ||
248 | u32 reg; | ||
249 | int i; | ||
250 | |||
251 | /* | ||
252 | * Wait until BBP and RF are ready. | ||
253 | */ | ||
254 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | ||
255 | rt2800_register_read(rt2x00dev, MAC_CSR0, ®); | ||
256 | if (reg && reg != ~0) | ||
257 | break; | ||
258 | msleep(1); | ||
259 | } | ||
260 | |||
261 | if (i == REGISTER_BUSY_COUNT) { | ||
262 | ERROR(rt2x00dev, "Unstable hardware.\n"); | ||
263 | return -EBUSY; | ||
264 | } | ||
265 | |||
266 | rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, ®); | ||
267 | rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000); | ||
268 | |||
269 | rt2800_register_read(rt2x00dev, MAC_SYS_CTRL, ®); | ||
270 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); | ||
271 | rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); | ||
272 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); | ||
273 | |||
274 | rt2800_register_write(rt2x00dev, USB_DMA_CFG, 0x00000000); | ||
275 | |||
276 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_DEVICE_MODE, 0, | ||
277 | USB_MODE_RESET, REGISTER_TIMEOUT); | ||
278 | |||
279 | rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, 0x00000000); | ||
280 | |||
281 | return 0; | ||
282 | } | ||
283 | |||
249 | static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) | 284 | static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) |
250 | { | 285 | { |
251 | u32 reg; | 286 | u32 reg; |
@@ -400,20 +435,21 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
400 | struct txentry_desc *txdesc) | 435 | struct txentry_desc *txdesc) |
401 | { | 436 | { |
402 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 437 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
403 | __le32 *txi = (__le32 *)(skb->data - TXWI_DESC_SIZE - TXINFO_DESC_SIZE); | 438 | __le32 *txi = (__le32 *) skb->data; |
439 | __le32 *txwi = (__le32 *) (skb->data + TXINFO_DESC_SIZE); | ||
404 | u32 word; | 440 | u32 word; |
405 | 441 | ||
406 | /* | 442 | /* |
407 | * Initialize TXWI descriptor | 443 | * Initialize TXWI descriptor |
408 | */ | 444 | */ |
409 | rt2800_write_txwi(skb, txdesc); | 445 | rt2800_write_txwi(txwi, txdesc); |
410 | 446 | ||
411 | /* | 447 | /* |
412 | * Initialize TXINFO descriptor | 448 | * Initialize TXINFO descriptor |
413 | */ | 449 | */ |
414 | rt2x00_desc_read(txi, 0, &word); | 450 | rt2x00_desc_read(txi, 0, &word); |
415 | rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, | 451 | rt2x00_set_field32(&word, TXINFO_W0_USB_DMA_TX_PKT_LEN, |
416 | skb->len + TXWI_DESC_SIZE); | 452 | skb->len - TXINFO_DESC_SIZE); |
417 | rt2x00_set_field32(&word, TXINFO_W0_WIV, | 453 | rt2x00_set_field32(&word, TXINFO_W0_WIV, |
418 | !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); | 454 | !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc->flags)); |
419 | rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2); | 455 | rt2x00_set_field32(&word, TXINFO_W0_QSEL, 2); |
@@ -426,6 +462,7 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
426 | /* | 462 | /* |
427 | * Register descriptor details in skb frame descriptor. | 463 | * Register descriptor details in skb frame descriptor. |
428 | */ | 464 | */ |
465 | skbdesc->flags |= SKBDESC_DESC_IN_SKB; | ||
429 | skbdesc->desc = txi; | 466 | skbdesc->desc = txi; |
430 | skbdesc->desc_len = TXINFO_DESC_SIZE + TXWI_DESC_SIZE; | 467 | skbdesc->desc_len = TXINFO_DESC_SIZE + TXWI_DESC_SIZE; |
431 | } | 468 | } |
@@ -433,51 +470,6 @@ static void rt2800usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
433 | /* | 470 | /* |
434 | * TX data initialization | 471 | * TX data initialization |
435 | */ | 472 | */ |
436 | static void rt2800usb_write_beacon(struct queue_entry *entry, | ||
437 | struct txentry_desc *txdesc) | ||
438 | { | ||
439 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
440 | unsigned int beacon_base; | ||
441 | u32 reg; | ||
442 | |||
443 | /* | ||
444 | * Disable beaconing while we are reloading the beacon data, | ||
445 | * otherwise we might be sending out invalid data. | ||
446 | */ | ||
447 | rt2800_register_read(rt2x00dev, BCN_TIME_CFG, ®); | ||
448 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 0); | ||
449 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | ||
450 | |||
451 | /* | ||
452 | * Add the TXWI for the beacon to the skb. | ||
453 | */ | ||
454 | rt2800_write_txwi(entry->skb, txdesc); | ||
455 | skb_push(entry->skb, TXWI_DESC_SIZE); | ||
456 | |||
457 | /* | ||
458 | * Write entire beacon with descriptor to register. | ||
459 | */ | ||
460 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); | ||
461 | rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, | ||
462 | USB_VENDOR_REQUEST_OUT, beacon_base, | ||
463 | entry->skb->data, entry->skb->len, | ||
464 | REGISTER_TIMEOUT32(entry->skb->len)); | ||
465 | |||
466 | /* | ||
467 | * Enable beaconing again. | ||
468 | */ | ||
469 | rt2x00_set_field32(®, BCN_TIME_CFG_TSF_TICKING, 1); | ||
470 | rt2x00_set_field32(®, BCN_TIME_CFG_TBTT_ENABLE, 1); | ||
471 | rt2x00_set_field32(®, BCN_TIME_CFG_BEACON_GEN, 1); | ||
472 | rt2800_register_write(rt2x00dev, BCN_TIME_CFG, reg); | ||
473 | |||
474 | /* | ||
475 | * Clean up the beacon skb. | ||
476 | */ | ||
477 | dev_kfree_skb(entry->skb); | ||
478 | entry->skb = NULL; | ||
479 | } | ||
480 | |||
481 | static int rt2800usb_get_tx_data_len(struct queue_entry *entry) | 473 | static int rt2800usb_get_tx_data_len(struct queue_entry *entry) |
482 | { | 474 | { |
483 | int length; | 475 | int length; |
@@ -595,6 +587,8 @@ static const struct rt2800_ops rt2800usb_rt2800_ops = { | |||
595 | .register_multiwrite = rt2x00usb_register_multiwrite, | 587 | .register_multiwrite = rt2x00usb_register_multiwrite, |
596 | 588 | ||
597 | .regbusy_read = rt2x00usb_regbusy_read, | 589 | .regbusy_read = rt2x00usb_regbusy_read, |
590 | |||
591 | .drv_init_registers = rt2800usb_init_registers, | ||
598 | }; | 592 | }; |
599 | 593 | ||
600 | static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) | 594 | static int rt2800usb_probe_hw(struct rt2x00_dev *rt2x00dev) |
@@ -659,7 +653,7 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { | |||
659 | .link_tuner = rt2800_link_tuner, | 653 | .link_tuner = rt2800_link_tuner, |
660 | .write_tx_desc = rt2800usb_write_tx_desc, | 654 | .write_tx_desc = rt2800usb_write_tx_desc, |
661 | .write_tx_data = rt2x00usb_write_tx_data, | 655 | .write_tx_data = rt2x00usb_write_tx_data, |
662 | .write_beacon = rt2800usb_write_beacon, | 656 | .write_beacon = rt2800_write_beacon, |
663 | .get_tx_data_len = rt2800usb_get_tx_data_len, | 657 | .get_tx_data_len = rt2800usb_get_tx_data_len, |
664 | .kick_tx_queue = rt2x00usb_kick_tx_queue, | 658 | .kick_tx_queue = rt2x00usb_kick_tx_queue, |
665 | .kill_tx_queue = rt2x00usb_kill_tx_queue, | 659 | .kill_tx_queue = rt2x00usb_kill_tx_queue, |
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.h b/drivers/net/wireless/rt2x00/rt2800usb.h index 2bca6a71a7f5..0722badccf86 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.h +++ b/drivers/net/wireless/rt2x00/rt2800usb.h | |||
@@ -32,43 +32,6 @@ | |||
32 | #define RT2800USB_H | 32 | #define RT2800USB_H |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * USB registers. | ||
36 | */ | ||
37 | |||
38 | /* | ||
39 | * USB_DMA_CFG | ||
40 | * RX_BULK_AGG_TIMEOUT: Rx Bulk Aggregation TimeOut in unit of 33ns. | ||
41 | * RX_BULK_AGG_LIMIT: Rx Bulk Aggregation Limit in unit of 256 bytes. | ||
42 | * PHY_CLEAR: phy watch dog enable. | ||
43 | * TX_CLEAR: Clear USB DMA TX path. | ||
44 | * TXOP_HALT: Halt TXOP count down when TX buffer is full. | ||
45 | * RX_BULK_AGG_EN: Enable Rx Bulk Aggregation. | ||
46 | * RX_BULK_EN: Enable USB DMA Rx. | ||
47 | * TX_BULK_EN: Enable USB DMA Tx. | ||
48 | * EP_OUT_VALID: OUT endpoint data valid. | ||
49 | * RX_BUSY: USB DMA RX FSM busy. | ||
50 | * TX_BUSY: USB DMA TX FSM busy. | ||
51 | */ | ||
52 | #define USB_DMA_CFG 0x02a0 | ||
53 | #define USB_DMA_CFG_RX_BULK_AGG_TIMEOUT FIELD32(0x000000ff) | ||
54 | #define USB_DMA_CFG_RX_BULK_AGG_LIMIT FIELD32(0x0000ff00) | ||
55 | #define USB_DMA_CFG_PHY_CLEAR FIELD32(0x00010000) | ||
56 | #define USB_DMA_CFG_TX_CLEAR FIELD32(0x00080000) | ||
57 | #define USB_DMA_CFG_TXOP_HALT FIELD32(0x00100000) | ||
58 | #define USB_DMA_CFG_RX_BULK_AGG_EN FIELD32(0x00200000) | ||
59 | #define USB_DMA_CFG_RX_BULK_EN FIELD32(0x00400000) | ||
60 | #define USB_DMA_CFG_TX_BULK_EN FIELD32(0x00800000) | ||
61 | #define USB_DMA_CFG_EP_OUT_VALID FIELD32(0x3f000000) | ||
62 | #define USB_DMA_CFG_RX_BUSY FIELD32(0x40000000) | ||
63 | #define USB_DMA_CFG_TX_BUSY FIELD32(0x80000000) | ||
64 | |||
65 | /* | ||
66 | * USB_CYC_CFG | ||
67 | */ | ||
68 | #define USB_CYC_CFG 0x02a4 | ||
69 | #define USB_CYC_CFG_CLOCK_CYCLE FIELD32(0x000000ff) | ||
70 | |||
71 | /* | ||
72 | * 8051 firmware image. | 35 | * 8051 firmware image. |
73 | */ | 36 | */ |
74 | #define FIRMWARE_RT2870 "rt2870.bin" | 37 | #define FIRMWARE_RT2870 "rt2870.bin" |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 6c1ff4c15c84..e7acc6abfd89 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <net/mac80211.h> | 39 | #include <net/mac80211.h> |
40 | 40 | ||
41 | #include "rt2x00debug.h" | 41 | #include "rt2x00debug.h" |
42 | #include "rt2x00dump.h" | ||
42 | #include "rt2x00leds.h" | 43 | #include "rt2x00leds.h" |
43 | #include "rt2x00reg.h" | 44 | #include "rt2x00reg.h" |
44 | #include "rt2x00queue.h" | 45 | #include "rt2x00queue.h" |
@@ -159,6 +160,7 @@ struct avg_val { | |||
159 | 160 | ||
160 | enum rt2x00_chip_intf { | 161 | enum rt2x00_chip_intf { |
161 | RT2X00_CHIP_INTF_PCI, | 162 | RT2X00_CHIP_INTF_PCI, |
163 | RT2X00_CHIP_INTF_PCIE, | ||
162 | RT2X00_CHIP_INTF_USB, | 164 | RT2X00_CHIP_INTF_USB, |
163 | RT2X00_CHIP_INTF_SOC, | 165 | RT2X00_CHIP_INTF_SOC, |
164 | }; | 166 | }; |
@@ -175,8 +177,7 @@ struct rt2x00_chip { | |||
175 | #define RT2570 0x2570 | 177 | #define RT2570 0x2570 |
176 | #define RT2661 0x2661 | 178 | #define RT2661 0x2661 |
177 | #define RT2573 0x2573 | 179 | #define RT2573 0x2573 |
178 | #define RT2860 0x2860 /* 2.4GHz PCI/CB */ | 180 | #define RT2860 0x2860 /* 2.4GHz */ |
179 | #define RT2870 0x2870 | ||
180 | #define RT2872 0x2872 /* WSOC */ | 181 | #define RT2872 0x2872 /* WSOC */ |
181 | #define RT2883 0x2883 /* WSOC */ | 182 | #define RT2883 0x2883 /* WSOC */ |
182 | #define RT3070 0x3070 | 183 | #define RT3070 0x3070 |
@@ -551,6 +552,8 @@ struct rt2x00lib_ops { | |||
551 | struct txentry_desc *txdesc); | 552 | struct txentry_desc *txdesc); |
552 | int (*write_tx_data) (struct queue_entry *entry, | 553 | int (*write_tx_data) (struct queue_entry *entry, |
553 | struct txentry_desc *txdesc); | 554 | struct txentry_desc *txdesc); |
555 | void (*write_tx_datadesc) (struct queue_entry *entry, | ||
556 | struct txentry_desc *txdesc); | ||
554 | void (*write_beacon) (struct queue_entry *entry, | 557 | void (*write_beacon) (struct queue_entry *entry, |
555 | struct txentry_desc *txdesc); | 558 | struct txentry_desc *txdesc); |
556 | int (*get_tx_data_len) (struct queue_entry *entry); | 559 | int (*get_tx_data_len) (struct queue_entry *entry); |
@@ -978,7 +981,13 @@ static inline bool rt2x00_intf(struct rt2x00_dev *rt2x00dev, | |||
978 | 981 | ||
979 | static inline bool rt2x00_is_pci(struct rt2x00_dev *rt2x00dev) | 982 | static inline bool rt2x00_is_pci(struct rt2x00_dev *rt2x00dev) |
980 | { | 983 | { |
981 | return rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI); | 984 | return rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI) || |
985 | rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE); | ||
986 | } | ||
987 | |||
988 | static inline bool rt2x00_is_pcie(struct rt2x00_dev *rt2x00dev) | ||
989 | { | ||
990 | return rt2x00_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE); | ||
982 | } | 991 | } |
983 | 992 | ||
984 | static inline bool rt2x00_is_usb(struct rt2x00_dev *rt2x00dev) | 993 | static inline bool rt2x00_is_usb(struct rt2x00_dev *rt2x00dev) |
@@ -999,6 +1008,13 @@ static inline bool rt2x00_is_soc(struct rt2x00_dev *rt2x00dev) | |||
999 | void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); | 1008 | void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); |
1000 | 1009 | ||
1001 | /** | 1010 | /** |
1011 | * rt2x00queue_unmap_skb - Unmap a skb from DMA. | ||
1012 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
1013 | * @skb: The skb to unmap. | ||
1014 | */ | ||
1015 | void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); | ||
1016 | |||
1017 | /** | ||
1002 | * rt2x00queue_get_queue - Convert queue index to queue pointer | 1018 | * rt2x00queue_get_queue - Convert queue index to queue pointer |
1003 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | 1019 | * @rt2x00dev: Pointer to &struct rt2x00_dev. |
1004 | * @queue: rt2x00 queue index (see &enum data_queue_qid). | 1020 | * @queue: rt2x00 queue index (see &enum data_queue_qid). |
@@ -1015,6 +1031,26 @@ struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, | |||
1015 | enum queue_index index); | 1031 | enum queue_index index); |
1016 | 1032 | ||
1017 | /* | 1033 | /* |
1034 | * Debugfs handlers. | ||
1035 | */ | ||
1036 | /** | ||
1037 | * rt2x00debug_dump_frame - Dump a frame to userspace through debugfs. | ||
1038 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
1039 | * @type: The type of frame that is being dumped. | ||
1040 | * @skb: The skb containing the frame to be dumped. | ||
1041 | */ | ||
1042 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | ||
1043 | void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, | ||
1044 | enum rt2x00_dump_type type, struct sk_buff *skb); | ||
1045 | #else | ||
1046 | static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, | ||
1047 | enum rt2x00_dump_type type, | ||
1048 | struct sk_buff *skb) | ||
1049 | { | ||
1050 | } | ||
1051 | #endif /* CONFIG_RT2X00_LIB_DEBUGFS */ | ||
1052 | |||
1053 | /* | ||
1018 | * Interrupt context handlers. | 1054 | * Interrupt context handlers. |
1019 | */ | 1055 | */ |
1020 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); | 1056 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c index 098315a271ca..8dbd634dae27 100644 --- a/drivers/net/wireless/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/rt2x00/rt2x00config.c | |||
@@ -170,23 +170,27 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | |||
170 | unsigned int ieee80211_flags) | 170 | unsigned int ieee80211_flags) |
171 | { | 171 | { |
172 | struct rt2x00lib_conf libconf; | 172 | struct rt2x00lib_conf libconf; |
173 | u16 hw_value; | ||
173 | 174 | ||
174 | memset(&libconf, 0, sizeof(libconf)); | 175 | memset(&libconf, 0, sizeof(libconf)); |
175 | 176 | ||
176 | libconf.conf = conf; | 177 | libconf.conf = conf; |
177 | 178 | ||
178 | if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) { | 179 | if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) { |
179 | if (conf_is_ht40(conf)) | 180 | if (conf_is_ht40(conf)) { |
180 | __set_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags); | 181 | __set_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags); |
181 | else | 182 | hw_value = rt2x00ht_center_channel(rt2x00dev, conf); |
183 | } else { | ||
182 | __clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags); | 184 | __clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags); |
185 | hw_value = conf->channel->hw_value; | ||
186 | } | ||
183 | 187 | ||
184 | memcpy(&libconf.rf, | 188 | memcpy(&libconf.rf, |
185 | &rt2x00dev->spec.channels[conf->channel->hw_value], | 189 | &rt2x00dev->spec.channels[hw_value], |
186 | sizeof(libconf.rf)); | 190 | sizeof(libconf.rf)); |
187 | 191 | ||
188 | memcpy(&libconf.channel, | 192 | memcpy(&libconf.channel, |
189 | &rt2x00dev->spec.channels_info[conf->channel->hw_value], | 193 | &rt2x00dev->spec.channels_info[hw_value], |
190 | sizeof(libconf.channel)); | 194 | sizeof(libconf.channel)); |
191 | } | 195 | } |
192 | 196 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00debug.c b/drivers/net/wireless/rt2x00/rt2x00debug.c index e9fe93fd8042..b0498e7e7aae 100644 --- a/drivers/net/wireless/rt2x00/rt2x00debug.c +++ b/drivers/net/wireless/rt2x00/rt2x00debug.c | |||
@@ -211,6 +211,7 @@ void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, | |||
211 | if (!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags)) | 211 | if (!test_bit(FRAME_DUMP_FILE_OPEN, &intf->frame_dump_flags)) |
212 | skb_queue_purge(&intf->frame_dump_skbqueue); | 212 | skb_queue_purge(&intf->frame_dump_skbqueue); |
213 | } | 213 | } |
214 | EXPORT_SYMBOL_GPL(rt2x00debug_dump_frame); | ||
214 | 215 | ||
215 | static int rt2x00debug_file_open(struct inode *inode, struct file *file) | 216 | static int rt2x00debug_file_open(struct inode *inode, struct file *file) |
216 | { | 217 | { |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 3ae468c4d760..0b8efe8e6785 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -211,11 +211,6 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
211 | bool success; | 211 | bool success; |
212 | 212 | ||
213 | /* | 213 | /* |
214 | * Unmap the skb. | ||
215 | */ | ||
216 | rt2x00queue_unmap_skb(rt2x00dev, entry->skb); | ||
217 | |||
218 | /* | ||
219 | * Remove L2 padding which was added during | 214 | * Remove L2 padding which was added during |
220 | */ | 215 | */ |
221 | if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags)) | 216 | if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags)) |
@@ -224,7 +219,7 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
224 | /* | 219 | /* |
225 | * If the IV/EIV data was stripped from the frame before it was | 220 | * If the IV/EIV data was stripped from the frame before it was |
226 | * passed to the hardware, we should now reinsert it again because | 221 | * passed to the hardware, we should now reinsert it again because |
227 | * mac80211 will expect the the same data to be present it the | 222 | * mac80211 will expect the same data to be present it the |
228 | * frame as it was passed to us. | 223 | * frame as it was passed to us. |
229 | */ | 224 | */ |
230 | if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) | 225 | if (test_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags)) |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dump.h b/drivers/net/wireless/rt2x00/rt2x00dump.h index ed303b423e41..6df2e0b746b8 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dump.h +++ b/drivers/net/wireless/rt2x00/rt2x00dump.h | |||
@@ -20,7 +20,12 @@ | |||
20 | 20 | ||
21 | /* | 21 | /* |
22 | Module: rt2x00dump | 22 | Module: rt2x00dump |
23 | Abstract: Data structures for the rt2x00debug & userspace. | 23 | Abstract: |
24 | Data structures for the rt2x00debug & userspace. | ||
25 | |||
26 | The declarations in this file can be used by both rt2x00 | ||
27 | and userspace and therefore should be kept together in | ||
28 | this file. | ||
24 | */ | 29 | */ |
25 | 30 | ||
26 | #ifndef RT2X00DUMP_H | 31 | #ifndef RT2X00DUMP_H |
diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c index 5a407602ce3e..c004cd3a8847 100644 --- a/drivers/net/wireless/rt2x00/rt2x00ht.c +++ b/drivers/net/wireless/rt2x00/rt2x00ht.c | |||
@@ -44,11 +44,22 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, | |||
44 | txdesc->mpdu_density = 0; | 44 | txdesc->mpdu_density = 0; |
45 | 45 | ||
46 | txdesc->ba_size = 7; /* FIXME: What value is needed? */ | 46 | txdesc->ba_size = 7; /* FIXME: What value is needed? */ |
47 | txdesc->stbc = 0; /* FIXME: What value is needed? */ | ||
48 | 47 | ||
49 | txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs); | 48 | txdesc->stbc = |
50 | if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) | 49 | (tx_info->flags & IEEE80211_TX_CTL_STBC) >> IEEE80211_TX_CTL_STBC_SHIFT; |
51 | txdesc->mcs |= 0x08; | 50 | |
51 | /* | ||
52 | * If IEEE80211_TX_RC_MCS is set txrate->idx just contains the | ||
53 | * mcs rate to be used | ||
54 | */ | ||
55 | if (txrate->flags & IEEE80211_TX_RC_MCS) { | ||
56 | txdesc->mcs = txrate->idx; | ||
57 | } else { | ||
58 | txdesc->mcs = rt2x00_get_rate_mcs(hwrate->mcs); | ||
59 | if (txrate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) | ||
60 | txdesc->mcs |= 0x08; | ||
61 | } | ||
62 | |||
52 | 63 | ||
53 | /* | 64 | /* |
54 | * Convert flags | 65 | * Convert flags |
@@ -84,3 +95,31 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, | |||
84 | else | 95 | else |
85 | txdesc->txop = TXOP_HTTXOP; | 96 | txdesc->txop = TXOP_HTTXOP; |
86 | } | 97 | } |
98 | |||
99 | u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev, | ||
100 | struct ieee80211_conf *conf) | ||
101 | { | ||
102 | struct hw_mode_spec *spec = &rt2x00dev->spec; | ||
103 | int center_channel; | ||
104 | u16 i; | ||
105 | |||
106 | /* | ||
107 | * Initialize center channel to current channel. | ||
108 | */ | ||
109 | center_channel = spec->channels[conf->channel->hw_value].channel; | ||
110 | |||
111 | /* | ||
112 | * Adjust center channel to HT40+ and HT40- operation. | ||
113 | */ | ||
114 | if (conf_is_ht40_plus(conf)) | ||
115 | center_channel += 2; | ||
116 | else if (conf_is_ht40_minus(conf)) | ||
117 | center_channel -= (center_channel == 14) ? 1 : 2; | ||
118 | |||
119 | for (i = 0; i < spec->num_channels; i++) | ||
120 | if (spec->channels[i].channel == center_channel) | ||
121 | return i; | ||
122 | |||
123 | WARN_ON(1); | ||
124 | return conf->channel->hw_value; | ||
125 | } | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index be2e37fb4071..ed27de1de57b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h | |||
@@ -27,8 +27,6 @@ | |||
27 | #ifndef RT2X00LIB_H | 27 | #ifndef RT2X00LIB_H |
28 | #define RT2X00LIB_H | 28 | #define RT2X00LIB_H |
29 | 29 | ||
30 | #include "rt2x00dump.h" | ||
31 | |||
32 | /* | 30 | /* |
33 | * Interval defines | 31 | * Interval defines |
34 | */ | 32 | */ |
@@ -107,13 +105,6 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev, | |||
107 | struct queue_entry *entry); | 105 | struct queue_entry *entry); |
108 | 106 | ||
109 | /** | 107 | /** |
110 | * rt2x00queue_unmap_skb - Unmap a skb from DMA. | ||
111 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
112 | * @skb: The skb to unmap. | ||
113 | */ | ||
114 | void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); | ||
115 | |||
116 | /** | ||
117 | * rt2x00queue_free_skb - free a skb | 108 | * rt2x00queue_free_skb - free a skb |
118 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | 109 | * @rt2x00dev: Pointer to &struct rt2x00_dev. |
119 | * @skb: The skb to free. | 110 | * @skb: The skb to free. |
@@ -296,8 +287,6 @@ static inline void rt2x00lib_free_firmware(struct rt2x00_dev *rt2x00dev) | |||
296 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS | 287 | #ifdef CONFIG_RT2X00_LIB_DEBUGFS |
297 | void rt2x00debug_register(struct rt2x00_dev *rt2x00dev); | 288 | void rt2x00debug_register(struct rt2x00_dev *rt2x00dev); |
298 | void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev); | 289 | void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev); |
299 | void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, | ||
300 | enum rt2x00_dump_type type, struct sk_buff *skb); | ||
301 | void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev, | 290 | void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev, |
302 | struct rxdone_entry_desc *rxdesc); | 291 | struct rxdone_entry_desc *rxdesc); |
303 | #else | 292 | #else |
@@ -309,12 +298,6 @@ static inline void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev) | |||
309 | { | 298 | { |
310 | } | 299 | } |
311 | 300 | ||
312 | static inline void rt2x00debug_dump_frame(struct rt2x00_dev *rt2x00dev, | ||
313 | enum rt2x00_dump_type type, | ||
314 | struct sk_buff *skb) | ||
315 | { | ||
316 | } | ||
317 | |||
318 | static inline void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev, | 301 | static inline void rt2x00debug_update_crypto(struct rt2x00_dev *rt2x00dev, |
319 | struct rxdone_entry_desc *rxdesc) | 302 | struct rxdone_entry_desc *rxdesc) |
320 | { | 303 | { |
@@ -384,12 +367,21 @@ static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, | |||
384 | void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, | 367 | void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, |
385 | struct txentry_desc *txdesc, | 368 | struct txentry_desc *txdesc, |
386 | const struct rt2x00_rate *hwrate); | 369 | const struct rt2x00_rate *hwrate); |
370 | |||
371 | u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev, | ||
372 | struct ieee80211_conf *conf); | ||
387 | #else | 373 | #else |
388 | static inline void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, | 374 | static inline void rt2x00ht_create_tx_descriptor(struct queue_entry *entry, |
389 | struct txentry_desc *txdesc, | 375 | struct txentry_desc *txdesc, |
390 | const struct rt2x00_rate *hwrate) | 376 | const struct rt2x00_rate *hwrate) |
391 | { | 377 | { |
392 | } | 378 | } |
379 | |||
380 | static inline u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev, | ||
381 | struct ieee80211_conf *conf) | ||
382 | { | ||
383 | return conf->channel->hw_value; | ||
384 | } | ||
393 | #endif /* CONFIG_RT2X00_LIB_HT */ | 385 | #endif /* CONFIG_RT2X00_LIB_HT */ |
394 | 386 | ||
395 | /* | 387 | /* |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index f71eee67f977..10eaffd12b1b 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c | |||
@@ -81,6 +81,24 @@ int rt2x00pci_write_tx_data(struct queue_entry *entry, | |||
81 | return -EINVAL; | 81 | return -EINVAL; |
82 | } | 82 | } |
83 | 83 | ||
84 | /* | ||
85 | * Add the requested extra tx headroom in front of the skb. | ||
86 | */ | ||
87 | skb_push(entry->skb, rt2x00dev->ops->extra_tx_headroom); | ||
88 | memset(entry->skb->data, 0, rt2x00dev->ops->extra_tx_headroom); | ||
89 | |||
90 | /* | ||
91 | * Call the driver's write_tx_datadesc function, if it exists. | ||
92 | */ | ||
93 | if (rt2x00dev->ops->lib->write_tx_datadesc) | ||
94 | rt2x00dev->ops->lib->write_tx_datadesc(entry, txdesc); | ||
95 | |||
96 | /* | ||
97 | * Map the skb to DMA. | ||
98 | */ | ||
99 | if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) | ||
100 | rt2x00queue_map_txskb(rt2x00dev, entry->skb); | ||
101 | |||
84 | return 0; | 102 | return 0; |
85 | } | 103 | } |
86 | EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data); | 104 | EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data); |
@@ -88,6 +106,34 @@ EXPORT_SYMBOL_GPL(rt2x00pci_write_tx_data); | |||
88 | /* | 106 | /* |
89 | * TX/RX data handlers. | 107 | * TX/RX data handlers. |
90 | */ | 108 | */ |
109 | void rt2x00pci_txdone(struct queue_entry *entry, | ||
110 | struct txdone_entry_desc *txdesc) | ||
111 | { | ||
112 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
113 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
114 | |||
115 | /* | ||
116 | * Unmap the skb. | ||
117 | */ | ||
118 | rt2x00queue_unmap_skb(rt2x00dev, entry->skb); | ||
119 | |||
120 | /* | ||
121 | * Remove the extra tx headroom from the skb. | ||
122 | */ | ||
123 | skb_pull(entry->skb, rt2x00dev->ops->extra_tx_headroom); | ||
124 | |||
125 | /* | ||
126 | * Signal that the TX descriptor is no longer in the skb. | ||
127 | */ | ||
128 | skbdesc->flags &= ~SKBDESC_DESC_IN_SKB; | ||
129 | |||
130 | /* | ||
131 | * Pass on to rt2x00lib. | ||
132 | */ | ||
133 | rt2x00lib_txdone(entry, txdesc); | ||
134 | } | ||
135 | EXPORT_SYMBOL_GPL(rt2x00pci_txdone); | ||
136 | |||
91 | void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | 137 | void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) |
92 | { | 138 | { |
93 | struct data_queue *queue = rt2x00dev->rx; | 139 | struct data_queue *queue = rt2x00dev->rx; |
@@ -305,7 +351,10 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) | |||
305 | rt2x00dev->irq = pci_dev->irq; | 351 | rt2x00dev->irq = pci_dev->irq; |
306 | rt2x00dev->name = pci_name(pci_dev); | 352 | rt2x00dev->name = pci_name(pci_dev); |
307 | 353 | ||
308 | rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI); | 354 | if (pci_dev->is_pcie) |
355 | rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE); | ||
356 | else | ||
357 | rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCI); | ||
309 | 358 | ||
310 | retval = rt2x00pci_alloc_reg(rt2x00dev); | 359 | retval = rt2x00pci_alloc_reg(rt2x00dev); |
311 | if (retval) | 360 | if (retval) |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h index 51bcef3839ce..00528b8a754d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.h +++ b/drivers/net/wireless/rt2x00/rt2x00pci.h | |||
@@ -109,6 +109,14 @@ struct queue_entry_priv_pci { | |||
109 | }; | 109 | }; |
110 | 110 | ||
111 | /** | 111 | /** |
112 | * rt2x00pci_txdone - Handle TX done events. | ||
113 | * @entry: The queue entry for which a TX done event was received. | ||
114 | * @txdesc: The TX done descriptor for the entry. | ||
115 | */ | ||
116 | void rt2x00pci_txdone(struct queue_entry *entry, | ||
117 | struct txdone_entry_desc *txdesc); | ||
118 | |||
119 | /** | ||
112 | * rt2x00pci_rxdone - Handle RX done events | 120 | * rt2x00pci_rxdone - Handle RX done events |
113 | * @rt2x00dev: Device pointer, see &struct rt2x00_dev. | 121 | * @rt2x00dev: Device pointer, see &struct rt2x00_dev. |
114 | */ | 122 | */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 20dbdd6fb904..35858b178e8f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -100,21 +100,8 @@ void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) | |||
100 | { | 100 | { |
101 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 101 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
102 | 102 | ||
103 | /* | ||
104 | * If device has requested headroom, we should make sure that | ||
105 | * is also mapped to the DMA so it can be used for transfering | ||
106 | * additional descriptor information to the hardware. | ||
107 | */ | ||
108 | skb_push(skb, rt2x00dev->ops->extra_tx_headroom); | ||
109 | |||
110 | skbdesc->skb_dma = | 103 | skbdesc->skb_dma = |
111 | dma_map_single(rt2x00dev->dev, skb->data, skb->len, DMA_TO_DEVICE); | 104 | dma_map_single(rt2x00dev->dev, skb->data, skb->len, DMA_TO_DEVICE); |
112 | |||
113 | /* | ||
114 | * Restore data pointer to original location again. | ||
115 | */ | ||
116 | skb_pull(skb, rt2x00dev->ops->extra_tx_headroom); | ||
117 | |||
118 | skbdesc->flags |= SKBDESC_DMA_MAPPED_TX; | 105 | skbdesc->flags |= SKBDESC_DMA_MAPPED_TX; |
119 | } | 106 | } |
120 | EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb); | 107 | EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb); |
@@ -130,16 +117,12 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) | |||
130 | } | 117 | } |
131 | 118 | ||
132 | if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) { | 119 | if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) { |
133 | /* | 120 | dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len, |
134 | * Add headroom to the skb length, it has been removed | ||
135 | * by the driver, but it was actually mapped to DMA. | ||
136 | */ | ||
137 | dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, | ||
138 | skb->len + rt2x00dev->ops->extra_tx_headroom, | ||
139 | DMA_TO_DEVICE); | 121 | DMA_TO_DEVICE); |
140 | skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX; | 122 | skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX; |
141 | } | 123 | } |
142 | } | 124 | } |
125 | EXPORT_SYMBOL_GPL(rt2x00queue_unmap_skb); | ||
143 | 126 | ||
144 | void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) | 127 | void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) |
145 | { | 128 | { |
@@ -421,7 +404,6 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, | |||
421 | { | 404 | { |
422 | struct data_queue *queue = entry->queue; | 405 | struct data_queue *queue = entry->queue; |
423 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; | 406 | struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; |
424 | enum rt2x00_dump_type dump_type; | ||
425 | 407 | ||
426 | rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc); | 408 | rt2x00dev->ops->lib->write_tx_desc(rt2x00dev, entry->skb, txdesc); |
427 | 409 | ||
@@ -429,9 +411,7 @@ static void rt2x00queue_write_tx_descriptor(struct queue_entry *entry, | |||
429 | * All processing on the frame has been completed, this means | 411 | * All processing on the frame has been completed, this means |
430 | * it is now ready to be dumped to userspace through debugfs. | 412 | * it is now ready to be dumped to userspace through debugfs. |
431 | */ | 413 | */ |
432 | dump_type = (txdesc->queue == QID_BEACON) ? | 414 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_TX, entry->skb); |
433 | DUMP_FRAME_BEACON : DUMP_FRAME_TX; | ||
434 | rt2x00debug_dump_frame(rt2x00dev, dump_type, entry->skb); | ||
435 | } | 415 | } |
436 | 416 | ||
437 | static void rt2x00queue_kick_tx_queue(struct queue_entry *entry, | 417 | static void rt2x00queue_kick_tx_queue(struct queue_entry *entry, |
@@ -537,9 +517,6 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, | |||
537 | return -EIO; | 517 | return -EIO; |
538 | } | 518 | } |
539 | 519 | ||
540 | if (test_bit(DRIVER_REQUIRE_DMA, &queue->rt2x00dev->flags)) | ||
541 | rt2x00queue_map_txskb(queue->rt2x00dev, skb); | ||
542 | |||
543 | set_bit(ENTRY_DATA_PENDING, &entry->flags); | 520 | set_bit(ENTRY_DATA_PENDING, &entry->flags); |
544 | 521 | ||
545 | rt2x00queue_index_inc(queue, Q_INDEX); | 522 | rt2x00queue_index_inc(queue, Q_INDEX); |
@@ -595,11 +572,6 @@ int rt2x00queue_update_beacon(struct rt2x00_dev *rt2x00dev, | |||
595 | skbdesc->entry = intf->beacon; | 572 | skbdesc->entry = intf->beacon; |
596 | 573 | ||
597 | /* | 574 | /* |
598 | * Write TX descriptor into reserved room in front of the beacon. | ||
599 | */ | ||
600 | rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); | ||
601 | |||
602 | /* | ||
603 | * Send beacon to hardware and enable beacon genaration.. | 575 | * Send beacon to hardware and enable beacon genaration.. |
604 | */ | 576 | */ |
605 | rt2x00dev->ops->lib->write_beacon(intf->beacon, &txdesc); | 577 | rt2x00dev->ops->lib->write_beacon(intf->beacon, &txdesc); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index bd1546ba7ad2..b45bc24c3dae 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -113,26 +113,6 @@ int rt2x00usb_vendor_request_buff(struct rt2x00_dev *rt2x00dev, | |||
113 | const u16 offset, void *buffer, | 113 | const u16 offset, void *buffer, |
114 | const u16 buffer_length, const int timeout) | 114 | const u16 buffer_length, const int timeout) |
115 | { | 115 | { |
116 | int status; | ||
117 | |||
118 | mutex_lock(&rt2x00dev->csr_mutex); | ||
119 | |||
120 | status = rt2x00usb_vendor_req_buff_lock(rt2x00dev, request, | ||
121 | requesttype, offset, buffer, | ||
122 | buffer_length, timeout); | ||
123 | |||
124 | mutex_unlock(&rt2x00dev->csr_mutex); | ||
125 | |||
126 | return status; | ||
127 | } | ||
128 | EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff); | ||
129 | |||
130 | int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev, | ||
131 | const u8 request, const u8 requesttype, | ||
132 | const u16 offset, const void *buffer, | ||
133 | const u16 buffer_length, | ||
134 | const int timeout) | ||
135 | { | ||
136 | int status = 0; | 116 | int status = 0; |
137 | unsigned char *tb; | 117 | unsigned char *tb; |
138 | u16 off, len, bsize; | 118 | u16 off, len, bsize; |
@@ -157,7 +137,7 @@ int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev, | |||
157 | 137 | ||
158 | return status; | 138 | return status; |
159 | } | 139 | } |
160 | EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_large_buff); | 140 | EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff); |
161 | 141 | ||
162 | int rt2x00usb_regbusy_read(struct rt2x00_dev *rt2x00dev, | 142 | int rt2x00usb_regbusy_read(struct rt2x00_dev *rt2x00dev, |
163 | const unsigned int offset, | 143 | const unsigned int offset, |
@@ -198,6 +178,11 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) | |||
198 | return; | 178 | return; |
199 | 179 | ||
200 | /* | 180 | /* |
181 | * Remove the descriptor from the front of the skb. | ||
182 | */ | ||
183 | skb_pull(entry->skb, entry->queue->desc_size); | ||
184 | |||
185 | /* | ||
201 | * Obtain the status about this packet. | 186 | * Obtain the status about this packet. |
202 | * Note that when the status is 0 it does not mean the | 187 | * Note that when the status is 0 it does not mean the |
203 | * frame was send out correctly. It only means the frame | 188 | * frame was send out correctly. It only means the frame |
@@ -243,10 +228,10 @@ int rt2x00usb_write_tx_data(struct queue_entry *entry, | |||
243 | rt2x00usb_interrupt_txdone, entry); | 228 | rt2x00usb_interrupt_txdone, entry); |
244 | 229 | ||
245 | /* | 230 | /* |
246 | * Make sure the skb->data pointer points to the frame, not the | 231 | * Call the driver's write_tx_datadesc function, if it exists. |
247 | * descriptor. | ||
248 | */ | 232 | */ |
249 | skb_pull(entry->skb, entry->queue->desc_size); | 233 | if (rt2x00dev->ops->lib->write_tx_datadesc) |
234 | rt2x00dev->ops->lib->write_tx_datadesc(entry, txdesc); | ||
250 | 235 | ||
251 | return 0; | 236 | return 0; |
252 | } | 237 | } |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index 621d0f829251..255b81ef9530 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h | |||
@@ -167,25 +167,6 @@ int rt2x00usb_vendor_req_buff_lock(struct rt2x00_dev *rt2x00dev, | |||
167 | const u16 buffer_length, const int timeout); | 167 | const u16 buffer_length, const int timeout); |
168 | 168 | ||
169 | /** | 169 | /** |
170 | * rt2x00usb_vendor_request_large_buff - Send register command to device (buffered) | ||
171 | * @rt2x00dev: Pointer to &struct rt2x00_dev | ||
172 | * @request: USB vendor command (See &enum rt2x00usb_vendor_request) | ||
173 | * @requesttype: Request type &USB_VENDOR_REQUEST_* | ||
174 | * @offset: Register start offset to perform action on | ||
175 | * @buffer: Buffer where information will be read/written to by device | ||
176 | * @buffer_length: Size of &buffer | ||
177 | * @timeout: Operation timeout | ||
178 | * | ||
179 | * This function is used to transfer register data in blocks larger | ||
180 | * then CSR_CACHE_SIZE. Use for firmware upload, keys and beacons. | ||
181 | */ | ||
182 | int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev, | ||
183 | const u8 request, const u8 requesttype, | ||
184 | const u16 offset, const void *buffer, | ||
185 | const u16 buffer_length, | ||
186 | const int timeout); | ||
187 | |||
188 | /** | ||
189 | * rt2x00usb_vendor_request_sw - Send single register command to device | 170 | * rt2x00usb_vendor_request_sw - Send single register command to device |
190 | * @rt2x00dev: Pointer to &struct rt2x00_dev | 171 | * @rt2x00dev: Pointer to &struct rt2x00_dev |
191 | * @request: USB vendor command (See &enum rt2x00usb_vendor_request) | 172 | * @request: USB vendor command (See &enum rt2x00usb_vendor_request) |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 6a74baf4e934..243df08ae910 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -1874,6 +1874,16 @@ static void rt61pci_write_beacon(struct queue_entry *entry, | |||
1874 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | 1874 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); |
1875 | 1875 | ||
1876 | /* | 1876 | /* |
1877 | * Write the TX descriptor for the beacon. | ||
1878 | */ | ||
1879 | rt61pci_write_tx_desc(rt2x00dev, entry->skb, txdesc); | ||
1880 | |||
1881 | /* | ||
1882 | * Dump beacon to userspace through debugfs. | ||
1883 | */ | ||
1884 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); | ||
1885 | |||
1886 | /* | ||
1877 | * Write entire beacon with descriptor to register. | 1887 | * Write entire beacon with descriptor to register. |
1878 | */ | 1888 | */ |
1879 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); | 1889 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); |
@@ -2100,7 +2110,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
2100 | __set_bit(TXDONE_UNKNOWN, &txdesc.flags); | 2110 | __set_bit(TXDONE_UNKNOWN, &txdesc.flags); |
2101 | txdesc.retry = 0; | 2111 | txdesc.retry = 0; |
2102 | 2112 | ||
2103 | rt2x00lib_txdone(entry_done, &txdesc); | 2113 | rt2x00pci_txdone(entry_done, &txdesc); |
2104 | entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | 2114 | entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
2105 | } | 2115 | } |
2106 | 2116 | ||
@@ -2120,7 +2130,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
2120 | } | 2130 | } |
2121 | txdesc.retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT); | 2131 | txdesc.retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT); |
2122 | 2132 | ||
2123 | rt2x00lib_txdone(entry, &txdesc); | 2133 | rt2x00pci_txdone(entry, &txdesc); |
2124 | } | 2134 | } |
2125 | } | 2135 | } |
2126 | 2136 | ||
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h index df80f1af22a4..e2e728ab0b2e 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.h +++ b/drivers/net/wireless/rt2x00/rt61pci.h | |||
@@ -153,13 +153,13 @@ struct hw_key_entry { | |||
153 | u8 key[16]; | 153 | u8 key[16]; |
154 | u8 tx_mic[8]; | 154 | u8 tx_mic[8]; |
155 | u8 rx_mic[8]; | 155 | u8 rx_mic[8]; |
156 | } __attribute__ ((packed)); | 156 | } __packed; |
157 | 157 | ||
158 | struct hw_pairwise_ta_entry { | 158 | struct hw_pairwise_ta_entry { |
159 | u8 address[6]; | 159 | u8 address[6]; |
160 | u8 cipher; | 160 | u8 cipher; |
161 | u8 reserved; | 161 | u8 reserved; |
162 | } __attribute__ ((packed)); | 162 | } __packed; |
163 | 163 | ||
164 | /* | 164 | /* |
165 | * Other on-chip shared memory space. | 165 | * Other on-chip shared memory space. |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 6e0d82efe924..113ad690f9d3 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -270,7 +270,6 @@ static int rt73usb_config_shared_key(struct rt2x00_dev *rt2x00dev, | |||
270 | { | 270 | { |
271 | struct hw_key_entry key_entry; | 271 | struct hw_key_entry key_entry; |
272 | struct rt2x00_field32 field; | 272 | struct rt2x00_field32 field; |
273 | int timeout; | ||
274 | u32 mask; | 273 | u32 mask; |
275 | u32 reg; | 274 | u32 reg; |
276 | 275 | ||
@@ -306,12 +305,8 @@ static int rt73usb_config_shared_key(struct rt2x00_dev *rt2x00dev, | |||
306 | sizeof(key_entry.rx_mic)); | 305 | sizeof(key_entry.rx_mic)); |
307 | 306 | ||
308 | reg = SHARED_KEY_ENTRY(key->hw_key_idx); | 307 | reg = SHARED_KEY_ENTRY(key->hw_key_idx); |
309 | timeout = REGISTER_TIMEOUT32(sizeof(key_entry)); | 308 | rt2x00usb_register_multiwrite(rt2x00dev, reg, |
310 | rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, | 309 | &key_entry, sizeof(key_entry)); |
311 | USB_VENDOR_REQUEST_OUT, reg, | ||
312 | &key_entry, | ||
313 | sizeof(key_entry), | ||
314 | timeout); | ||
315 | 310 | ||
316 | /* | 311 | /* |
317 | * The cipher types are stored over 2 registers. | 312 | * The cipher types are stored over 2 registers. |
@@ -372,7 +367,6 @@ static int rt73usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev, | |||
372 | { | 367 | { |
373 | struct hw_pairwise_ta_entry addr_entry; | 368 | struct hw_pairwise_ta_entry addr_entry; |
374 | struct hw_key_entry key_entry; | 369 | struct hw_key_entry key_entry; |
375 | int timeout; | ||
376 | u32 mask; | 370 | u32 mask; |
377 | u32 reg; | 371 | u32 reg; |
378 | 372 | ||
@@ -407,17 +401,11 @@ static int rt73usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev, | |||
407 | sizeof(key_entry.rx_mic)); | 401 | sizeof(key_entry.rx_mic)); |
408 | 402 | ||
409 | reg = PAIRWISE_KEY_ENTRY(key->hw_key_idx); | 403 | reg = PAIRWISE_KEY_ENTRY(key->hw_key_idx); |
410 | timeout = REGISTER_TIMEOUT32(sizeof(key_entry)); | 404 | rt2x00usb_register_multiwrite(rt2x00dev, reg, |
411 | rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, | 405 | &key_entry, sizeof(key_entry)); |
412 | USB_VENDOR_REQUEST_OUT, reg, | ||
413 | &key_entry, | ||
414 | sizeof(key_entry), | ||
415 | timeout); | ||
416 | 406 | ||
417 | /* | 407 | /* |
418 | * Send the address and cipher type to the hardware register. | 408 | * Send the address and cipher type to the hardware register. |
419 | * This data fits within the CSR cache size, so we can use | ||
420 | * rt2x00usb_register_multiwrite() directly. | ||
421 | */ | 409 | */ |
422 | memset(&addr_entry, 0, sizeof(addr_entry)); | 410 | memset(&addr_entry, 0, sizeof(addr_entry)); |
423 | memcpy(&addr_entry, crypto->address, ETH_ALEN); | 411 | memcpy(&addr_entry, crypto->address, ETH_ALEN); |
@@ -1092,11 +1080,7 @@ static int rt73usb_load_firmware(struct rt2x00_dev *rt2x00dev, | |||
1092 | /* | 1080 | /* |
1093 | * Write firmware to device. | 1081 | * Write firmware to device. |
1094 | */ | 1082 | */ |
1095 | rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, | 1083 | rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, data, len); |
1096 | USB_VENDOR_REQUEST_OUT, | ||
1097 | FIRMWARE_IMAGE_BASE, | ||
1098 | data, len, | ||
1099 | REGISTER_TIMEOUT32(len)); | ||
1100 | 1084 | ||
1101 | /* | 1085 | /* |
1102 | * Send firmware request to device to load firmware, | 1086 | * Send firmware request to device to load firmware, |
@@ -1442,7 +1426,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1442 | struct txentry_desc *txdesc) | 1426 | struct txentry_desc *txdesc) |
1443 | { | 1427 | { |
1444 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 1428 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1445 | __le32 *txd = (__le32 *)(skb->data - TXD_DESC_SIZE); | 1429 | __le32 *txd = (__le32 *) skb->data; |
1446 | u32 word; | 1430 | u32 word; |
1447 | 1431 | ||
1448 | /* | 1432 | /* |
@@ -1505,6 +1489,7 @@ static void rt73usb_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1505 | /* | 1489 | /* |
1506 | * Register descriptor details in skb frame descriptor. | 1490 | * Register descriptor details in skb frame descriptor. |
1507 | */ | 1491 | */ |
1492 | skbdesc->flags |= SKBDESC_DESC_IN_SKB; | ||
1508 | skbdesc->desc = txd; | 1493 | skbdesc->desc = txd; |
1509 | skbdesc->desc_len = TXD_DESC_SIZE; | 1494 | skbdesc->desc_len = TXD_DESC_SIZE; |
1510 | } | 1495 | } |
@@ -1528,18 +1513,27 @@ static void rt73usb_write_beacon(struct queue_entry *entry, | |||
1528 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); | 1513 | rt2x00usb_register_write(rt2x00dev, TXRX_CSR9, reg); |
1529 | 1514 | ||
1530 | /* | 1515 | /* |
1531 | * Take the descriptor in front of the skb into account. | 1516 | * Add space for the descriptor in front of the skb. |
1532 | */ | 1517 | */ |
1533 | skb_push(entry->skb, TXD_DESC_SIZE); | 1518 | skb_push(entry->skb, TXD_DESC_SIZE); |
1519 | memset(entry->skb->data, 0, TXD_DESC_SIZE); | ||
1520 | |||
1521 | /* | ||
1522 | * Write the TX descriptor for the beacon. | ||
1523 | */ | ||
1524 | rt73usb_write_tx_desc(rt2x00dev, entry->skb, txdesc); | ||
1525 | |||
1526 | /* | ||
1527 | * Dump beacon to userspace through debugfs. | ||
1528 | */ | ||
1529 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_BEACON, entry->skb); | ||
1534 | 1530 | ||
1535 | /* | 1531 | /* |
1536 | * Write entire beacon with descriptor to register. | 1532 | * Write entire beacon with descriptor to register. |
1537 | */ | 1533 | */ |
1538 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); | 1534 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); |
1539 | rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE, | 1535 | rt2x00usb_register_multiwrite(rt2x00dev, beacon_base, |
1540 | USB_VENDOR_REQUEST_OUT, beacon_base, | 1536 | entry->skb->data, entry->skb->len); |
1541 | entry->skb->data, entry->skb->len, | ||
1542 | REGISTER_TIMEOUT32(entry->skb->len)); | ||
1543 | 1537 | ||
1544 | /* | 1538 | /* |
1545 | * Enable beaconing again. | 1539 | * Enable beaconing again. |
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h index 7abe7eb14555..44d5b2bebd39 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.h +++ b/drivers/net/wireless/rt2x00/rt73usb.h | |||
@@ -108,13 +108,13 @@ struct hw_key_entry { | |||
108 | u8 key[16]; | 108 | u8 key[16]; |
109 | u8 tx_mic[8]; | 109 | u8 tx_mic[8]; |
110 | u8 rx_mic[8]; | 110 | u8 rx_mic[8]; |
111 | } __attribute__ ((packed)); | 111 | } __packed; |
112 | 112 | ||
113 | struct hw_pairwise_ta_entry { | 113 | struct hw_pairwise_ta_entry { |
114 | u8 address[6]; | 114 | u8 address[6]; |
115 | u8 cipher; | 115 | u8 cipher; |
116 | u8 reserved; | 116 | u8 reserved; |
117 | } __attribute__ ((packed)); | 117 | } __packed; |
118 | 118 | ||
119 | /* | 119 | /* |
120 | * Since NULL frame won't be that long (256 byte), | 120 | * Since NULL frame won't be that long (256 byte), |