diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-20 20:43:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-20 20:43:29 -0400 |
commit | db6d8c7a4027b48d797b369a53f8470aaeed7063 (patch) | |
tree | e140c104a89abc2154e1f41a7db8ebecbb6fa0b4 /drivers/net/wireless/rt2x00/rt61pci.c | |
parent | 3a533374283aea50eab3976d8a6d30532175f009 (diff) | |
parent | fb65a7c091529bfffb1262515252c0d0f6241c5c (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (1232 commits)
iucv: Fix bad merging.
net_sched: Add size table for qdiscs
net_sched: Add accessor function for packet length for qdiscs
net_sched: Add qdisc_enqueue wrapper
highmem: Export totalhigh_pages.
ipv6 mcast: Omit redundant address family checks in ip6_mc_source().
net: Use standard structures for generic socket address structures.
ipv6 netns: Make several "global" sysctl variables namespace aware.
netns: Use net_eq() to compare net-namespaces for optimization.
ipv6: remove unused macros from net/ipv6.h
ipv6: remove unused parameter from ip6_ra_control
tcp: fix kernel panic with listening_get_next
tcp: Remove redundant checks when setting eff_sacks
tcp: options clean up
tcp: Fix MD5 signatures for non-linear skbs
sctp: Update sctp global memory limit allocations.
sctp: remove unnecessary byteshifting, calculate directly in big-endian
sctp: Allow only 1 listening socket with SO_REUSEADDR
sctp: Do not leak memory on multiple listen() calls
sctp: Support ipv6only AF_INET6 sockets.
...
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt61pci.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt61pci.c | 344 |
1 files changed, 152 insertions, 192 deletions
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 580f90b63de7..f7c1f92c1448 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -330,6 +330,17 @@ static int rt61pci_blink_set(struct led_classdev *led_cdev, | |||
330 | 330 | ||
331 | return 0; | 331 | return 0; |
332 | } | 332 | } |
333 | |||
334 | static void rt61pci_init_led(struct rt2x00_dev *rt2x00dev, | ||
335 | struct rt2x00_led *led, | ||
336 | enum led_type type) | ||
337 | { | ||
338 | led->rt2x00dev = rt2x00dev; | ||
339 | led->type = type; | ||
340 | led->led_dev.brightness_set = rt61pci_brightness_set; | ||
341 | led->led_dev.blink_set = rt61pci_blink_set; | ||
342 | led->flags = LED_INITIALIZED; | ||
343 | } | ||
333 | #endif /* CONFIG_RT61PCI_LEDS */ | 344 | #endif /* CONFIG_RT61PCI_LEDS */ |
334 | 345 | ||
335 | /* | 346 | /* |
@@ -1018,49 +1029,35 @@ static int rt61pci_load_firmware(struct rt2x00_dev *rt2x00dev, const void *data, | |||
1018 | static void rt61pci_init_rxentry(struct rt2x00_dev *rt2x00dev, | 1029 | static void rt61pci_init_rxentry(struct rt2x00_dev *rt2x00dev, |
1019 | struct queue_entry *entry) | 1030 | struct queue_entry *entry) |
1020 | { | 1031 | { |
1021 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; | 1032 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
1033 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
1022 | u32 word; | 1034 | u32 word; |
1023 | 1035 | ||
1024 | rt2x00_desc_read(priv_rx->desc, 5, &word); | 1036 | rt2x00_desc_read(entry_priv->desc, 5, &word); |
1025 | rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS, | 1037 | rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS, |
1026 | priv_rx->data_dma); | 1038 | skbdesc->skb_dma); |
1027 | rt2x00_desc_write(priv_rx->desc, 5, word); | 1039 | rt2x00_desc_write(entry_priv->desc, 5, word); |
1028 | 1040 | ||
1029 | rt2x00_desc_read(priv_rx->desc, 0, &word); | 1041 | rt2x00_desc_read(entry_priv->desc, 0, &word); |
1030 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); | 1042 | rt2x00_set_field32(&word, RXD_W0_OWNER_NIC, 1); |
1031 | rt2x00_desc_write(priv_rx->desc, 0, word); | 1043 | rt2x00_desc_write(entry_priv->desc, 0, word); |
1032 | } | 1044 | } |
1033 | 1045 | ||
1034 | static void rt61pci_init_txentry(struct rt2x00_dev *rt2x00dev, | 1046 | static void rt61pci_init_txentry(struct rt2x00_dev *rt2x00dev, |
1035 | struct queue_entry *entry) | 1047 | struct queue_entry *entry) |
1036 | { | 1048 | { |
1037 | struct queue_entry_priv_pci_tx *priv_tx = entry->priv_data; | 1049 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
1038 | u32 word; | 1050 | u32 word; |
1039 | 1051 | ||
1040 | rt2x00_desc_read(priv_tx->desc, 1, &word); | 1052 | rt2x00_desc_read(entry_priv->desc, 0, &word); |
1041 | rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1); | ||
1042 | rt2x00_desc_write(priv_tx->desc, 1, word); | ||
1043 | |||
1044 | rt2x00_desc_read(priv_tx->desc, 5, &word); | ||
1045 | rt2x00_set_field32(&word, TXD_W5_PID_TYPE, entry->queue->qid); | ||
1046 | rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, entry->entry_idx); | ||
1047 | rt2x00_desc_write(priv_tx->desc, 5, word); | ||
1048 | |||
1049 | rt2x00_desc_read(priv_tx->desc, 6, &word); | ||
1050 | rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, | ||
1051 | priv_tx->data_dma); | ||
1052 | rt2x00_desc_write(priv_tx->desc, 6, word); | ||
1053 | |||
1054 | rt2x00_desc_read(priv_tx->desc, 0, &word); | ||
1055 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); | 1053 | rt2x00_set_field32(&word, TXD_W0_VALID, 0); |
1056 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); | 1054 | rt2x00_set_field32(&word, TXD_W0_OWNER_NIC, 0); |
1057 | rt2x00_desc_write(priv_tx->desc, 0, word); | 1055 | rt2x00_desc_write(entry_priv->desc, 0, word); |
1058 | } | 1056 | } |
1059 | 1057 | ||
1060 | static int rt61pci_init_queues(struct rt2x00_dev *rt2x00dev) | 1058 | static int rt61pci_init_queues(struct rt2x00_dev *rt2x00dev) |
1061 | { | 1059 | { |
1062 | struct queue_entry_priv_pci_rx *priv_rx; | 1060 | struct queue_entry_priv_pci *entry_priv; |
1063 | struct queue_entry_priv_pci_tx *priv_tx; | ||
1064 | u32 reg; | 1061 | u32 reg; |
1065 | 1062 | ||
1066 | /* | 1063 | /* |
@@ -1082,28 +1079,28 @@ static int rt61pci_init_queues(struct rt2x00_dev *rt2x00dev) | |||
1082 | rt2x00dev->tx[0].desc_size / 4); | 1079 | rt2x00dev->tx[0].desc_size / 4); |
1083 | rt2x00pci_register_write(rt2x00dev, TX_RING_CSR1, reg); | 1080 | rt2x00pci_register_write(rt2x00dev, TX_RING_CSR1, reg); |
1084 | 1081 | ||
1085 | priv_tx = rt2x00dev->tx[0].entries[0].priv_data; | 1082 | entry_priv = rt2x00dev->tx[0].entries[0].priv_data; |
1086 | rt2x00pci_register_read(rt2x00dev, AC0_BASE_CSR, ®); | 1083 | rt2x00pci_register_read(rt2x00dev, AC0_BASE_CSR, ®); |
1087 | rt2x00_set_field32(®, AC0_BASE_CSR_RING_REGISTER, | 1084 | rt2x00_set_field32(®, AC0_BASE_CSR_RING_REGISTER, |
1088 | priv_tx->desc_dma); | 1085 | entry_priv->desc_dma); |
1089 | rt2x00pci_register_write(rt2x00dev, AC0_BASE_CSR, reg); | 1086 | rt2x00pci_register_write(rt2x00dev, AC0_BASE_CSR, reg); |
1090 | 1087 | ||
1091 | priv_tx = rt2x00dev->tx[1].entries[0].priv_data; | 1088 | entry_priv = rt2x00dev->tx[1].entries[0].priv_data; |
1092 | rt2x00pci_register_read(rt2x00dev, AC1_BASE_CSR, ®); | 1089 | rt2x00pci_register_read(rt2x00dev, AC1_BASE_CSR, ®); |
1093 | rt2x00_set_field32(®, AC1_BASE_CSR_RING_REGISTER, | 1090 | rt2x00_set_field32(®, AC1_BASE_CSR_RING_REGISTER, |
1094 | priv_tx->desc_dma); | 1091 | entry_priv->desc_dma); |
1095 | rt2x00pci_register_write(rt2x00dev, AC1_BASE_CSR, reg); | 1092 | rt2x00pci_register_write(rt2x00dev, AC1_BASE_CSR, reg); |
1096 | 1093 | ||
1097 | priv_tx = rt2x00dev->tx[2].entries[0].priv_data; | 1094 | entry_priv = rt2x00dev->tx[2].entries[0].priv_data; |
1098 | rt2x00pci_register_read(rt2x00dev, AC2_BASE_CSR, ®); | 1095 | rt2x00pci_register_read(rt2x00dev, AC2_BASE_CSR, ®); |
1099 | rt2x00_set_field32(®, AC2_BASE_CSR_RING_REGISTER, | 1096 | rt2x00_set_field32(®, AC2_BASE_CSR_RING_REGISTER, |
1100 | priv_tx->desc_dma); | 1097 | entry_priv->desc_dma); |
1101 | rt2x00pci_register_write(rt2x00dev, AC2_BASE_CSR, reg); | 1098 | rt2x00pci_register_write(rt2x00dev, AC2_BASE_CSR, reg); |
1102 | 1099 | ||
1103 | priv_tx = rt2x00dev->tx[3].entries[0].priv_data; | 1100 | entry_priv = rt2x00dev->tx[3].entries[0].priv_data; |
1104 | rt2x00pci_register_read(rt2x00dev, AC3_BASE_CSR, ®); | 1101 | rt2x00pci_register_read(rt2x00dev, AC3_BASE_CSR, ®); |
1105 | rt2x00_set_field32(®, AC3_BASE_CSR_RING_REGISTER, | 1102 | rt2x00_set_field32(®, AC3_BASE_CSR_RING_REGISTER, |
1106 | priv_tx->desc_dma); | 1103 | entry_priv->desc_dma); |
1107 | rt2x00pci_register_write(rt2x00dev, AC3_BASE_CSR, reg); | 1104 | rt2x00pci_register_write(rt2x00dev, AC3_BASE_CSR, reg); |
1108 | 1105 | ||
1109 | rt2x00pci_register_read(rt2x00dev, RX_RING_CSR, ®); | 1106 | rt2x00pci_register_read(rt2x00dev, RX_RING_CSR, ®); |
@@ -1113,10 +1110,10 @@ static int rt61pci_init_queues(struct rt2x00_dev *rt2x00dev) | |||
1113 | rt2x00_set_field32(®, RX_RING_CSR_RXD_WRITEBACK_SIZE, 4); | 1110 | rt2x00_set_field32(®, RX_RING_CSR_RXD_WRITEBACK_SIZE, 4); |
1114 | rt2x00pci_register_write(rt2x00dev, RX_RING_CSR, reg); | 1111 | rt2x00pci_register_write(rt2x00dev, RX_RING_CSR, reg); |
1115 | 1112 | ||
1116 | priv_rx = rt2x00dev->rx->entries[0].priv_data; | 1113 | entry_priv = rt2x00dev->rx->entries[0].priv_data; |
1117 | rt2x00pci_register_read(rt2x00dev, RX_BASE_CSR, ®); | 1114 | rt2x00pci_register_read(rt2x00dev, RX_BASE_CSR, ®); |
1118 | rt2x00_set_field32(®, RX_BASE_CSR_RING_REGISTER, | 1115 | rt2x00_set_field32(®, RX_BASE_CSR_RING_REGISTER, |
1119 | priv_rx->desc_dma); | 1116 | entry_priv->desc_dma); |
1120 | rt2x00pci_register_write(rt2x00dev, RX_BASE_CSR, reg); | 1117 | rt2x00pci_register_write(rt2x00dev, RX_BASE_CSR, reg); |
1121 | 1118 | ||
1122 | rt2x00pci_register_read(rt2x00dev, TX_DMA_DST_CSR, ®); | 1119 | rt2x00pci_register_read(rt2x00dev, TX_DMA_DST_CSR, ®); |
@@ -1294,25 +1291,32 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev) | |||
1294 | return 0; | 1291 | return 0; |
1295 | } | 1292 | } |
1296 | 1293 | ||
1297 | static int rt61pci_init_bbp(struct rt2x00_dev *rt2x00dev) | 1294 | static int rt61pci_wait_bbp_ready(struct rt2x00_dev *rt2x00dev) |
1298 | { | 1295 | { |
1299 | unsigned int i; | 1296 | unsigned int i; |
1300 | u16 eeprom; | ||
1301 | u8 reg_id; | ||
1302 | u8 value; | 1297 | u8 value; |
1303 | 1298 | ||
1304 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 1299 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { |
1305 | rt61pci_bbp_read(rt2x00dev, 0, &value); | 1300 | rt61pci_bbp_read(rt2x00dev, 0, &value); |
1306 | if ((value != 0xff) && (value != 0x00)) | 1301 | if ((value != 0xff) && (value != 0x00)) |
1307 | goto continue_csr_init; | 1302 | return 0; |
1308 | NOTICE(rt2x00dev, "Waiting for BBP register.\n"); | ||
1309 | udelay(REGISTER_BUSY_DELAY); | 1303 | udelay(REGISTER_BUSY_DELAY); |
1310 | } | 1304 | } |
1311 | 1305 | ||
1312 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); | 1306 | ERROR(rt2x00dev, "BBP register access failed, aborting.\n"); |
1313 | return -EACCES; | 1307 | return -EACCES; |
1308 | } | ||
1309 | |||
1310 | static int rt61pci_init_bbp(struct rt2x00_dev *rt2x00dev) | ||
1311 | { | ||
1312 | unsigned int i; | ||
1313 | u16 eeprom; | ||
1314 | u8 reg_id; | ||
1315 | u8 value; | ||
1316 | |||
1317 | if (unlikely(rt61pci_wait_bbp_ready(rt2x00dev))) | ||
1318 | return -EACCES; | ||
1314 | 1319 | ||
1315 | continue_csr_init: | ||
1316 | rt61pci_bbp_write(rt2x00dev, 3, 0x00); | 1320 | rt61pci_bbp_write(rt2x00dev, 3, 0x00); |
1317 | rt61pci_bbp_write(rt2x00dev, 15, 0x30); | 1321 | rt61pci_bbp_write(rt2x00dev, 15, 0x30); |
1318 | rt61pci_bbp_write(rt2x00dev, 21, 0xc8); | 1322 | rt61pci_bbp_write(rt2x00dev, 21, 0xc8); |
@@ -1361,7 +1365,8 @@ static void rt61pci_toggle_rx(struct rt2x00_dev *rt2x00dev, | |||
1361 | 1365 | ||
1362 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); | 1366 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®); |
1363 | rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, | 1367 | rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX, |
1364 | state == STATE_RADIO_RX_OFF); | 1368 | (state == STATE_RADIO_RX_OFF) || |
1369 | (state == STATE_RADIO_RX_OFF_LINK)); | ||
1365 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); | 1370 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg); |
1366 | } | 1371 | } |
1367 | 1372 | ||
@@ -1413,17 +1418,10 @@ static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev) | |||
1413 | /* | 1418 | /* |
1414 | * Initialize all registers. | 1419 | * Initialize all registers. |
1415 | */ | 1420 | */ |
1416 | if (rt61pci_init_queues(rt2x00dev) || | 1421 | if (unlikely(rt61pci_init_queues(rt2x00dev) || |
1417 | rt61pci_init_registers(rt2x00dev) || | 1422 | rt61pci_init_registers(rt2x00dev) || |
1418 | rt61pci_init_bbp(rt2x00dev)) { | 1423 | rt61pci_init_bbp(rt2x00dev))) |
1419 | ERROR(rt2x00dev, "Register initialization failed.\n"); | ||
1420 | return -EIO; | 1424 | return -EIO; |
1421 | } | ||
1422 | |||
1423 | /* | ||
1424 | * Enable interrupts. | ||
1425 | */ | ||
1426 | rt61pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON); | ||
1427 | 1425 | ||
1428 | /* | 1426 | /* |
1429 | * Enable RX. | 1427 | * Enable RX. |
@@ -1455,11 +1453,6 @@ static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
1455 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, 1); | 1453 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, 1); |
1456 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, 1); | 1454 | rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, 1); |
1457 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | 1455 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); |
1458 | |||
1459 | /* | ||
1460 | * Disable interrupts. | ||
1461 | */ | ||
1462 | rt61pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_OFF); | ||
1463 | } | 1456 | } |
1464 | 1457 | ||
1465 | static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) | 1458 | static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) |
@@ -1467,7 +1460,6 @@ static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) | |||
1467 | u32 reg; | 1460 | u32 reg; |
1468 | unsigned int i; | 1461 | unsigned int i; |
1469 | char put_to_sleep; | 1462 | char put_to_sleep; |
1470 | char current_state; | ||
1471 | 1463 | ||
1472 | put_to_sleep = (state != STATE_AWAKE); | 1464 | put_to_sleep = (state != STATE_AWAKE); |
1473 | 1465 | ||
@@ -1483,16 +1475,12 @@ static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state) | |||
1483 | */ | 1475 | */ |
1484 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { | 1476 | for (i = 0; i < REGISTER_BUSY_COUNT; i++) { |
1485 | rt2x00pci_register_read(rt2x00dev, MAC_CSR12, ®); | 1477 | rt2x00pci_register_read(rt2x00dev, MAC_CSR12, ®); |
1486 | current_state = | 1478 | state = rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE); |
1487 | rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE); | 1479 | if (state == !put_to_sleep) |
1488 | if (current_state == !put_to_sleep) | ||
1489 | return 0; | 1480 | return 0; |
1490 | msleep(10); | 1481 | msleep(10); |
1491 | } | 1482 | } |
1492 | 1483 | ||
1493 | NOTICE(rt2x00dev, "Device failed to enter state %d, " | ||
1494 | "current device state %d.\n", !put_to_sleep, current_state); | ||
1495 | |||
1496 | return -EBUSY; | 1484 | return -EBUSY; |
1497 | } | 1485 | } |
1498 | 1486 | ||
@@ -1510,11 +1498,13 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1510 | break; | 1498 | break; |
1511 | case STATE_RADIO_RX_ON: | 1499 | case STATE_RADIO_RX_ON: |
1512 | case STATE_RADIO_RX_ON_LINK: | 1500 | case STATE_RADIO_RX_ON_LINK: |
1513 | rt61pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); | ||
1514 | break; | ||
1515 | case STATE_RADIO_RX_OFF: | 1501 | case STATE_RADIO_RX_OFF: |
1516 | case STATE_RADIO_RX_OFF_LINK: | 1502 | case STATE_RADIO_RX_OFF_LINK: |
1517 | rt61pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF); | 1503 | rt61pci_toggle_rx(rt2x00dev, state); |
1504 | break; | ||
1505 | case STATE_RADIO_IRQ_ON: | ||
1506 | case STATE_RADIO_IRQ_OFF: | ||
1507 | rt61pci_toggle_irq(rt2x00dev, state); | ||
1518 | break; | 1508 | break; |
1519 | case STATE_DEEP_SLEEP: | 1509 | case STATE_DEEP_SLEEP: |
1520 | case STATE_SLEEP: | 1510 | case STATE_SLEEP: |
@@ -1527,6 +1517,10 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1527 | break; | 1517 | break; |
1528 | } | 1518 | } |
1529 | 1519 | ||
1520 | if (unlikely(retval)) | ||
1521 | ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n", | ||
1522 | state, retval); | ||
1523 | |||
1530 | return retval; | 1524 | return retval; |
1531 | } | 1525 | } |
1532 | 1526 | ||
@@ -1535,8 +1529,7 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev, | |||
1535 | */ | 1529 | */ |
1536 | static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | 1530 | static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, |
1537 | struct sk_buff *skb, | 1531 | struct sk_buff *skb, |
1538 | struct txentry_desc *txdesc, | 1532 | struct txentry_desc *txdesc) |
1539 | struct ieee80211_tx_control *control) | ||
1540 | { | 1533 | { |
1541 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 1534 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1542 | __le32 *txd = skbdesc->desc; | 1535 | __le32 *txd = skbdesc->desc; |
@@ -1552,6 +1545,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1552 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); | 1545 | rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max); |
1553 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); | 1546 | rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER); |
1554 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); | 1547 | rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1); |
1548 | rt2x00_set_field32(&word, TXD_W1_BUFFER_COUNT, 1); | ||
1555 | rt2x00_desc_write(txd, 1, word); | 1549 | rt2x00_desc_write(txd, 1, word); |
1556 | 1550 | ||
1557 | rt2x00_desc_read(txd, 2, &word); | 1551 | rt2x00_desc_read(txd, 2, &word); |
@@ -1562,14 +1556,22 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1562 | rt2x00_desc_write(txd, 2, word); | 1556 | rt2x00_desc_write(txd, 2, word); |
1563 | 1557 | ||
1564 | rt2x00_desc_read(txd, 5, &word); | 1558 | rt2x00_desc_read(txd, 5, &word); |
1559 | rt2x00_set_field32(&word, TXD_W5_PID_TYPE, skbdesc->entry->queue->qid); | ||
1560 | rt2x00_set_field32(&word, TXD_W5_PID_SUBTYPE, | ||
1561 | skbdesc->entry->entry_idx); | ||
1565 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, | 1562 | rt2x00_set_field32(&word, TXD_W5_TX_POWER, |
1566 | TXPOWER_TO_DEV(rt2x00dev->tx_power)); | 1563 | TXPOWER_TO_DEV(rt2x00dev->tx_power)); |
1567 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); | 1564 | rt2x00_set_field32(&word, TXD_W5_WAITING_DMA_DONE_INT, 1); |
1568 | rt2x00_desc_write(txd, 5, word); | 1565 | rt2x00_desc_write(txd, 5, word); |
1569 | 1566 | ||
1567 | rt2x00_desc_read(txd, 6, &word); | ||
1568 | rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, | ||
1569 | skbdesc->skb_dma); | ||
1570 | rt2x00_desc_write(txd, 6, word); | ||
1571 | |||
1570 | if (skbdesc->desc_len > TXINFO_SIZE) { | 1572 | if (skbdesc->desc_len > TXINFO_SIZE) { |
1571 | rt2x00_desc_read(txd, 11, &word); | 1573 | rt2x00_desc_read(txd, 11, &word); |
1572 | rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, skbdesc->data_len); | 1574 | rt2x00_set_field32(&word, TXD_W11_BUFFER_LENGTH0, skb->len); |
1573 | rt2x00_desc_write(txd, 11, word); | 1575 | rt2x00_desc_write(txd, 11, word); |
1574 | } | 1576 | } |
1575 | 1577 | ||
@@ -1586,10 +1588,9 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1586 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); | 1588 | test_bit(ENTRY_TXD_OFDM_RATE, &txdesc->flags)); |
1587 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); | 1589 | rt2x00_set_field32(&word, TXD_W0_IFS, txdesc->ifs); |
1588 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, | 1590 | rt2x00_set_field32(&word, TXD_W0_RETRY_MODE, |
1589 | !!(control->flags & | 1591 | test_bit(ENTRY_TXD_RETRY_MODE, &txdesc->flags)); |
1590 | IEEE80211_TXCTL_LONG_RETRY_LIMIT)); | ||
1591 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); | 1592 | rt2x00_set_field32(&word, TXD_W0_TKIP_MIC, 0); |
1592 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skbdesc->data_len); | 1593 | rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, skb->len); |
1593 | rt2x00_set_field32(&word, TXD_W0_BURST, | 1594 | rt2x00_set_field32(&word, TXD_W0_BURST, |
1594 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); | 1595 | test_bit(ENTRY_TXD_BURST, &txdesc->flags)); |
1595 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); | 1596 | rt2x00_set_field32(&word, TXD_W0_CIPHER_ALG, CIPHER_NONE); |
@@ -1599,12 +1600,47 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1599 | /* | 1600 | /* |
1600 | * TX data initialization | 1601 | * TX data initialization |
1601 | */ | 1602 | */ |
1603 | static void rt61pci_write_beacon(struct queue_entry *entry) | ||
1604 | { | ||
1605 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | ||
1606 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
1607 | unsigned int beacon_base; | ||
1608 | u32 reg; | ||
1609 | |||
1610 | /* | ||
1611 | * Disable beaconing while we are reloading the beacon data, | ||
1612 | * otherwise we might be sending out invalid data. | ||
1613 | */ | ||
1614 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
1615 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
1616 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
1617 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
1618 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
1619 | |||
1620 | /* | ||
1621 | * Write entire beacon with descriptor to register. | ||
1622 | */ | ||
1623 | beacon_base = HW_BEACON_OFFSET(entry->entry_idx); | ||
1624 | rt2x00pci_register_multiwrite(rt2x00dev, | ||
1625 | beacon_base, | ||
1626 | skbdesc->desc, skbdesc->desc_len); | ||
1627 | rt2x00pci_register_multiwrite(rt2x00dev, | ||
1628 | beacon_base + skbdesc->desc_len, | ||
1629 | entry->skb->data, entry->skb->len); | ||
1630 | |||
1631 | /* | ||
1632 | * Clean up beacon skb. | ||
1633 | */ | ||
1634 | dev_kfree_skb_any(entry->skb); | ||
1635 | entry->skb = NULL; | ||
1636 | } | ||
1637 | |||
1602 | static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | 1638 | static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, |
1603 | const unsigned int queue) | 1639 | const enum data_queue_qid queue) |
1604 | { | 1640 | { |
1605 | u32 reg; | 1641 | u32 reg; |
1606 | 1642 | ||
1607 | if (queue == RT2X00_BCN_QUEUE_BEACON) { | 1643 | if (queue == QID_BEACON) { |
1608 | /* | 1644 | /* |
1609 | * For Wi-Fi faily generated beacons between participating | 1645 | * For Wi-Fi faily generated beacons between participating |
1610 | * stations. Set TBTT phase adaptive adjustment step to 8us. | 1646 | * stations. Set TBTT phase adaptive adjustment step to 8us. |
@@ -1622,14 +1658,10 @@ static void rt61pci_kick_tx_queue(struct rt2x00_dev *rt2x00dev, | |||
1622 | } | 1658 | } |
1623 | 1659 | ||
1624 | rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); | 1660 | rt2x00pci_register_read(rt2x00dev, TX_CNTL_CSR, ®); |
1625 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, | 1661 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC0, (queue == QID_AC_BE)); |
1626 | (queue == IEEE80211_TX_QUEUE_DATA0)); | 1662 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, (queue == QID_AC_BK)); |
1627 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC1, | 1663 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, (queue == QID_AC_VI)); |
1628 | (queue == IEEE80211_TX_QUEUE_DATA1)); | 1664 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, (queue == QID_AC_VO)); |
1629 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC2, | ||
1630 | (queue == IEEE80211_TX_QUEUE_DATA2)); | ||
1631 | rt2x00_set_field32(®, TX_CNTL_CSR_KICK_TX_AC3, | ||
1632 | (queue == IEEE80211_TX_QUEUE_DATA3)); | ||
1633 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); | 1665 | rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg); |
1634 | } | 1666 | } |
1635 | 1667 | ||
@@ -1680,14 +1712,13 @@ static int rt61pci_agc_to_rssi(struct rt2x00_dev *rt2x00dev, int rxd_w1) | |||
1680 | static void rt61pci_fill_rxdone(struct queue_entry *entry, | 1712 | static void rt61pci_fill_rxdone(struct queue_entry *entry, |
1681 | struct rxdone_entry_desc *rxdesc) | 1713 | struct rxdone_entry_desc *rxdesc) |
1682 | { | 1714 | { |
1683 | struct queue_entry_priv_pci_rx *priv_rx = entry->priv_data; | 1715 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
1684 | u32 word0; | 1716 | u32 word0; |
1685 | u32 word1; | 1717 | u32 word1; |
1686 | 1718 | ||
1687 | rt2x00_desc_read(priv_rx->desc, 0, &word0); | 1719 | rt2x00_desc_read(entry_priv->desc, 0, &word0); |
1688 | rt2x00_desc_read(priv_rx->desc, 1, &word1); | 1720 | rt2x00_desc_read(entry_priv->desc, 1, &word1); |
1689 | 1721 | ||
1690 | rxdesc->flags = 0; | ||
1691 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) | 1722 | if (rt2x00_get_field32(word0, RXD_W0_CRC_ERROR)) |
1692 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; | 1723 | rxdesc->flags |= RX_FLAG_FAILED_FCS_CRC; |
1693 | 1724 | ||
@@ -1701,7 +1732,6 @@ static void rt61pci_fill_rxdone(struct queue_entry *entry, | |||
1701 | rxdesc->rssi = rt61pci_agc_to_rssi(entry->queue->rt2x00dev, word1); | 1732 | rxdesc->rssi = rt61pci_agc_to_rssi(entry->queue->rt2x00dev, word1); |
1702 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); | 1733 | rxdesc->size = rt2x00_get_field32(word0, RXD_W0_DATABYTE_COUNT); |
1703 | 1734 | ||
1704 | rxdesc->dev_flags = 0; | ||
1705 | if (rt2x00_get_field32(word0, RXD_W0_OFDM)) | 1735 | if (rt2x00_get_field32(word0, RXD_W0_OFDM)) |
1706 | rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP; | 1736 | rxdesc->dev_flags |= RXDONE_SIGNAL_PLCP; |
1707 | if (rt2x00_get_field32(word0, RXD_W0_MY_BSS)) | 1737 | if (rt2x00_get_field32(word0, RXD_W0_MY_BSS)) |
@@ -1716,7 +1746,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
1716 | struct data_queue *queue; | 1746 | struct data_queue *queue; |
1717 | struct queue_entry *entry; | 1747 | struct queue_entry *entry; |
1718 | struct queue_entry *entry_done; | 1748 | struct queue_entry *entry_done; |
1719 | struct queue_entry_priv_pci_tx *priv_tx; | 1749 | struct queue_entry_priv_pci *entry_priv; |
1720 | struct txdone_entry_desc txdesc; | 1750 | struct txdone_entry_desc txdesc; |
1721 | u32 word; | 1751 | u32 word; |
1722 | u32 reg; | 1752 | u32 reg; |
@@ -1761,8 +1791,8 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
1761 | continue; | 1791 | continue; |
1762 | 1792 | ||
1763 | entry = &queue->entries[index]; | 1793 | entry = &queue->entries[index]; |
1764 | priv_tx = entry->priv_data; | 1794 | entry_priv = entry->priv_data; |
1765 | rt2x00_desc_read(priv_tx->desc, 0, &word); | 1795 | rt2x00_desc_read(entry_priv->desc, 0, &word); |
1766 | 1796 | ||
1767 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || | 1797 | if (rt2x00_get_field32(word, TXD_W0_OWNER_NIC) || |
1768 | !rt2x00_get_field32(word, TXD_W0_VALID)) | 1798 | !rt2x00_get_field32(word, TXD_W0_VALID)) |
@@ -1777,20 +1807,31 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
1777 | "TX status report missed for entry %d\n", | 1807 | "TX status report missed for entry %d\n", |
1778 | entry_done->entry_idx); | 1808 | entry_done->entry_idx); |
1779 | 1809 | ||
1780 | txdesc.status = TX_FAIL_OTHER; | 1810 | txdesc.flags = 0; |
1811 | __set_bit(TXDONE_UNKNOWN, &txdesc.flags); | ||
1781 | txdesc.retry = 0; | 1812 | txdesc.retry = 0; |
1782 | 1813 | ||
1783 | rt2x00pci_txdone(rt2x00dev, entry_done, &txdesc); | 1814 | rt2x00lib_txdone(entry_done, &txdesc); |
1784 | entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | 1815 | entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
1785 | } | 1816 | } |
1786 | 1817 | ||
1787 | /* | 1818 | /* |
1788 | * Obtain the status about this packet. | 1819 | * Obtain the status about this packet. |
1789 | */ | 1820 | */ |
1790 | txdesc.status = rt2x00_get_field32(reg, STA_CSR4_TX_RESULT); | 1821 | txdesc.flags = 0; |
1822 | switch (rt2x00_get_field32(reg, STA_CSR4_TX_RESULT)) { | ||
1823 | case 0: /* Success, maybe with retry */ | ||
1824 | __set_bit(TXDONE_SUCCESS, &txdesc.flags); | ||
1825 | break; | ||
1826 | case 6: /* Failure, excessive retries */ | ||
1827 | __set_bit(TXDONE_EXCESSIVE_RETRY, &txdesc.flags); | ||
1828 | /* Don't break, this is a failed frame! */ | ||
1829 | default: /* Failure */ | ||
1830 | __set_bit(TXDONE_FAILURE, &txdesc.flags); | ||
1831 | } | ||
1791 | txdesc.retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT); | 1832 | txdesc.retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT); |
1792 | 1833 | ||
1793 | rt2x00pci_txdone(rt2x00dev, entry, &txdesc); | 1834 | rt2x00lib_txdone(entry, &txdesc); |
1794 | } | 1835 | } |
1795 | } | 1836 | } |
1796 | 1837 | ||
@@ -1976,7 +2017,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1976 | * To determine the RT chip we have to read the | 2017 | * To determine the RT chip we have to read the |
1977 | * PCI header of the device. | 2018 | * PCI header of the device. |
1978 | */ | 2019 | */ |
1979 | pci_read_config_word(rt2x00dev_pci(rt2x00dev), | 2020 | pci_read_config_word(to_pci_dev(rt2x00dev->dev), |
1980 | PCI_CONFIG_HEADER_DEVICE, &device); | 2021 | PCI_CONFIG_HEADER_DEVICE, &device); |
1981 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); | 2022 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); |
1982 | rt2x00pci_register_read(rt2x00dev, MAC_CSR0, ®); | 2023 | rt2x00pci_register_read(rt2x00dev, MAC_CSR0, ®); |
@@ -2078,31 +2119,11 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
2078 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); | 2119 | rt2x00_eeprom_read(rt2x00dev, EEPROM_LED, &eeprom); |
2079 | value = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE); | 2120 | value = rt2x00_get_field16(eeprom, EEPROM_LED_LED_MODE); |
2080 | 2121 | ||
2081 | rt2x00dev->led_radio.rt2x00dev = rt2x00dev; | 2122 | rt61pci_init_led(rt2x00dev, &rt2x00dev->led_radio, LED_TYPE_RADIO); |
2082 | rt2x00dev->led_radio.type = LED_TYPE_RADIO; | 2123 | rt61pci_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); |
2083 | rt2x00dev->led_radio.led_dev.brightness_set = | 2124 | if (value == LED_MODE_SIGNAL_STRENGTH) |
2084 | rt61pci_brightness_set; | 2125 | rt61pci_init_led(rt2x00dev, &rt2x00dev->led_qual, |
2085 | rt2x00dev->led_radio.led_dev.blink_set = | 2126 | LED_TYPE_QUALITY); |
2086 | rt61pci_blink_set; | ||
2087 | rt2x00dev->led_radio.flags = LED_INITIALIZED; | ||
2088 | |||
2089 | rt2x00dev->led_assoc.rt2x00dev = rt2x00dev; | ||
2090 | rt2x00dev->led_assoc.type = LED_TYPE_ASSOC; | ||
2091 | rt2x00dev->led_assoc.led_dev.brightness_set = | ||
2092 | rt61pci_brightness_set; | ||
2093 | rt2x00dev->led_assoc.led_dev.blink_set = | ||
2094 | rt61pci_blink_set; | ||
2095 | rt2x00dev->led_assoc.flags = LED_INITIALIZED; | ||
2096 | |||
2097 | if (value == LED_MODE_SIGNAL_STRENGTH) { | ||
2098 | rt2x00dev->led_qual.rt2x00dev = rt2x00dev; | ||
2099 | rt2x00dev->led_qual.type = LED_TYPE_QUALITY; | ||
2100 | rt2x00dev->led_qual.led_dev.brightness_set = | ||
2101 | rt61pci_brightness_set; | ||
2102 | rt2x00dev->led_qual.led_dev.blink_set = | ||
2103 | rt61pci_blink_set; | ||
2104 | rt2x00dev->led_qual.flags = LED_INITIALIZED; | ||
2105 | } | ||
2106 | 2127 | ||
2107 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value); | 2128 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_LED_MODE, value); |
2108 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0, | 2129 | rt2x00_set_field16(&rt2x00dev->led_mcu_reg, MCU_LEDCS_POLARITY_GPIO_0, |
@@ -2258,13 +2279,11 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2258 | */ | 2279 | */ |
2259 | rt2x00dev->hw->flags = | 2280 | rt2x00dev->hw->flags = |
2260 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | | 2281 | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE | |
2261 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; | 2282 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
2283 | IEEE80211_HW_SIGNAL_DBM; | ||
2262 | rt2x00dev->hw->extra_tx_headroom = 0; | 2284 | rt2x00dev->hw->extra_tx_headroom = 0; |
2263 | rt2x00dev->hw->max_signal = MAX_SIGNAL; | ||
2264 | rt2x00dev->hw->max_rssi = MAX_RX_SSI; | ||
2265 | rt2x00dev->hw->queues = 4; | ||
2266 | 2285 | ||
2267 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); | 2286 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); |
2268 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | 2287 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, |
2269 | rt2x00_eeprom_addr(rt2x00dev, | 2288 | rt2x00_eeprom_addr(rt2x00dev, |
2270 | EEPROM_MAC_ADDR_0)); | 2289 | EEPROM_MAC_ADDR_0)); |
@@ -2327,9 +2346,10 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
2327 | rt61pci_probe_hw_mode(rt2x00dev); | 2346 | rt61pci_probe_hw_mode(rt2x00dev); |
2328 | 2347 | ||
2329 | /* | 2348 | /* |
2330 | * This device requires firmware. | 2349 | * This device requires firmware and DMA mapped skbs. |
2331 | */ | 2350 | */ |
2332 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); | 2351 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); |
2352 | __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); | ||
2333 | 2353 | ||
2334 | /* | 2354 | /* |
2335 | * Set the rssi offset. | 2355 | * Set the rssi offset. |
@@ -2370,67 +2390,6 @@ static u64 rt61pci_get_tsf(struct ieee80211_hw *hw) | |||
2370 | return tsf; | 2390 | return tsf; |
2371 | } | 2391 | } |
2372 | 2392 | ||
2373 | static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
2374 | struct ieee80211_tx_control *control) | ||
2375 | { | ||
2376 | struct rt2x00_dev *rt2x00dev = hw->priv; | ||
2377 | struct rt2x00_intf *intf = vif_to_intf(control->vif); | ||
2378 | struct queue_entry_priv_pci_tx *priv_tx; | ||
2379 | struct skb_frame_desc *skbdesc; | ||
2380 | unsigned int beacon_base; | ||
2381 | u32 reg; | ||
2382 | |||
2383 | if (unlikely(!intf->beacon)) | ||
2384 | return -ENOBUFS; | ||
2385 | |||
2386 | priv_tx = intf->beacon->priv_data; | ||
2387 | memset(priv_tx->desc, 0, intf->beacon->queue->desc_size); | ||
2388 | |||
2389 | /* | ||
2390 | * Fill in skb descriptor | ||
2391 | */ | ||
2392 | skbdesc = get_skb_frame_desc(skb); | ||
2393 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
2394 | skbdesc->flags |= FRAME_DESC_DRIVER_GENERATED; | ||
2395 | skbdesc->data = skb->data; | ||
2396 | skbdesc->data_len = skb->len; | ||
2397 | skbdesc->desc = priv_tx->desc; | ||
2398 | skbdesc->desc_len = intf->beacon->queue->desc_size; | ||
2399 | skbdesc->entry = intf->beacon; | ||
2400 | |||
2401 | /* | ||
2402 | * Disable beaconing while we are reloading the beacon data, | ||
2403 | * otherwise we might be sending out invalid data. | ||
2404 | */ | ||
2405 | rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, ®); | ||
2406 | rt2x00_set_field32(®, TXRX_CSR9_TSF_TICKING, 0); | ||
2407 | rt2x00_set_field32(®, TXRX_CSR9_TBTT_ENABLE, 0); | ||
2408 | rt2x00_set_field32(®, TXRX_CSR9_BEACON_GEN, 0); | ||
2409 | rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg); | ||
2410 | |||
2411 | /* | ||
2412 | * mac80211 doesn't provide the control->queue variable | ||
2413 | * for beacons. Set our own queue identification so | ||
2414 | * it can be used during descriptor initialization. | ||
2415 | */ | ||
2416 | control->queue = RT2X00_BCN_QUEUE_BEACON; | ||
2417 | rt2x00lib_write_tx_desc(rt2x00dev, skb, control); | ||
2418 | |||
2419 | /* | ||
2420 | * Write entire beacon with descriptor to register, | ||
2421 | * and kick the beacon generator. | ||
2422 | */ | ||
2423 | beacon_base = HW_BEACON_OFFSET(intf->beacon->entry_idx); | ||
2424 | rt2x00pci_register_multiwrite(rt2x00dev, beacon_base, | ||
2425 | skbdesc->desc, skbdesc->desc_len); | ||
2426 | rt2x00pci_register_multiwrite(rt2x00dev, | ||
2427 | beacon_base + skbdesc->desc_len, | ||
2428 | skbdesc->data, skbdesc->data_len); | ||
2429 | rt61pci_kick_tx_queue(rt2x00dev, control->queue); | ||
2430 | |||
2431 | return 0; | ||
2432 | } | ||
2433 | |||
2434 | static const struct ieee80211_ops rt61pci_mac80211_ops = { | 2393 | static const struct ieee80211_ops rt61pci_mac80211_ops = { |
2435 | .tx = rt2x00mac_tx, | 2394 | .tx = rt2x00mac_tx, |
2436 | .start = rt2x00mac_start, | 2395 | .start = rt2x00mac_start, |
@@ -2446,7 +2405,6 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = { | |||
2446 | .conf_tx = rt2x00mac_conf_tx, | 2405 | .conf_tx = rt2x00mac_conf_tx, |
2447 | .get_tx_stats = rt2x00mac_get_tx_stats, | 2406 | .get_tx_stats = rt2x00mac_get_tx_stats, |
2448 | .get_tsf = rt61pci_get_tsf, | 2407 | .get_tsf = rt61pci_get_tsf, |
2449 | .beacon_update = rt61pci_beacon_update, | ||
2450 | }; | 2408 | }; |
2451 | 2409 | ||
2452 | static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { | 2410 | static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { |
@@ -2466,6 +2424,7 @@ static const struct rt2x00lib_ops rt61pci_rt2x00_ops = { | |||
2466 | .link_tuner = rt61pci_link_tuner, | 2424 | .link_tuner = rt61pci_link_tuner, |
2467 | .write_tx_desc = rt61pci_write_tx_desc, | 2425 | .write_tx_desc = rt61pci_write_tx_desc, |
2468 | .write_tx_data = rt2x00pci_write_tx_data, | 2426 | .write_tx_data = rt2x00pci_write_tx_data, |
2427 | .write_beacon = rt61pci_write_beacon, | ||
2469 | .kick_tx_queue = rt61pci_kick_tx_queue, | 2428 | .kick_tx_queue = rt61pci_kick_tx_queue, |
2470 | .fill_rxdone = rt61pci_fill_rxdone, | 2429 | .fill_rxdone = rt61pci_fill_rxdone, |
2471 | .config_filter = rt61pci_config_filter, | 2430 | .config_filter = rt61pci_config_filter, |
@@ -2478,21 +2437,21 @@ static const struct data_queue_desc rt61pci_queue_rx = { | |||
2478 | .entry_num = RX_ENTRIES, | 2437 | .entry_num = RX_ENTRIES, |
2479 | .data_size = DATA_FRAME_SIZE, | 2438 | .data_size = DATA_FRAME_SIZE, |
2480 | .desc_size = RXD_DESC_SIZE, | 2439 | .desc_size = RXD_DESC_SIZE, |
2481 | .priv_size = sizeof(struct queue_entry_priv_pci_rx), | 2440 | .priv_size = sizeof(struct queue_entry_priv_pci), |
2482 | }; | 2441 | }; |
2483 | 2442 | ||
2484 | static const struct data_queue_desc rt61pci_queue_tx = { | 2443 | static const struct data_queue_desc rt61pci_queue_tx = { |
2485 | .entry_num = TX_ENTRIES, | 2444 | .entry_num = TX_ENTRIES, |
2486 | .data_size = DATA_FRAME_SIZE, | 2445 | .data_size = DATA_FRAME_SIZE, |
2487 | .desc_size = TXD_DESC_SIZE, | 2446 | .desc_size = TXD_DESC_SIZE, |
2488 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | 2447 | .priv_size = sizeof(struct queue_entry_priv_pci), |
2489 | }; | 2448 | }; |
2490 | 2449 | ||
2491 | static const struct data_queue_desc rt61pci_queue_bcn = { | 2450 | static const struct data_queue_desc rt61pci_queue_bcn = { |
2492 | .entry_num = 4 * BEACON_ENTRIES, | 2451 | .entry_num = 4 * BEACON_ENTRIES, |
2493 | .data_size = 0, /* No DMA required for beacons */ | 2452 | .data_size = 0, /* No DMA required for beacons */ |
2494 | .desc_size = TXINFO_SIZE, | 2453 | .desc_size = TXINFO_SIZE, |
2495 | .priv_size = sizeof(struct queue_entry_priv_pci_tx), | 2454 | .priv_size = sizeof(struct queue_entry_priv_pci), |
2496 | }; | 2455 | }; |
2497 | 2456 | ||
2498 | static const struct rt2x00_ops rt61pci_ops = { | 2457 | static const struct rt2x00_ops rt61pci_ops = { |
@@ -2501,6 +2460,7 @@ static const struct rt2x00_ops rt61pci_ops = { | |||
2501 | .max_ap_intf = 4, | 2460 | .max_ap_intf = 4, |
2502 | .eeprom_size = EEPROM_SIZE, | 2461 | .eeprom_size = EEPROM_SIZE, |
2503 | .rf_size = RF_SIZE, | 2462 | .rf_size = RF_SIZE, |
2463 | .tx_queues = NUM_TX_QUEUES, | ||
2504 | .rx = &rt61pci_queue_rx, | 2464 | .rx = &rt61pci_queue_rx, |
2505 | .tx = &rt61pci_queue_tx, | 2465 | .tx = &rt61pci_queue_tx, |
2506 | .bcn = &rt61pci_queue_bcn, | 2466 | .bcn = &rt61pci_queue_bcn, |