diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/zd1211rw/Kconfig | 7 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/Makefile | 3 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_chip.c | 121 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_chip.h | 55 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_ieee80211.c | 191 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_ieee80211.h | 29 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.c | 1536 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.h | 112 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_netdev.c | 264 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_netdev.h | 45 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_usb.c | 282 | ||||
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_usb.h | 31 |
12 files changed, 1008 insertions, 1668 deletions
diff --git a/drivers/net/wireless/zd1211rw/Kconfig b/drivers/net/wireless/zd1211rw/Kconfig index d1ab24a95630..74b31eafe72d 100644 --- a/drivers/net/wireless/zd1211rw/Kconfig +++ b/drivers/net/wireless/zd1211rw/Kconfig | |||
@@ -1,14 +1,13 @@ | |||
1 | config ZD1211RW | 1 | config ZD1211RW |
2 | tristate "ZyDAS ZD1211/ZD1211B USB-wireless support" | 2 | tristate "ZyDAS ZD1211/ZD1211B USB-wireless support" |
3 | depends on USB && IEEE80211_SOFTMAC && WLAN_80211 && EXPERIMENTAL | 3 | depends on USB && MAC80211 && WLAN_80211 && EXPERIMENTAL |
4 | select WIRELESS_EXT | ||
5 | select FW_LOADER | 4 | select FW_LOADER |
6 | ---help--- | 5 | ---help--- |
7 | This is an experimental driver for the ZyDAS ZD1211/ZD1211B wireless | 6 | This is an experimental driver for the ZyDAS ZD1211/ZD1211B wireless |
8 | chip, present in many USB-wireless adapters. | 7 | chip, present in many USB-wireless adapters. |
9 | 8 | ||
10 | Device firmware is required alongside this driver. You can download the | 9 | Device firmware is required alongside this driver. You can download |
11 | firmware distribution from http://zd1211.ath.cx/get-firmware | 10 | the firmware distribution from http://zd1211.ath.cx/get-firmware |
12 | 11 | ||
13 | config ZD1211RW_DEBUG | 12 | config ZD1211RW_DEBUG |
14 | bool "ZyDAS ZD1211 debugging" | 13 | bool "ZyDAS ZD1211 debugging" |
diff --git a/drivers/net/wireless/zd1211rw/Makefile b/drivers/net/wireless/zd1211rw/Makefile index 7a2f2a98edab..cc36126cee88 100644 --- a/drivers/net/wireless/zd1211rw/Makefile +++ b/drivers/net/wireless/zd1211rw/Makefile | |||
@@ -1,7 +1,6 @@ | |||
1 | obj-$(CONFIG_ZD1211RW) += zd1211rw.o | 1 | obj-$(CONFIG_ZD1211RW) += zd1211rw.o |
2 | 2 | ||
3 | zd1211rw-objs := zd_chip.o zd_ieee80211.o \ | 3 | zd1211rw-objs := zd_chip.o zd_ieee80211.o zd_mac.o \ |
4 | zd_mac.o zd_netdev.o \ | ||
5 | zd_rf_al2230.o zd_rf_rf2959.o \ | 4 | zd_rf_al2230.o zd_rf_rf2959.o \ |
6 | zd_rf_al7230b.o zd_rf_uw2453.o \ | 5 | zd_rf_al7230b.o zd_rf_uw2453.o \ |
7 | zd_rf.o zd_usb.o | 6 | zd_rf.o zd_usb.o |
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index f831b68f1b9c..ef9527c978b7 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c | |||
@@ -30,12 +30,12 @@ | |||
30 | #include "zd_rf.h" | 30 | #include "zd_rf.h" |
31 | 31 | ||
32 | void zd_chip_init(struct zd_chip *chip, | 32 | void zd_chip_init(struct zd_chip *chip, |
33 | struct net_device *netdev, | 33 | struct ieee80211_hw *hw, |
34 | struct usb_interface *intf) | 34 | struct usb_interface *intf) |
35 | { | 35 | { |
36 | memset(chip, 0, sizeof(*chip)); | 36 | memset(chip, 0, sizeof(*chip)); |
37 | mutex_init(&chip->mutex); | 37 | mutex_init(&chip->mutex); |
38 | zd_usb_init(&chip->usb, netdev, intf); | 38 | zd_usb_init(&chip->usb, hw, intf); |
39 | zd_rf_init(&chip->rf); | 39 | zd_rf_init(&chip->rf); |
40 | } | 40 | } |
41 | 41 | ||
@@ -50,7 +50,7 @@ void zd_chip_clear(struct zd_chip *chip) | |||
50 | 50 | ||
51 | static int scnprint_mac_oui(struct zd_chip *chip, char *buffer, size_t size) | 51 | static int scnprint_mac_oui(struct zd_chip *chip, char *buffer, size_t size) |
52 | { | 52 | { |
53 | u8 *addr = zd_usb_to_netdev(&chip->usb)->dev_addr; | 53 | u8 *addr = zd_mac_get_perm_addr(zd_chip_to_mac(chip)); |
54 | return scnprintf(buffer, size, "%02x-%02x-%02x", | 54 | return scnprintf(buffer, size, "%02x-%02x-%02x", |
55 | addr[0], addr[1], addr[2]); | 55 | addr[0], addr[1], addr[2]); |
56 | } | 56 | } |
@@ -378,15 +378,18 @@ int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr) | |||
378 | }; | 378 | }; |
379 | DECLARE_MAC_BUF(mac); | 379 | DECLARE_MAC_BUF(mac); |
380 | 380 | ||
381 | reqs[0].value = (mac_addr[3] << 24) | 381 | if (mac_addr) { |
382 | | (mac_addr[2] << 16) | 382 | reqs[0].value = (mac_addr[3] << 24) |
383 | | (mac_addr[1] << 8) | 383 | | (mac_addr[2] << 16) |
384 | | mac_addr[0]; | 384 | | (mac_addr[1] << 8) |
385 | reqs[1].value = (mac_addr[5] << 8) | 385 | | mac_addr[0]; |
386 | | mac_addr[4]; | 386 | reqs[1].value = (mac_addr[5] << 8) |
387 | 387 | | mac_addr[4]; | |
388 | dev_dbg_f(zd_chip_dev(chip), | 388 | dev_dbg_f(zd_chip_dev(chip), |
389 | "mac addr %s\n", print_mac(mac, mac_addr)); | 389 | "mac addr %s\n", print_mac(mac, mac_addr)); |
390 | } else { | ||
391 | dev_dbg_f(zd_chip_dev(chip), "set NULL mac\n"); | ||
392 | } | ||
390 | 393 | ||
391 | mutex_lock(&chip->mutex); | 394 | mutex_lock(&chip->mutex); |
392 | r = zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs)); | 395 | r = zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs)); |
@@ -980,7 +983,7 @@ static int print_fw_version(struct zd_chip *chip) | |||
980 | return 0; | 983 | return 0; |
981 | } | 984 | } |
982 | 985 | ||
983 | static int set_mandatory_rates(struct zd_chip *chip, enum ieee80211_std std) | 986 | static int set_mandatory_rates(struct zd_chip *chip, int mode) |
984 | { | 987 | { |
985 | u32 rates; | 988 | u32 rates; |
986 | ZD_ASSERT(mutex_is_locked(&chip->mutex)); | 989 | ZD_ASSERT(mutex_is_locked(&chip->mutex)); |
@@ -988,11 +991,11 @@ static int set_mandatory_rates(struct zd_chip *chip, enum ieee80211_std std) | |||
988 | * that the device is supporting. Until further notice we should try | 991 | * that the device is supporting. Until further notice we should try |
989 | * to support 802.11g also for full speed USB. | 992 | * to support 802.11g also for full speed USB. |
990 | */ | 993 | */ |
991 | switch (std) { | 994 | switch (mode) { |
992 | case IEEE80211B: | 995 | case MODE_IEEE80211B: |
993 | rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M; | 996 | rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M; |
994 | break; | 997 | break; |
995 | case IEEE80211G: | 998 | case MODE_IEEE80211G: |
996 | rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M| | 999 | rates = CR_RATE_1M|CR_RATE_2M|CR_RATE_5_5M|CR_RATE_11M| |
997 | CR_RATE_6M|CR_RATE_12M|CR_RATE_24M; | 1000 | CR_RATE_6M|CR_RATE_12M|CR_RATE_24M; |
998 | break; | 1001 | break; |
@@ -1003,24 +1006,17 @@ static int set_mandatory_rates(struct zd_chip *chip, enum ieee80211_std std) | |||
1003 | } | 1006 | } |
1004 | 1007 | ||
1005 | int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip, | 1008 | int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip, |
1006 | u8 rts_rate, int preamble) | 1009 | int preamble) |
1007 | { | 1010 | { |
1008 | int rts_mod = ZD_RX_CCK; | ||
1009 | u32 value = 0; | 1011 | u32 value = 0; |
1010 | 1012 | ||
1011 | /* Modulation bit */ | 1013 | dev_dbg_f(zd_chip_dev(chip), "preamble=%x\n", preamble); |
1012 | if (ZD_MODULATION_TYPE(rts_rate) == ZD_OFDM) | ||
1013 | rts_mod = ZD_RX_OFDM; | ||
1014 | |||
1015 | dev_dbg_f(zd_chip_dev(chip), "rts_rate=%x preamble=%x\n", | ||
1016 | rts_rate, preamble); | ||
1017 | |||
1018 | value |= ZD_PURE_RATE(rts_rate) << RTSCTS_SH_RTS_RATE; | ||
1019 | value |= rts_mod << RTSCTS_SH_RTS_MOD_TYPE; | ||
1020 | value |= preamble << RTSCTS_SH_RTS_PMB_TYPE; | 1014 | value |= preamble << RTSCTS_SH_RTS_PMB_TYPE; |
1021 | value |= preamble << RTSCTS_SH_CTS_PMB_TYPE; | 1015 | value |= preamble << RTSCTS_SH_CTS_PMB_TYPE; |
1022 | 1016 | ||
1023 | /* We always send 11M self-CTS messages, like the vendor driver. */ | 1017 | /* We always send 11M RTS/self-CTS messages, like the vendor driver. */ |
1018 | value |= ZD_PURE_RATE(ZD_CCK_RATE_11M) << RTSCTS_SH_RTS_RATE; | ||
1019 | value |= ZD_RX_CCK << RTSCTS_SH_RTS_MOD_TYPE; | ||
1024 | value |= ZD_PURE_RATE(ZD_CCK_RATE_11M) << RTSCTS_SH_CTS_RATE; | 1020 | value |= ZD_PURE_RATE(ZD_CCK_RATE_11M) << RTSCTS_SH_CTS_RATE; |
1025 | value |= ZD_RX_CCK << RTSCTS_SH_CTS_MOD_TYPE; | 1021 | value |= ZD_RX_CCK << RTSCTS_SH_CTS_MOD_TYPE; |
1026 | 1022 | ||
@@ -1109,7 +1105,7 @@ int zd_chip_init_hw(struct zd_chip *chip) | |||
1109 | * It might be discussed, whether we should suppport pure b mode for | 1105 | * It might be discussed, whether we should suppport pure b mode for |
1110 | * full speed USB. | 1106 | * full speed USB. |
1111 | */ | 1107 | */ |
1112 | r = set_mandatory_rates(chip, IEEE80211G); | 1108 | r = set_mandatory_rates(chip, MODE_IEEE80211G); |
1113 | if (r) | 1109 | if (r) |
1114 | goto out; | 1110 | goto out; |
1115 | /* Disabling interrupts is certainly a smart thing here. | 1111 | /* Disabling interrupts is certainly a smart thing here. |
@@ -1320,12 +1316,17 @@ out: | |||
1320 | return r; | 1316 | return r; |
1321 | } | 1317 | } |
1322 | 1318 | ||
1323 | int zd_chip_set_basic_rates_locked(struct zd_chip *chip, u16 cr_rates) | 1319 | int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates) |
1324 | { | 1320 | { |
1325 | ZD_ASSERT((cr_rates & ~(CR_RATES_80211B | CR_RATES_80211G)) == 0); | 1321 | int r; |
1326 | dev_dbg_f(zd_chip_dev(chip), "%x\n", cr_rates); | 1322 | |
1323 | if (cr_rates & ~(CR_RATES_80211B|CR_RATES_80211G)) | ||
1324 | return -EINVAL; | ||
1327 | 1325 | ||
1328 | return zd_iowrite32_locked(chip, cr_rates, CR_BASIC_RATE_TBL); | 1326 | mutex_lock(&chip->mutex); |
1327 | r = zd_iowrite32_locked(chip, cr_rates, CR_BASIC_RATE_TBL); | ||
1328 | mutex_unlock(&chip->mutex); | ||
1329 | return r; | ||
1329 | } | 1330 | } |
1330 | 1331 | ||
1331 | static int ofdm_qual_db(u8 status_quality, u8 zd_rate, unsigned int size) | 1332 | static int ofdm_qual_db(u8 status_quality, u8 zd_rate, unsigned int size) |
@@ -1468,56 +1469,44 @@ u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size, | |||
1468 | { | 1469 | { |
1469 | return (status->frame_status&ZD_RX_OFDM) ? | 1470 | return (status->frame_status&ZD_RX_OFDM) ? |
1470 | ofdm_qual_percent(status->signal_quality_ofdm, | 1471 | ofdm_qual_percent(status->signal_quality_ofdm, |
1471 | zd_rate_from_ofdm_plcp_header(rx_frame), | 1472 | zd_rate_from_ofdm_plcp_header(rx_frame), |
1472 | size) : | 1473 | size) : |
1473 | cck_qual_percent(status->signal_quality_cck); | 1474 | cck_qual_percent(status->signal_quality_cck); |
1474 | } | 1475 | } |
1475 | 1476 | ||
1476 | u8 zd_rx_strength_percent(u8 rssi) | 1477 | /** |
1477 | { | 1478 | * zd_rx_rate - report zd-rate |
1478 | int r = (rssi*100) / 41; | 1479 | * @rx_frame - received frame |
1479 | if (r > 100) | 1480 | * @rx_status - rx_status as given by the device |
1480 | r = 100; | 1481 | * |
1481 | return (u8) r; | 1482 | * This function converts the rate as encoded in the received packet to the |
1482 | } | 1483 | * zd-rate, we are using on other places in the driver. |
1483 | 1484 | */ | |
1484 | u16 zd_rx_rate(const void *rx_frame, const struct rx_status *status) | 1485 | u8 zd_rx_rate(const void *rx_frame, const struct rx_status *status) |
1485 | { | 1486 | { |
1486 | static const u16 ofdm_rates[] = { | 1487 | u8 zd_rate; |
1487 | [ZD_OFDM_PLCP_RATE_6M] = 60, | ||
1488 | [ZD_OFDM_PLCP_RATE_9M] = 90, | ||
1489 | [ZD_OFDM_PLCP_RATE_12M] = 120, | ||
1490 | [ZD_OFDM_PLCP_RATE_18M] = 180, | ||
1491 | [ZD_OFDM_PLCP_RATE_24M] = 240, | ||
1492 | [ZD_OFDM_PLCP_RATE_36M] = 360, | ||
1493 | [ZD_OFDM_PLCP_RATE_48M] = 480, | ||
1494 | [ZD_OFDM_PLCP_RATE_54M] = 540, | ||
1495 | }; | ||
1496 | u16 rate; | ||
1497 | if (status->frame_status & ZD_RX_OFDM) { | 1488 | if (status->frame_status & ZD_RX_OFDM) { |
1498 | /* Deals with PLCP OFDM rate (not zd_rates) */ | 1489 | zd_rate = zd_rate_from_ofdm_plcp_header(rx_frame); |
1499 | u8 ofdm_rate = zd_ofdm_plcp_header_rate(rx_frame); | ||
1500 | rate = ofdm_rates[ofdm_rate & 0xf]; | ||
1501 | } else { | 1490 | } else { |
1502 | switch (zd_cck_plcp_header_signal(rx_frame)) { | 1491 | switch (zd_cck_plcp_header_signal(rx_frame)) { |
1503 | case ZD_CCK_PLCP_SIGNAL_1M: | 1492 | case ZD_CCK_PLCP_SIGNAL_1M: |
1504 | rate = 10; | 1493 | zd_rate = ZD_CCK_RATE_1M; |
1505 | break; | 1494 | break; |
1506 | case ZD_CCK_PLCP_SIGNAL_2M: | 1495 | case ZD_CCK_PLCP_SIGNAL_2M: |
1507 | rate = 20; | 1496 | zd_rate = ZD_CCK_RATE_2M; |
1508 | break; | 1497 | break; |
1509 | case ZD_CCK_PLCP_SIGNAL_5M5: | 1498 | case ZD_CCK_PLCP_SIGNAL_5M5: |
1510 | rate = 55; | 1499 | zd_rate = ZD_CCK_RATE_5_5M; |
1511 | break; | 1500 | break; |
1512 | case ZD_CCK_PLCP_SIGNAL_11M: | 1501 | case ZD_CCK_PLCP_SIGNAL_11M: |
1513 | rate = 110; | 1502 | zd_rate = ZD_CCK_RATE_11M; |
1514 | break; | 1503 | break; |
1515 | default: | 1504 | default: |
1516 | rate = 0; | 1505 | zd_rate = 0; |
1517 | } | 1506 | } |
1518 | } | 1507 | } |
1519 | 1508 | ||
1520 | return rate; | 1509 | return zd_rate; |
1521 | } | 1510 | } |
1522 | 1511 | ||
1523 | int zd_chip_switch_radio_on(struct zd_chip *chip) | 1512 | int zd_chip_switch_radio_on(struct zd_chip *chip) |
@@ -1557,20 +1546,22 @@ void zd_chip_disable_int(struct zd_chip *chip) | |||
1557 | mutex_unlock(&chip->mutex); | 1546 | mutex_unlock(&chip->mutex); |
1558 | } | 1547 | } |
1559 | 1548 | ||
1560 | int zd_chip_enable_rx(struct zd_chip *chip) | 1549 | int zd_chip_enable_rxtx(struct zd_chip *chip) |
1561 | { | 1550 | { |
1562 | int r; | 1551 | int r; |
1563 | 1552 | ||
1564 | mutex_lock(&chip->mutex); | 1553 | mutex_lock(&chip->mutex); |
1554 | zd_usb_enable_tx(&chip->usb); | ||
1565 | r = zd_usb_enable_rx(&chip->usb); | 1555 | r = zd_usb_enable_rx(&chip->usb); |
1566 | mutex_unlock(&chip->mutex); | 1556 | mutex_unlock(&chip->mutex); |
1567 | return r; | 1557 | return r; |
1568 | } | 1558 | } |
1569 | 1559 | ||
1570 | void zd_chip_disable_rx(struct zd_chip *chip) | 1560 | void zd_chip_disable_rxtx(struct zd_chip *chip) |
1571 | { | 1561 | { |
1572 | mutex_lock(&chip->mutex); | 1562 | mutex_lock(&chip->mutex); |
1573 | zd_usb_disable_rx(&chip->usb); | 1563 | zd_usb_disable_rx(&chip->usb); |
1564 | zd_usb_disable_tx(&chip->usb); | ||
1574 | mutex_unlock(&chip->mutex); | 1565 | mutex_unlock(&chip->mutex); |
1575 | } | 1566 | } |
1576 | 1567 | ||
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h index 8009b70213e2..a88a56932239 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.h +++ b/drivers/net/wireless/zd1211rw/zd_chip.h | |||
@@ -433,9 +433,10 @@ enum { | |||
433 | #define CR_GROUP_HASH_P2 CTL_REG(0x0628) | 433 | #define CR_GROUP_HASH_P2 CTL_REG(0x0628) |
434 | 434 | ||
435 | #define CR_RX_TIMEOUT CTL_REG(0x062C) | 435 | #define CR_RX_TIMEOUT CTL_REG(0x062C) |
436 | |||
436 | /* Basic rates supported by the BSS. When producing ACK or CTS messages, the | 437 | /* Basic rates supported by the BSS. When producing ACK or CTS messages, the |
437 | * device will use a rate in this table that is less than or equal to the rate | 438 | * device will use a rate in this table that is less than or equal to the rate |
438 | * of the incoming frame which prompted the response */ | 439 | * of the incoming frame which prompted the response. */ |
439 | #define CR_BASIC_RATE_TBL CTL_REG(0x0630) | 440 | #define CR_BASIC_RATE_TBL CTL_REG(0x0630) |
440 | #define CR_RATE_1M (1 << 0) /* 802.11b */ | 441 | #define CR_RATE_1M (1 << 0) /* 802.11b */ |
441 | #define CR_RATE_2M (1 << 1) /* 802.11b */ | 442 | #define CR_RATE_2M (1 << 1) /* 802.11b */ |
@@ -509,14 +510,37 @@ enum { | |||
509 | #define CR_UNDERRUN_CNT CTL_REG(0x0688) | 510 | #define CR_UNDERRUN_CNT CTL_REG(0x0688) |
510 | 511 | ||
511 | #define CR_RX_FILTER CTL_REG(0x068c) | 512 | #define CR_RX_FILTER CTL_REG(0x068c) |
513 | #define RX_FILTER_ASSOC_REQUEST (1 << 0) | ||
512 | #define RX_FILTER_ASSOC_RESPONSE (1 << 1) | 514 | #define RX_FILTER_ASSOC_RESPONSE (1 << 1) |
515 | #define RX_FILTER_REASSOC_REQUEST (1 << 2) | ||
513 | #define RX_FILTER_REASSOC_RESPONSE (1 << 3) | 516 | #define RX_FILTER_REASSOC_RESPONSE (1 << 3) |
517 | #define RX_FILTER_PROBE_REQUEST (1 << 4) | ||
514 | #define RX_FILTER_PROBE_RESPONSE (1 << 5) | 518 | #define RX_FILTER_PROBE_RESPONSE (1 << 5) |
519 | /* bits 6 and 7 reserved */ | ||
515 | #define RX_FILTER_BEACON (1 << 8) | 520 | #define RX_FILTER_BEACON (1 << 8) |
521 | #define RX_FILTER_ATIM (1 << 9) | ||
516 | #define RX_FILTER_DISASSOC (1 << 10) | 522 | #define RX_FILTER_DISASSOC (1 << 10) |
517 | #define RX_FILTER_AUTH (1 << 11) | 523 | #define RX_FILTER_AUTH (1 << 11) |
518 | #define AP_RX_FILTER 0x0400feff | 524 | #define RX_FILTER_DEAUTH (1 << 12) |
519 | #define STA_RX_FILTER 0x0000ffff | 525 | #define RX_FILTER_PSPOLL (1 << 26) |
526 | #define RX_FILTER_RTS (1 << 27) | ||
527 | #define RX_FILTER_CTS (1 << 28) | ||
528 | #define RX_FILTER_ACK (1 << 29) | ||
529 | #define RX_FILTER_CFEND (1 << 30) | ||
530 | #define RX_FILTER_CFACK (1 << 31) | ||
531 | |||
532 | /* Enable bits for all frames you are interested in. */ | ||
533 | #define STA_RX_FILTER (RX_FILTER_ASSOC_REQUEST | RX_FILTER_ASSOC_RESPONSE | \ | ||
534 | RX_FILTER_REASSOC_REQUEST | RX_FILTER_REASSOC_RESPONSE | \ | ||
535 | RX_FILTER_PROBE_REQUEST | RX_FILTER_PROBE_RESPONSE | \ | ||
536 | (0x3 << 6) /* vendor driver sets these reserved bits */ | \ | ||
537 | RX_FILTER_BEACON | RX_FILTER_ATIM | RX_FILTER_DISASSOC | \ | ||
538 | RX_FILTER_AUTH | RX_FILTER_DEAUTH | \ | ||
539 | (0x7 << 13) /* vendor driver sets these reserved bits */ | \ | ||
540 | RX_FILTER_PSPOLL | RX_FILTER_ACK) /* 0x2400ffff */ | ||
541 | |||
542 | #define RX_FILTER_CTRL (RX_FILTER_RTS | RX_FILTER_CTS | \ | ||
543 | RX_FILTER_CFEND | RX_FILTER_CFACK) | ||
520 | 544 | ||
521 | /* Monitor mode sets filter to 0xfffff */ | 545 | /* Monitor mode sets filter to 0xfffff */ |
522 | 546 | ||
@@ -730,7 +754,7 @@ static inline struct zd_chip *zd_rf_to_chip(struct zd_rf *rf) | |||
730 | #define zd_chip_dev(chip) (&(chip)->usb.intf->dev) | 754 | #define zd_chip_dev(chip) (&(chip)->usb.intf->dev) |
731 | 755 | ||
732 | void zd_chip_init(struct zd_chip *chip, | 756 | void zd_chip_init(struct zd_chip *chip, |
733 | struct net_device *netdev, | 757 | struct ieee80211_hw *hw, |
734 | struct usb_interface *intf); | 758 | struct usb_interface *intf); |
735 | void zd_chip_clear(struct zd_chip *chip); | 759 | void zd_chip_clear(struct zd_chip *chip); |
736 | int zd_chip_read_mac_addr_fw(struct zd_chip *chip, u8 *addr); | 760 | int zd_chip_read_mac_addr_fw(struct zd_chip *chip, u8 *addr); |
@@ -835,14 +859,12 @@ int zd_chip_switch_radio_on(struct zd_chip *chip); | |||
835 | int zd_chip_switch_radio_off(struct zd_chip *chip); | 859 | int zd_chip_switch_radio_off(struct zd_chip *chip); |
836 | int zd_chip_enable_int(struct zd_chip *chip); | 860 | int zd_chip_enable_int(struct zd_chip *chip); |
837 | void zd_chip_disable_int(struct zd_chip *chip); | 861 | void zd_chip_disable_int(struct zd_chip *chip); |
838 | int zd_chip_enable_rx(struct zd_chip *chip); | 862 | int zd_chip_enable_rxtx(struct zd_chip *chip); |
839 | void zd_chip_disable_rx(struct zd_chip *chip); | 863 | void zd_chip_disable_rxtx(struct zd_chip *chip); |
840 | int zd_chip_enable_hwint(struct zd_chip *chip); | 864 | int zd_chip_enable_hwint(struct zd_chip *chip); |
841 | int zd_chip_disable_hwint(struct zd_chip *chip); | 865 | int zd_chip_disable_hwint(struct zd_chip *chip); |
842 | int zd_chip_generic_patch_6m_band(struct zd_chip *chip, int channel); | 866 | int zd_chip_generic_patch_6m_band(struct zd_chip *chip, int channel); |
843 | 867 | int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip, int preamble); | |
844 | int zd_chip_set_rts_cts_rate_locked(struct zd_chip *chip, | ||
845 | u8 rts_rate, int preamble); | ||
846 | 868 | ||
847 | static inline int zd_get_encryption_type(struct zd_chip *chip, u32 *type) | 869 | static inline int zd_get_encryption_type(struct zd_chip *chip, u32 *type) |
848 | { | 870 | { |
@@ -859,17 +881,7 @@ static inline int zd_chip_get_basic_rates(struct zd_chip *chip, u16 *cr_rates) | |||
859 | return zd_ioread16(chip, CR_BASIC_RATE_TBL, cr_rates); | 881 | return zd_ioread16(chip, CR_BASIC_RATE_TBL, cr_rates); |
860 | } | 882 | } |
861 | 883 | ||
862 | int zd_chip_set_basic_rates_locked(struct zd_chip *chip, u16 cr_rates); | 884 | int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates); |
863 | |||
864 | static inline int zd_chip_set_basic_rates(struct zd_chip *chip, u16 cr_rates) | ||
865 | { | ||
866 | int r; | ||
867 | |||
868 | mutex_lock(&chip->mutex); | ||
869 | r = zd_chip_set_basic_rates_locked(chip, cr_rates); | ||
870 | mutex_unlock(&chip->mutex); | ||
871 | return r; | ||
872 | } | ||
873 | 885 | ||
874 | int zd_chip_lock_phy_regs(struct zd_chip *chip); | 886 | int zd_chip_lock_phy_regs(struct zd_chip *chip); |
875 | int zd_chip_unlock_phy_regs(struct zd_chip *chip); | 887 | int zd_chip_unlock_phy_regs(struct zd_chip *chip); |
@@ -893,9 +905,8 @@ struct rx_status; | |||
893 | 905 | ||
894 | u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size, | 906 | u8 zd_rx_qual_percent(const void *rx_frame, unsigned int size, |
895 | const struct rx_status *status); | 907 | const struct rx_status *status); |
896 | u8 zd_rx_strength_percent(u8 rssi); | ||
897 | 908 | ||
898 | u16 zd_rx_rate(const void *rx_frame, const struct rx_status *status); | 909 | u8 zd_rx_rate(const void *rx_frame, const struct rx_status *status); |
899 | 910 | ||
900 | struct zd_mc_hash { | 911 | struct zd_mc_hash { |
901 | u32 low; | 912 | u32 low; |
diff --git a/drivers/net/wireless/zd1211rw/zd_ieee80211.c b/drivers/net/wireless/zd1211rw/zd_ieee80211.c index 189160efd2ae..77cfe5e78230 100644 --- a/drivers/net/wireless/zd1211rw/zd_ieee80211.c +++ b/drivers/net/wireless/zd1211rw/zd_ieee80211.c | |||
@@ -16,178 +16,85 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | /* | 18 | /* |
19 | * A lot of this code is generic and should be moved into the upper layers | 19 | * In the long term, we'll probably find a better way of handling regulatory |
20 | * at some point. | 20 | * requirements outside of the driver. |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <linux/errno.h> | ||
24 | #include <linux/wireless.h> | ||
25 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
26 | #include <net/ieee80211.h> | 24 | #include <net/mac80211.h> |
27 | 25 | ||
28 | #include "zd_def.h" | ||
29 | #include "zd_ieee80211.h" | 26 | #include "zd_ieee80211.h" |
30 | #include "zd_mac.h" | 27 | #include "zd_mac.h" |
31 | 28 | ||
29 | struct channel_range { | ||
30 | u8 regdomain; | ||
31 | u8 start; | ||
32 | u8 end; /* exclusive (channel must be less than end) */ | ||
33 | }; | ||
34 | |||
32 | static const struct channel_range channel_ranges[] = { | 35 | static const struct channel_range channel_ranges[] = { |
33 | [0] = { 0, 0}, | 36 | { ZD_REGDOMAIN_FCC, 1, 12 }, |
34 | [ZD_REGDOMAIN_FCC] = { 1, 12}, | 37 | { ZD_REGDOMAIN_IC, 1, 12 }, |
35 | [ZD_REGDOMAIN_IC] = { 1, 12}, | 38 | { ZD_REGDOMAIN_ETSI, 1, 14 }, |
36 | [ZD_REGDOMAIN_ETSI] = { 1, 14}, | 39 | { ZD_REGDOMAIN_JAPAN, 1, 14 }, |
37 | [ZD_REGDOMAIN_JAPAN] = { 1, 14}, | 40 | { ZD_REGDOMAIN_SPAIN, 1, 14 }, |
38 | [ZD_REGDOMAIN_SPAIN] = { 1, 14}, | 41 | { ZD_REGDOMAIN_FRANCE, 1, 14 }, |
39 | [ZD_REGDOMAIN_FRANCE] = { 1, 14}, | ||
40 | 42 | ||
41 | /* Japan originally only had channel 14 available (see CHNL_ID 0x40 in | 43 | /* Japan originally only had channel 14 available (see CHNL_ID 0x40 in |
42 | * 802.11). However, in 2001 the range was extended to include channels | 44 | * 802.11). However, in 2001 the range was extended to include channels |
43 | * 1-13. The ZyDAS devices still use the old region code but are | 45 | * 1-13. The ZyDAS devices still use the old region code but are |
44 | * designed to allow the extra channel access in Japan. */ | 46 | * designed to allow the extra channel access in Japan. */ |
45 | [ZD_REGDOMAIN_JAPAN_ADD] = { 1, 15}, | 47 | { ZD_REGDOMAIN_JAPAN_ADD, 1, 15 }, |
46 | }; | 48 | }; |
47 | 49 | ||
48 | const struct channel_range *zd_channel_range(u8 regdomain) | 50 | static const struct channel_range *zd_channel_range(u8 regdomain) |
49 | { | ||
50 | if (regdomain >= ARRAY_SIZE(channel_ranges)) | ||
51 | regdomain = 0; | ||
52 | return &channel_ranges[regdomain]; | ||
53 | } | ||
54 | |||
55 | int zd_regdomain_supports_channel(u8 regdomain, u8 channel) | ||
56 | { | ||
57 | const struct channel_range *range = zd_channel_range(regdomain); | ||
58 | return range->start <= channel && channel < range->end; | ||
59 | } | ||
60 | |||
61 | int zd_regdomain_supported(u8 regdomain) | ||
62 | { | 51 | { |
63 | const struct channel_range *range = zd_channel_range(regdomain); | 52 | int i; |
64 | return range->start != 0; | 53 | for (i = 0; i < ARRAY_SIZE(channel_ranges); i++) { |
65 | } | 54 | const struct channel_range *range = &channel_ranges[i]; |
66 | 55 | if (range->regdomain == regdomain) | |
67 | /* Stores channel frequencies in MHz. */ | 56 | return range; |
68 | static const u16 channel_frequencies[] = { | ||
69 | 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, | ||
70 | 2452, 2457, 2462, 2467, 2472, 2484, | ||
71 | }; | ||
72 | |||
73 | #define NUM_CHANNELS ARRAY_SIZE(channel_frequencies) | ||
74 | |||
75 | static int compute_freq(struct iw_freq *freq, u32 mhz, u32 hz) | ||
76 | { | ||
77 | u32 factor; | ||
78 | |||
79 | freq->e = 0; | ||
80 | if (mhz >= 1000000000U) { | ||
81 | pr_debug("zd1211 mhz %u to large\n", mhz); | ||
82 | freq->m = 0; | ||
83 | return -EINVAL; | ||
84 | } | ||
85 | |||
86 | factor = 1000; | ||
87 | while (mhz >= factor) { | ||
88 | |||
89 | freq->e += 1; | ||
90 | factor *= 10; | ||
91 | } | ||
92 | |||
93 | factor /= 1000U; | ||
94 | freq->m = mhz * (1000000U/factor) + hz/factor; | ||
95 | |||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | int zd_channel_to_freq(struct iw_freq *freq, u8 channel) | ||
100 | { | ||
101 | if (channel > NUM_CHANNELS) { | ||
102 | freq->m = 0; | ||
103 | freq->e = 0; | ||
104 | return -EINVAL; | ||
105 | } | ||
106 | if (!channel) { | ||
107 | freq->m = 0; | ||
108 | freq->e = 0; | ||
109 | return -EINVAL; | ||
110 | } | 57 | } |
111 | return compute_freq(freq, channel_frequencies[channel-1], 0); | 58 | return NULL; |
112 | } | 59 | } |
113 | 60 | ||
114 | static int freq_to_mhz(const struct iw_freq *freq) | 61 | #define CHAN_TO_IDX(chan) ((chan) - 1) |
115 | { | ||
116 | u32 factor; | ||
117 | int e; | ||
118 | |||
119 | /* Such high frequencies are not supported. */ | ||
120 | if (freq->e > 6) | ||
121 | return -EINVAL; | ||
122 | |||
123 | factor = 1; | ||
124 | for (e = freq->e; e > 0; --e) { | ||
125 | factor *= 10; | ||
126 | } | ||
127 | factor = 1000000U / factor; | ||
128 | |||
129 | if (freq->m % factor) { | ||
130 | return -EINVAL; | ||
131 | } | ||
132 | |||
133 | return freq->m / factor; | ||
134 | } | ||
135 | 62 | ||
136 | int zd_find_channel(u8 *channel, const struct iw_freq *freq) | 63 | static void unmask_bg_channels(struct ieee80211_hw *hw, |
64 | const struct channel_range *range, | ||
65 | struct ieee80211_hw_mode *mode) | ||
137 | { | 66 | { |
138 | int i, r; | 67 | u8 channel; |
139 | u32 mhz; | ||
140 | |||
141 | if (freq->m < 1000) { | ||
142 | if (freq->m > NUM_CHANNELS || freq->m == 0) | ||
143 | return -EINVAL; | ||
144 | *channel = freq->m; | ||
145 | return 1; | ||
146 | } | ||
147 | |||
148 | r = freq_to_mhz(freq); | ||
149 | if (r < 0) | ||
150 | return r; | ||
151 | mhz = r; | ||
152 | 68 | ||
153 | for (i = 0; i < NUM_CHANNELS; i++) { | 69 | for (channel = range->start; channel < range->end; channel++) { |
154 | if (mhz == channel_frequencies[i]) { | 70 | struct ieee80211_channel *chan = |
155 | *channel = i+1; | 71 | &mode->channels[CHAN_TO_IDX(channel)]; |
156 | return 1; | 72 | chan->flag |= IEEE80211_CHAN_W_SCAN | |
157 | } | 73 | IEEE80211_CHAN_W_ACTIVE_SCAN | |
74 | IEEE80211_CHAN_W_IBSS; | ||
158 | } | 75 | } |
159 | |||
160 | return -EINVAL; | ||
161 | } | 76 | } |
162 | 77 | ||
163 | int zd_geo_init(struct ieee80211_device *ieee, u8 regdomain) | 78 | void zd_geo_init(struct ieee80211_hw *hw, u8 regdomain) |
164 | { | 79 | { |
165 | struct ieee80211_geo geo; | 80 | struct zd_mac *mac = zd_hw_mac(hw); |
166 | const struct channel_range *range; | 81 | const struct channel_range *range; |
167 | int i; | ||
168 | u8 channel; | ||
169 | 82 | ||
170 | dev_dbg(zd_mac_dev(zd_netdev_mac(ieee->dev)), | 83 | dev_dbg(zd_mac_dev(mac), "regdomain %#02x\n", regdomain); |
171 | "regdomain %#04x\n", regdomain); | ||
172 | 84 | ||
173 | range = zd_channel_range(regdomain); | 85 | range = zd_channel_range(regdomain); |
174 | if (range->start == 0) { | 86 | if (!range) { |
175 | dev_err(zd_mac_dev(zd_netdev_mac(ieee->dev)), | 87 | /* The vendor driver overrides the regulatory domain and |
176 | "zd1211 regdomain %#04x not supported\n", | 88 | * allowed channel registers and unconditionally restricts |
177 | regdomain); | 89 | * available channels to 1-11 everywhere. Match their |
178 | return -EINVAL; | 90 | * questionable behaviour only for regdomains which we don't |
91 | * recognise. */ | ||
92 | dev_warn(zd_mac_dev(mac), "Unrecognised regulatory domain: " | ||
93 | "%#02x. Defaulting to FCC.\n", regdomain); | ||
94 | range = zd_channel_range(ZD_REGDOMAIN_FCC); | ||
179 | } | 95 | } |
180 | 96 | ||
181 | memset(&geo, 0, sizeof(geo)); | 97 | unmask_bg_channels(hw, range, &mac->modes[0]); |
182 | 98 | unmask_bg_channels(hw, range, &mac->modes[1]); | |
183 | for (i = 0, channel = range->start; channel < range->end; channel++) { | ||
184 | struct ieee80211_channel *chan = &geo.bg[i++]; | ||
185 | chan->freq = channel_frequencies[channel - 1]; | ||
186 | chan->channel = channel; | ||
187 | } | ||
188 | |||
189 | geo.bg_channels = i; | ||
190 | memcpy(geo.name, "XX ", 4); | ||
191 | ieee80211_set_geo(ieee, &geo); | ||
192 | return 0; | ||
193 | } | 99 | } |
100 | |||
diff --git a/drivers/net/wireless/zd1211rw/zd_ieee80211.h b/drivers/net/wireless/zd1211rw/zd_ieee80211.h index fbf6491dce7e..98b87cfe874c 100644 --- a/drivers/net/wireless/zd1211rw/zd_ieee80211.h +++ b/drivers/net/wireless/zd1211rw/zd_ieee80211.h | |||
@@ -1,7 +1,7 @@ | |||
1 | #ifndef _ZD_IEEE80211_H | 1 | #ifndef _ZD_IEEE80211_H |
2 | #define _ZD_IEEE80211_H | 2 | #define _ZD_IEEE80211_H |
3 | 3 | ||
4 | #include <net/ieee80211.h> | 4 | #include <net/mac80211.h> |
5 | 5 | ||
6 | /* Additional definitions from the standards. | 6 | /* Additional definitions from the standards. |
7 | */ | 7 | */ |
@@ -19,22 +19,7 @@ enum { | |||
19 | MAX_CHANNEL24 = 14, | 19 | MAX_CHANNEL24 = 14, |
20 | }; | 20 | }; |
21 | 21 | ||
22 | struct channel_range { | 22 | void zd_geo_init(struct ieee80211_hw *hw, u8 regdomain); |
23 | u8 start; | ||
24 | u8 end; /* exclusive (channel must be less than end) */ | ||
25 | }; | ||
26 | |||
27 | struct iw_freq; | ||
28 | |||
29 | int zd_geo_init(struct ieee80211_device *ieee, u8 regdomain); | ||
30 | |||
31 | const struct channel_range *zd_channel_range(u8 regdomain); | ||
32 | int zd_regdomain_supports_channel(u8 regdomain, u8 channel); | ||
33 | int zd_regdomain_supported(u8 regdomain); | ||
34 | |||
35 | /* for 2.4 GHz band */ | ||
36 | int zd_channel_to_freq(struct iw_freq *freq, u8 channel); | ||
37 | int zd_find_channel(u8 *channel, const struct iw_freq *freq); | ||
38 | 23 | ||
39 | #define ZD_PLCP_SERVICE_LENGTH_EXTENSION 0x80 | 24 | #define ZD_PLCP_SERVICE_LENGTH_EXTENSION 0x80 |
40 | 25 | ||
@@ -54,8 +39,8 @@ static inline u8 zd_ofdm_plcp_header_rate(const struct ofdm_plcp_header *header) | |||
54 | * | 39 | * |
55 | * See the struct zd_ctrlset definition in zd_mac.h. | 40 | * See the struct zd_ctrlset definition in zd_mac.h. |
56 | */ | 41 | */ |
57 | #define ZD_OFDM_PLCP_RATE_6M 0xb | 42 | #define ZD_OFDM_PLCP_RATE_6M 0xb |
58 | #define ZD_OFDM_PLCP_RATE_9M 0xf | 43 | #define ZD_OFDM_PLCP_RATE_9M 0xf |
59 | #define ZD_OFDM_PLCP_RATE_12M 0xa | 44 | #define ZD_OFDM_PLCP_RATE_12M 0xa |
60 | #define ZD_OFDM_PLCP_RATE_18M 0xe | 45 | #define ZD_OFDM_PLCP_RATE_18M 0xe |
61 | #define ZD_OFDM_PLCP_RATE_24M 0x9 | 46 | #define ZD_OFDM_PLCP_RATE_24M 0x9 |
@@ -87,10 +72,4 @@ static inline u8 zd_cck_plcp_header_signal(const struct cck_plcp_header *header) | |||
87 | #define ZD_CCK_PLCP_SIGNAL_5M5 0x37 | 72 | #define ZD_CCK_PLCP_SIGNAL_5M5 0x37 |
88 | #define ZD_CCK_PLCP_SIGNAL_11M 0x6e | 73 | #define ZD_CCK_PLCP_SIGNAL_11M 0x6e |
89 | 74 | ||
90 | enum ieee80211_std { | ||
91 | IEEE80211B = 0x01, | ||
92 | IEEE80211A = 0x02, | ||
93 | IEEE80211G = 0x04, | ||
94 | }; | ||
95 | |||
96 | #endif /* _ZD_IEEE80211_H */ | 75 | #endif /* _ZD_IEEE80211_H */ |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 5298a8bf1129..aaffd081b1bf 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -1,5 +1,7 @@ | |||
1 | /* zd_mac.c | 1 | /* zd_mac.c |
2 | * | 2 | * |
3 | * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu> | ||
4 | * | ||
3 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
4 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
5 | * the Free Software Foundation; either version 2 of the License, or | 7 | * the Free Software Foundation; either version 2 of the License, or |
@@ -17,7 +19,6 @@ | |||
17 | 19 | ||
18 | #include <linux/netdevice.h> | 20 | #include <linux/netdevice.h> |
19 | #include <linux/etherdevice.h> | 21 | #include <linux/etherdevice.h> |
20 | #include <linux/wireless.h> | ||
21 | #include <linux/usb.h> | 22 | #include <linux/usb.h> |
22 | #include <linux/jiffies.h> | 23 | #include <linux/jiffies.h> |
23 | #include <net/ieee80211_radiotap.h> | 24 | #include <net/ieee80211_radiotap.h> |
@@ -26,81 +27,105 @@ | |||
26 | #include "zd_chip.h" | 27 | #include "zd_chip.h" |
27 | #include "zd_mac.h" | 28 | #include "zd_mac.h" |
28 | #include "zd_ieee80211.h" | 29 | #include "zd_ieee80211.h" |
29 | #include "zd_netdev.h" | ||
30 | #include "zd_rf.h" | 30 | #include "zd_rf.h" |
31 | 31 | ||
32 | static void ieee_init(struct ieee80211_device *ieee); | 32 | /* This table contains the hardware specific values for the modulation rates. */ |
33 | static void softmac_init(struct ieee80211softmac_device *sm); | 33 | static const struct ieee80211_rate zd_rates[] = { |
34 | static void set_rts_cts_work(struct work_struct *work); | 34 | { .rate = 10, |
35 | static void set_basic_rates_work(struct work_struct *work); | 35 | .val = ZD_CCK_RATE_1M, |
36 | .flags = IEEE80211_RATE_CCK }, | ||
37 | { .rate = 20, | ||
38 | .val = ZD_CCK_RATE_2M, | ||
39 | .val2 = ZD_CCK_RATE_2M | ZD_CCK_PREA_SHORT, | ||
40 | .flags = IEEE80211_RATE_CCK_2 }, | ||
41 | { .rate = 55, | ||
42 | .val = ZD_CCK_RATE_5_5M, | ||
43 | .val2 = ZD_CCK_RATE_5_5M | ZD_CCK_PREA_SHORT, | ||
44 | .flags = IEEE80211_RATE_CCK_2 }, | ||
45 | { .rate = 110, | ||
46 | .val = ZD_CCK_RATE_11M, | ||
47 | .val2 = ZD_CCK_RATE_11M | ZD_CCK_PREA_SHORT, | ||
48 | .flags = IEEE80211_RATE_CCK_2 }, | ||
49 | { .rate = 60, | ||
50 | .val = ZD_OFDM_RATE_6M, | ||
51 | .flags = IEEE80211_RATE_OFDM }, | ||
52 | { .rate = 90, | ||
53 | .val = ZD_OFDM_RATE_9M, | ||
54 | .flags = IEEE80211_RATE_OFDM }, | ||
55 | { .rate = 120, | ||
56 | .val = ZD_OFDM_RATE_12M, | ||
57 | .flags = IEEE80211_RATE_OFDM }, | ||
58 | { .rate = 180, | ||
59 | .val = ZD_OFDM_RATE_18M, | ||
60 | .flags = IEEE80211_RATE_OFDM }, | ||
61 | { .rate = 240, | ||
62 | .val = ZD_OFDM_RATE_24M, | ||
63 | .flags = IEEE80211_RATE_OFDM }, | ||
64 | { .rate = 360, | ||
65 | .val = ZD_OFDM_RATE_36M, | ||
66 | .flags = IEEE80211_RATE_OFDM }, | ||
67 | { .rate = 480, | ||
68 | .val = ZD_OFDM_RATE_48M, | ||
69 | .flags = IEEE80211_RATE_OFDM }, | ||
70 | { .rate = 540, | ||
71 | .val = ZD_OFDM_RATE_54M, | ||
72 | .flags = IEEE80211_RATE_OFDM }, | ||
73 | }; | ||
74 | |||
75 | static const struct ieee80211_channel zd_channels[] = { | ||
76 | { .chan = 1, | ||
77 | .freq = 2412}, | ||
78 | { .chan = 2, | ||
79 | .freq = 2417}, | ||
80 | { .chan = 3, | ||
81 | .freq = 2422}, | ||
82 | { .chan = 4, | ||
83 | .freq = 2427}, | ||
84 | { .chan = 5, | ||
85 | .freq = 2432}, | ||
86 | { .chan = 6, | ||
87 | .freq = 2437}, | ||
88 | { .chan = 7, | ||
89 | .freq = 2442}, | ||
90 | { .chan = 8, | ||
91 | .freq = 2447}, | ||
92 | { .chan = 9, | ||
93 | .freq = 2452}, | ||
94 | { .chan = 10, | ||
95 | .freq = 2457}, | ||
96 | { .chan = 11, | ||
97 | .freq = 2462}, | ||
98 | { .chan = 12, | ||
99 | .freq = 2467}, | ||
100 | { .chan = 13, | ||
101 | .freq = 2472}, | ||
102 | { .chan = 14, | ||
103 | .freq = 2484} | ||
104 | }; | ||
36 | 105 | ||
37 | static void housekeeping_init(struct zd_mac *mac); | 106 | static void housekeeping_init(struct zd_mac *mac); |
38 | static void housekeeping_enable(struct zd_mac *mac); | 107 | static void housekeeping_enable(struct zd_mac *mac); |
39 | static void housekeeping_disable(struct zd_mac *mac); | 108 | static void housekeeping_disable(struct zd_mac *mac); |
40 | 109 | ||
41 | static void set_multicast_hash_handler(struct work_struct *work); | 110 | int zd_mac_preinit_hw(struct ieee80211_hw *hw) |
42 | |||
43 | static void do_rx(unsigned long mac_ptr); | ||
44 | |||
45 | int zd_mac_init(struct zd_mac *mac, | ||
46 | struct net_device *netdev, | ||
47 | struct usb_interface *intf) | ||
48 | { | ||
49 | struct ieee80211_device *ieee = zd_netdev_ieee80211(netdev); | ||
50 | |||
51 | memset(mac, 0, sizeof(*mac)); | ||
52 | spin_lock_init(&mac->lock); | ||
53 | mac->netdev = netdev; | ||
54 | INIT_DELAYED_WORK(&mac->set_rts_cts_work, set_rts_cts_work); | ||
55 | INIT_DELAYED_WORK(&mac->set_basic_rates_work, set_basic_rates_work); | ||
56 | |||
57 | skb_queue_head_init(&mac->rx_queue); | ||
58 | tasklet_init(&mac->rx_tasklet, do_rx, (unsigned long)mac); | ||
59 | tasklet_disable(&mac->rx_tasklet); | ||
60 | |||
61 | ieee_init(ieee); | ||
62 | softmac_init(ieee80211_priv(netdev)); | ||
63 | zd_chip_init(&mac->chip, netdev, intf); | ||
64 | housekeeping_init(mac); | ||
65 | INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler); | ||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | static int reset_channel(struct zd_mac *mac) | ||
70 | { | ||
71 | int r; | ||
72 | unsigned long flags; | ||
73 | const struct channel_range *range; | ||
74 | |||
75 | spin_lock_irqsave(&mac->lock, flags); | ||
76 | range = zd_channel_range(mac->regdomain); | ||
77 | if (!range->start) { | ||
78 | r = -EINVAL; | ||
79 | goto out; | ||
80 | } | ||
81 | mac->requested_channel = range->start; | ||
82 | r = 0; | ||
83 | out: | ||
84 | spin_unlock_irqrestore(&mac->lock, flags); | ||
85 | return r; | ||
86 | } | ||
87 | |||
88 | int zd_mac_preinit_hw(struct zd_mac *mac) | ||
89 | { | 111 | { |
90 | int r; | 112 | int r; |
91 | u8 addr[ETH_ALEN]; | 113 | u8 addr[ETH_ALEN]; |
114 | struct zd_mac *mac = zd_hw_mac(hw); | ||
92 | 115 | ||
93 | r = zd_chip_read_mac_addr_fw(&mac->chip, addr); | 116 | r = zd_chip_read_mac_addr_fw(&mac->chip, addr); |
94 | if (r) | 117 | if (r) |
95 | return r; | 118 | return r; |
96 | 119 | ||
97 | memcpy(mac->netdev->dev_addr, addr, ETH_ALEN); | 120 | SET_IEEE80211_PERM_ADDR(hw, addr); |
121 | |||
98 | return 0; | 122 | return 0; |
99 | } | 123 | } |
100 | 124 | ||
101 | int zd_mac_init_hw(struct zd_mac *mac) | 125 | int zd_mac_init_hw(struct ieee80211_hw *hw) |
102 | { | 126 | { |
103 | int r; | 127 | int r; |
128 | struct zd_mac *mac = zd_hw_mac(hw); | ||
104 | struct zd_chip *chip = &mac->chip; | 129 | struct zd_chip *chip = &mac->chip; |
105 | u8 default_regdomain; | 130 | u8 default_regdomain; |
106 | 131 | ||
@@ -116,22 +141,9 @@ int zd_mac_init_hw(struct zd_mac *mac) | |||
116 | r = zd_read_regdomain(chip, &default_regdomain); | 141 | r = zd_read_regdomain(chip, &default_regdomain); |
117 | if (r) | 142 | if (r) |
118 | goto disable_int; | 143 | goto disable_int; |
119 | if (!zd_regdomain_supported(default_regdomain)) { | ||
120 | /* The vendor driver overrides the regulatory domain and | ||
121 | * allowed channel registers and unconditionally restricts | ||
122 | * available channels to 1-11 everywhere. Match their | ||
123 | * questionable behaviour only for regdomains which we don't | ||
124 | * recognise. */ | ||
125 | dev_warn(zd_mac_dev(mac), "Unrecognised regulatory domain: " | ||
126 | "%#04x. Defaulting to FCC.\n", default_regdomain); | ||
127 | default_regdomain = ZD_REGDOMAIN_FCC; | ||
128 | } | ||
129 | spin_lock_irq(&mac->lock); | 144 | spin_lock_irq(&mac->lock); |
130 | mac->regdomain = mac->default_regdomain = default_regdomain; | 145 | mac->regdomain = mac->default_regdomain = default_regdomain; |
131 | spin_unlock_irq(&mac->lock); | 146 | spin_unlock_irq(&mac->lock); |
132 | r = reset_channel(mac); | ||
133 | if (r) | ||
134 | goto disable_int; | ||
135 | 147 | ||
136 | /* We must inform the device that we are doing encryption/decryption in | 148 | /* We must inform the device that we are doing encryption/decryption in |
137 | * software at the moment. */ | 149 | * software at the moment. */ |
@@ -139,9 +151,7 @@ int zd_mac_init_hw(struct zd_mac *mac) | |||
139 | if (r) | 151 | if (r) |
140 | goto disable_int; | 152 | goto disable_int; |
141 | 153 | ||
142 | r = zd_geo_init(zd_mac_to_ieee80211(mac), mac->regdomain); | 154 | zd_geo_init(hw, mac->regdomain); |
143 | if (r) | ||
144 | goto disable_int; | ||
145 | 155 | ||
146 | r = 0; | 156 | r = 0; |
147 | disable_int: | 157 | disable_int: |
@@ -153,8 +163,6 @@ out: | |||
153 | void zd_mac_clear(struct zd_mac *mac) | 163 | void zd_mac_clear(struct zd_mac *mac) |
154 | { | 164 | { |
155 | flush_workqueue(zd_workqueue); | 165 | flush_workqueue(zd_workqueue); |
156 | skb_queue_purge(&mac->rx_queue); | ||
157 | tasklet_kill(&mac->rx_tasklet); | ||
158 | zd_chip_clear(&mac->chip); | 166 | zd_chip_clear(&mac->chip); |
159 | ZD_ASSERT(!spin_is_locked(&mac->lock)); | 167 | ZD_ASSERT(!spin_is_locked(&mac->lock)); |
160 | ZD_MEMCLEAR(mac, sizeof(struct zd_mac)); | 168 | ZD_MEMCLEAR(mac, sizeof(struct zd_mac)); |
@@ -162,34 +170,27 @@ void zd_mac_clear(struct zd_mac *mac) | |||
162 | 170 | ||
163 | static int set_rx_filter(struct zd_mac *mac) | 171 | static int set_rx_filter(struct zd_mac *mac) |
164 | { | 172 | { |
165 | struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); | 173 | unsigned long flags; |
166 | u32 filter = (ieee->iw_mode == IW_MODE_MONITOR) ? ~0 : STA_RX_FILTER; | 174 | u32 filter = STA_RX_FILTER; |
167 | return zd_iowrite32(&mac->chip, CR_RX_FILTER, filter); | ||
168 | } | ||
169 | 175 | ||
170 | static int set_sniffer(struct zd_mac *mac) | 176 | spin_lock_irqsave(&mac->lock, flags); |
171 | { | 177 | if (mac->pass_ctrl) |
172 | struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); | 178 | filter |= RX_FILTER_CTRL; |
173 | return zd_iowrite32(&mac->chip, CR_SNIFFER_ON, | 179 | spin_unlock_irqrestore(&mac->lock, flags); |
174 | ieee->iw_mode == IW_MODE_MONITOR ? 1 : 0); | 180 | |
175 | return 0; | 181 | return zd_iowrite32(&mac->chip, CR_RX_FILTER, filter); |
176 | } | 182 | } |
177 | 183 | ||
178 | static int set_mc_hash(struct zd_mac *mac) | 184 | static int set_mc_hash(struct zd_mac *mac) |
179 | { | 185 | { |
180 | struct zd_mc_hash hash; | 186 | struct zd_mc_hash hash; |
181 | struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); | ||
182 | |||
183 | zd_mc_clear(&hash); | 187 | zd_mc_clear(&hash); |
184 | if (ieee->iw_mode == IW_MODE_MONITOR) | ||
185 | zd_mc_add_all(&hash); | ||
186 | |||
187 | return zd_chip_set_multicast_hash(&mac->chip, &hash); | 188 | return zd_chip_set_multicast_hash(&mac->chip, &hash); |
188 | } | 189 | } |
189 | 190 | ||
190 | int zd_mac_open(struct net_device *netdev) | 191 | static int zd_op_start(struct ieee80211_hw *hw) |
191 | { | 192 | { |
192 | struct zd_mac *mac = zd_netdev_mac(netdev); | 193 | struct zd_mac *mac = zd_hw_mac(hw); |
193 | struct zd_chip *chip = &mac->chip; | 194 | struct zd_chip *chip = &mac->chip; |
194 | struct zd_usb *usb = &chip->usb; | 195 | struct zd_usb *usb = &chip->usb; |
195 | int r; | 196 | int r; |
@@ -200,46 +201,33 @@ int zd_mac_open(struct net_device *netdev) | |||
200 | goto out; | 201 | goto out; |
201 | } | 202 | } |
202 | 203 | ||
203 | tasklet_enable(&mac->rx_tasklet); | ||
204 | |||
205 | r = zd_chip_enable_int(chip); | 204 | r = zd_chip_enable_int(chip); |
206 | if (r < 0) | 205 | if (r < 0) |
207 | goto out; | 206 | goto out; |
208 | 207 | ||
209 | r = zd_write_mac_addr(chip, netdev->dev_addr); | ||
210 | if (r) | ||
211 | goto disable_int; | ||
212 | |||
213 | r = zd_chip_set_basic_rates(chip, CR_RATES_80211B | CR_RATES_80211G); | 208 | r = zd_chip_set_basic_rates(chip, CR_RATES_80211B | CR_RATES_80211G); |
214 | if (r < 0) | 209 | if (r < 0) |
215 | goto disable_int; | 210 | goto disable_int; |
216 | r = set_rx_filter(mac); | 211 | r = set_rx_filter(mac); |
217 | if (r) | 212 | if (r) |
218 | goto disable_int; | 213 | goto disable_int; |
219 | r = set_sniffer(mac); | ||
220 | if (r) | ||
221 | goto disable_int; | ||
222 | r = set_mc_hash(mac); | 214 | r = set_mc_hash(mac); |
223 | if (r) | 215 | if (r) |
224 | goto disable_int; | 216 | goto disable_int; |
225 | r = zd_chip_switch_radio_on(chip); | 217 | r = zd_chip_switch_radio_on(chip); |
226 | if (r < 0) | 218 | if (r < 0) |
227 | goto disable_int; | 219 | goto disable_int; |
228 | r = zd_chip_set_channel(chip, mac->requested_channel); | 220 | r = zd_chip_enable_rxtx(chip); |
229 | if (r < 0) | ||
230 | goto disable_radio; | ||
231 | r = zd_chip_enable_rx(chip); | ||
232 | if (r < 0) | 221 | if (r < 0) |
233 | goto disable_radio; | 222 | goto disable_radio; |
234 | r = zd_chip_enable_hwint(chip); | 223 | r = zd_chip_enable_hwint(chip); |
235 | if (r < 0) | 224 | if (r < 0) |
236 | goto disable_rx; | 225 | goto disable_rxtx; |
237 | 226 | ||
238 | housekeeping_enable(mac); | 227 | housekeeping_enable(mac); |
239 | ieee80211softmac_start(netdev); | ||
240 | return 0; | 228 | return 0; |
241 | disable_rx: | 229 | disable_rxtx: |
242 | zd_chip_disable_rx(chip); | 230 | zd_chip_disable_rxtx(chip); |
243 | disable_radio: | 231 | disable_radio: |
244 | zd_chip_switch_radio_off(chip); | 232 | zd_chip_switch_radio_off(chip); |
245 | disable_int: | 233 | disable_int: |
@@ -248,494 +236,190 @@ out: | |||
248 | return r; | 236 | return r; |
249 | } | 237 | } |
250 | 238 | ||
251 | int zd_mac_stop(struct net_device *netdev) | 239 | /** |
240 | * clear_tx_skb_control_block - clears the control block of tx skbuffs | ||
241 | * @skb: a &struct sk_buff pointer | ||
242 | * | ||
243 | * This clears the control block of skbuff buffers, which were transmitted to | ||
244 | * the device. Notify that the function is not thread-safe, so prevent | ||
245 | * multiple calls. | ||
246 | */ | ||
247 | static void clear_tx_skb_control_block(struct sk_buff *skb) | ||
248 | { | ||
249 | struct zd_tx_skb_control_block *cb = | ||
250 | (struct zd_tx_skb_control_block *)skb->cb; | ||
251 | |||
252 | kfree(cb->control); | ||
253 | cb->control = NULL; | ||
254 | } | ||
255 | |||
256 | /** | ||
257 | * kfree_tx_skb - frees a tx skbuff | ||
258 | * @skb: a &struct sk_buff pointer | ||
259 | * | ||
260 | * Frees the tx skbuff. Frees also the allocated control structure in the | ||
261 | * control block if necessary. | ||
262 | */ | ||
263 | static void kfree_tx_skb(struct sk_buff *skb) | ||
252 | { | 264 | { |
253 | struct zd_mac *mac = zd_netdev_mac(netdev); | 265 | clear_tx_skb_control_block(skb); |
254 | struct zd_chip *chip = &mac->chip; | 266 | dev_kfree_skb_any(skb); |
267 | } | ||
255 | 268 | ||
256 | netif_stop_queue(netdev); | 269 | static void zd_op_stop(struct ieee80211_hw *hw) |
270 | { | ||
271 | struct zd_mac *mac = zd_hw_mac(hw); | ||
272 | struct zd_chip *chip = &mac->chip; | ||
273 | struct sk_buff *skb; | ||
274 | struct sk_buff_head *ack_wait_queue = &mac->ack_wait_queue; | ||
257 | 275 | ||
258 | /* | 276 | /* The order here deliberately is a little different from the open() |
259 | * The order here deliberately is a little different from the open() | ||
260 | * method, since we need to make sure there is no opportunity for RX | 277 | * method, since we need to make sure there is no opportunity for RX |
261 | * frames to be processed by softmac after we have stopped it. | 278 | * frames to be processed by mac80211 after we have stopped it. |
262 | */ | 279 | */ |
263 | 280 | ||
264 | zd_chip_disable_rx(chip); | 281 | zd_chip_disable_rxtx(chip); |
265 | skb_queue_purge(&mac->rx_queue); | ||
266 | tasklet_disable(&mac->rx_tasklet); | ||
267 | housekeeping_disable(mac); | 282 | housekeeping_disable(mac); |
268 | ieee80211softmac_stop(netdev); | ||
269 | |||
270 | /* Ensure no work items are running or queued from this point */ | ||
271 | cancel_delayed_work(&mac->set_rts_cts_work); | ||
272 | cancel_delayed_work(&mac->set_basic_rates_work); | ||
273 | flush_workqueue(zd_workqueue); | 283 | flush_workqueue(zd_workqueue); |
274 | mac->updating_rts_rate = 0; | ||
275 | mac->updating_basic_rates = 0; | ||
276 | 284 | ||
277 | zd_chip_disable_hwint(chip); | 285 | zd_chip_disable_hwint(chip); |
278 | zd_chip_switch_radio_off(chip); | 286 | zd_chip_switch_radio_off(chip); |
279 | zd_chip_disable_int(chip); | 287 | zd_chip_disable_int(chip); |
280 | 288 | ||
281 | return 0; | ||
282 | } | ||
283 | |||
284 | int zd_mac_set_mac_address(struct net_device *netdev, void *p) | ||
285 | { | ||
286 | int r; | ||
287 | unsigned long flags; | ||
288 | struct sockaddr *addr = p; | ||
289 | struct zd_mac *mac = zd_netdev_mac(netdev); | ||
290 | struct zd_chip *chip = &mac->chip; | ||
291 | DECLARE_MAC_BUF(mac2); | ||
292 | 289 | ||
293 | if (!is_valid_ether_addr(addr->sa_data)) | 290 | while ((skb = skb_dequeue(ack_wait_queue))) |
294 | return -EADDRNOTAVAIL; | 291 | kfree_tx_skb(skb); |
295 | |||
296 | dev_dbg_f(zd_mac_dev(mac), | ||
297 | "Setting MAC to %s\n", print_mac(mac2, addr->sa_data)); | ||
298 | |||
299 | if (netdev->flags & IFF_UP) { | ||
300 | r = zd_write_mac_addr(chip, addr->sa_data); | ||
301 | if (r) | ||
302 | return r; | ||
303 | } | ||
304 | |||
305 | spin_lock_irqsave(&mac->lock, flags); | ||
306 | memcpy(netdev->dev_addr, addr->sa_data, ETH_ALEN); | ||
307 | spin_unlock_irqrestore(&mac->lock, flags); | ||
308 | |||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | static void set_multicast_hash_handler(struct work_struct *work) | ||
313 | { | ||
314 | struct zd_mac *mac = container_of(work, struct zd_mac, | ||
315 | set_multicast_hash_work); | ||
316 | struct zd_mc_hash hash; | ||
317 | |||
318 | spin_lock_irq(&mac->lock); | ||
319 | hash = mac->multicast_hash; | ||
320 | spin_unlock_irq(&mac->lock); | ||
321 | |||
322 | zd_chip_set_multicast_hash(&mac->chip, &hash); | ||
323 | } | ||
324 | |||
325 | void zd_mac_set_multicast_list(struct net_device *dev) | ||
326 | { | ||
327 | struct zd_mac *mac = zd_netdev_mac(dev); | ||
328 | struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); | ||
329 | struct zd_mc_hash hash; | ||
330 | struct dev_mc_list *mc; | ||
331 | unsigned long flags; | ||
332 | DECLARE_MAC_BUF(mac2); | ||
333 | |||
334 | if (dev->flags & (IFF_PROMISC|IFF_ALLMULTI) || | ||
335 | ieee->iw_mode == IW_MODE_MONITOR) { | ||
336 | zd_mc_add_all(&hash); | ||
337 | } else { | ||
338 | zd_mc_clear(&hash); | ||
339 | for (mc = dev->mc_list; mc; mc = mc->next) { | ||
340 | dev_dbg_f(zd_mac_dev(mac), "mc addr %s\n", | ||
341 | print_mac(mac2, mc->dmi_addr)); | ||
342 | zd_mc_add_addr(&hash, mc->dmi_addr); | ||
343 | } | ||
344 | } | ||
345 | |||
346 | spin_lock_irqsave(&mac->lock, flags); | ||
347 | mac->multicast_hash = hash; | ||
348 | spin_unlock_irqrestore(&mac->lock, flags); | ||
349 | queue_work(zd_workqueue, &mac->set_multicast_hash_work); | ||
350 | } | 292 | } |
351 | 293 | ||
352 | int zd_mac_set_regdomain(struct zd_mac *mac, u8 regdomain) | 294 | /** |
353 | { | 295 | * init_tx_skb_control_block - initializes skb control block |
354 | int r; | 296 | * @skb: a &sk_buff pointer |
355 | u8 channel; | 297 | * @dev: pointer to the mac80221 device |
356 | 298 | * @control: mac80211 tx control applying for the frame in @skb | |
357 | ZD_ASSERT(!irqs_disabled()); | 299 | * |
358 | spin_lock_irq(&mac->lock); | 300 | * Initializes the control block of the skbuff to be transmitted. |
359 | if (regdomain == 0) { | 301 | */ |
360 | regdomain = mac->default_regdomain; | 302 | static int init_tx_skb_control_block(struct sk_buff *skb, |
361 | } | 303 | struct ieee80211_hw *hw, |
362 | if (!zd_regdomain_supported(regdomain)) { | 304 | struct ieee80211_tx_control *control) |
363 | spin_unlock_irq(&mac->lock); | 305 | { |
364 | return -EINVAL; | 306 | struct zd_tx_skb_control_block *cb = |
365 | } | 307 | (struct zd_tx_skb_control_block *)skb->cb; |
366 | mac->regdomain = regdomain; | 308 | |
367 | channel = mac->requested_channel; | 309 | ZD_ASSERT(sizeof(*cb) <= sizeof(skb->cb)); |
368 | spin_unlock_irq(&mac->lock); | 310 | memset(cb, 0, sizeof(*cb)); |
369 | 311 | cb->hw= hw; | |
370 | r = zd_geo_init(zd_mac_to_ieee80211(mac), regdomain); | 312 | cb->control = kmalloc(sizeof(*control), GFP_ATOMIC); |
371 | if (r) | 313 | if (cb->control == NULL) |
372 | return r; | 314 | return -ENOMEM; |
373 | if (!zd_regdomain_supports_channel(regdomain, channel)) { | 315 | memcpy(cb->control, control, sizeof(*control)); |
374 | r = reset_channel(mac); | ||
375 | if (r) | ||
376 | return r; | ||
377 | } | ||
378 | 316 | ||
379 | return 0; | 317 | return 0; |
380 | } | 318 | } |
381 | 319 | ||
382 | u8 zd_mac_get_regdomain(struct zd_mac *mac) | 320 | /** |
383 | { | 321 | * tx_status - reports tx status of a packet if required |
384 | unsigned long flags; | 322 | * @hw - a &struct ieee80211_hw pointer |
385 | u8 regdomain; | 323 | * @skb - a sk-buffer |
386 | 324 | * @status - the tx status of the packet without control information | |
387 | spin_lock_irqsave(&mac->lock, flags); | 325 | * @success - True for successfull transmission of the frame |
388 | regdomain = mac->regdomain; | 326 | * |
389 | spin_unlock_irqrestore(&mac->lock, flags); | 327 | * This information calls ieee80211_tx_status_irqsafe() if required by the |
390 | return regdomain; | 328 | * control information. It copies the control information into the status |
391 | } | 329 | * information. |
392 | 330 | * | |
393 | /* Fallback to lowest rate, if rate is unknown. */ | 331 | * If no status information has been requested, the skb is freed. |
394 | static u8 rate_to_zd_rate(u8 rate) | 332 | */ |
395 | { | 333 | static void tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, |
396 | switch (rate) { | 334 | struct ieee80211_tx_status *status, |
397 | case IEEE80211_CCK_RATE_2MB: | 335 | bool success) |
398 | return ZD_CCK_RATE_2M; | ||
399 | case IEEE80211_CCK_RATE_5MB: | ||
400 | return ZD_CCK_RATE_5_5M; | ||
401 | case IEEE80211_CCK_RATE_11MB: | ||
402 | return ZD_CCK_RATE_11M; | ||
403 | case IEEE80211_OFDM_RATE_6MB: | ||
404 | return ZD_OFDM_RATE_6M; | ||
405 | case IEEE80211_OFDM_RATE_9MB: | ||
406 | return ZD_OFDM_RATE_9M; | ||
407 | case IEEE80211_OFDM_RATE_12MB: | ||
408 | return ZD_OFDM_RATE_12M; | ||
409 | case IEEE80211_OFDM_RATE_18MB: | ||
410 | return ZD_OFDM_RATE_18M; | ||
411 | case IEEE80211_OFDM_RATE_24MB: | ||
412 | return ZD_OFDM_RATE_24M; | ||
413 | case IEEE80211_OFDM_RATE_36MB: | ||
414 | return ZD_OFDM_RATE_36M; | ||
415 | case IEEE80211_OFDM_RATE_48MB: | ||
416 | return ZD_OFDM_RATE_48M; | ||
417 | case IEEE80211_OFDM_RATE_54MB: | ||
418 | return ZD_OFDM_RATE_54M; | ||
419 | } | ||
420 | return ZD_CCK_RATE_1M; | ||
421 | } | ||
422 | |||
423 | static u16 rate_to_cr_rate(u8 rate) | ||
424 | { | ||
425 | switch (rate) { | ||
426 | case IEEE80211_CCK_RATE_2MB: | ||
427 | return CR_RATE_1M; | ||
428 | case IEEE80211_CCK_RATE_5MB: | ||
429 | return CR_RATE_5_5M; | ||
430 | case IEEE80211_CCK_RATE_11MB: | ||
431 | return CR_RATE_11M; | ||
432 | case IEEE80211_OFDM_RATE_6MB: | ||
433 | return CR_RATE_6M; | ||
434 | case IEEE80211_OFDM_RATE_9MB: | ||
435 | return CR_RATE_9M; | ||
436 | case IEEE80211_OFDM_RATE_12MB: | ||
437 | return CR_RATE_12M; | ||
438 | case IEEE80211_OFDM_RATE_18MB: | ||
439 | return CR_RATE_18M; | ||
440 | case IEEE80211_OFDM_RATE_24MB: | ||
441 | return CR_RATE_24M; | ||
442 | case IEEE80211_OFDM_RATE_36MB: | ||
443 | return CR_RATE_36M; | ||
444 | case IEEE80211_OFDM_RATE_48MB: | ||
445 | return CR_RATE_48M; | ||
446 | case IEEE80211_OFDM_RATE_54MB: | ||
447 | return CR_RATE_54M; | ||
448 | } | ||
449 | return CR_RATE_1M; | ||
450 | } | ||
451 | |||
452 | static void try_enable_tx(struct zd_mac *mac) | ||
453 | { | ||
454 | unsigned long flags; | ||
455 | |||
456 | spin_lock_irqsave(&mac->lock, flags); | ||
457 | if (mac->updating_rts_rate == 0 && mac->updating_basic_rates == 0) | ||
458 | netif_wake_queue(mac->netdev); | ||
459 | spin_unlock_irqrestore(&mac->lock, flags); | ||
460 | } | ||
461 | |||
462 | static void set_rts_cts_work(struct work_struct *work) | ||
463 | { | 336 | { |
464 | struct zd_mac *mac = | 337 | struct zd_tx_skb_control_block *cb = (struct zd_tx_skb_control_block *) |
465 | container_of(work, struct zd_mac, set_rts_cts_work.work); | 338 | skb->cb; |
466 | unsigned long flags; | ||
467 | u8 rts_rate; | ||
468 | unsigned int short_preamble; | ||
469 | |||
470 | mutex_lock(&mac->chip.mutex); | ||
471 | |||
472 | spin_lock_irqsave(&mac->lock, flags); | ||
473 | mac->updating_rts_rate = 0; | ||
474 | rts_rate = mac->rts_rate; | ||
475 | short_preamble = mac->short_preamble; | ||
476 | spin_unlock_irqrestore(&mac->lock, flags); | ||
477 | |||
478 | zd_chip_set_rts_cts_rate_locked(&mac->chip, rts_rate, short_preamble); | ||
479 | mutex_unlock(&mac->chip.mutex); | ||
480 | 339 | ||
481 | try_enable_tx(mac); | 340 | ZD_ASSERT(cb->control != NULL); |
341 | memcpy(&status->control, cb->control, sizeof(status->control)); | ||
342 | if (!success) | ||
343 | status->excessive_retries = 1; | ||
344 | clear_tx_skb_control_block(skb); | ||
345 | ieee80211_tx_status_irqsafe(hw, skb, status); | ||
482 | } | 346 | } |
483 | 347 | ||
484 | static void set_basic_rates_work(struct work_struct *work) | 348 | /** |
349 | * zd_mac_tx_failed - callback for failed frames | ||
350 | * @dev: the mac80211 wireless device | ||
351 | * | ||
352 | * This function is called if a frame couldn't be succesfully be | ||
353 | * transferred. The first frame from the tx queue, will be selected and | ||
354 | * reported as error to the upper layers. | ||
355 | */ | ||
356 | void zd_mac_tx_failed(struct ieee80211_hw *hw) | ||
485 | { | 357 | { |
486 | struct zd_mac *mac = | 358 | struct sk_buff_head *q = &zd_hw_mac(hw)->ack_wait_queue; |
487 | container_of(work, struct zd_mac, set_basic_rates_work.work); | 359 | struct sk_buff *skb; |
488 | unsigned long flags; | 360 | struct ieee80211_tx_status status = {{0}}; |
489 | u16 basic_rates; | ||
490 | |||
491 | mutex_lock(&mac->chip.mutex); | ||
492 | |||
493 | spin_lock_irqsave(&mac->lock, flags); | ||
494 | mac->updating_basic_rates = 0; | ||
495 | basic_rates = mac->basic_rates; | ||
496 | spin_unlock_irqrestore(&mac->lock, flags); | ||
497 | |||
498 | zd_chip_set_basic_rates_locked(&mac->chip, basic_rates); | ||
499 | mutex_unlock(&mac->chip.mutex); | ||
500 | 361 | ||
501 | try_enable_tx(mac); | 362 | skb = skb_dequeue(q); |
363 | if (skb == NULL) | ||
364 | return; | ||
365 | tx_status(hw, skb, &status, 0); | ||
502 | } | 366 | } |
503 | 367 | ||
504 | static void bssinfo_change(struct net_device *netdev, u32 changes) | 368 | /** |
505 | { | 369 | * zd_mac_tx_to_dev - callback for USB layer |
506 | struct zd_mac *mac = zd_netdev_mac(netdev); | 370 | * @skb: a &sk_buff pointer |
507 | struct ieee80211softmac_device *softmac = ieee80211_priv(netdev); | 371 | * @error: error value, 0 if transmission successful |
508 | struct ieee80211softmac_bss_info *bssinfo = &softmac->bssinfo; | 372 | * |
509 | int need_set_rts_cts = 0; | 373 | * Informs the MAC layer that the frame has successfully transferred to the |
510 | int need_set_rates = 0; | 374 | * device. If an ACK is required and the transfer to the device has been |
511 | u16 basic_rates; | 375 | * successful, the packets are put on the @ack_wait_queue with |
512 | unsigned long flags; | 376 | * the control set removed. |
513 | 377 | */ | |
514 | dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes); | 378 | void zd_mac_tx_to_dev(struct sk_buff *skb, int error) |
515 | 379 | { | |
516 | if (changes & IEEE80211SOFTMAC_BSSINFOCHG_SHORT_PREAMBLE) { | 380 | struct zd_tx_skb_control_block *cb = |
517 | spin_lock_irqsave(&mac->lock, flags); | 381 | (struct zd_tx_skb_control_block *)skb->cb; |
518 | mac->short_preamble = bssinfo->short_preamble; | 382 | struct ieee80211_hw *hw = cb->hw; |
519 | spin_unlock_irqrestore(&mac->lock, flags); | 383 | |
520 | need_set_rts_cts = 1; | 384 | if (likely(cb->control)) { |
521 | } | 385 | skb_pull(skb, sizeof(struct zd_ctrlset)); |
522 | 386 | if (unlikely(error || | |
523 | if (changes & IEEE80211SOFTMAC_BSSINFOCHG_RATES) { | 387 | (cb->control->flags & IEEE80211_TXCTL_NO_ACK))) |
524 | /* Set RTS rate to highest available basic rate */ | 388 | { |
525 | u8 hi_rate = ieee80211softmac_highest_supported_rate(softmac, | 389 | struct ieee80211_tx_status status = {{0}}; |
526 | &bssinfo->supported_rates, 1); | 390 | tx_status(hw, skb, &status, !error); |
527 | hi_rate = rate_to_zd_rate(hi_rate); | ||
528 | |||
529 | spin_lock_irqsave(&mac->lock, flags); | ||
530 | if (hi_rate != mac->rts_rate) { | ||
531 | mac->rts_rate = hi_rate; | ||
532 | need_set_rts_cts = 1; | ||
533 | } | ||
534 | spin_unlock_irqrestore(&mac->lock, flags); | ||
535 | |||
536 | /* Set basic rates */ | ||
537 | need_set_rates = 1; | ||
538 | if (bssinfo->supported_rates.count == 0) { | ||
539 | /* Allow the device to be flexible */ | ||
540 | basic_rates = CR_RATES_80211B | CR_RATES_80211G; | ||
541 | } else { | 391 | } else { |
542 | int i = 0; | 392 | struct sk_buff_head *q = |
543 | basic_rates = 0; | 393 | &zd_hw_mac(hw)->ack_wait_queue; |
544 | 394 | ||
545 | for (i = 0; i < bssinfo->supported_rates.count; i++) { | 395 | skb_queue_tail(q, skb); |
546 | u16 rate = bssinfo->supported_rates.rates[i]; | 396 | while (skb_queue_len(q) > ZD_MAC_MAX_ACK_WAITERS) |
547 | if ((rate & IEEE80211_BASIC_RATE_MASK) == 0) | 397 | zd_mac_tx_failed(hw); |
548 | continue; | ||
549 | |||
550 | rate &= ~IEEE80211_BASIC_RATE_MASK; | ||
551 | basic_rates |= rate_to_cr_rate(rate); | ||
552 | } | ||
553 | } | 398 | } |
554 | spin_lock_irqsave(&mac->lock, flags); | 399 | } else { |
555 | mac->basic_rates = basic_rates; | 400 | kfree_tx_skb(skb); |
556 | spin_unlock_irqrestore(&mac->lock, flags); | ||
557 | } | ||
558 | |||
559 | /* Schedule any changes we made above */ | ||
560 | |||
561 | spin_lock_irqsave(&mac->lock, flags); | ||
562 | if (need_set_rts_cts && !mac->updating_rts_rate) { | ||
563 | mac->updating_rts_rate = 1; | ||
564 | netif_stop_queue(mac->netdev); | ||
565 | queue_delayed_work(zd_workqueue, &mac->set_rts_cts_work, 0); | ||
566 | } | ||
567 | if (need_set_rates && !mac->updating_basic_rates) { | ||
568 | mac->updating_basic_rates = 1; | ||
569 | netif_stop_queue(mac->netdev); | ||
570 | queue_delayed_work(zd_workqueue, &mac->set_basic_rates_work, | ||
571 | 0); | ||
572 | } | ||
573 | spin_unlock_irqrestore(&mac->lock, flags); | ||
574 | } | ||
575 | |||
576 | static void set_channel(struct net_device *netdev, u8 channel) | ||
577 | { | ||
578 | struct zd_mac *mac = zd_netdev_mac(netdev); | ||
579 | |||
580 | dev_dbg_f(zd_mac_dev(mac), "channel %d\n", channel); | ||
581 | |||
582 | zd_chip_set_channel(&mac->chip, channel); | ||
583 | } | ||
584 | |||
585 | int zd_mac_request_channel(struct zd_mac *mac, u8 channel) | ||
586 | { | ||
587 | unsigned long lock_flags; | ||
588 | struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); | ||
589 | |||
590 | if (ieee->iw_mode == IW_MODE_INFRA) | ||
591 | return -EPERM; | ||
592 | |||
593 | spin_lock_irqsave(&mac->lock, lock_flags); | ||
594 | if (!zd_regdomain_supports_channel(mac->regdomain, channel)) { | ||
595 | spin_unlock_irqrestore(&mac->lock, lock_flags); | ||
596 | return -EINVAL; | ||
597 | } | ||
598 | mac->requested_channel = channel; | ||
599 | spin_unlock_irqrestore(&mac->lock, lock_flags); | ||
600 | if (netif_running(mac->netdev)) | ||
601 | return zd_chip_set_channel(&mac->chip, channel); | ||
602 | else | ||
603 | return 0; | ||
604 | } | ||
605 | |||
606 | u8 zd_mac_get_channel(struct zd_mac *mac) | ||
607 | { | ||
608 | u8 channel = zd_chip_get_channel(&mac->chip); | ||
609 | |||
610 | dev_dbg_f(zd_mac_dev(mac), "channel %u\n", channel); | ||
611 | return channel; | ||
612 | } | ||
613 | |||
614 | int zd_mac_set_mode(struct zd_mac *mac, u32 mode) | ||
615 | { | ||
616 | struct ieee80211_device *ieee; | ||
617 | |||
618 | switch (mode) { | ||
619 | case IW_MODE_AUTO: | ||
620 | case IW_MODE_ADHOC: | ||
621 | case IW_MODE_INFRA: | ||
622 | mac->netdev->type = ARPHRD_ETHER; | ||
623 | break; | ||
624 | case IW_MODE_MONITOR: | ||
625 | mac->netdev->type = ARPHRD_IEEE80211_RADIOTAP; | ||
626 | break; | ||
627 | default: | ||
628 | dev_dbg_f(zd_mac_dev(mac), "wrong mode %u\n", mode); | ||
629 | return -EINVAL; | ||
630 | } | ||
631 | |||
632 | ieee = zd_mac_to_ieee80211(mac); | ||
633 | ZD_ASSERT(!irqs_disabled()); | ||
634 | spin_lock_irq(&ieee->lock); | ||
635 | ieee->iw_mode = mode; | ||
636 | spin_unlock_irq(&ieee->lock); | ||
637 | |||
638 | if (netif_running(mac->netdev)) { | ||
639 | int r = set_rx_filter(mac); | ||
640 | if (r) | ||
641 | return r; | ||
642 | return set_sniffer(mac); | ||
643 | } | ||
644 | |||
645 | return 0; | ||
646 | } | ||
647 | |||
648 | int zd_mac_get_mode(struct zd_mac *mac, u32 *mode) | ||
649 | { | ||
650 | unsigned long flags; | ||
651 | struct ieee80211_device *ieee; | ||
652 | |||
653 | ieee = zd_mac_to_ieee80211(mac); | ||
654 | spin_lock_irqsave(&ieee->lock, flags); | ||
655 | *mode = ieee->iw_mode; | ||
656 | spin_unlock_irqrestore(&ieee->lock, flags); | ||
657 | return 0; | ||
658 | } | ||
659 | |||
660 | int zd_mac_get_range(struct zd_mac *mac, struct iw_range *range) | ||
661 | { | ||
662 | int i; | ||
663 | const struct channel_range *channel_range; | ||
664 | u8 regdomain; | ||
665 | |||
666 | memset(range, 0, sizeof(*range)); | ||
667 | |||
668 | /* FIXME: Not so important and depends on the mode. For 802.11g | ||
669 | * usually this value is used. It seems to be that Bit/s number is | ||
670 | * given here. | ||
671 | */ | ||
672 | range->throughput = 27 * 1000 * 1000; | ||
673 | |||
674 | range->max_qual.qual = 100; | ||
675 | range->max_qual.level = 100; | ||
676 | |||
677 | /* FIXME: Needs still to be tuned. */ | ||
678 | range->avg_qual.qual = 71; | ||
679 | range->avg_qual.level = 80; | ||
680 | |||
681 | /* FIXME: depends on standard? */ | ||
682 | range->min_rts = 256; | ||
683 | range->max_rts = 2346; | ||
684 | |||
685 | range->min_frag = MIN_FRAG_THRESHOLD; | ||
686 | range->max_frag = MAX_FRAG_THRESHOLD; | ||
687 | |||
688 | range->max_encoding_tokens = WEP_KEYS; | ||
689 | range->num_encoding_sizes = 2; | ||
690 | range->encoding_size[0] = 5; | ||
691 | range->encoding_size[1] = WEP_KEY_LEN; | ||
692 | |||
693 | range->we_version_compiled = WIRELESS_EXT; | ||
694 | range->we_version_source = 20; | ||
695 | |||
696 | range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | | ||
697 | IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP; | ||
698 | |||
699 | ZD_ASSERT(!irqs_disabled()); | ||
700 | spin_lock_irq(&mac->lock); | ||
701 | regdomain = mac->regdomain; | ||
702 | spin_unlock_irq(&mac->lock); | ||
703 | channel_range = zd_channel_range(regdomain); | ||
704 | |||
705 | range->num_channels = channel_range->end - channel_range->start; | ||
706 | range->old_num_channels = range->num_channels; | ||
707 | range->num_frequency = range->num_channels; | ||
708 | range->old_num_frequency = range->num_frequency; | ||
709 | |||
710 | for (i = 0; i < range->num_frequency; i++) { | ||
711 | struct iw_freq *freq = &range->freq[i]; | ||
712 | freq->i = channel_range->start + i; | ||
713 | zd_channel_to_freq(freq, freq->i); | ||
714 | } | 401 | } |
715 | |||
716 | return 0; | ||
717 | } | 402 | } |
718 | 403 | ||
719 | static int zd_calc_tx_length_us(u8 *service, u8 zd_rate, u16 tx_length) | 404 | static int zd_calc_tx_length_us(u8 *service, u8 zd_rate, u16 tx_length) |
720 | { | 405 | { |
721 | /* ZD_PURE_RATE() must be used to remove the modulation type flag of | 406 | /* ZD_PURE_RATE() must be used to remove the modulation type flag of |
722 | * the zd-rate values. */ | 407 | * the zd-rate values. |
408 | */ | ||
723 | static const u8 rate_divisor[] = { | 409 | static const u8 rate_divisor[] = { |
724 | [ZD_PURE_RATE(ZD_CCK_RATE_1M)] = 1, | 410 | [ZD_PURE_RATE(ZD_CCK_RATE_1M)] = 1, |
725 | [ZD_PURE_RATE(ZD_CCK_RATE_2M)] = 2, | 411 | [ZD_PURE_RATE(ZD_CCK_RATE_2M)] = 2, |
726 | 412 | /* Bits must be doubled. */ | |
727 | /* bits must be doubled */ | 413 | [ZD_PURE_RATE(ZD_CCK_RATE_5_5M)] = 11, |
728 | [ZD_PURE_RATE(ZD_CCK_RATE_5_5M)] = 11, | 414 | [ZD_PURE_RATE(ZD_CCK_RATE_11M)] = 11, |
729 | 415 | [ZD_PURE_RATE(ZD_OFDM_RATE_6M)] = 6, | |
730 | [ZD_PURE_RATE(ZD_CCK_RATE_11M)] = 11, | 416 | [ZD_PURE_RATE(ZD_OFDM_RATE_9M)] = 9, |
731 | [ZD_PURE_RATE(ZD_OFDM_RATE_6M)] = 6, | 417 | [ZD_PURE_RATE(ZD_OFDM_RATE_12M)] = 12, |
732 | [ZD_PURE_RATE(ZD_OFDM_RATE_9M)] = 9, | 418 | [ZD_PURE_RATE(ZD_OFDM_RATE_18M)] = 18, |
733 | [ZD_PURE_RATE(ZD_OFDM_RATE_12M)] = 12, | 419 | [ZD_PURE_RATE(ZD_OFDM_RATE_24M)] = 24, |
734 | [ZD_PURE_RATE(ZD_OFDM_RATE_18M)] = 18, | 420 | [ZD_PURE_RATE(ZD_OFDM_RATE_36M)] = 36, |
735 | [ZD_PURE_RATE(ZD_OFDM_RATE_24M)] = 24, | 421 | [ZD_PURE_RATE(ZD_OFDM_RATE_48M)] = 48, |
736 | [ZD_PURE_RATE(ZD_OFDM_RATE_36M)] = 36, | 422 | [ZD_PURE_RATE(ZD_OFDM_RATE_54M)] = 54, |
737 | [ZD_PURE_RATE(ZD_OFDM_RATE_48M)] = 48, | ||
738 | [ZD_PURE_RATE(ZD_OFDM_RATE_54M)] = 54, | ||
739 | }; | 423 | }; |
740 | 424 | ||
741 | u32 bits = (u32)tx_length * 8; | 425 | u32 bits = (u32)tx_length * 8; |
@@ -764,34 +448,10 @@ static int zd_calc_tx_length_us(u8 *service, u8 zd_rate, u16 tx_length) | |||
764 | return bits/divisor; | 448 | return bits/divisor; |
765 | } | 449 | } |
766 | 450 | ||
767 | static void cs_set_modulation(struct zd_mac *mac, struct zd_ctrlset *cs, | ||
768 | struct ieee80211_hdr_4addr *hdr) | ||
769 | { | ||
770 | struct ieee80211softmac_device *softmac = ieee80211_priv(mac->netdev); | ||
771 | u16 ftype = WLAN_FC_GET_TYPE(le16_to_cpu(hdr->frame_ctl)); | ||
772 | u8 rate; | ||
773 | int is_mgt = (ftype == IEEE80211_FTYPE_MGMT) != 0; | ||
774 | int is_multicast = is_multicast_ether_addr(hdr->addr1); | ||
775 | int short_preamble = ieee80211softmac_short_preamble_ok(softmac, | ||
776 | is_multicast, is_mgt); | ||
777 | |||
778 | rate = ieee80211softmac_suggest_txrate(softmac, is_multicast, is_mgt); | ||
779 | cs->modulation = rate_to_zd_rate(rate); | ||
780 | |||
781 | /* Set short preamble bit when appropriate */ | ||
782 | if (short_preamble && ZD_MODULATION_TYPE(cs->modulation) == ZD_CCK | ||
783 | && cs->modulation != ZD_CCK_RATE_1M) | ||
784 | cs->modulation |= ZD_CCK_PREA_SHORT; | ||
785 | } | ||
786 | |||
787 | static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, | 451 | static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, |
788 | struct ieee80211_hdr_4addr *header) | 452 | struct ieee80211_hdr *header, u32 flags) |
789 | { | 453 | { |
790 | struct ieee80211softmac_device *softmac = ieee80211_priv(mac->netdev); | 454 | u16 fctl = le16_to_cpu(header->frame_control); |
791 | unsigned int tx_length = le16_to_cpu(cs->tx_length); | ||
792 | u16 fctl = le16_to_cpu(header->frame_ctl); | ||
793 | u16 ftype = WLAN_FC_GET_TYPE(fctl); | ||
794 | u16 stype = WLAN_FC_GET_STYPE(fctl); | ||
795 | 455 | ||
796 | /* | 456 | /* |
797 | * CONTROL TODO: | 457 | * CONTROL TODO: |
@@ -802,7 +462,7 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, | |||
802 | cs->control = 0; | 462 | cs->control = 0; |
803 | 463 | ||
804 | /* First fragment */ | 464 | /* First fragment */ |
805 | if (WLAN_GET_SEQ_FRAG(le16_to_cpu(header->seq_ctl)) == 0) | 465 | if (flags & IEEE80211_TXCTL_FIRST_FRAGMENT) |
806 | cs->control |= ZD_CS_NEED_RANDOM_BACKOFF; | 466 | cs->control |= ZD_CS_NEED_RANDOM_BACKOFF; |
807 | 467 | ||
808 | /* Multicast */ | 468 | /* Multicast */ |
@@ -810,54 +470,37 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, | |||
810 | cs->control |= ZD_CS_MULTICAST; | 470 | cs->control |= ZD_CS_MULTICAST; |
811 | 471 | ||
812 | /* PS-POLL */ | 472 | /* PS-POLL */ |
813 | if (ftype == IEEE80211_FTYPE_CTL && stype == IEEE80211_STYPE_PSPOLL) | 473 | if ((fctl & (IEEE80211_FCTL_FTYPE|IEEE80211_FCTL_STYPE)) == |
474 | (IEEE80211_FTYPE_CTL|IEEE80211_STYPE_PSPOLL)) | ||
814 | cs->control |= ZD_CS_PS_POLL_FRAME; | 475 | cs->control |= ZD_CS_PS_POLL_FRAME; |
815 | 476 | ||
816 | /* Unicast data frames over the threshold should have RTS */ | 477 | if (flags & IEEE80211_TXCTL_USE_RTS_CTS) |
817 | if (!is_multicast_ether_addr(header->addr1) && | ||
818 | ftype != IEEE80211_FTYPE_MGMT && | ||
819 | tx_length > zd_netdev_ieee80211(mac->netdev)->rts) | ||
820 | cs->control |= ZD_CS_RTS; | 478 | cs->control |= ZD_CS_RTS; |
821 | 479 | ||
822 | /* Use CTS-to-self protection if required */ | 480 | if (flags & IEEE80211_TXCTL_USE_CTS_PROTECT) |
823 | if (ZD_MODULATION_TYPE(cs->modulation) == ZD_OFDM && | ||
824 | ieee80211softmac_protection_needed(softmac)) { | ||
825 | /* FIXME: avoid sending RTS *and* self-CTS, is that correct? */ | ||
826 | cs->control &= ~ZD_CS_RTS; | ||
827 | cs->control |= ZD_CS_SELF_CTS; | 481 | cs->control |= ZD_CS_SELF_CTS; |
828 | } | ||
829 | 482 | ||
830 | /* FIXME: Management frame? */ | 483 | /* FIXME: Management frame? */ |
831 | } | 484 | } |
832 | 485 | ||
833 | static int fill_ctrlset(struct zd_mac *mac, | 486 | static int fill_ctrlset(struct zd_mac *mac, |
834 | struct ieee80211_txb *txb, | 487 | struct sk_buff *skb, |
835 | int frag_num) | 488 | struct ieee80211_tx_control *control) |
836 | { | 489 | { |
837 | int r; | 490 | int r; |
838 | struct sk_buff *skb = txb->fragments[frag_num]; | 491 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
839 | struct ieee80211_hdr_4addr *hdr = | 492 | unsigned int frag_len = skb->len + FCS_LEN; |
840 | (struct ieee80211_hdr_4addr *) skb->data; | ||
841 | unsigned int frag_len = skb->len + IEEE80211_FCS_LEN; | ||
842 | unsigned int next_frag_len; | ||
843 | unsigned int packet_length; | 493 | unsigned int packet_length; |
844 | struct zd_ctrlset *cs = (struct zd_ctrlset *) | 494 | struct zd_ctrlset *cs = (struct zd_ctrlset *) |
845 | skb_push(skb, sizeof(struct zd_ctrlset)); | 495 | skb_push(skb, sizeof(struct zd_ctrlset)); |
846 | 496 | ||
847 | if (frag_num+1 < txb->nr_frags) { | ||
848 | next_frag_len = txb->fragments[frag_num+1]->len + | ||
849 | IEEE80211_FCS_LEN; | ||
850 | } else { | ||
851 | next_frag_len = 0; | ||
852 | } | ||
853 | ZD_ASSERT(frag_len <= 0xffff); | 497 | ZD_ASSERT(frag_len <= 0xffff); |
854 | ZD_ASSERT(next_frag_len <= 0xffff); | ||
855 | 498 | ||
856 | cs_set_modulation(mac, cs, hdr); | 499 | cs->modulation = control->tx_rate; |
857 | 500 | ||
858 | cs->tx_length = cpu_to_le16(frag_len); | 501 | cs->tx_length = cpu_to_le16(frag_len); |
859 | 502 | ||
860 | cs_set_control(mac, cs, hdr); | 503 | cs_set_control(mac, cs, hdr, control->flags); |
861 | 504 | ||
862 | packet_length = frag_len + sizeof(struct zd_ctrlset) + 10; | 505 | packet_length = frag_len + sizeof(struct zd_ctrlset) + 10; |
863 | ZD_ASSERT(packet_length <= 0xffff); | 506 | ZD_ASSERT(packet_length <= 0xffff); |
@@ -886,419 +529,399 @@ static int fill_ctrlset(struct zd_mac *mac, | |||
886 | if (r < 0) | 529 | if (r < 0) |
887 | return r; | 530 | return r; |
888 | cs->current_length = cpu_to_le16(r); | 531 | cs->current_length = cpu_to_le16(r); |
889 | 532 | cs->next_frame_length = 0; | |
890 | if (next_frag_len == 0) { | ||
891 | cs->next_frame_length = 0; | ||
892 | } else { | ||
893 | r = zd_calc_tx_length_us(NULL, ZD_RATE(cs->modulation), | ||
894 | next_frag_len); | ||
895 | if (r < 0) | ||
896 | return r; | ||
897 | cs->next_frame_length = cpu_to_le16(r); | ||
898 | } | ||
899 | 533 | ||
900 | return 0; | 534 | return 0; |
901 | } | 535 | } |
902 | 536 | ||
903 | static int zd_mac_tx(struct zd_mac *mac, struct ieee80211_txb *txb, int pri) | 537 | /** |
538 | * zd_op_tx - transmits a network frame to the device | ||
539 | * | ||
540 | * @dev: mac80211 hardware device | ||
541 | * @skb: socket buffer | ||
542 | * @control: the control structure | ||
543 | * | ||
544 | * This function transmit an IEEE 802.11 network frame to the device. The | ||
545 | * control block of the skbuff will be initialized. If necessary the incoming | ||
546 | * mac80211 queues will be stopped. | ||
547 | */ | ||
548 | static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb, | ||
549 | struct ieee80211_tx_control *control) | ||
904 | { | 550 | { |
905 | int i, r; | 551 | struct zd_mac *mac = zd_hw_mac(hw); |
906 | struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); | 552 | int r; |
907 | 553 | ||
908 | for (i = 0; i < txb->nr_frags; i++) { | 554 | r = fill_ctrlset(mac, skb, control); |
909 | struct sk_buff *skb = txb->fragments[i]; | 555 | if (r) |
556 | return r; | ||
910 | 557 | ||
911 | r = fill_ctrlset(mac, txb, i); | 558 | r = init_tx_skb_control_block(skb, hw, control); |
912 | if (r) { | 559 | if (r) |
913 | ieee->stats.tx_dropped++; | 560 | return r; |
914 | return r; | 561 | r = zd_usb_tx(&mac->chip.usb, skb); |
915 | } | 562 | if (r) { |
916 | r = zd_usb_tx(&mac->chip.usb, skb->data, skb->len); | 563 | clear_tx_skb_control_block(skb); |
917 | if (r) { | 564 | return r; |
918 | ieee->stats.tx_dropped++; | ||
919 | return r; | ||
920 | } | ||
921 | } | 565 | } |
922 | |||
923 | /* FIXME: shouldn't this be handled by the upper layers? */ | ||
924 | mac->netdev->trans_start = jiffies; | ||
925 | |||
926 | ieee80211_txb_free(txb); | ||
927 | return 0; | 566 | return 0; |
928 | } | 567 | } |
929 | 568 | ||
930 | struct zd_rt_hdr { | 569 | /** |
931 | struct ieee80211_radiotap_header rt_hdr; | 570 | * filter_ack - filters incoming packets for acknowledgements |
932 | u8 rt_flags; | 571 | * @dev: the mac80211 device |
933 | u8 rt_rate; | 572 | * @rx_hdr: received header |
934 | u16 rt_channel; | 573 | * @stats: the status for the received packet |
935 | u16 rt_chbitmask; | ||
936 | } __attribute__((packed)); | ||
937 | |||
938 | static void fill_rt_header(void *buffer, struct zd_mac *mac, | ||
939 | const struct ieee80211_rx_stats *stats, | ||
940 | const struct rx_status *status) | ||
941 | { | ||
942 | struct zd_rt_hdr *hdr = buffer; | ||
943 | |||
944 | hdr->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION; | ||
945 | hdr->rt_hdr.it_pad = 0; | ||
946 | hdr->rt_hdr.it_len = cpu_to_le16(sizeof(struct zd_rt_hdr)); | ||
947 | hdr->rt_hdr.it_present = cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | | ||
948 | (1 << IEEE80211_RADIOTAP_CHANNEL) | | ||
949 | (1 << IEEE80211_RADIOTAP_RATE)); | ||
950 | |||
951 | hdr->rt_flags = 0; | ||
952 | if (status->decryption_type & (ZD_RX_WEP64|ZD_RX_WEP128|ZD_RX_WEP256)) | ||
953 | hdr->rt_flags |= IEEE80211_RADIOTAP_F_WEP; | ||
954 | |||
955 | hdr->rt_rate = stats->rate / 5; | ||
956 | |||
957 | /* FIXME: 802.11a */ | ||
958 | hdr->rt_channel = cpu_to_le16(ieee80211chan2mhz( | ||
959 | _zd_chip_get_channel(&mac->chip))); | ||
960 | hdr->rt_chbitmask = cpu_to_le16(IEEE80211_CHAN_2GHZ | | ||
961 | ((status->frame_status & ZD_RX_FRAME_MODULATION_MASK) == | ||
962 | ZD_RX_OFDM ? IEEE80211_CHAN_OFDM : IEEE80211_CHAN_CCK)); | ||
963 | } | ||
964 | |||
965 | /* Returns 1 if the data packet is for us and 0 otherwise. */ | ||
966 | static int is_data_packet_for_us(struct ieee80211_device *ieee, | ||
967 | struct ieee80211_hdr_4addr *hdr) | ||
968 | { | ||
969 | struct net_device *netdev = ieee->dev; | ||
970 | u16 fc = le16_to_cpu(hdr->frame_ctl); | ||
971 | |||
972 | ZD_ASSERT(WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA); | ||
973 | |||
974 | switch (ieee->iw_mode) { | ||
975 | case IW_MODE_ADHOC: | ||
976 | if ((fc & (IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS)) != 0 || | ||
977 | compare_ether_addr(hdr->addr3, ieee->bssid) != 0) | ||
978 | return 0; | ||
979 | break; | ||
980 | case IW_MODE_AUTO: | ||
981 | case IW_MODE_INFRA: | ||
982 | if ((fc & (IEEE80211_FCTL_TODS|IEEE80211_FCTL_FROMDS)) != | ||
983 | IEEE80211_FCTL_FROMDS || | ||
984 | compare_ether_addr(hdr->addr2, ieee->bssid) != 0) | ||
985 | return 0; | ||
986 | break; | ||
987 | default: | ||
988 | ZD_ASSERT(ieee->iw_mode != IW_MODE_MONITOR); | ||
989 | return 0; | ||
990 | } | ||
991 | |||
992 | return compare_ether_addr(hdr->addr1, netdev->dev_addr) == 0 || | ||
993 | (is_multicast_ether_addr(hdr->addr1) && | ||
994 | compare_ether_addr(hdr->addr3, netdev->dev_addr) != 0) || | ||
995 | (netdev->flags & IFF_PROMISC); | ||
996 | } | ||
997 | |||
998 | /* Filters received packets. The function returns 1 if the packet should be | ||
999 | * forwarded to ieee80211_rx(). If the packet should be ignored the function | ||
1000 | * returns 0. If an invalid packet is found the function returns -EINVAL. | ||
1001 | * | 574 | * |
1002 | * The function calls ieee80211_rx_mgt() directly. | 575 | * This functions looks for ACK packets and tries to match them with the |
576 | * frames in the tx queue. If a match is found the frame will be dequeued and | ||
577 | * the upper layers is informed about the successful transmission. If | ||
578 | * mac80211 queues have been stopped and the number of frames still to be | ||
579 | * transmitted is low the queues will be opened again. | ||
1003 | * | 580 | * |
1004 | * It has been based on ieee80211_rx_any. | 581 | * Returns 1 if the frame was an ACK, 0 if it was ignored. |
1005 | */ | 582 | */ |
1006 | static int filter_rx(struct ieee80211_device *ieee, | 583 | static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr, |
1007 | const u8 *buffer, unsigned int length, | 584 | struct ieee80211_rx_status *stats) |
1008 | struct ieee80211_rx_stats *stats) | ||
1009 | { | 585 | { |
1010 | struct ieee80211_hdr_4addr *hdr; | 586 | u16 fc = le16_to_cpu(rx_hdr->frame_control); |
1011 | u16 fc; | 587 | struct sk_buff *skb; |
1012 | 588 | struct sk_buff_head *q; | |
1013 | if (ieee->iw_mode == IW_MODE_MONITOR) | 589 | unsigned long flags; |
1014 | return 1; | ||
1015 | |||
1016 | hdr = (struct ieee80211_hdr_4addr *)buffer; | ||
1017 | fc = le16_to_cpu(hdr->frame_ctl); | ||
1018 | if ((fc & IEEE80211_FCTL_VERS) != 0) | ||
1019 | return -EINVAL; | ||
1020 | 590 | ||
1021 | switch (WLAN_FC_GET_TYPE(fc)) { | 591 | if ((fc & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) != |
1022 | case IEEE80211_FTYPE_MGMT: | 592 | (IEEE80211_FTYPE_CTL | IEEE80211_STYPE_ACK)) |
1023 | if (length < sizeof(struct ieee80211_hdr_3addr)) | ||
1024 | return -EINVAL; | ||
1025 | ieee80211_rx_mgt(ieee, hdr, stats); | ||
1026 | return 0; | 593 | return 0; |
1027 | case IEEE80211_FTYPE_CTL: | ||
1028 | return 0; | ||
1029 | case IEEE80211_FTYPE_DATA: | ||
1030 | /* Ignore invalid short buffers */ | ||
1031 | if (length < sizeof(struct ieee80211_hdr_3addr)) | ||
1032 | return -EINVAL; | ||
1033 | return is_data_packet_for_us(ieee, hdr); | ||
1034 | } | ||
1035 | 594 | ||
1036 | return -EINVAL; | 595 | q = &zd_hw_mac(hw)->ack_wait_queue; |
596 | spin_lock_irqsave(&q->lock, flags); | ||
597 | for (skb = q->next; skb != (struct sk_buff *)q; skb = skb->next) { | ||
598 | struct ieee80211_hdr *tx_hdr; | ||
599 | |||
600 | tx_hdr = (struct ieee80211_hdr *)skb->data; | ||
601 | if (likely(!compare_ether_addr(tx_hdr->addr2, rx_hdr->addr1))) | ||
602 | { | ||
603 | struct ieee80211_tx_status status = {{0}}; | ||
604 | status.flags = IEEE80211_TX_STATUS_ACK; | ||
605 | status.ack_signal = stats->ssi; | ||
606 | __skb_unlink(skb, q); | ||
607 | tx_status(hw, skb, &status, 1); | ||
608 | goto out; | ||
609 | } | ||
610 | } | ||
611 | out: | ||
612 | spin_unlock_irqrestore(&q->lock, flags); | ||
613 | return 1; | ||
1037 | } | 614 | } |
1038 | 615 | ||
1039 | static void update_qual_rssi(struct zd_mac *mac, | 616 | int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length) |
1040 | const u8 *buffer, unsigned int length, | ||
1041 | u8 qual_percent, u8 rssi_percent) | ||
1042 | { | 617 | { |
1043 | unsigned long flags; | 618 | struct zd_mac *mac = zd_hw_mac(hw); |
1044 | struct ieee80211_hdr_3addr *hdr; | 619 | struct ieee80211_rx_status stats; |
1045 | int i; | 620 | const struct rx_status *status; |
621 | struct sk_buff *skb; | ||
622 | int bad_frame = 0; | ||
1046 | 623 | ||
1047 | hdr = (struct ieee80211_hdr_3addr *)buffer; | 624 | if (length < ZD_PLCP_HEADER_SIZE + 10 /* IEEE80211_1ADDR_LEN */ + |
1048 | if (length < offsetof(struct ieee80211_hdr_3addr, addr3)) | 625 | FCS_LEN + sizeof(struct rx_status)) |
1049 | return; | 626 | return -EINVAL; |
1050 | if (compare_ether_addr(hdr->addr2, zd_mac_to_ieee80211(mac)->bssid) != 0) | ||
1051 | return; | ||
1052 | 627 | ||
1053 | spin_lock_irqsave(&mac->lock, flags); | 628 | memset(&stats, 0, sizeof(stats)); |
1054 | i = mac->stats_count % ZD_MAC_STATS_BUFFER_SIZE; | ||
1055 | mac->qual_buffer[i] = qual_percent; | ||
1056 | mac->rssi_buffer[i] = rssi_percent; | ||
1057 | mac->stats_count++; | ||
1058 | spin_unlock_irqrestore(&mac->lock, flags); | ||
1059 | } | ||
1060 | 629 | ||
1061 | static int fill_rx_stats(struct ieee80211_rx_stats *stats, | 630 | /* Note about pass_failed_fcs and pass_ctrl access below: |
1062 | const struct rx_status **pstatus, | 631 | * mac locking intentionally omitted here, as this is the only unlocked |
1063 | struct zd_mac *mac, | 632 | * reader and the only writer is configure_filter. Plus, if there were |
1064 | const u8 *buffer, unsigned int length) | 633 | * any races accessing these variables, it wouldn't really matter. |
1065 | { | 634 | * If mac80211 ever provides a way for us to access filter flags |
1066 | const struct rx_status *status; | 635 | * from outside configure_filter, we could improve on this. Also, this |
636 | * situation may change once we implement some kind of DMA-into-skb | ||
637 | * RX path. */ | ||
1067 | 638 | ||
1068 | *pstatus = status = (struct rx_status *) | 639 | /* Caller has to ensure that length >= sizeof(struct rx_status). */ |
640 | status = (struct rx_status *) | ||
1069 | (buffer + (length - sizeof(struct rx_status))); | 641 | (buffer + (length - sizeof(struct rx_status))); |
1070 | if (status->frame_status & ZD_RX_ERROR) { | 642 | if (status->frame_status & ZD_RX_ERROR) { |
1071 | struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); | 643 | if (mac->pass_failed_fcs && |
1072 | ieee->stats.rx_errors++; | 644 | (status->frame_status & ZD_RX_CRC32_ERROR)) { |
1073 | if (status->frame_status & ZD_RX_TIMEOUT_ERROR) | 645 | stats.flag |= RX_FLAG_FAILED_FCS_CRC; |
1074 | ieee->stats.rx_missed_errors++; | 646 | bad_frame = 1; |
1075 | else if (status->frame_status & ZD_RX_FIFO_OVERRUN_ERROR) | 647 | } else { |
1076 | ieee->stats.rx_fifo_errors++; | 648 | return -EINVAL; |
1077 | else if (status->frame_status & ZD_RX_DECRYPTION_ERROR) | ||
1078 | ieee->ieee_stats.rx_discards_undecryptable++; | ||
1079 | else if (status->frame_status & ZD_RX_CRC32_ERROR) { | ||
1080 | ieee->stats.rx_crc_errors++; | ||
1081 | ieee->ieee_stats.rx_fcs_errors++; | ||
1082 | } | 649 | } |
1083 | else if (status->frame_status & ZD_RX_CRC16_ERROR) | ||
1084 | ieee->stats.rx_crc_errors++; | ||
1085 | return -EINVAL; | ||
1086 | } | 650 | } |
1087 | 651 | ||
1088 | memset(stats, 0, sizeof(struct ieee80211_rx_stats)); | 652 | stats.channel = _zd_chip_get_channel(&mac->chip); |
1089 | stats->len = length - (ZD_PLCP_HEADER_SIZE + IEEE80211_FCS_LEN + | 653 | stats.freq = zd_channels[stats.channel - 1].freq; |
1090 | + sizeof(struct rx_status)); | 654 | stats.phymode = MODE_IEEE80211G; |
1091 | /* FIXME: 802.11a */ | 655 | stats.ssi = status->signal_strength; |
1092 | stats->freq = IEEE80211_24GHZ_BAND; | 656 | stats.signal = zd_rx_qual_percent(buffer, |
1093 | stats->received_channel = _zd_chip_get_channel(&mac->chip); | ||
1094 | stats->rssi = zd_rx_strength_percent(status->signal_strength); | ||
1095 | stats->signal = zd_rx_qual_percent(buffer, | ||
1096 | length - sizeof(struct rx_status), | 657 | length - sizeof(struct rx_status), |
1097 | status); | 658 | status); |
1098 | stats->mask = IEEE80211_STATMASK_RSSI | IEEE80211_STATMASK_SIGNAL; | 659 | stats.rate = zd_rx_rate(buffer, status); |
1099 | stats->rate = zd_rx_rate(buffer, status); | 660 | |
1100 | if (stats->rate) | 661 | length -= ZD_PLCP_HEADER_SIZE + sizeof(struct rx_status); |
1101 | stats->mask |= IEEE80211_STATMASK_RATE; | 662 | buffer += ZD_PLCP_HEADER_SIZE; |
663 | |||
664 | /* Except for bad frames, filter each frame to see if it is an ACK, in | ||
665 | * which case our internal TX tracking is updated. Normally we then | ||
666 | * bail here as there's no need to pass ACKs on up to the stack, but | ||
667 | * there is also the case where the stack has requested us to pass | ||
668 | * control frames on up (pass_ctrl) which we must consider. */ | ||
669 | if (!bad_frame && | ||
670 | filter_ack(hw, (struct ieee80211_hdr *)buffer, &stats) | ||
671 | && !mac->pass_ctrl) | ||
672 | return 0; | ||
1102 | 673 | ||
674 | skb = dev_alloc_skb(length); | ||
675 | if (skb == NULL) | ||
676 | return -ENOMEM; | ||
677 | memcpy(skb_put(skb, length), buffer, length); | ||
678 | |||
679 | ieee80211_rx_irqsafe(hw, skb, &stats); | ||
1103 | return 0; | 680 | return 0; |
1104 | } | 681 | } |
1105 | 682 | ||
1106 | static void zd_mac_rx(struct zd_mac *mac, struct sk_buff *skb) | 683 | static int zd_op_add_interface(struct ieee80211_hw *hw, |
684 | struct ieee80211_if_init_conf *conf) | ||
1107 | { | 685 | { |
1108 | int r; | 686 | struct zd_mac *mac = zd_hw_mac(hw); |
1109 | struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); | ||
1110 | struct ieee80211_rx_stats stats; | ||
1111 | const struct rx_status *status; | ||
1112 | 687 | ||
1113 | if (skb->len < ZD_PLCP_HEADER_SIZE + IEEE80211_1ADDR_LEN + | 688 | /* using IEEE80211_IF_TYPE_INVALID to indicate no mode selected */ |
1114 | IEEE80211_FCS_LEN + sizeof(struct rx_status)) | 689 | if (mac->type != IEEE80211_IF_TYPE_INVALID) |
1115 | { | 690 | return -EOPNOTSUPP; |
1116 | ieee->stats.rx_errors++; | ||
1117 | ieee->stats.rx_length_errors++; | ||
1118 | goto free_skb; | ||
1119 | } | ||
1120 | 691 | ||
1121 | r = fill_rx_stats(&stats, &status, mac, skb->data, skb->len); | 692 | switch (conf->type) { |
1122 | if (r) { | 693 | case IEEE80211_IF_TYPE_MNTR: |
1123 | /* Only packets with rx errors are included here. | 694 | case IEEE80211_IF_TYPE_STA: |
1124 | * The error stats have already been set in fill_rx_stats. | 695 | mac->type = conf->type; |
1125 | */ | 696 | break; |
1126 | goto free_skb; | 697 | default: |
698 | return -EOPNOTSUPP; | ||
1127 | } | 699 | } |
1128 | 700 | ||
1129 | __skb_pull(skb, ZD_PLCP_HEADER_SIZE); | 701 | return zd_write_mac_addr(&mac->chip, conf->mac_addr); |
1130 | __skb_trim(skb, skb->len - | 702 | } |
1131 | (IEEE80211_FCS_LEN + sizeof(struct rx_status))); | ||
1132 | 703 | ||
1133 | ZD_ASSERT(IS_ALIGNED((unsigned long)skb->data, 4)); | 704 | static void zd_op_remove_interface(struct ieee80211_hw *hw, |
705 | struct ieee80211_if_init_conf *conf) | ||
706 | { | ||
707 | struct zd_mac *mac = zd_hw_mac(hw); | ||
708 | mac->type = IEEE80211_IF_TYPE_INVALID; | ||
709 | zd_write_mac_addr(&mac->chip, NULL); | ||
710 | } | ||
1134 | 711 | ||
1135 | update_qual_rssi(mac, skb->data, skb->len, stats.signal, | 712 | static int zd_op_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) |
1136 | status->signal_strength); | 713 | { |
714 | struct zd_mac *mac = zd_hw_mac(hw); | ||
715 | return zd_chip_set_channel(&mac->chip, conf->channel); | ||
716 | } | ||
1137 | 717 | ||
1138 | r = filter_rx(ieee, skb->data, skb->len, &stats); | 718 | static int zd_op_config_interface(struct ieee80211_hw *hw, int if_id, |
1139 | if (r <= 0) { | 719 | struct ieee80211_if_conf *conf) |
1140 | if (r < 0) { | 720 | { |
1141 | ieee->stats.rx_errors++; | 721 | struct zd_mac *mac = zd_hw_mac(hw); |
1142 | dev_dbg_f(zd_mac_dev(mac), "Error in packet.\n"); | ||
1143 | } | ||
1144 | goto free_skb; | ||
1145 | } | ||
1146 | 722 | ||
1147 | if (ieee->iw_mode == IW_MODE_MONITOR) | 723 | spin_lock_irq(&mac->lock); |
1148 | fill_rt_header(skb_push(skb, sizeof(struct zd_rt_hdr)), mac, | 724 | mac->associated = is_valid_ether_addr(conf->bssid); |
1149 | &stats, status); | 725 | spin_unlock_irq(&mac->lock); |
1150 | 726 | ||
1151 | r = ieee80211_rx(ieee, skb, &stats); | 727 | /* TODO: do hardware bssid filtering */ |
1152 | if (r) | 728 | return 0; |
1153 | return; | ||
1154 | free_skb: | ||
1155 | /* We are always in a soft irq. */ | ||
1156 | dev_kfree_skb(skb); | ||
1157 | } | 729 | } |
1158 | 730 | ||
1159 | static void do_rx(unsigned long mac_ptr) | 731 | static void set_multicast_hash_handler(struct work_struct *work) |
1160 | { | 732 | { |
1161 | struct zd_mac *mac = (struct zd_mac *)mac_ptr; | 733 | struct zd_mac *mac = |
1162 | struct sk_buff *skb; | 734 | container_of(work, struct zd_mac, set_multicast_hash_work); |
735 | struct zd_mc_hash hash; | ||
1163 | 736 | ||
1164 | while ((skb = skb_dequeue(&mac->rx_queue)) != NULL) | 737 | spin_lock_irq(&mac->lock); |
1165 | zd_mac_rx(mac, skb); | 738 | hash = mac->multicast_hash; |
1166 | } | 739 | spin_unlock_irq(&mac->lock); |
1167 | 740 | ||
1168 | int zd_mac_rx_irq(struct zd_mac *mac, const u8 *buffer, unsigned int length) | 741 | zd_chip_set_multicast_hash(&mac->chip, &hash); |
1169 | { | ||
1170 | struct sk_buff *skb; | ||
1171 | unsigned int reserved = | ||
1172 | ALIGN(max_t(unsigned int, | ||
1173 | sizeof(struct zd_rt_hdr), ZD_PLCP_HEADER_SIZE), 4) - | ||
1174 | ZD_PLCP_HEADER_SIZE; | ||
1175 | |||
1176 | skb = dev_alloc_skb(reserved + length); | ||
1177 | if (!skb) { | ||
1178 | struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); | ||
1179 | dev_warn(zd_mac_dev(mac), "Could not allocate skb.\n"); | ||
1180 | ieee->stats.rx_dropped++; | ||
1181 | return -ENOMEM; | ||
1182 | } | ||
1183 | skb_reserve(skb, reserved); | ||
1184 | memcpy(__skb_put(skb, length), buffer, length); | ||
1185 | skb_queue_tail(&mac->rx_queue, skb); | ||
1186 | tasklet_schedule(&mac->rx_tasklet); | ||
1187 | return 0; | ||
1188 | } | 742 | } |
1189 | 743 | ||
1190 | static int netdev_tx(struct ieee80211_txb *txb, struct net_device *netdev, | 744 | static void set_rx_filter_handler(struct work_struct *work) |
1191 | int pri) | ||
1192 | { | 745 | { |
1193 | return zd_mac_tx(zd_netdev_mac(netdev), txb, pri); | 746 | struct zd_mac *mac = |
747 | container_of(work, struct zd_mac, set_rx_filter_work); | ||
748 | int r; | ||
749 | |||
750 | dev_dbg_f(zd_mac_dev(mac), "\n"); | ||
751 | r = set_rx_filter(mac); | ||
752 | if (r) | ||
753 | dev_err(zd_mac_dev(mac), "set_rx_filter_handler error %d\n", r); | ||
1194 | } | 754 | } |
1195 | 755 | ||
1196 | static void set_security(struct net_device *netdev, | 756 | #define SUPPORTED_FIF_FLAGS \ |
1197 | struct ieee80211_security *sec) | 757 | (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | FIF_CONTROL | \ |
758 | FIF_OTHER_BSS) | ||
759 | static void zd_op_configure_filter(struct ieee80211_hw *hw, | ||
760 | unsigned int changed_flags, | ||
761 | unsigned int *new_flags, | ||
762 | int mc_count, struct dev_mc_list *mclist) | ||
1198 | { | 763 | { |
1199 | struct ieee80211_device *ieee = zd_netdev_ieee80211(netdev); | 764 | struct zd_mc_hash hash; |
1200 | struct ieee80211_security *secinfo = &ieee->sec; | 765 | struct zd_mac *mac = zd_hw_mac(hw); |
1201 | int keyidx; | 766 | unsigned long flags; |
1202 | 767 | int i; | |
1203 | dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)), "\n"); | ||
1204 | |||
1205 | for (keyidx = 0; keyidx<WEP_KEYS; keyidx++) | ||
1206 | if (sec->flags & (1<<keyidx)) { | ||
1207 | secinfo->encode_alg[keyidx] = sec->encode_alg[keyidx]; | ||
1208 | secinfo->key_sizes[keyidx] = sec->key_sizes[keyidx]; | ||
1209 | memcpy(secinfo->keys[keyidx], sec->keys[keyidx], | ||
1210 | SCM_KEY_LEN); | ||
1211 | } | ||
1212 | 768 | ||
1213 | if (sec->flags & SEC_ACTIVE_KEY) { | 769 | /* Only deal with supported flags */ |
1214 | secinfo->active_key = sec->active_key; | 770 | changed_flags &= SUPPORTED_FIF_FLAGS; |
1215 | dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)), | 771 | *new_flags &= SUPPORTED_FIF_FLAGS; |
1216 | " .active_key = %d\n", sec->active_key); | 772 | |
1217 | } | 773 | /* changed_flags is always populated but this driver |
1218 | if (sec->flags & SEC_UNICAST_GROUP) { | 774 | * doesn't support all FIF flags so its possible we don't |
1219 | secinfo->unicast_uses_group = sec->unicast_uses_group; | 775 | * need to do anything */ |
1220 | dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)), | 776 | if (!changed_flags) |
1221 | " .unicast_uses_group = %d\n", | 777 | return; |
1222 | sec->unicast_uses_group); | 778 | |
1223 | } | 779 | if (*new_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) { |
1224 | if (sec->flags & SEC_LEVEL) { | 780 | zd_mc_add_all(&hash); |
1225 | secinfo->level = sec->level; | 781 | } else { |
1226 | dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)), | 782 | DECLARE_MAC_BUF(macbuf); |
1227 | " .level = %d\n", sec->level); | 783 | |
1228 | } | 784 | zd_mc_clear(&hash); |
1229 | if (sec->flags & SEC_ENABLED) { | 785 | for (i = 0; i < mc_count; i++) { |
1230 | secinfo->enabled = sec->enabled; | 786 | if (!mclist) |
1231 | dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)), | 787 | break; |
1232 | " .enabled = %d\n", sec->enabled); | 788 | dev_dbg_f(zd_mac_dev(mac), "mc addr %s\n", |
1233 | } | 789 | print_mac(macbuf, mclist->dmi_addr)); |
1234 | if (sec->flags & SEC_ENCRYPT) { | 790 | zd_mc_add_addr(&hash, mclist->dmi_addr); |
1235 | secinfo->encrypt = sec->encrypt; | 791 | mclist = mclist->next; |
1236 | dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)), | 792 | } |
1237 | " .encrypt = %d\n", sec->encrypt); | ||
1238 | } | ||
1239 | if (sec->flags & SEC_AUTH_MODE) { | ||
1240 | secinfo->auth_mode = sec->auth_mode; | ||
1241 | dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)), | ||
1242 | " .auth_mode = %d\n", sec->auth_mode); | ||
1243 | } | 793 | } |
794 | |||
795 | spin_lock_irqsave(&mac->lock, flags); | ||
796 | mac->pass_failed_fcs = !!(*new_flags & FIF_FCSFAIL); | ||
797 | mac->pass_ctrl = !!(*new_flags & FIF_CONTROL); | ||
798 | mac->multicast_hash = hash; | ||
799 | spin_unlock_irqrestore(&mac->lock, flags); | ||
800 | queue_work(zd_workqueue, &mac->set_multicast_hash_work); | ||
801 | |||
802 | if (changed_flags & FIF_CONTROL) | ||
803 | queue_work(zd_workqueue, &mac->set_rx_filter_work); | ||
804 | |||
805 | /* no handling required for FIF_OTHER_BSS as we don't currently | ||
806 | * do BSSID filtering */ | ||
807 | /* FIXME: in future it would be nice to enable the probe response | ||
808 | * filter (so that the driver doesn't see them) until | ||
809 | * FIF_BCN_PRBRESP_PROMISC is set. however due to atomicity here, we'd | ||
810 | * have to schedule work to enable prbresp reception, which might | ||
811 | * happen too late. For now we'll just listen and forward them all the | ||
812 | * time. */ | ||
1244 | } | 813 | } |
1245 | 814 | ||
1246 | static void ieee_init(struct ieee80211_device *ieee) | 815 | static void set_rts_cts_work(struct work_struct *work) |
1247 | { | 816 | { |
1248 | ieee->mode = IEEE_B | IEEE_G; | 817 | struct zd_mac *mac = |
1249 | ieee->freq_band = IEEE80211_24GHZ_BAND; | 818 | container_of(work, struct zd_mac, set_rts_cts_work); |
1250 | ieee->modulation = IEEE80211_OFDM_MODULATION | IEEE80211_CCK_MODULATION; | 819 | unsigned long flags; |
1251 | ieee->tx_headroom = sizeof(struct zd_ctrlset); | 820 | unsigned int short_preamble; |
1252 | ieee->set_security = set_security; | 821 | |
1253 | ieee->hard_start_xmit = netdev_tx; | 822 | mutex_lock(&mac->chip.mutex); |
1254 | 823 | ||
1255 | /* Software encryption/decryption for now */ | 824 | spin_lock_irqsave(&mac->lock, flags); |
1256 | ieee->host_build_iv = 0; | 825 | mac->updating_rts_rate = 0; |
1257 | ieee->host_encrypt = 1; | 826 | short_preamble = mac->short_preamble; |
1258 | ieee->host_decrypt = 1; | 827 | spin_unlock_irqrestore(&mac->lock, flags); |
1259 | 828 | ||
1260 | /* FIXME: default to managed mode, until ieee80211 and zd1211rw can | 829 | zd_chip_set_rts_cts_rate_locked(&mac->chip, short_preamble); |
1261 | * correctly support AUTO */ | 830 | mutex_unlock(&mac->chip.mutex); |
1262 | ieee->iw_mode = IW_MODE_INFRA; | ||
1263 | } | 831 | } |
1264 | 832 | ||
1265 | static void softmac_init(struct ieee80211softmac_device *sm) | 833 | static void zd_op_erp_ie_changed(struct ieee80211_hw *hw, u8 changes, |
834 | int cts_protection, int preamble) | ||
1266 | { | 835 | { |
1267 | sm->set_channel = set_channel; | 836 | struct zd_mac *mac = zd_hw_mac(hw); |
1268 | sm->bssinfo_change = bssinfo_change; | 837 | unsigned long flags; |
838 | |||
839 | dev_dbg_f(zd_mac_dev(mac), "changes: %x\n", changes); | ||
840 | |||
841 | if (changes & IEEE80211_ERP_CHANGE_PREAMBLE) { | ||
842 | spin_lock_irqsave(&mac->lock, flags); | ||
843 | mac->short_preamble = !preamble; | ||
844 | if (!mac->updating_rts_rate) { | ||
845 | mac->updating_rts_rate = 1; | ||
846 | /* FIXME: should disable TX here, until work has | ||
847 | * completed and RTS_CTS reg is updated */ | ||
848 | queue_work(zd_workqueue, &mac->set_rts_cts_work); | ||
849 | } | ||
850 | spin_unlock_irqrestore(&mac->lock, flags); | ||
851 | } | ||
1269 | } | 852 | } |
1270 | 853 | ||
1271 | struct iw_statistics *zd_mac_get_wireless_stats(struct net_device *ndev) | 854 | static const struct ieee80211_ops zd_ops = { |
855 | .tx = zd_op_tx, | ||
856 | .start = zd_op_start, | ||
857 | .stop = zd_op_stop, | ||
858 | .add_interface = zd_op_add_interface, | ||
859 | .remove_interface = zd_op_remove_interface, | ||
860 | .config = zd_op_config, | ||
861 | .config_interface = zd_op_config_interface, | ||
862 | .configure_filter = zd_op_configure_filter, | ||
863 | .erp_ie_changed = zd_op_erp_ie_changed, | ||
864 | }; | ||
865 | |||
866 | struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) | ||
1272 | { | 867 | { |
1273 | struct zd_mac *mac = zd_netdev_mac(ndev); | 868 | struct zd_mac *mac; |
1274 | struct iw_statistics *iw_stats = &mac->iw_stats; | 869 | struct ieee80211_hw *hw; |
1275 | unsigned int i, count, qual_total, rssi_total; | 870 | int i; |
1276 | 871 | ||
1277 | memset(iw_stats, 0, sizeof(struct iw_statistics)); | 872 | hw = ieee80211_alloc_hw(sizeof(struct zd_mac), &zd_ops); |
1278 | /* We are not setting the status, because ieee->state is not updated | 873 | if (!hw) { |
1279 | * at all and this driver doesn't track authentication state. | 874 | dev_dbg_f(&intf->dev, "out of memory\n"); |
1280 | */ | 875 | return NULL; |
1281 | spin_lock_irq(&mac->lock); | ||
1282 | count = mac->stats_count < ZD_MAC_STATS_BUFFER_SIZE ? | ||
1283 | mac->stats_count : ZD_MAC_STATS_BUFFER_SIZE; | ||
1284 | qual_total = rssi_total = 0; | ||
1285 | for (i = 0; i < count; i++) { | ||
1286 | qual_total += mac->qual_buffer[i]; | ||
1287 | rssi_total += mac->rssi_buffer[i]; | ||
1288 | } | 876 | } |
1289 | spin_unlock_irq(&mac->lock); | 877 | |
1290 | iw_stats->qual.updated = IW_QUAL_NOISE_INVALID; | 878 | mac = zd_hw_mac(hw); |
1291 | if (count > 0) { | 879 | |
1292 | iw_stats->qual.qual = qual_total / count; | 880 | memset(mac, 0, sizeof(*mac)); |
1293 | iw_stats->qual.level = rssi_total / count; | 881 | spin_lock_init(&mac->lock); |
1294 | iw_stats->qual.updated |= | 882 | mac->hw = hw; |
1295 | IW_QUAL_QUAL_UPDATED|IW_QUAL_LEVEL_UPDATED; | 883 | |
1296 | } else { | 884 | mac->type = IEEE80211_IF_TYPE_INVALID; |
1297 | iw_stats->qual.updated |= | 885 | |
1298 | IW_QUAL_QUAL_INVALID|IW_QUAL_LEVEL_INVALID; | 886 | memcpy(mac->channels, zd_channels, sizeof(zd_channels)); |
887 | memcpy(mac->rates, zd_rates, sizeof(zd_rates)); | ||
888 | mac->modes[0].mode = MODE_IEEE80211G; | ||
889 | mac->modes[0].num_rates = ARRAY_SIZE(zd_rates); | ||
890 | mac->modes[0].rates = mac->rates; | ||
891 | mac->modes[0].num_channels = ARRAY_SIZE(zd_channels); | ||
892 | mac->modes[0].channels = mac->channels; | ||
893 | mac->modes[1].mode = MODE_IEEE80211B; | ||
894 | mac->modes[1].num_rates = 4; | ||
895 | mac->modes[1].rates = mac->rates; | ||
896 | mac->modes[1].num_channels = ARRAY_SIZE(zd_channels); | ||
897 | mac->modes[1].channels = mac->channels; | ||
898 | |||
899 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | ||
900 | IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED; | ||
901 | hw->max_rssi = 100; | ||
902 | hw->max_signal = 100; | ||
903 | |||
904 | hw->queues = 1; | ||
905 | hw->extra_tx_headroom = sizeof(struct zd_ctrlset); | ||
906 | |||
907 | skb_queue_head_init(&mac->ack_wait_queue); | ||
908 | |||
909 | for (i = 0; i < 2; i++) { | ||
910 | if (ieee80211_register_hwmode(hw, &mac->modes[i])) { | ||
911 | dev_dbg_f(&intf->dev, "cannot register hwmode\n"); | ||
912 | ieee80211_free_hw(hw); | ||
913 | return NULL; | ||
914 | } | ||
1299 | } | 915 | } |
1300 | /* TODO: update counter */ | 916 | |
1301 | return iw_stats; | 917 | zd_chip_init(&mac->chip, hw, intf); |
918 | housekeeping_init(mac); | ||
919 | INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler); | ||
920 | INIT_WORK(&mac->set_rts_cts_work, set_rts_cts_work); | ||
921 | INIT_WORK(&mac->set_rx_filter_work, set_rx_filter_handler); | ||
922 | |||
923 | SET_IEEE80211_DEV(hw, &intf->dev); | ||
924 | return hw; | ||
1302 | } | 925 | } |
1303 | 926 | ||
1304 | #define LINK_LED_WORK_DELAY HZ | 927 | #define LINK_LED_WORK_DELAY HZ |
@@ -1308,18 +931,17 @@ static void link_led_handler(struct work_struct *work) | |||
1308 | struct zd_mac *mac = | 931 | struct zd_mac *mac = |
1309 | container_of(work, struct zd_mac, housekeeping.link_led_work.work); | 932 | container_of(work, struct zd_mac, housekeeping.link_led_work.work); |
1310 | struct zd_chip *chip = &mac->chip; | 933 | struct zd_chip *chip = &mac->chip; |
1311 | struct ieee80211softmac_device *sm = ieee80211_priv(mac->netdev); | ||
1312 | int is_associated; | 934 | int is_associated; |
1313 | int r; | 935 | int r; |
1314 | 936 | ||
1315 | spin_lock_irq(&mac->lock); | 937 | spin_lock_irq(&mac->lock); |
1316 | is_associated = sm->associnfo.associated != 0; | 938 | is_associated = mac->associated; |
1317 | spin_unlock_irq(&mac->lock); | 939 | spin_unlock_irq(&mac->lock); |
1318 | 940 | ||
1319 | r = zd_chip_control_leds(chip, | 941 | r = zd_chip_control_leds(chip, |
1320 | is_associated ? LED_ASSOCIATED : LED_SCANNING); | 942 | is_associated ? LED_ASSOCIATED : LED_SCANNING); |
1321 | if (r) | 943 | if (r) |
1322 | dev_err(zd_mac_dev(mac), "zd_chip_control_leds error %d\n", r); | 944 | dev_dbg_f(zd_mac_dev(mac), "zd_chip_control_leds error %d\n", r); |
1323 | 945 | ||
1324 | queue_delayed_work(zd_workqueue, &mac->housekeeping.link_led_work, | 946 | queue_delayed_work(zd_workqueue, &mac->housekeeping.link_led_work, |
1325 | LINK_LED_WORK_DELAY); | 947 | LINK_LED_WORK_DELAY); |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h index 1b15bde3ff60..ed5417ca2d10 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.h +++ b/drivers/net/wireless/zd1211rw/zd_mac.h | |||
@@ -18,14 +18,11 @@ | |||
18 | #ifndef _ZD_MAC_H | 18 | #ifndef _ZD_MAC_H |
19 | #define _ZD_MAC_H | 19 | #define _ZD_MAC_H |
20 | 20 | ||
21 | #include <linux/wireless.h> | ||
22 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
23 | #include <linux/workqueue.h> | 22 | #include <net/mac80211.h> |
24 | #include <net/ieee80211.h> | ||
25 | #include <net/ieee80211softmac.h> | ||
26 | 23 | ||
27 | #include "zd_chip.h" | 24 | #include "zd_chip.h" |
28 | #include "zd_netdev.h" | 25 | #include "zd_ieee80211.h" |
29 | 26 | ||
30 | struct zd_ctrlset { | 27 | struct zd_ctrlset { |
31 | u8 modulation; | 28 | u8 modulation; |
@@ -57,7 +54,7 @@ struct zd_ctrlset { | |||
57 | /* The two possible modulation types. Notify that 802.11b doesn't use the CCK | 54 | /* The two possible modulation types. Notify that 802.11b doesn't use the CCK |
58 | * codeing for the 1 and 2 MBit/s rate. We stay with the term here to remain | 55 | * codeing for the 1 and 2 MBit/s rate. We stay with the term here to remain |
59 | * consistent with uses the term at other places. | 56 | * consistent with uses the term at other places. |
60 | */ | 57 | */ |
61 | #define ZD_CCK 0x00 | 58 | #define ZD_CCK 0x00 |
62 | #define ZD_OFDM 0x10 | 59 | #define ZD_OFDM 0x10 |
63 | 60 | ||
@@ -141,58 +138,68 @@ struct rx_status { | |||
141 | #define ZD_RX_CRC16_ERROR 0x40 | 138 | #define ZD_RX_CRC16_ERROR 0x40 |
142 | #define ZD_RX_ERROR 0x80 | 139 | #define ZD_RX_ERROR 0x80 |
143 | 140 | ||
141 | enum mac_flags { | ||
142 | MAC_FIXED_CHANNEL = 0x01, | ||
143 | }; | ||
144 | |||
144 | struct housekeeping { | 145 | struct housekeeping { |
145 | struct delayed_work link_led_work; | 146 | struct delayed_work link_led_work; |
146 | }; | 147 | }; |
147 | 148 | ||
149 | /** | ||
150 | * struct zd_tx_skb_control_block - control block for tx skbuffs | ||
151 | * @control: &struct ieee80211_tx_control pointer | ||
152 | * @context: context pointer | ||
153 | * | ||
154 | * This structure is used to fill the cb field in an &sk_buff to transmit. | ||
155 | * The control field is NULL, if there is no requirement from the mac80211 | ||
156 | * stack to report about the packet ACK. This is the case if the flag | ||
157 | * IEEE80211_TXCTL_NO_ACK is not set in &struct ieee80211_tx_control. | ||
158 | */ | ||
159 | struct zd_tx_skb_control_block { | ||
160 | struct ieee80211_tx_control *control; | ||
161 | struct ieee80211_hw *hw; | ||
162 | void *context; | ||
163 | }; | ||
164 | |||
148 | #define ZD_MAC_STATS_BUFFER_SIZE 16 | 165 | #define ZD_MAC_STATS_BUFFER_SIZE 16 |
149 | 166 | ||
167 | #define ZD_MAC_MAX_ACK_WAITERS 10 | ||
168 | |||
150 | struct zd_mac { | 169 | struct zd_mac { |
151 | struct zd_chip chip; | 170 | struct zd_chip chip; |
152 | spinlock_t lock; | 171 | spinlock_t lock; |
153 | struct net_device *netdev; | 172 | struct ieee80211_hw *hw; |
154 | |||
155 | /* Unlocked reading possible */ | ||
156 | struct iw_statistics iw_stats; | ||
157 | |||
158 | struct housekeeping housekeeping; | 173 | struct housekeeping housekeeping; |
159 | struct work_struct set_multicast_hash_work; | 174 | struct work_struct set_multicast_hash_work; |
175 | struct work_struct set_rts_cts_work; | ||
176 | struct work_struct set_rx_filter_work; | ||
160 | struct zd_mc_hash multicast_hash; | 177 | struct zd_mc_hash multicast_hash; |
161 | struct delayed_work set_rts_cts_work; | ||
162 | struct delayed_work set_basic_rates_work; | ||
163 | |||
164 | struct tasklet_struct rx_tasklet; | ||
165 | struct sk_buff_head rx_queue; | ||
166 | |||
167 | unsigned int stats_count; | ||
168 | u8 qual_buffer[ZD_MAC_STATS_BUFFER_SIZE]; | ||
169 | u8 rssi_buffer[ZD_MAC_STATS_BUFFER_SIZE]; | ||
170 | u8 regdomain; | 178 | u8 regdomain; |
171 | u8 default_regdomain; | 179 | u8 default_regdomain; |
172 | u8 requested_channel; | 180 | int type; |
173 | 181 | int associated; | |
174 | /* A bitpattern of cr_rates */ | 182 | struct sk_buff_head ack_wait_queue; |
175 | u16 basic_rates; | 183 | struct ieee80211_channel channels[14]; |
176 | 184 | struct ieee80211_rate rates[12]; | |
177 | /* A zd_rate */ | 185 | struct ieee80211_hw_mode modes[2]; |
178 | u8 rts_rate; | ||
179 | 186 | ||
180 | /* Short preamble (used for RTS/CTS) */ | 187 | /* Short preamble (used for RTS/CTS) */ |
181 | unsigned int short_preamble:1; | 188 | unsigned int short_preamble:1; |
182 | 189 | ||
183 | /* flags to indicate update in progress */ | 190 | /* flags to indicate update in progress */ |
184 | unsigned int updating_rts_rate:1; | 191 | unsigned int updating_rts_rate:1; |
185 | unsigned int updating_basic_rates:1; | ||
186 | }; | ||
187 | 192 | ||
188 | static inline struct ieee80211_device *zd_mac_to_ieee80211(struct zd_mac *mac) | 193 | /* whether to pass frames with CRC errors to stack */ |
189 | { | 194 | unsigned int pass_failed_fcs:1; |
190 | return zd_netdev_ieee80211(mac->netdev); | ||
191 | } | ||
192 | 195 | ||
193 | static inline struct zd_mac *zd_netdev_mac(struct net_device *netdev) | 196 | /* whether to pass control frames to stack */ |
197 | unsigned int pass_ctrl:1; | ||
198 | }; | ||
199 | |||
200 | static inline struct zd_mac *zd_hw_mac(struct ieee80211_hw *hw) | ||
194 | { | 201 | { |
195 | return ieee80211softmac_priv(netdev); | 202 | return hw->priv; |
196 | } | 203 | } |
197 | 204 | ||
198 | static inline struct zd_mac *zd_chip_to_mac(struct zd_chip *chip) | 205 | static inline struct zd_mac *zd_chip_to_mac(struct zd_chip *chip) |
@@ -205,35 +212,22 @@ static inline struct zd_mac *zd_usb_to_mac(struct zd_usb *usb) | |||
205 | return zd_chip_to_mac(zd_usb_to_chip(usb)); | 212 | return zd_chip_to_mac(zd_usb_to_chip(usb)); |
206 | } | 213 | } |
207 | 214 | ||
215 | static inline u8 *zd_mac_get_perm_addr(struct zd_mac *mac) | ||
216 | { | ||
217 | return mac->hw->wiphy->perm_addr; | ||
218 | } | ||
219 | |||
208 | #define zd_mac_dev(mac) (zd_chip_dev(&(mac)->chip)) | 220 | #define zd_mac_dev(mac) (zd_chip_dev(&(mac)->chip)) |
209 | 221 | ||
210 | int zd_mac_init(struct zd_mac *mac, | 222 | struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf); |
211 | struct net_device *netdev, | ||
212 | struct usb_interface *intf); | ||
213 | void zd_mac_clear(struct zd_mac *mac); | 223 | void zd_mac_clear(struct zd_mac *mac); |
214 | 224 | ||
215 | int zd_mac_preinit_hw(struct zd_mac *mac); | 225 | int zd_mac_preinit_hw(struct ieee80211_hw *hw); |
216 | int zd_mac_init_hw(struct zd_mac *mac); | 226 | int zd_mac_init_hw(struct ieee80211_hw *hw); |
217 | |||
218 | int zd_mac_open(struct net_device *netdev); | ||
219 | int zd_mac_stop(struct net_device *netdev); | ||
220 | int zd_mac_set_mac_address(struct net_device *dev, void *p); | ||
221 | void zd_mac_set_multicast_list(struct net_device *netdev); | ||
222 | |||
223 | int zd_mac_rx_irq(struct zd_mac *mac, const u8 *buffer, unsigned int length); | ||
224 | |||
225 | int zd_mac_set_regdomain(struct zd_mac *zd_mac, u8 regdomain); | ||
226 | u8 zd_mac_get_regdomain(struct zd_mac *zd_mac); | ||
227 | |||
228 | int zd_mac_request_channel(struct zd_mac *mac, u8 channel); | ||
229 | u8 zd_mac_get_channel(struct zd_mac *mac); | ||
230 | |||
231 | int zd_mac_set_mode(struct zd_mac *mac, u32 mode); | ||
232 | int zd_mac_get_mode(struct zd_mac *mac, u32 *mode); | ||
233 | |||
234 | int zd_mac_get_range(struct zd_mac *mac, struct iw_range *range); | ||
235 | 227 | ||
236 | struct iw_statistics *zd_mac_get_wireless_stats(struct net_device *ndev); | 228 | int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length); |
229 | void zd_mac_tx_failed(struct ieee80211_hw *hw); | ||
230 | void zd_mac_tx_to_dev(struct sk_buff *skb, int error); | ||
237 | 231 | ||
238 | #ifdef DEBUG | 232 | #ifdef DEBUG |
239 | void zd_dump_rx_status(const struct rx_status *status); | 233 | void zd_dump_rx_status(const struct rx_status *status); |
diff --git a/drivers/net/wireless/zd1211rw/zd_netdev.c b/drivers/net/wireless/zd1211rw/zd_netdev.c deleted file mode 100644 index 047cab3d87df..000000000000 --- a/drivers/net/wireless/zd1211rw/zd_netdev.c +++ /dev/null | |||
@@ -1,264 +0,0 @@ | |||
1 | /* zd_netdev.c | ||
2 | * | ||
3 | * This program is free software; you can redistribute it and/or modify | ||
4 | * it under the terms of the GNU General Public License as published by | ||
5 | * the Free Software Foundation; either version 2 of the License, or | ||
6 | * (at your option) any later version. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program; if not, write to the Free Software | ||
15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
16 | */ | ||
17 | |||
18 | #include <linux/netdevice.h> | ||
19 | #include <linux/etherdevice.h> | ||
20 | #include <linux/skbuff.h> | ||
21 | #include <net/ieee80211.h> | ||
22 | #include <net/ieee80211softmac.h> | ||
23 | #include <net/ieee80211softmac_wx.h> | ||
24 | #include <net/iw_handler.h> | ||
25 | |||
26 | #include "zd_def.h" | ||
27 | #include "zd_netdev.h" | ||
28 | #include "zd_mac.h" | ||
29 | #include "zd_ieee80211.h" | ||
30 | |||
31 | /* Region 0 means reset regdomain to default. */ | ||
32 | static int zd_set_regdomain(struct net_device *netdev, | ||
33 | struct iw_request_info *info, | ||
34 | union iwreq_data *req, char *extra) | ||
35 | { | ||
36 | const u8 *regdomain = (u8 *)req; | ||
37 | return zd_mac_set_regdomain(zd_netdev_mac(netdev), *regdomain); | ||
38 | } | ||
39 | |||
40 | static int zd_get_regdomain(struct net_device *netdev, | ||
41 | struct iw_request_info *info, | ||
42 | union iwreq_data *req, char *extra) | ||
43 | { | ||
44 | u8 *regdomain = (u8 *)req; | ||
45 | if (!regdomain) | ||
46 | return -EINVAL; | ||
47 | *regdomain = zd_mac_get_regdomain(zd_netdev_mac(netdev)); | ||
48 | return 0; | ||
49 | } | ||
50 | |||
51 | static const struct iw_priv_args zd_priv_args[] = { | ||
52 | { | ||
53 | .cmd = ZD_PRIV_SET_REGDOMAIN, | ||
54 | .set_args = IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, | ||
55 | .name = "set_regdomain", | ||
56 | }, | ||
57 | { | ||
58 | .cmd = ZD_PRIV_GET_REGDOMAIN, | ||
59 | .get_args = IW_PRIV_TYPE_BYTE | IW_PRIV_SIZE_FIXED | 1, | ||
60 | .name = "get_regdomain", | ||
61 | }, | ||
62 | }; | ||
63 | |||
64 | #define PRIV_OFFSET(x) [(x)-SIOCIWFIRSTPRIV] | ||
65 | |||
66 | static const iw_handler zd_priv_handler[] = { | ||
67 | PRIV_OFFSET(ZD_PRIV_SET_REGDOMAIN) = zd_set_regdomain, | ||
68 | PRIV_OFFSET(ZD_PRIV_GET_REGDOMAIN) = zd_get_regdomain, | ||
69 | }; | ||
70 | |||
71 | static int iw_get_name(struct net_device *netdev, | ||
72 | struct iw_request_info *info, | ||
73 | union iwreq_data *req, char *extra) | ||
74 | { | ||
75 | /* FIXME: check whether 802.11a will also supported */ | ||
76 | strlcpy(req->name, "IEEE 802.11b/g", IFNAMSIZ); | ||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | static int iw_get_nick(struct net_device *netdev, | ||
81 | struct iw_request_info *info, | ||
82 | union iwreq_data *req, char *extra) | ||
83 | { | ||
84 | strcpy(extra, "zd1211"); | ||
85 | req->data.length = strlen(extra); | ||
86 | req->data.flags = 1; | ||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | static int iw_set_freq(struct net_device *netdev, | ||
91 | struct iw_request_info *info, | ||
92 | union iwreq_data *req, char *extra) | ||
93 | { | ||
94 | int r; | ||
95 | struct zd_mac *mac = zd_netdev_mac(netdev); | ||
96 | struct iw_freq *freq = &req->freq; | ||
97 | u8 channel; | ||
98 | |||
99 | r = zd_find_channel(&channel, freq); | ||
100 | if (r < 0) | ||
101 | return r; | ||
102 | r = zd_mac_request_channel(mac, channel); | ||
103 | return r; | ||
104 | } | ||
105 | |||
106 | static int iw_get_freq(struct net_device *netdev, | ||
107 | struct iw_request_info *info, | ||
108 | union iwreq_data *req, char *extra) | ||
109 | { | ||
110 | struct zd_mac *mac = zd_netdev_mac(netdev); | ||
111 | struct iw_freq *freq = &req->freq; | ||
112 | |||
113 | return zd_channel_to_freq(freq, zd_mac_get_channel(mac)); | ||
114 | } | ||
115 | |||
116 | static int iw_set_mode(struct net_device *netdev, | ||
117 | struct iw_request_info *info, | ||
118 | union iwreq_data *req, char *extra) | ||
119 | { | ||
120 | return zd_mac_set_mode(zd_netdev_mac(netdev), req->mode); | ||
121 | } | ||
122 | |||
123 | static int iw_get_mode(struct net_device *netdev, | ||
124 | struct iw_request_info *info, | ||
125 | union iwreq_data *req, char *extra) | ||
126 | { | ||
127 | return zd_mac_get_mode(zd_netdev_mac(netdev), &req->mode); | ||
128 | } | ||
129 | |||
130 | static int iw_get_range(struct net_device *netdev, | ||
131 | struct iw_request_info *info, | ||
132 | union iwreq_data *req, char *extra) | ||
133 | { | ||
134 | struct iw_range *range = (struct iw_range *)extra; | ||
135 | |||
136 | dev_dbg_f(zd_mac_dev(zd_netdev_mac(netdev)), "\n"); | ||
137 | req->data.length = sizeof(*range); | ||
138 | return zd_mac_get_range(zd_netdev_mac(netdev), range); | ||
139 | } | ||
140 | |||
141 | static int iw_set_encode(struct net_device *netdev, | ||
142 | struct iw_request_info *info, | ||
143 | union iwreq_data *data, | ||
144 | char *extra) | ||
145 | { | ||
146 | return ieee80211_wx_set_encode(zd_netdev_ieee80211(netdev), info, | ||
147 | data, extra); | ||
148 | } | ||
149 | |||
150 | static int iw_get_encode(struct net_device *netdev, | ||
151 | struct iw_request_info *info, | ||
152 | union iwreq_data *data, | ||
153 | char *extra) | ||
154 | { | ||
155 | return ieee80211_wx_get_encode(zd_netdev_ieee80211(netdev), info, | ||
156 | data, extra); | ||
157 | } | ||
158 | |||
159 | static int iw_set_encodeext(struct net_device *netdev, | ||
160 | struct iw_request_info *info, | ||
161 | union iwreq_data *data, | ||
162 | char *extra) | ||
163 | { | ||
164 | return ieee80211_wx_set_encodeext(zd_netdev_ieee80211(netdev), info, | ||
165 | data, extra); | ||
166 | } | ||
167 | |||
168 | static int iw_get_encodeext(struct net_device *netdev, | ||
169 | struct iw_request_info *info, | ||
170 | union iwreq_data *data, | ||
171 | char *extra) | ||
172 | { | ||
173 | return ieee80211_wx_get_encodeext(zd_netdev_ieee80211(netdev), info, | ||
174 | data, extra); | ||
175 | } | ||
176 | |||
177 | #define WX(x) [(x)-SIOCIWFIRST] | ||
178 | |||
179 | static const iw_handler zd_standard_iw_handlers[] = { | ||
180 | WX(SIOCGIWNAME) = iw_get_name, | ||
181 | WX(SIOCGIWNICKN) = iw_get_nick, | ||
182 | WX(SIOCSIWFREQ) = iw_set_freq, | ||
183 | WX(SIOCGIWFREQ) = iw_get_freq, | ||
184 | WX(SIOCSIWMODE) = iw_set_mode, | ||
185 | WX(SIOCGIWMODE) = iw_get_mode, | ||
186 | WX(SIOCGIWRANGE) = iw_get_range, | ||
187 | WX(SIOCSIWENCODE) = iw_set_encode, | ||
188 | WX(SIOCGIWENCODE) = iw_get_encode, | ||
189 | WX(SIOCSIWENCODEEXT) = iw_set_encodeext, | ||
190 | WX(SIOCGIWENCODEEXT) = iw_get_encodeext, | ||
191 | WX(SIOCSIWAUTH) = ieee80211_wx_set_auth, | ||
192 | WX(SIOCGIWAUTH) = ieee80211_wx_get_auth, | ||
193 | WX(SIOCSIWSCAN) = ieee80211softmac_wx_trigger_scan, | ||
194 | WX(SIOCGIWSCAN) = ieee80211softmac_wx_get_scan_results, | ||
195 | WX(SIOCSIWESSID) = ieee80211softmac_wx_set_essid, | ||
196 | WX(SIOCGIWESSID) = ieee80211softmac_wx_get_essid, | ||
197 | WX(SIOCSIWAP) = ieee80211softmac_wx_set_wap, | ||
198 | WX(SIOCGIWAP) = ieee80211softmac_wx_get_wap, | ||
199 | WX(SIOCSIWRATE) = ieee80211softmac_wx_set_rate, | ||
200 | WX(SIOCGIWRATE) = ieee80211softmac_wx_get_rate, | ||
201 | WX(SIOCSIWGENIE) = ieee80211softmac_wx_set_genie, | ||
202 | WX(SIOCGIWGENIE) = ieee80211softmac_wx_get_genie, | ||
203 | WX(SIOCSIWMLME) = ieee80211softmac_wx_set_mlme, | ||
204 | }; | ||
205 | |||
206 | static const struct iw_handler_def iw_handler_def = { | ||
207 | .standard = zd_standard_iw_handlers, | ||
208 | .num_standard = ARRAY_SIZE(zd_standard_iw_handlers), | ||
209 | .private = zd_priv_handler, | ||
210 | .num_private = ARRAY_SIZE(zd_priv_handler), | ||
211 | .private_args = zd_priv_args, | ||
212 | .num_private_args = ARRAY_SIZE(zd_priv_args), | ||
213 | .get_wireless_stats = zd_mac_get_wireless_stats, | ||
214 | }; | ||
215 | |||
216 | struct net_device *zd_netdev_alloc(struct usb_interface *intf) | ||
217 | { | ||
218 | int r; | ||
219 | struct net_device *netdev; | ||
220 | struct zd_mac *mac; | ||
221 | |||
222 | netdev = alloc_ieee80211softmac(sizeof(struct zd_mac)); | ||
223 | if (!netdev) { | ||
224 | dev_dbg_f(&intf->dev, "out of memory\n"); | ||
225 | return NULL; | ||
226 | } | ||
227 | |||
228 | mac = zd_netdev_mac(netdev); | ||
229 | r = zd_mac_init(mac, netdev, intf); | ||
230 | if (r) { | ||
231 | usb_set_intfdata(intf, NULL); | ||
232 | free_ieee80211(netdev); | ||
233 | return NULL; | ||
234 | } | ||
235 | |||
236 | SET_NETDEV_DEV(netdev, &intf->dev); | ||
237 | |||
238 | dev_dbg_f(&intf->dev, "netdev->flags %#06hx\n", netdev->flags); | ||
239 | dev_dbg_f(&intf->dev, "netdev->features %#010lx\n", netdev->features); | ||
240 | |||
241 | netdev->open = zd_mac_open; | ||
242 | netdev->stop = zd_mac_stop; | ||
243 | /* netdev->get_stats = */ | ||
244 | netdev->set_multicast_list = zd_mac_set_multicast_list; | ||
245 | netdev->set_mac_address = zd_mac_set_mac_address; | ||
246 | netdev->wireless_handlers = &iw_handler_def; | ||
247 | /* netdev->ethtool_ops = */ | ||
248 | |||
249 | return netdev; | ||
250 | } | ||
251 | |||
252 | void zd_netdev_free(struct net_device *netdev) | ||
253 | { | ||
254 | if (!netdev) | ||
255 | return; | ||
256 | |||
257 | zd_mac_clear(zd_netdev_mac(netdev)); | ||
258 | free_ieee80211(netdev); | ||
259 | } | ||
260 | |||
261 | void zd_netdev_disconnect(struct net_device *netdev) | ||
262 | { | ||
263 | unregister_netdev(netdev); | ||
264 | } | ||
diff --git a/drivers/net/wireless/zd1211rw/zd_netdev.h b/drivers/net/wireless/zd1211rw/zd_netdev.h deleted file mode 100644 index 374a957073c1..000000000000 --- a/drivers/net/wireless/zd1211rw/zd_netdev.h +++ /dev/null | |||
@@ -1,45 +0,0 @@ | |||
1 | /* zd_netdev.h: Header for net device related functions. | ||
2 | * | ||
3 | * This program is free software; you can redistribute it and/or modify | ||
4 | * it under the terms of the GNU General Public License as published by | ||
5 | * the Free Software Foundation; either version 2 of the License, or | ||
6 | * (at your option) any later version. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program; if not, write to the Free Software | ||
15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
16 | */ | ||
17 | |||
18 | #ifndef _ZD_NETDEV_H | ||
19 | #define _ZD_NETDEV_H | ||
20 | |||
21 | #include <linux/usb.h> | ||
22 | #include <linux/netdevice.h> | ||
23 | #include <net/ieee80211.h> | ||
24 | |||
25 | #define ZD_PRIV_SET_REGDOMAIN (SIOCIWFIRSTPRIV) | ||
26 | #define ZD_PRIV_GET_REGDOMAIN (SIOCIWFIRSTPRIV+1) | ||
27 | |||
28 | static inline struct ieee80211_device *zd_netdev_ieee80211( | ||
29 | struct net_device *ndev) | ||
30 | { | ||
31 | return netdev_priv(ndev); | ||
32 | } | ||
33 | |||
34 | static inline struct net_device *zd_ieee80211_to_netdev( | ||
35 | struct ieee80211_device *ieee) | ||
36 | { | ||
37 | return ieee->dev; | ||
38 | } | ||
39 | |||
40 | struct net_device *zd_netdev_alloc(struct usb_interface *intf); | ||
41 | void zd_netdev_free(struct net_device *netdev); | ||
42 | |||
43 | void zd_netdev_disconnect(struct net_device *netdev); | ||
44 | |||
45 | #endif /* _ZD_NETDEV_H */ | ||
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index c755b6923812..3429576a95f7 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c | |||
@@ -17,18 +17,16 @@ | |||
17 | 17 | ||
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/module.h> | ||
21 | #include <linux/firmware.h> | 20 | #include <linux/firmware.h> |
22 | #include <linux/device.h> | 21 | #include <linux/device.h> |
23 | #include <linux/errno.h> | 22 | #include <linux/errno.h> |
24 | #include <linux/skbuff.h> | 23 | #include <linux/skbuff.h> |
25 | #include <linux/usb.h> | 24 | #include <linux/usb.h> |
26 | #include <linux/workqueue.h> | 25 | #include <linux/workqueue.h> |
27 | #include <net/ieee80211.h> | 26 | #include <net/mac80211.h> |
28 | #include <asm/unaligned.h> | 27 | #include <asm/unaligned.h> |
29 | 28 | ||
30 | #include "zd_def.h" | 29 | #include "zd_def.h" |
31 | #include "zd_netdev.h" | ||
32 | #include "zd_mac.h" | 30 | #include "zd_mac.h" |
33 | #include "zd_usb.h" | 31 | #include "zd_usb.h" |
34 | 32 | ||
@@ -353,18 +351,6 @@ out: | |||
353 | spin_unlock(&intr->lock); | 351 | spin_unlock(&intr->lock); |
354 | } | 352 | } |
355 | 353 | ||
356 | static inline void handle_retry_failed_int(struct urb *urb) | ||
357 | { | ||
358 | struct zd_usb *usb = urb->context; | ||
359 | struct zd_mac *mac = zd_usb_to_mac(usb); | ||
360 | struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); | ||
361 | |||
362 | ieee->stats.tx_errors++; | ||
363 | ieee->ieee_stats.tx_retry_limit_exceeded++; | ||
364 | dev_dbg_f(urb_dev(urb), "retry failed interrupt\n"); | ||
365 | } | ||
366 | |||
367 | |||
368 | static void int_urb_complete(struct urb *urb) | 354 | static void int_urb_complete(struct urb *urb) |
369 | { | 355 | { |
370 | int r; | 356 | int r; |
@@ -400,7 +386,7 @@ static void int_urb_complete(struct urb *urb) | |||
400 | handle_regs_int(urb); | 386 | handle_regs_int(urb); |
401 | break; | 387 | break; |
402 | case USB_INT_ID_RETRY_FAILED: | 388 | case USB_INT_ID_RETRY_FAILED: |
403 | handle_retry_failed_int(urb); | 389 | zd_mac_tx_failed(zd_usb_to_hw(urb->context)); |
404 | break; | 390 | break; |
405 | default: | 391 | default: |
406 | dev_dbg_f(urb_dev(urb), "error: urb %p unknown id %x\n", urb, | 392 | dev_dbg_f(urb_dev(urb), "error: urb %p unknown id %x\n", urb, |
@@ -530,14 +516,10 @@ static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer, | |||
530 | unsigned int length) | 516 | unsigned int length) |
531 | { | 517 | { |
532 | int i; | 518 | int i; |
533 | struct zd_mac *mac = zd_usb_to_mac(usb); | ||
534 | const struct rx_length_info *length_info; | 519 | const struct rx_length_info *length_info; |
535 | 520 | ||
536 | if (length < sizeof(struct rx_length_info)) { | 521 | if (length < sizeof(struct rx_length_info)) { |
537 | /* It's not a complete packet anyhow. */ | 522 | /* It's not a complete packet anyhow. */ |
538 | struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); | ||
539 | ieee->stats.rx_errors++; | ||
540 | ieee->stats.rx_length_errors++; | ||
541 | return; | 523 | return; |
542 | } | 524 | } |
543 | length_info = (struct rx_length_info *) | 525 | length_info = (struct rx_length_info *) |
@@ -561,13 +543,13 @@ static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer, | |||
561 | n = l+k; | 543 | n = l+k; |
562 | if (n > length) | 544 | if (n > length) |
563 | return; | 545 | return; |
564 | zd_mac_rx_irq(mac, buffer+l, k); | 546 | zd_mac_rx(zd_usb_to_hw(usb), buffer+l, k); |
565 | if (i >= 2) | 547 | if (i >= 2) |
566 | return; | 548 | return; |
567 | l = (n+3) & ~3; | 549 | l = (n+3) & ~3; |
568 | } | 550 | } |
569 | } else { | 551 | } else { |
570 | zd_mac_rx_irq(mac, buffer, length); | 552 | zd_mac_rx(zd_usb_to_hw(usb), buffer, length); |
571 | } | 553 | } |
572 | } | 554 | } |
573 | 555 | ||
@@ -629,7 +611,7 @@ resubmit: | |||
629 | usb_submit_urb(urb, GFP_ATOMIC); | 611 | usb_submit_urb(urb, GFP_ATOMIC); |
630 | } | 612 | } |
631 | 613 | ||
632 | static struct urb *alloc_urb(struct zd_usb *usb) | 614 | static struct urb *alloc_rx_urb(struct zd_usb *usb) |
633 | { | 615 | { |
634 | struct usb_device *udev = zd_usb_to_usbdev(usb); | 616 | struct usb_device *udev = zd_usb_to_usbdev(usb); |
635 | struct urb *urb; | 617 | struct urb *urb; |
@@ -653,7 +635,7 @@ static struct urb *alloc_urb(struct zd_usb *usb) | |||
653 | return urb; | 635 | return urb; |
654 | } | 636 | } |
655 | 637 | ||
656 | static void free_urb(struct urb *urb) | 638 | static void free_rx_urb(struct urb *urb) |
657 | { | 639 | { |
658 | if (!urb) | 640 | if (!urb) |
659 | return; | 641 | return; |
@@ -671,11 +653,11 @@ int zd_usb_enable_rx(struct zd_usb *usb) | |||
671 | dev_dbg_f(zd_usb_dev(usb), "\n"); | 653 | dev_dbg_f(zd_usb_dev(usb), "\n"); |
672 | 654 | ||
673 | r = -ENOMEM; | 655 | r = -ENOMEM; |
674 | urbs = kcalloc(URBS_COUNT, sizeof(struct urb *), GFP_KERNEL); | 656 | urbs = kcalloc(RX_URBS_COUNT, sizeof(struct urb *), GFP_KERNEL); |
675 | if (!urbs) | 657 | if (!urbs) |
676 | goto error; | 658 | goto error; |
677 | for (i = 0; i < URBS_COUNT; i++) { | 659 | for (i = 0; i < RX_URBS_COUNT; i++) { |
678 | urbs[i] = alloc_urb(usb); | 660 | urbs[i] = alloc_rx_urb(usb); |
679 | if (!urbs[i]) | 661 | if (!urbs[i]) |
680 | goto error; | 662 | goto error; |
681 | } | 663 | } |
@@ -688,10 +670,10 @@ int zd_usb_enable_rx(struct zd_usb *usb) | |||
688 | goto error; | 670 | goto error; |
689 | } | 671 | } |
690 | rx->urbs = urbs; | 672 | rx->urbs = urbs; |
691 | rx->urbs_count = URBS_COUNT; | 673 | rx->urbs_count = RX_URBS_COUNT; |
692 | spin_unlock_irq(&rx->lock); | 674 | spin_unlock_irq(&rx->lock); |
693 | 675 | ||
694 | for (i = 0; i < URBS_COUNT; i++) { | 676 | for (i = 0; i < RX_URBS_COUNT; i++) { |
695 | r = usb_submit_urb(urbs[i], GFP_KERNEL); | 677 | r = usb_submit_urb(urbs[i], GFP_KERNEL); |
696 | if (r) | 678 | if (r) |
697 | goto error_submit; | 679 | goto error_submit; |
@@ -699,7 +681,7 @@ int zd_usb_enable_rx(struct zd_usb *usb) | |||
699 | 681 | ||
700 | return 0; | 682 | return 0; |
701 | error_submit: | 683 | error_submit: |
702 | for (i = 0; i < URBS_COUNT; i++) { | 684 | for (i = 0; i < RX_URBS_COUNT; i++) { |
703 | usb_kill_urb(urbs[i]); | 685 | usb_kill_urb(urbs[i]); |
704 | } | 686 | } |
705 | spin_lock_irq(&rx->lock); | 687 | spin_lock_irq(&rx->lock); |
@@ -708,8 +690,8 @@ error_submit: | |||
708 | spin_unlock_irq(&rx->lock); | 690 | spin_unlock_irq(&rx->lock); |
709 | error: | 691 | error: |
710 | if (urbs) { | 692 | if (urbs) { |
711 | for (i = 0; i < URBS_COUNT; i++) | 693 | for (i = 0; i < RX_URBS_COUNT; i++) |
712 | free_urb(urbs[i]); | 694 | free_rx_urb(urbs[i]); |
713 | } | 695 | } |
714 | return r; | 696 | return r; |
715 | } | 697 | } |
@@ -731,7 +713,7 @@ void zd_usb_disable_rx(struct zd_usb *usb) | |||
731 | 713 | ||
732 | for (i = 0; i < count; i++) { | 714 | for (i = 0; i < count; i++) { |
733 | usb_kill_urb(urbs[i]); | 715 | usb_kill_urb(urbs[i]); |
734 | free_urb(urbs[i]); | 716 | free_rx_urb(urbs[i]); |
735 | } | 717 | } |
736 | kfree(urbs); | 718 | kfree(urbs); |
737 | 719 | ||
@@ -741,9 +723,142 @@ void zd_usb_disable_rx(struct zd_usb *usb) | |||
741 | spin_unlock_irqrestore(&rx->lock, flags); | 723 | spin_unlock_irqrestore(&rx->lock, flags); |
742 | } | 724 | } |
743 | 725 | ||
726 | /** | ||
727 | * zd_usb_disable_tx - disable transmission | ||
728 | * @usb: the zd1211rw-private USB structure | ||
729 | * | ||
730 | * Frees all URBs in the free list and marks the transmission as disabled. | ||
731 | */ | ||
732 | void zd_usb_disable_tx(struct zd_usb *usb) | ||
733 | { | ||
734 | struct zd_usb_tx *tx = &usb->tx; | ||
735 | unsigned long flags; | ||
736 | struct list_head *pos, *n; | ||
737 | |||
738 | spin_lock_irqsave(&tx->lock, flags); | ||
739 | list_for_each_safe(pos, n, &tx->free_urb_list) { | ||
740 | list_del(pos); | ||
741 | usb_free_urb(list_entry(pos, struct urb, urb_list)); | ||
742 | } | ||
743 | tx->enabled = 0; | ||
744 | tx->submitted_urbs = 0; | ||
745 | /* The stopped state is ignored, relying on ieee80211_wake_queues() | ||
746 | * in a potentionally following zd_usb_enable_tx(). | ||
747 | */ | ||
748 | spin_unlock_irqrestore(&tx->lock, flags); | ||
749 | } | ||
750 | |||
751 | /** | ||
752 | * zd_usb_enable_tx - enables transmission | ||
753 | * @usb: a &struct zd_usb pointer | ||
754 | * | ||
755 | * This function enables transmission and prepares the &zd_usb_tx data | ||
756 | * structure. | ||
757 | */ | ||
758 | void zd_usb_enable_tx(struct zd_usb *usb) | ||
759 | { | ||
760 | unsigned long flags; | ||
761 | struct zd_usb_tx *tx = &usb->tx; | ||
762 | |||
763 | spin_lock_irqsave(&tx->lock, flags); | ||
764 | tx->enabled = 1; | ||
765 | tx->submitted_urbs = 0; | ||
766 | ieee80211_wake_queues(zd_usb_to_hw(usb)); | ||
767 | tx->stopped = 0; | ||
768 | spin_unlock_irqrestore(&tx->lock, flags); | ||
769 | } | ||
770 | |||
771 | /** | ||
772 | * alloc_tx_urb - provides an tx URB | ||
773 | * @usb: a &struct zd_usb pointer | ||
774 | * | ||
775 | * Allocates a new URB. If possible takes the urb from the free list in | ||
776 | * usb->tx. | ||
777 | */ | ||
778 | static struct urb *alloc_tx_urb(struct zd_usb *usb) | ||
779 | { | ||
780 | struct zd_usb_tx *tx = &usb->tx; | ||
781 | unsigned long flags; | ||
782 | struct list_head *entry; | ||
783 | struct urb *urb; | ||
784 | |||
785 | spin_lock_irqsave(&tx->lock, flags); | ||
786 | if (list_empty(&tx->free_urb_list)) { | ||
787 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
788 | goto out; | ||
789 | } | ||
790 | entry = tx->free_urb_list.next; | ||
791 | list_del(entry); | ||
792 | urb = list_entry(entry, struct urb, urb_list); | ||
793 | out: | ||
794 | spin_unlock_irqrestore(&tx->lock, flags); | ||
795 | return urb; | ||
796 | } | ||
797 | |||
798 | /** | ||
799 | * free_tx_urb - frees a used tx URB | ||
800 | * @usb: a &struct zd_usb pointer | ||
801 | * @urb: URB to be freed | ||
802 | * | ||
803 | * Frees the the transmission URB, which means to put it on the free URB | ||
804 | * list. | ||
805 | */ | ||
806 | static void free_tx_urb(struct zd_usb *usb, struct urb *urb) | ||
807 | { | ||
808 | struct zd_usb_tx *tx = &usb->tx; | ||
809 | unsigned long flags; | ||
810 | |||
811 | spin_lock_irqsave(&tx->lock, flags); | ||
812 | if (!tx->enabled) { | ||
813 | usb_free_urb(urb); | ||
814 | goto out; | ||
815 | } | ||
816 | list_add(&urb->urb_list, &tx->free_urb_list); | ||
817 | out: | ||
818 | spin_unlock_irqrestore(&tx->lock, flags); | ||
819 | } | ||
820 | |||
821 | static void tx_dec_submitted_urbs(struct zd_usb *usb) | ||
822 | { | ||
823 | struct zd_usb_tx *tx = &usb->tx; | ||
824 | unsigned long flags; | ||
825 | |||
826 | spin_lock_irqsave(&tx->lock, flags); | ||
827 | --tx->submitted_urbs; | ||
828 | if (tx->stopped && tx->submitted_urbs <= ZD_USB_TX_LOW) { | ||
829 | ieee80211_wake_queues(zd_usb_to_hw(usb)); | ||
830 | tx->stopped = 0; | ||
831 | } | ||
832 | spin_unlock_irqrestore(&tx->lock, flags); | ||
833 | } | ||
834 | |||
835 | static void tx_inc_submitted_urbs(struct zd_usb *usb) | ||
836 | { | ||
837 | struct zd_usb_tx *tx = &usb->tx; | ||
838 | unsigned long flags; | ||
839 | |||
840 | spin_lock_irqsave(&tx->lock, flags); | ||
841 | ++tx->submitted_urbs; | ||
842 | if (!tx->stopped && tx->submitted_urbs > ZD_USB_TX_HIGH) { | ||
843 | ieee80211_stop_queues(zd_usb_to_hw(usb)); | ||
844 | tx->stopped = 1; | ||
845 | } | ||
846 | spin_unlock_irqrestore(&tx->lock, flags); | ||
847 | } | ||
848 | |||
849 | /** | ||
850 | * tx_urb_complete - completes the execution of an URB | ||
851 | * @urb: a URB | ||
852 | * | ||
853 | * This function is called if the URB has been transferred to a device or an | ||
854 | * error has happened. | ||
855 | */ | ||
744 | static void tx_urb_complete(struct urb *urb) | 856 | static void tx_urb_complete(struct urb *urb) |
745 | { | 857 | { |
746 | int r; | 858 | int r; |
859 | struct sk_buff *skb; | ||
860 | struct zd_tx_skb_control_block *cb; | ||
861 | struct zd_usb *usb; | ||
747 | 862 | ||
748 | switch (urb->status) { | 863 | switch (urb->status) { |
749 | case 0: | 864 | case 0: |
@@ -761,9 +876,12 @@ static void tx_urb_complete(struct urb *urb) | |||
761 | goto resubmit; | 876 | goto resubmit; |
762 | } | 877 | } |
763 | free_urb: | 878 | free_urb: |
764 | usb_buffer_free(urb->dev, urb->transfer_buffer_length, | 879 | skb = (struct sk_buff *)urb->context; |
765 | urb->transfer_buffer, urb->transfer_dma); | 880 | zd_mac_tx_to_dev(skb, urb->status); |
766 | usb_free_urb(urb); | 881 | cb = (struct zd_tx_skb_control_block *)skb->cb; |
882 | usb = &zd_hw_mac(cb->hw)->chip.usb; | ||
883 | free_tx_urb(usb, urb); | ||
884 | tx_dec_submitted_urbs(usb); | ||
767 | return; | 885 | return; |
768 | resubmit: | 886 | resubmit: |
769 | r = usb_submit_urb(urb, GFP_ATOMIC); | 887 | r = usb_submit_urb(urb, GFP_ATOMIC); |
@@ -773,43 +891,40 @@ resubmit: | |||
773 | } | 891 | } |
774 | } | 892 | } |
775 | 893 | ||
776 | /* Puts the frame on the USB endpoint. It doesn't wait for | 894 | /** |
777 | * completion. The frame must contain the control set. | 895 | * zd_usb_tx: initiates transfer of a frame of the device |
896 | * | ||
897 | * @usb: the zd1211rw-private USB structure | ||
898 | * @skb: a &struct sk_buff pointer | ||
899 | * | ||
900 | * This function tranmits a frame to the device. It doesn't wait for | ||
901 | * completion. The frame must contain the control set and have all the | ||
902 | * control set information available. | ||
903 | * | ||
904 | * The function returns 0 if the transfer has been successfully initiated. | ||
778 | */ | 905 | */ |
779 | int zd_usb_tx(struct zd_usb *usb, const u8 *frame, unsigned int length) | 906 | int zd_usb_tx(struct zd_usb *usb, struct sk_buff *skb) |
780 | { | 907 | { |
781 | int r; | 908 | int r; |
782 | struct usb_device *udev = zd_usb_to_usbdev(usb); | 909 | struct usb_device *udev = zd_usb_to_usbdev(usb); |
783 | struct urb *urb; | 910 | struct urb *urb; |
784 | void *buffer; | ||
785 | 911 | ||
786 | urb = usb_alloc_urb(0, GFP_ATOMIC); | 912 | urb = alloc_tx_urb(usb); |
787 | if (!urb) { | 913 | if (!urb) { |
788 | r = -ENOMEM; | 914 | r = -ENOMEM; |
789 | goto out; | 915 | goto out; |
790 | } | 916 | } |
791 | 917 | ||
792 | buffer = usb_buffer_alloc(zd_usb_to_usbdev(usb), length, GFP_ATOMIC, | ||
793 | &urb->transfer_dma); | ||
794 | if (!buffer) { | ||
795 | r = -ENOMEM; | ||
796 | goto error_free_urb; | ||
797 | } | ||
798 | memcpy(buffer, frame, length); | ||
799 | |||
800 | usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_DATA_OUT), | 918 | usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_DATA_OUT), |
801 | buffer, length, tx_urb_complete, NULL); | 919 | skb->data, skb->len, tx_urb_complete, skb); |
802 | urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
803 | 920 | ||
804 | r = usb_submit_urb(urb, GFP_ATOMIC); | 921 | r = usb_submit_urb(urb, GFP_ATOMIC); |
805 | if (r) | 922 | if (r) |
806 | goto error; | 923 | goto error; |
924 | tx_inc_submitted_urbs(usb); | ||
807 | return 0; | 925 | return 0; |
808 | error: | 926 | error: |
809 | usb_buffer_free(zd_usb_to_usbdev(usb), length, buffer, | 927 | free_tx_urb(usb, urb); |
810 | urb->transfer_dma); | ||
811 | error_free_urb: | ||
812 | usb_free_urb(urb); | ||
813 | out: | 928 | out: |
814 | return r; | 929 | return r; |
815 | } | 930 | } |
@@ -838,16 +953,20 @@ static inline void init_usb_rx(struct zd_usb *usb) | |||
838 | 953 | ||
839 | static inline void init_usb_tx(struct zd_usb *usb) | 954 | static inline void init_usb_tx(struct zd_usb *usb) |
840 | { | 955 | { |
841 | /* FIXME: at this point we will allocate a fixed number of urb's for | 956 | struct zd_usb_tx *tx = &usb->tx; |
842 | * use in a cyclic scheme */ | 957 | spin_lock_init(&tx->lock); |
958 | tx->enabled = 0; | ||
959 | tx->stopped = 0; | ||
960 | INIT_LIST_HEAD(&tx->free_urb_list); | ||
961 | tx->submitted_urbs = 0; | ||
843 | } | 962 | } |
844 | 963 | ||
845 | void zd_usb_init(struct zd_usb *usb, struct net_device *netdev, | 964 | void zd_usb_init(struct zd_usb *usb, struct ieee80211_hw *hw, |
846 | struct usb_interface *intf) | 965 | struct usb_interface *intf) |
847 | { | 966 | { |
848 | memset(usb, 0, sizeof(*usb)); | 967 | memset(usb, 0, sizeof(*usb)); |
849 | usb->intf = usb_get_intf(intf); | 968 | usb->intf = usb_get_intf(intf); |
850 | usb_set_intfdata(usb->intf, netdev); | 969 | usb_set_intfdata(usb->intf, hw); |
851 | init_usb_interrupt(usb); | 970 | init_usb_interrupt(usb); |
852 | init_usb_tx(usb); | 971 | init_usb_tx(usb); |
853 | init_usb_rx(usb); | 972 | init_usb_rx(usb); |
@@ -973,7 +1092,7 @@ int zd_usb_init_hw(struct zd_usb *usb) | |||
973 | return r; | 1092 | return r; |
974 | } | 1093 | } |
975 | 1094 | ||
976 | r = zd_mac_init_hw(mac); | 1095 | r = zd_mac_init_hw(mac->hw); |
977 | if (r) { | 1096 | if (r) { |
978 | dev_dbg_f(zd_usb_dev(usb), | 1097 | dev_dbg_f(zd_usb_dev(usb), |
979 | "couldn't initialize mac. Error number %d\n", r); | 1098 | "couldn't initialize mac. Error number %d\n", r); |
@@ -987,9 +1106,9 @@ int zd_usb_init_hw(struct zd_usb *usb) | |||
987 | static int probe(struct usb_interface *intf, const struct usb_device_id *id) | 1106 | static int probe(struct usb_interface *intf, const struct usb_device_id *id) |
988 | { | 1107 | { |
989 | int r; | 1108 | int r; |
990 | struct zd_usb *usb; | ||
991 | struct usb_device *udev = interface_to_usbdev(intf); | 1109 | struct usb_device *udev = interface_to_usbdev(intf); |
992 | struct net_device *netdev = NULL; | 1110 | struct zd_usb *usb; |
1111 | struct ieee80211_hw *hw = NULL; | ||
993 | 1112 | ||
994 | print_id(udev); | 1113 | print_id(udev); |
995 | 1114 | ||
@@ -1007,57 +1126,65 @@ static int probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1007 | goto error; | 1126 | goto error; |
1008 | } | 1127 | } |
1009 | 1128 | ||
1010 | usb_reset_device(interface_to_usbdev(intf)); | 1129 | r = usb_reset_device(udev); |
1130 | if (r) { | ||
1131 | dev_err(&intf->dev, | ||
1132 | "couldn't reset usb device. Error number %d\n", r); | ||
1133 | goto error; | ||
1134 | } | ||
1011 | 1135 | ||
1012 | netdev = zd_netdev_alloc(intf); | 1136 | hw = zd_mac_alloc_hw(intf); |
1013 | if (netdev == NULL) { | 1137 | if (hw == NULL) { |
1014 | r = -ENOMEM; | 1138 | r = -ENOMEM; |
1015 | goto error; | 1139 | goto error; |
1016 | } | 1140 | } |
1017 | 1141 | ||
1018 | usb = &zd_netdev_mac(netdev)->chip.usb; | 1142 | usb = &zd_hw_mac(hw)->chip.usb; |
1019 | usb->is_zd1211b = (id->driver_info == DEVICE_ZD1211B) != 0; | 1143 | usb->is_zd1211b = (id->driver_info == DEVICE_ZD1211B) != 0; |
1020 | 1144 | ||
1021 | r = zd_mac_preinit_hw(zd_netdev_mac(netdev)); | 1145 | r = zd_mac_preinit_hw(hw); |
1022 | if (r) { | 1146 | if (r) { |
1023 | dev_dbg_f(&intf->dev, | 1147 | dev_dbg_f(&intf->dev, |
1024 | "couldn't initialize mac. Error number %d\n", r); | 1148 | "couldn't initialize mac. Error number %d\n", r); |
1025 | goto error; | 1149 | goto error; |
1026 | } | 1150 | } |
1027 | 1151 | ||
1028 | r = register_netdev(netdev); | 1152 | r = ieee80211_register_hw(hw); |
1029 | if (r) { | 1153 | if (r) { |
1030 | dev_dbg_f(&intf->dev, | 1154 | dev_dbg_f(&intf->dev, |
1031 | "couldn't register netdev. Error number %d\n", r); | 1155 | "couldn't register device. Error number %d\n", r); |
1032 | goto error; | 1156 | goto error; |
1033 | } | 1157 | } |
1034 | 1158 | ||
1035 | dev_dbg_f(&intf->dev, "successful\n"); | 1159 | dev_dbg_f(&intf->dev, "successful\n"); |
1036 | dev_info(&intf->dev,"%s\n", netdev->name); | 1160 | dev_info(&intf->dev, "%s\n", wiphy_name(hw->wiphy)); |
1037 | return 0; | 1161 | return 0; |
1038 | error: | 1162 | error: |
1039 | usb_reset_device(interface_to_usbdev(intf)); | 1163 | usb_reset_device(interface_to_usbdev(intf)); |
1040 | zd_netdev_free(netdev); | 1164 | if (hw) { |
1165 | zd_mac_clear(zd_hw_mac(hw)); | ||
1166 | ieee80211_free_hw(hw); | ||
1167 | } | ||
1041 | return r; | 1168 | return r; |
1042 | } | 1169 | } |
1043 | 1170 | ||
1044 | static void disconnect(struct usb_interface *intf) | 1171 | static void disconnect(struct usb_interface *intf) |
1045 | { | 1172 | { |
1046 | struct net_device *netdev = zd_intf_to_netdev(intf); | 1173 | struct ieee80211_hw *hw = zd_intf_to_hw(intf); |
1047 | struct zd_mac *mac; | 1174 | struct zd_mac *mac; |
1048 | struct zd_usb *usb; | 1175 | struct zd_usb *usb; |
1049 | 1176 | ||
1050 | /* Either something really bad happened, or we're just dealing with | 1177 | /* Either something really bad happened, or we're just dealing with |
1051 | * a DEVICE_INSTALLER. */ | 1178 | * a DEVICE_INSTALLER. */ |
1052 | if (netdev == NULL) | 1179 | if (hw == NULL) |
1053 | return; | 1180 | return; |
1054 | 1181 | ||
1055 | mac = zd_netdev_mac(netdev); | 1182 | mac = zd_hw_mac(hw); |
1056 | usb = &mac->chip.usb; | 1183 | usb = &mac->chip.usb; |
1057 | 1184 | ||
1058 | dev_dbg_f(zd_usb_dev(usb), "\n"); | 1185 | dev_dbg_f(zd_usb_dev(usb), "\n"); |
1059 | 1186 | ||
1060 | zd_netdev_disconnect(netdev); | 1187 | ieee80211_unregister_hw(hw); |
1061 | 1188 | ||
1062 | /* Just in case something has gone wrong! */ | 1189 | /* Just in case something has gone wrong! */ |
1063 | zd_usb_disable_rx(usb); | 1190 | zd_usb_disable_rx(usb); |
@@ -1070,12 +1197,13 @@ static void disconnect(struct usb_interface *intf) | |||
1070 | */ | 1197 | */ |
1071 | usb_reset_device(interface_to_usbdev(intf)); | 1198 | usb_reset_device(interface_to_usbdev(intf)); |
1072 | 1199 | ||
1073 | zd_netdev_free(netdev); | 1200 | zd_mac_clear(mac); |
1201 | ieee80211_free_hw(hw); | ||
1074 | dev_dbg(&intf->dev, "disconnected\n"); | 1202 | dev_dbg(&intf->dev, "disconnected\n"); |
1075 | } | 1203 | } |
1076 | 1204 | ||
1077 | static struct usb_driver driver = { | 1205 | static struct usb_driver driver = { |
1078 | .name = "zd1211rw", | 1206 | .name = KBUILD_MODNAME, |
1079 | .id_table = usb_ids, | 1207 | .id_table = usb_ids, |
1080 | .probe = probe, | 1208 | .probe = probe, |
1081 | .disconnect = disconnect, | 1209 | .disconnect = disconnect, |
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h index 961a7a12ad68..42159fc49cf8 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.h +++ b/drivers/net/wireless/zd1211rw/zd_usb.h | |||
@@ -26,6 +26,9 @@ | |||
26 | 26 | ||
27 | #include "zd_def.h" | 27 | #include "zd_def.h" |
28 | 28 | ||
29 | #define ZD_USB_TX_HIGH 5 | ||
30 | #define ZD_USB_TX_LOW 2 | ||
31 | |||
29 | enum devicetype { | 32 | enum devicetype { |
30 | DEVICE_ZD1211 = 0, | 33 | DEVICE_ZD1211 = 0, |
31 | DEVICE_ZD1211B = 1, | 34 | DEVICE_ZD1211B = 1, |
@@ -165,7 +168,7 @@ static inline struct usb_int_regs *get_read_regs(struct zd_usb_interrupt *intr) | |||
165 | return (struct usb_int_regs *)intr->read_regs.buffer; | 168 | return (struct usb_int_regs *)intr->read_regs.buffer; |
166 | } | 169 | } |
167 | 170 | ||
168 | #define URBS_COUNT 5 | 171 | #define RX_URBS_COUNT 5 |
169 | 172 | ||
170 | struct zd_usb_rx { | 173 | struct zd_usb_rx { |
171 | spinlock_t lock; | 174 | spinlock_t lock; |
@@ -176,8 +179,21 @@ struct zd_usb_rx { | |||
176 | int urbs_count; | 179 | int urbs_count; |
177 | }; | 180 | }; |
178 | 181 | ||
182 | /** | ||
183 | * struct zd_usb_tx - structure used for transmitting frames | ||
184 | * @lock: lock for transmission | ||
185 | * @free_urb_list: list of free URBs, contains all the URBs, which can be used | ||
186 | * @submitted_urbs: atomic integer that counts the URBs having sent to the | ||
187 | * device, which haven't been completed | ||
188 | * @enabled: enabled flag, indicates whether tx is enabled | ||
189 | * @stopped: indicates whether higher level tx queues are stopped | ||
190 | */ | ||
179 | struct zd_usb_tx { | 191 | struct zd_usb_tx { |
180 | spinlock_t lock; | 192 | spinlock_t lock; |
193 | struct list_head free_urb_list; | ||
194 | int submitted_urbs; | ||
195 | int enabled; | ||
196 | int stopped; | ||
181 | }; | 197 | }; |
182 | 198 | ||
183 | /* Contains the usb parts. The structure doesn't require a lock because intf | 199 | /* Contains the usb parts. The structure doesn't require a lock because intf |
@@ -198,17 +214,17 @@ static inline struct usb_device *zd_usb_to_usbdev(struct zd_usb *usb) | |||
198 | return interface_to_usbdev(usb->intf); | 214 | return interface_to_usbdev(usb->intf); |
199 | } | 215 | } |
200 | 216 | ||
201 | static inline struct net_device *zd_intf_to_netdev(struct usb_interface *intf) | 217 | static inline struct ieee80211_hw *zd_intf_to_hw(struct usb_interface *intf) |
202 | { | 218 | { |
203 | return usb_get_intfdata(intf); | 219 | return usb_get_intfdata(intf); |
204 | } | 220 | } |
205 | 221 | ||
206 | static inline struct net_device *zd_usb_to_netdev(struct zd_usb *usb) | 222 | static inline struct ieee80211_hw *zd_usb_to_hw(struct zd_usb *usb) |
207 | { | 223 | { |
208 | return zd_intf_to_netdev(usb->intf); | 224 | return zd_intf_to_hw(usb->intf); |
209 | } | 225 | } |
210 | 226 | ||
211 | void zd_usb_init(struct zd_usb *usb, struct net_device *netdev, | 227 | void zd_usb_init(struct zd_usb *usb, struct ieee80211_hw *hw, |
212 | struct usb_interface *intf); | 228 | struct usb_interface *intf); |
213 | int zd_usb_init_hw(struct zd_usb *usb); | 229 | int zd_usb_init_hw(struct zd_usb *usb); |
214 | void zd_usb_clear(struct zd_usb *usb); | 230 | void zd_usb_clear(struct zd_usb *usb); |
@@ -221,7 +237,10 @@ void zd_usb_disable_int(struct zd_usb *usb); | |||
221 | int zd_usb_enable_rx(struct zd_usb *usb); | 237 | int zd_usb_enable_rx(struct zd_usb *usb); |
222 | void zd_usb_disable_rx(struct zd_usb *usb); | 238 | void zd_usb_disable_rx(struct zd_usb *usb); |
223 | 239 | ||
224 | int zd_usb_tx(struct zd_usb *usb, const u8 *frame, unsigned int length); | 240 | void zd_usb_enable_tx(struct zd_usb *usb); |
241 | void zd_usb_disable_tx(struct zd_usb *usb); | ||
242 | |||
243 | int zd_usb_tx(struct zd_usb *usb, struct sk_buff *skb); | ||
225 | 244 | ||
226 | int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, | 245 | int zd_usb_ioread16v(struct zd_usb *usb, u16 *values, |
227 | const zd_addr_t *addresses, unsigned int count); | 246 | const zd_addr_t *addresses, unsigned int count); |