1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051
|
/***********************************************************************
** Copyright (C) 2003 ACX100 Open Source Project
**
** The contents of this file are subject to the Mozilla Public
** License Version 1.1 (the "License"); you may not use this file
** except in compliance with the License. You may obtain a copy of
** the License at http://www.mozilla.org/MPL/
**
** Software distributed under the License is distributed on an "AS
** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
** implied. See the License for the specific language governing
** rights and limitations under the License.
**
** Alternatively, the contents of this file may be used under the
** terms of the GNU Public License version 2 (the "GPL"), in which
** case the provisions of the GPL are applicable instead of the
** above. If you wish to allow the use of your version of this file
** only under the terms of the GPL and not to allow others to use
** your version of this file under the MPL, indicate your decision
** by deleting the provisions above and replace them with the notice
** and other provisions required by the GPL. If you do not delete
** the provisions above, a recipient may use your version of this
** file under either the MPL or the GPL.
** ---------------------------------------------------------------------
** Inquiries regarding the ACX100 Open Source Project can be
** made directly to:
**
** acx100-users@lists.sf.net
** http://acx100.sf.net
** ---------------------------------------------------------------------
*/
/***********************************************************************
** Forward declarations of types
*/
typedef struct tx tx_t;
typedef struct acx_device acx_device_t;
typedef struct client client_t;
typedef struct rxdesc rxdesc_t;
typedef struct txdesc txdesc_t;
typedef struct rxhostdesc rxhostdesc_t;
typedef struct txhostdesc txhostdesc_t;
/***********************************************************************
** Debug / log functionality
*/
enum {
L_LOCK = (ACX_DEBUG>1)*0x0001, /* locking debug log */
L_INIT = (ACX_DEBUG>0)*0x0002, /* special card initialization logging */
L_IRQ = (ACX_DEBUG>0)*0x0004, /* interrupt stuff */
L_ASSOC = (ACX_DEBUG>0)*0x0008, /* assocation (network join) and station log */
L_FUNC = (ACX_DEBUG>1)*0x0020, /* logging of function enter / leave */
L_XFER = (ACX_DEBUG>1)*0x0080, /* logging of transfers and mgmt */
L_DATA = (ACX_DEBUG>1)*0x0100, /* logging of transfer data */
L_DEBUG = (ACX_DEBUG>1)*0x0200, /* log of debug info */
L_IOCTL = (ACX_DEBUG>0)*0x0400, /* log ioctl calls */
L_CTL = (ACX_DEBUG>1)*0x0800, /* log of low-level ctl commands */
L_BUFR = (ACX_DEBUG>1)*0x1000, /* debug rx buffer mgmt (ring buffer etc.) */
L_XFER_BEACON = (ACX_DEBUG>1)*0x2000, /* also log beacon packets */
L_BUFT = (ACX_DEBUG>1)*0x4000, /* debug tx buffer mgmt (ring buffer etc.) */
L_USBRXTX = (ACX_DEBUG>0)*0x8000, /* debug USB rx/tx operations */
L_BUF = L_BUFR + L_BUFT,
L_ANY = 0xffff
};
#if ACX_DEBUG
extern unsigned int acx_debug;
#else
enum { acx_debug = 0 };
#endif
/***********************************************************************
** Random helpers
*/
#define ACX_PACKED __attribute__ ((packed))
#define VEC_SIZE(a) (sizeof(a)/sizeof(a[0]))
/* Use worker_queues for 2.5/2.6 kernels and queue tasks for 2.4 kernels
(used for the 'bottom half' of the interrupt routine) */
#include <linux/workqueue.h>
#define USE_WORKER_TASKS
#define WORK_STRUCT struct work_struct
#define SCHEDULE_WORK schedule_work
#define FLUSH_SCHEDULED_WORK flush_scheduled_work
/***********************************************************************
** Constants
*/
#define OK 0
#define NOT_OK 1
/* The supported chip models */
#define CHIPTYPE_ACX100 1
#define CHIPTYPE_ACX111 2
#define IS_ACX100(adev) ((adev)->chip_type == CHIPTYPE_ACX100)
#define IS_ACX111(adev) ((adev)->chip_type == CHIPTYPE_ACX111)
/* Supported interfaces */
#define DEVTYPE_PCI 0
#define DEVTYPE_USB 1
#if !defined(CONFIG_ACX_PCI) && !defined(CONFIG_ACX_USB)
#error Driver must include PCI and/or USB support. You selected neither.
#endif
#if defined(CONFIG_ACX_PCI)
#if !defined(CONFIG_ACX_USB)
#define IS_PCI(adev) 1
#else
#define IS_PCI(adev) ((adev)->dev_type == DEVTYPE_PCI)
#endif
#else
#define IS_PCI(adev) 0
#endif
#if defined(CONFIG_ACX_USB)
#if !defined(CONFIG_ACX_PCI)
#define IS_USB(adev) 1
#else
#define IS_USB(adev) ((adev)->dev_type == DEVTYPE_USB)
#endif
#else
#define IS_USB(adev) 0
#endif
/* Driver defaults */
#define DEFAULT_DTIM_INTERVAL 10
/* used to be 2048, but FreeBSD driver changed it to 4096 to work properly
** in noisy wlans */
#define DEFAULT_MSDU_LIFETIME 4096
#define DEFAULT_RTS_THRESHOLD 2312 /* max. size: disable RTS mechanism */
#define DEFAULT_BEACON_INTERVAL 100
#define ACX100_BAP_DATALEN_MAX 4096
#define ACX100_RID_GUESSING_MAXLEN 2048 /* I'm not really sure */
#define ACX100_RIDDATA_MAXLEN ACX100_RID_GUESSING_MAXLEN
/* Support Constants */
/* Radio type names, found in Win98 driver's TIACXLN.INF */
#define RADIO_MAXIM_0D 0x0d
#define RADIO_RFMD_11 0x11
#define RADIO_RALINK_15 0x15
/* used in ACX111 cards (WG311v2, WL-121, ...): */
#define RADIO_RADIA_16 0x16
/* most likely *sometimes* used in ACX111 cards: */
#define RADIO_UNKNOWN_17 0x17
/* FwRad19.bin was found in a Safecom driver; must be an ACX111 radio: */
#define RADIO_UNKNOWN_19 0x19
#define RADIO_UNKNOWN_1B 0x1b /* radio in SafeCom SWLUT-54125 USB adapter; entirely unknown!! */
/* Controller Commands */
/* can be found in table cmdTable in firmware "Rev. 1.5.0" (FW150) */
#define ACX1xx_CMD_RESET 0x00
#define ACX1xx_CMD_INTERROGATE 0x01
#define ACX1xx_CMD_CONFIGURE 0x02
#define ACX1xx_CMD_ENABLE_RX 0x03
#define ACX1xx_CMD_ENABLE_TX 0x04
#define ACX1xx_CMD_DISABLE_RX 0x05
#define ACX1xx_CMD_DISABLE_TX 0x06
#define ACX1xx_CMD_FLUSH_QUEUE 0x07
#define ACX1xx_CMD_SCAN 0x08
#define ACX1xx_CMD_STOP_SCAN 0x09
#define ACX1xx_CMD_CONFIG_TIM 0x0a
#define ACX1xx_CMD_JOIN 0x0b
#define ACX1xx_CMD_WEP_MGMT 0x0c
#ifdef OLD_FIRMWARE_VERSIONS
#define ACX100_CMD_HALT 0x0e /* mapped to unknownCMD in FW150 */
#else
#define ACX1xx_CMD_MEM_READ 0x0d
#define ACX1xx_CMD_MEM_WRITE 0x0e
#endif
#define ACX1xx_CMD_SLEEP 0x0f
#define ACX1xx_CMD_WAKE 0x10
#define ACX1xx_CMD_UNKNOWN_11 0x11 /* mapped to unknownCMD in FW150 */
#define ACX100_CMD_INIT_MEMORY 0x12
#define ACX1FF_CMD_DISABLE_RADIO 0x12 /* new firmware? TNETW1450? */
#define ACX1xx_CMD_CONFIG_BEACON 0x13
#define ACX1xx_CMD_CONFIG_PROBE_RESPONSE 0x14
#define ACX1xx_CMD_CONFIG_NULL_DATA 0x15
#define ACX1xx_CMD_CONFIG_PROBE_REQUEST 0x16
#define ACX1xx_CMD_FCC_TEST 0x17
#define ACX1xx_CMD_RADIOINIT 0x18
#define ACX111_CMD_RADIOCALIB 0x19
#define ACX1FF_CMD_NOISE_HISTOGRAM 0x1c /* new firmware? TNETW1450? */
#define ACX1FF_CMD_RX_RESET 0x1d /* new firmware? TNETW1450? */
#define ACX1FF_CMD_LNA_CONTROL 0x20 /* new firmware? TNETW1450? */
#define ACX1FF_CMD_CONTROL_DBG_TRACE 0x21 /* new firmware? TNETW1450? */
/* 'After Interrupt' Commands */
#define ACX_AFTER_IRQ_CMD_STOP_SCAN 0x01
#define ACX_AFTER_IRQ_CMD_ASSOCIATE 0x02
#define ACX_AFTER_IRQ_CMD_RADIO_RECALIB 0x04
#define ACX_AFTER_IRQ_UPDATE_CARD_CFG 0x08
#define ACX_AFTER_IRQ_TX_CLEANUP 0x10
#define ACX_AFTER_IRQ_COMPLETE_SCAN 0x20
#define ACX_AFTER_IRQ_RESTART_SCAN 0x40
/***********************************************************************
** Tx/Rx buffer sizes and watermarks
**
** This will alloc and use DMAable buffers of
** WLAN_A4FR_MAXLEN_WEP_FCS * (RX_CNT + TX_CNT) bytes
** RX/TX_CNT=32 -> ~150k DMA buffers
** RX/TX_CNT=16 -> ~75k DMA buffers
**
** 2005-10-10: reduced memory usage by lowering both to 16
*/
#define RX_CNT 16
#define TX_CNT 16
/* we clean up txdescs when we have N free txdesc: */
#define TX_CLEAN_BACKLOG (TX_CNT/4)
#define TX_START_CLEAN (TX_CNT - TX_CLEAN_BACKLOG)
#define TX_EMERG_CLEAN 2
/* we stop queue if we have < N free txbufs: */
#define TX_STOP_QUEUE 3
/* we start queue if we have >= N free txbufs: */
#define TX_START_QUEUE 5
/***********************************************************************
** Interrogate/Configure cmd constants
**
** NB: length includes JUST the data part of the IE
** (does not include size of the (type,len) pair)
**
** TODO: seems that acx100, acx100usb, acx111 have some differences,
** fix code with regard to this!
*/
#define DEF_IE(name, val, len) enum { ACX##name=val, ACX##name##_LEN=len }
/* Information Elements: Network Parameters, Static Configuration Entities */
/* these are handled by real_cfgtable in firmware "Rev 1.5.0" (FW150) */
DEF_IE(1xx_IE_UNKNOWN_00 ,0x0000, -1); /* mapped to cfgInvalid in FW150 */
DEF_IE(100_IE_ACX_TIMER ,0x0001, 0x10);
DEF_IE(1xx_IE_POWER_MGMT ,0x0002, 0x06); /* TNETW1450: length 0x18!! */
DEF_IE(1xx_IE_QUEUE_CONFIG ,0x0003, 0x1c);
DEF_IE(100_IE_BLOCK_SIZE ,0x0004, 0x02);
DEF_IE(1FF_IE_SLOT_TIME ,0x0004, 0x08); /* later firmware versions only? */
DEF_IE(1xx_IE_MEMORY_CONFIG_OPTIONS ,0x0005, 0x14);
DEF_IE(1FF_IE_QUEUE_HEAD ,0x0005, 0x14 /* FIXME: length? */);
DEF_IE(1xx_IE_RATE_FALLBACK ,0x0006, 0x01); /* TNETW1450: length 2 */
DEF_IE(100_IE_WEP_OPTIONS ,0x0007, 0x03);
DEF_IE(111_IE_RADIO_BAND ,0x0007, -1);
DEF_IE(1FF_IE_TIMING_CFG ,0x0007, -1); /* later firmware versions; TNETW1450 only? */
DEF_IE(100_IE_SSID ,0x0008, 0x20); /* huh? */
DEF_IE(1xx_IE_MEMORY_MAP ,0x0008, 0x28); /* huh? TNETW1450 has length 0x40!! */
DEF_IE(1xx_IE_SCAN_STATUS ,0x0009, 0x04); /* mapped to cfgInvalid in FW150 */
DEF_IE(1xx_IE_ASSOC_ID ,0x000a, 0x02);
DEF_IE(1xx_IE_UNKNOWN_0B ,0x000b, -1); /* mapped to cfgInvalid in FW150 */
DEF_IE(1FF_IE_TX_POWER_LEVEL_TABLE ,0x000b, 0x18); /* later firmware versions; TNETW1450 only? */
DEF_IE(100_IE_UNKNOWN_0C ,0x000c, -1); /* very small implementation in FW150! */
/* ACX100 has an equivalent struct in the cmd mailbox directly after reset.
* 0x14c seems extremely large, will trash stack on failure (memset!)
* in case of small input struct --> OOPS! */
DEF_IE(111_IE_CONFIG_OPTIONS ,0x000c, 0x14c);
DEF_IE(1xx_IE_FWREV ,0x000d, 0x18);
DEF_IE(1xx_IE_FCS_ERROR_COUNT ,0x000e, 0x04);
DEF_IE(1xx_IE_MEDIUM_USAGE ,0x000f, 0x08);
DEF_IE(1xx_IE_RXCONFIG ,0x0010, 0x04);
DEF_IE(100_IE_UNKNOWN_11 ,0x0011, -1); /* NONBINARY: large implementation in FW150! link quality readings or so? */
DEF_IE(111_IE_QUEUE_THRESH ,0x0011, -1);
DEF_IE(100_IE_UNKNOWN_12 ,0x0012, -1); /* NONBINARY: VERY large implementation in FW150!! */
DEF_IE(111_IE_BSS_POWER_SAVE ,0x0012, /* -1 */ 2);
DEF_IE(1xx_IE_FIRMWARE_STATISTICS ,0x0013, 0x9c); /* TNETW1450: length 0x134!! */
DEF_IE(1FF_IE_RX_INTR_CONFIG ,0x0014, 0x14); /* later firmware versions, TNETW1450 only? */
DEF_IE(1xx_IE_FEATURE_CONFIG ,0x0015, 0x08);
DEF_IE(111_IE_KEY_CHOOSE ,0x0016, 0x04); /* for rekeying. really len=4?? */
DEF_IE(1FF_IE_MISC_CONFIG_TABLE ,0x0017, 0x04); /* later firmware versions, TNETW1450 only? */
DEF_IE(1FF_IE_WONE_CONFIG ,0x0018, -1); /* later firmware versions, TNETW1450 only? */
DEF_IE(1FF_IE_TID_CONFIG ,0x001a, 0x2c); /* later firmware versions, TNETW1450 only? */
DEF_IE(1FF_IE_CALIB_ASSESSMENT ,0x001e, 0x04); /* later firmware versions, TNETW1450 only? */
DEF_IE(1FF_IE_BEACON_FILTER_OPTIONS ,0x001f, 0x02); /* later firmware versions, TNETW1450 only? */
DEF_IE(1FF_IE_LOW_RSSI_THRESH_OPT ,0x0020, 0x04); /* later firmware versions, TNETW1450 only? */
DEF_IE(1FF_IE_NOISE_HISTOGRAM_RESULTS ,0x0021, 0x30); /* later firmware versions, TNETW1450 only? */
DEF_IE(1FF_IE_PACKET_DETECT_THRESH ,0x0023, 0x04); /* later firmware versions, TNETW1450 only? */
DEF_IE(1FF_IE_TX_CONFIG_OPTIONS ,0x0024, 0x04); /* later firmware versions, TNETW1450 only? */
DEF_IE(1FF_IE_CCA_THRESHOLD ,0x0025, 0x02); /* later firmware versions, TNETW1450 only? */
DEF_IE(1FF_IE_EVENT_MASK ,0x0026, 0x08); /* later firmware versions, TNETW1450 only? */
DEF_IE(1FF_IE_DTIM_PERIOD ,0x0027, 0x02); /* later firmware versions, TNETW1450 only? */
DEF_IE(1FF_IE_ACI_CONFIG_SET ,0x0029, 0x06); /* later firmware versions; maybe TNETW1450 only? */
DEF_IE(1FF_IE_EEPROM_VER ,0x0030, 0x04); /* later firmware versions; maybe TNETW1450 only? */
DEF_IE(1xx_IE_DOT11_STATION_ID ,0x1001, 0x06);
DEF_IE(100_IE_DOT11_UNKNOWN_1002 ,0x1002, -1); /* mapped to cfgInvalid in FW150 */
DEF_IE(111_IE_DOT11_FRAG_THRESH ,0x1002, -1); /* mapped to cfgInvalid in FW150; TNETW1450 has length 2!! */
DEF_IE(100_IE_DOT11_BEACON_PERIOD ,0x1003, 0x02); /* mapped to cfgInvalid in FW150 */
DEF_IE(1xx_IE_DOT11_DTIM_PERIOD ,0x1004, -1); /* mapped to cfgInvalid in FW150 */
DEF_IE(1FF_IE_DOT11_MAX_RX_LIFETIME ,0x1004, -1); /* later firmware versions; maybe TNETW1450 only? */
DEF_IE(1xx_IE_DOT11_SHORT_RETRY_LIMIT ,0x1005, 0x01); /* TNETW1450: length 2 */
DEF_IE(1xx_IE_DOT11_LONG_RETRY_LIMIT ,0x1006, 0x01); /* TNETW1450: length 2 */
DEF_IE(100_IE_DOT11_WEP_DEFAULT_KEY_WRITE ,0x1007, 0x20); /* configure default keys; TNETW1450 has length 0x24!! */
DEF_IE(1xx_IE_DOT11_MAX_XMIT_MSDU_LIFETIME ,0x1008, 0x04);
DEF_IE(1xx_IE_DOT11_GROUP_ADDR ,0x1009, -1);
DEF_IE(1xx_IE_DOT11_CURRENT_REG_DOMAIN ,0x100a, 0x02);
/* It's harmless to have larger struct. Use USB case always. */
DEF_IE(1xx_IE_DOT11_CURRENT_ANTENNA ,0x100b, 0x02); /* in fact len=1 for PCI */
DEF_IE(1xx_IE_DOT11_UNKNOWN_100C ,0x100c, -1); /* mapped to cfgInvalid in FW150 */
DEF_IE(1xx_IE_DOT11_TX_POWER_LEVEL ,0x100d, 0x01); /* TNETW1450 has length 2!! */
DEF_IE(1xx_IE_DOT11_CURRENT_CCA_MODE ,0x100e, 0x02); /* in fact len=1 for PCI */
/* USB doesn't return anything - len==0?! */
DEF_IE(100_IE_DOT11_ED_THRESHOLD ,0x100f, 0x04);
DEF_IE(1xx_IE_DOT11_WEP_DEFAULT_KEY_SET ,0x1010, 0x01); /* set default key ID; TNETW1450: length 2 */
DEF_IE(100_IE_DOT11_UNKNOWN_1011 ,0x1011, -1); /* mapped to cfgInvalid in FW150 */
DEF_IE(1FF_IE_DOT11_CURR_5GHZ_REGDOM ,0x1011, -1); /* later firmware versions; maybe TNETW1450 only? */
DEF_IE(100_IE_DOT11_UNKNOWN_1012 ,0x1012, -1); /* mapped to cfgInvalid in FW150 */
DEF_IE(100_IE_DOT11_UNKNOWN_1013 ,0x1013, -1); /* mapped to cfgInvalid in FW150 */
#if 0
/* Experimentally obtained on acx100, fw 1.9.8.b
** -1 means that fw returned 'invalid IE'
** 0200 FC00 nnnn... are test read contents: u16 type, u16 len, data
** (AA are poison bytes marking bytes not written by fw)
**
** Looks like acx100 fw does not update len field (thus len=256-4=FC here)
** A number of IEs seem to trash type,len fields
** IEs marked 'huge' return gobs of data (no poison bytes remain)
*/
DEF_IE(100_IE_INVAL_00, 0x0000, -1);
DEF_IE(100_IE_INVAL_01, 0x0001, -1); /* IE_ACX_TIMER, len=16 on older fw */
DEF_IE(100_IE_POWER_MGMT, 0x0002, 4); /* 0200FC00 00040000 AAAAAAAA */
DEF_IE(100_IE_QUEUE_CONFIG, 0x0003, 28); /* 0300FC00 48060000 9CAD0000 0101AAAA DCB00000 E4B00000 9CAA0000 00AAAAAA */
DEF_IE(100_IE_BLOCK_SIZE, 0x0004, 2); /* 0400FC00 0001AAAA AAAAAAAA AAAAAAAA */
/* write only: */
DEF_IE(100_IE_MEMORY_CONFIG_OPTIONS, 0x0005, 20);
DEF_IE(100_IE_RATE_FALLBACK, 0x0006, 1); /* 0600FC00 00AAAAAA AAAAAAAA AAAAAAAA */
/* write only: */
DEF_IE(100_IE_WEP_OPTIONS, 0x0007, 3);
DEF_IE(100_IE_MEMORY_MAP, 0x0008, 40); /* huge: 0800FC00 30000000 6CA20000 70A20000... */
/* gives INVAL on read: */
DEF_IE(100_IE_SCAN_STATUS, 0x0009, -1);
DEF_IE(100_IE_ASSOC_ID, 0x000a, 2); /* huge: 0A00FC00 00000000 01040800 00000000... */
DEF_IE(100_IE_INVAL_0B, 0x000b, -1);
/* 'command rejected': */
DEF_IE(100_IE_CONFIG_OPTIONS, 0x000c, -3);
DEF_IE(100_IE_FWREV, 0x000d, 24); /* 0D00FC00 52657620 312E392E 382E6200 AAAAAAAA AAAAAAAA 05050201 AAAAAAAA */
DEF_IE(100_IE_FCS_ERROR_COUNT, 0x000e, 4);
DEF_IE(100_IE_MEDIUM_USAGE, 0x000f, 8); /* E41F0000 2D780300 FCC91300 AAAAAAAA */
DEF_IE(100_IE_RXCONFIG, 0x0010, 4); /* 1000FC00 00280000 AAAAAAAA AAAAAAAA */
DEF_IE(100_IE_QUEUE_THRESH, 0x0011, 12); /* 1100FC00 AAAAAAAA 00000000 00000000 */
DEF_IE(100_IE_BSS_POWER_SAVE, 0x0012, 1); /* 1200FC00 00AAAAAA AAAAAAAA AAAAAAAA */
/* read only, variable len */
DEF_IE(100_IE_FIRMWARE_STATISTICS, 0x0013, 256); /* 0000AC00 00000000 ... */
DEF_IE(100_IE_INT_CONFIG, 0x0014, 20); /* 00000000 00000000 00000000 00000000 5D74D105 00000000 AAAAAAAA AAAAAAAA */
DEF_IE(100_IE_FEATURE_CONFIG, 0x0015, 8); /* 1500FC00 16000000 AAAAAAAA AAAAAAAA */
/* returns 'invalid MAC': */
DEF_IE(100_IE_KEY_CHOOSE, 0x0016, -4);
DEF_IE(100_IE_INVAL_17, 0x0017, -1);
DEF_IE(100_IE_UNKNOWN_18, 0x0018, 0); /* null len?! 1800FC00 AAAAAAAA AAAAAAAA AAAAAAAA */
DEF_IE(100_IE_UNKNOWN_19, 0x0019, 256); /* huge: 1900FC00 9C1F00EA FEFFFFEA FEFFFFEA... */
DEF_IE(100_IE_INVAL_1A, 0x001A, -1);
DEF_IE(100_IE_DOT11_INVAL_1000, 0x1000, -1);
DEF_IE(100_IE_DOT11_STATION_ID, 0x1001, 6); /* huge: 0110FC00 58B10E2F 03000000 00000000... */
DEF_IE(100_IE_DOT11_INVAL_1002, 0x1002, -1);
DEF_IE(100_IE_DOT11_INVAL_1003, 0x1003, -1);
DEF_IE(100_IE_DOT11_INVAL_1004, 0x1004, -1);
DEF_IE(100_IE_DOT11_SHORT_RETRY_LIMIT, 0x1005, 1);
DEF_IE(100_IE_DOT11_LONG_RETRY_LIMIT, 0x1006, 1);
/* write only: */
DEF_IE(100_IE_DOT11_WEP_DEFAULT_KEY_WRITE, 0x1007, 32);
DEF_IE(100_IE_DOT11_MAX_XMIT_MSDU_LIFETIME, 0x1008, 4); /* huge: 0810FC00 00020000 F4010000 00000000... */
/* undoc but returns something */
DEF_IE(100_IE_DOT11_GROUP_ADDR, 0x1009, 12); /* huge: 0910FC00 00000000 00000000 00000000... */
DEF_IE(100_IE_DOT11_CURRENT_REG_DOMAIN, 0x100a, 1); /* 0A10FC00 30AAAAAA AAAAAAAA AAAAAAAA */
DEF_IE(100_IE_DOT11_CURRENT_ANTENNA, 0x100b, 1); /* 0B10FC00 8FAAAAAA AAAAAAAA AAAAAAAA */
DEF_IE(100_IE_DOT11_INVAL_100C, 0x100c, -1);
DEF_IE(100_IE_DOT11_TX_POWER_LEVEL, 0x100d, 2); /* 00000000 0100AAAA AAAAAAAA AAAAAAAA */
DEF_IE(100_IE_DOT11_CURRENT_CCA_MODE, 0x100e, 1); /* 0E10FC00 0DAAAAAA AAAAAAAA AAAAAAAA */
DEF_IE(100_IE_DOT11_ED_THRESHOLD, 0x100f, 4); /* 0F10FC00 70000000 AAAAAAAA AAAAAAAA */
/* set default key ID */
DEF_IE(100_IE_DOT11_WEP_DEFAULT_KEY_SET, 0x1010, 1); /* 1010FC00 00AAAAAA AAAAAAAA AAAAAAAA */
DEF_IE(100_IE_DOT11_INVAL_1011, 0x1011, -1);
DEF_IE(100_IE_DOT11_INVAL_1012, 0x1012, -1);
DEF_IE(100_IE_DOT11_INVAL_1013, 0x1013, -1);
DEF_IE(100_IE_DOT11_UNKNOWN_1014, 0x1014, 256); /* huge */
DEF_IE(100_IE_DOT11_UNKNOWN_1015, 0x1015, 256); /* huge */
DEF_IE(100_IE_DOT11_UNKNOWN_1016, 0x1016, 256); /* huge */
DEF_IE(100_IE_DOT11_UNKNOWN_1017, 0x1017, 256); /* huge */
DEF_IE(100_IE_DOT11_UNKNOWN_1018, 0x1018, 256); /* huge */
DEF_IE(100_IE_DOT11_UNKNOWN_1019, 0x1019, 256); /* huge */
#endif
#if 0
/* Experimentally obtained on PCI acx111 Xterasys XN-2522g, fw 1.2.1.34
** -1 means that fw returned 'invalid IE'
** 0400 0800 nnnn... are test read contents: u16 type, u16 len, data
** (AA are poison bytes marking bytes not written by fw)
**
** Looks like acx111 fw reports real len!
*/
DEF_IE(111_IE_INVAL_00, 0x0000, -1);
DEF_IE(111_IE_INVAL_01, 0x0001, -1);
DEF_IE(111_IE_POWER_MGMT, 0x0002, 12);
/* write only, variable len: 12 + rxqueue_cnt*8 + txqueue_cnt*4: */
DEF_IE(111_IE_MEMORY_CONFIG, 0x0003, 24);
DEF_IE(111_IE_BLOCK_SIZE, 0x0004, 8); /* 04000800 AA00AAAA AAAAAAAA */
/* variable len: 8 + rxqueue_cnt*8 + txqueue_cnt*8: */
DEF_IE(111_IE_QUEUE_HEAD, 0x0005, 24);
DEF_IE(111_IE_RATE_FALLBACK, 0x0006, 1);
/* acx100 name:WEP_OPTIONS */
/* said to have len:1 (not true, actually returns 12 bytes): */
DEF_IE(111_IE_RADIO_BAND, 0x0007, 12); /* 07000C00 AAAA1F00 FF03AAAA AAAAAAAA */
DEF_IE(111_IE_MEMORY_MAP, 0x0008, 48);
/* said to have len:4, but gives INVAL on read: */
DEF_IE(111_IE_SCAN_STATUS, 0x0009, -1);
DEF_IE(111_IE_ASSOC_ID, 0x000a, 2);
/* write only, len is not known: */
DEF_IE(111_IE_UNKNOWN_0B, 0x000b, 0);
/* read only, variable len. I see 67 byte reads: */
DEF_IE(111_IE_CONFIG_OPTIONS, 0x000c, 67); /* 0C004300 01160500 ... */
DEF_IE(111_IE_FWREV, 0x000d, 24);
DEF_IE(111_IE_FCS_ERROR_COUNT, 0x000e, 4);
DEF_IE(111_IE_MEDIUM_USAGE, 0x000f, 8);
DEF_IE(111_IE_RXCONFIG, 0x0010, 4);
DEF_IE(111_IE_QUEUE_THRESH, 0x0011, 12);
DEF_IE(111_IE_BSS_POWER_SAVE, 0x0012, 1);
/* read only, variable len. I see 240 byte reads: */
DEF_IE(111_IE_FIRMWARE_STATISTICS, 0x0013, 240); /* 1300F000 00000000 ... */
/* said to have len=17. looks like fw pads it to 20: */
DEF_IE(111_IE_INT_CONFIG, 0x0014, 20); /* 14001400 00000000 00000000 00000000 00000000 00000000 */
DEF_IE(111_IE_FEATURE_CONFIG, 0x0015, 8);
/* said to be name:KEY_INDICATOR, len:4, but gives INVAL on read: */
DEF_IE(111_IE_KEY_CHOOSE, 0x0016, -1);
/* said to have len:4, but in fact returns 8: */
DEF_IE(111_IE_MAX_USB_XFR, 0x0017, 8); /* 17000800 00014000 00000000 */
DEF_IE(111_IE_INVAL_18, 0x0018, -1);
DEF_IE(111_IE_INVAL_19, 0x0019, -1);
/* undoc but returns something: */
/* huh, fw indicates len=20 but uses 4 more bytes in buffer??? */
DEF_IE(111_IE_UNKNOWN_1A, 0x001A, 20); /* 1A001400 AA00AAAA 0000020F FF030000 00020000 00000007 04000000 */
DEF_IE(111_IE_DOT11_INVAL_1000, 0x1000, -1);
DEF_IE(111_IE_DOT11_STATION_ID, 0x1001, 6);
DEF_IE(111_IE_DOT11_FRAG_THRESH, 0x1002, 2);
/* acx100 only? gives INVAL on read: */
DEF_IE(111_IE_DOT11_BEACON_PERIOD, 0x1003, -1);
/* said to be MAX_RECV_MSDU_LIFETIME: */
DEF_IE(111_IE_DOT11_DTIM_PERIOD, 0x1004, 4);
DEF_IE(111_IE_DOT11_SHORT_RETRY_LIMIT, 0x1005, 1);
DEF_IE(111_IE_DOT11_LONG_RETRY_LIMIT, 0x1006, 1);
/* acx100 only? gives INVAL on read: */
DEF_IE(111_IE_DOT11_WEP_DEFAULT_KEY_WRITE, 0x1007, -1);
DEF_IE(111_IE_DOT11_MAX_XMIT_MSDU_LIFETIME, 0x1008, 4);
/* undoc but returns something. maybe it's 2 multicast MACs to listen to? */
DEF_IE(111_IE_DOT11_GROUP_ADDR, 0x1009, 12); /* 09100C00 00000000 00000000 00000000 */
DEF_IE(111_IE_DOT11_CURRENT_REG_DOMAIN, 0x100a, 1);
DEF_IE(111_IE_DOT11_CURRENT_ANTENNA, 0x100b, 2);
DEF_IE(111_IE_DOT11_INVAL_100C, 0x100c, -1);
DEF_IE(111_IE_DOT11_TX_POWER_LEVEL, 0x100d, 1);
/* said to have len=1 but gives INVAL on read: */
DEF_IE(111_IE_DOT11_CURRENT_CCA_MODE, 0x100e, -1);
/* said to have len=4 but gives INVAL on read: */
DEF_IE(111_IE_DOT11_ED_THRESHOLD, 0x100f, -1);
/* set default key ID. write only: */
DEF_IE(111_IE_DOT11_WEP_DEFAULT_KEY_SET, 0x1010, 1);
/* undoc but returns something: */
DEF_IE(111_IE_DOT11_UNKNOWN_1011, 0x1011, 1); /* 11100100 20 */
DEF_IE(111_IE_DOT11_INVAL_1012, 0x1012, -1);
DEF_IE(111_IE_DOT11_INVAL_1013, 0x1013, -1);
#endif
/***********************************************************************
**Information Frames Structures
*/
/* Used in beacon frames and the like */
#define DOT11RATEBYTE_1 (1*2)
#define DOT11RATEBYTE_2 (2*2)
#define DOT11RATEBYTE_5_5 (5*2+1)
#define DOT11RATEBYTE_11 (11*2)
#define DOT11RATEBYTE_22 (22*2)
#define DOT11RATEBYTE_6_G (6*2)
#define DOT11RATEBYTE_9_G (9*2)
#define DOT11RATEBYTE_12_G (12*2)
#define DOT11RATEBYTE_18_G (18*2)
#define DOT11RATEBYTE_24_G (24*2)
#define DOT11RATEBYTE_36_G (36*2)
#define DOT11RATEBYTE_48_G (48*2)
#define DOT11RATEBYTE_54_G (54*2)
#define DOT11RATEBYTE_BASIC 0x80 /* flags rates included in basic rate set */
/***********************************************************************
** rxbuffer_t
**
** This is the format of rx data returned by acx
*/
/* I've hoped it's a 802.11 PHY header, but no...
* so far, I've seen on acx111:
* 0000 3a00 0000 0000 IBSS Beacons
* 0000 3c00 0000 0000 ESS Beacons
* 0000 2700 0000 0000 Probe requests
* --vda
*/
typedef struct phy_hdr {
u8 unknown[4];
u8 acx111_unknown[4];
} ACX_PACKED phy_hdr_t;
/* seems to be a bit similar to hfa384x_rx_frame.
* These fields are still not quite obvious, though.
* Some seem to have different meanings... */
#define RXBUF_HDRSIZE 12
#define RXBUF_BYTES_RCVD(adev, rxbuf) \
((le16_to_cpu((rxbuf)->mac_cnt_rcvd) & 0xfff) - (adev)->phy_header_len)
#define RXBUF_BYTES_USED(rxbuf) \
((le16_to_cpu((rxbuf)->mac_cnt_rcvd) & 0xfff) + RXBUF_HDRSIZE)
/* USBism */
#define RXBUF_IS_TXSTAT(rxbuf) (le16_to_cpu((rxbuf)->mac_cnt_rcvd) & 0x8000)
/*
mac_cnt_rcvd:
12 bits: length of frame from control field to first byte of FCS
3 bits: reserved
1 bit: 1 = it's a tx status info, not a rx packet (USB only)
mac_cnt_mblks:
6 bits: number of memory block used to store frame in adapter memory
1 bit: Traffic Indicator bit in TIM of received Beacon was set
mac_status: 1 byte (bitmap):
7 Matching BSSID
6 Matching SSID
5 BDCST Address 1 field is a broadcast
4 VBM received beacon frame has more than one set bit (?!)
3 TIM Set bit representing this station is set in TIM of received beacon
2 GROUP Address 1 is a multicast
1 ADDR1 Address 1 matches our MAC
0 FCSGD FSC is good
phy_stat_baseband: 1 byte (bitmap):
7 Preamble frame had a long preamble
6 PLCP Error CRC16 error in PLCP header
5 Unsup_Mod unsupported modulation
4 Selected Antenna antenna 1 was used to receive this frame
3 PBCC/CCK frame used: 1=PBCC, 0=CCK modulation
2 OFDM frame used OFDM modulation
1 TI Protection protection frame was detected
0 Reserved
phy_plcp_signal: 1 byte:
Receive PLCP Signal field from the Baseband Processor
phy_level: 1 byte:
receive AGC gain level (can be used to measure receive signal strength)
phy_snr: 1 byte:
estimated noise power of equalized receive signal
at input of FEC decoder (can be used to measure receive signal quality)
time: 4 bytes:
timestamp sampled from either the Access Manager TSF counter
or free-running microsecond counter when the MAC receives
first byte of PLCP header.
*/
typedef struct rxbuffer {
u16 mac_cnt_rcvd; /* only 12 bits are len! (0xfff) */
u8 mac_cnt_mblks;
u8 mac_status;
u8 phy_stat_baseband; /* bit 0x80: used LNA (Low-Noise Amplifier) */
u8 phy_plcp_signal;
u8 phy_level; /* PHY stat */
u8 phy_snr; /* PHY stat */
u32 time; /* timestamp upon MAC rcv first byte */
/* 4-byte (acx100) or 8-byte (acx111) phy header will be here
** if RX_CFG1_INCLUDE_PHY_HDR is in effect:
** phy_hdr_t phy */
wlan_hdr_a3_t hdr_a3;
/* maximally sized data part of wlan packet */
u8 data_a3[WLAN_A4FR_MAXLEN_WEP_FCS - WLAN_HDR_A3_LEN];
/* can add hdr/data_a4 if needed */
} ACX_PACKED rxbuffer_t;
/*--- Firmware statistics ----------------------------------------------------*/
/* define a random 100 bytes more to catch firmware versions which
* provide a bigger struct */
#define FW_STATS_FUTURE_EXTENSION 100
typedef struct fw_stats_tx {
u32 tx_desc_of;
} ACX_PACKED fw_stats_tx_t;
typedef struct fw_stats_rx {
u32 rx_oom;
u32 rx_hdr_of;
u32 rx_hw_stuck; /* old: u32 rx_hdr_use_next */
u32 rx_dropped_frame;
u32 rx_frame_ptr_err;
u32 rx_xfr_hint_trig;
u32 rx_aci_events; /* later versions only */
u32 rx_aci_resets; /* later versions only */
} ACX_PACKED fw_stats_rx_t;
typedef struct fw_stats_dma {
u32 rx_dma_req;
u32 rx_dma_err;
u32 tx_dma_req;
u32 tx_dma_err;
} ACX_PACKED fw_stats_dma_t;
typedef struct fw_stats_irq {
u32 cmd_cplt;
u32 fiq;
u32 rx_hdrs;
u32 rx_cmplt;
u32 rx_mem_of;
u32 rx_rdys;
u32 irqs;
u32 tx_procs;
u32 decrypt_done;
u32 dma_0_done;
u32 dma_1_done;
u32 tx_exch_complet;
u32 commands;
u32 rx_procs;
u32 hw_pm_mode_changes;
u32 host_acks;
u32 pci_pm;
u32 acm_wakeups;
} ACX_PACKED fw_stats_irq_t;
typedef struct fw_stats_wep {
u32 wep_key_count;
u32 wep_default_key_count;
u32 dot11_def_key_mib;
u32 wep_key_not_found;
u32 wep_decrypt_fail;
u32 wep_pkt_decrypt;
u32 wep_decrypt_irqs;
} ACX_PACKED fw_stats_wep_t;
typedef struct fw_stats_pwr {
u32 tx_start_ctr;
u32 no_ps_tx_too_short;
u32 rx_start_ctr;
u32 no_ps_rx_too_short;
u32 lppd_started;
u32 no_lppd_too_noisy;
u32 no_lppd_too_short;
u32 no_lppd_matching_frame;
} ACX_PACKED fw_stats_pwr_t;
typedef struct fw_stats_mic {
u32 mic_rx_pkts;
u32 mic_calc_fail;
} ACX_PACKED fw_stats_mic_t;
typedef struct fw_stats_aes {
u32 aes_enc_fail;
u32 aes_dec_fail;
u32 aes_enc_pkts;
u32 aes_dec_pkts;
u32 aes_enc_irq;
u32 aes_dec_irq;
} ACX_PACKED fw_stats_aes_t;
typedef struct fw_stats_event {
u32 heartbeat;
u32 calibration;
u32 rx_mismatch;
u32 rx_mem_empty;
u32 rx_pool;
u32 oom_late;
u32 phy_tx_err;
u32 tx_stuck;
} ACX_PACKED fw_stats_event_t;
/* mainly for size calculation only */
typedef struct fw_stats {
u16 type;
u16 len;
fw_stats_tx_t tx;
fw_stats_rx_t rx;
fw_stats_dma_t dma;
fw_stats_irq_t irq;
fw_stats_wep_t wep;
fw_stats_pwr_t pwr;
fw_stats_mic_t mic;
fw_stats_aes_t aes;
fw_stats_event_t evt;
u8 _padding[FW_STATS_FUTURE_EXTENSION];
} fw_stats_t;
/* Firmware version struct */
typedef struct fw_ver {
u16 cmd;
u16 size;
char fw_id[20];
u32 hw_id;
} ACX_PACKED fw_ver_t;
#define FW_ID_SIZE 20
/*--- WEP stuff --------------------------------------------------------------*/
#define DOT11_MAX_DEFAULT_WEP_KEYS 4
/* non-firmware struct, no packing necessary */
typedef struct wep_key {
size_t size; /* most often used member first */
u8 index;
u8 key[29];
u16 strange_filler;
} wep_key_t; /* size = 264 bytes (33*8) */
/* FIXME: We don't have size 264! Or is there 2 bytes beyond the key
* (strange_filler)? */
/* non-firmware struct, no packing necessary */
typedef struct key_struct {
u8 addr[ETH_ALEN]; /* 0x00 */
u16 filler1; /* 0x06 */
u32 filler2; /* 0x08 */
u32 index; /* 0x0c */
u16 len; /* 0x10 */
u8 key[29]; /* 0x12; is this long enough??? */
} key_struct_t; /* size = 276. FIXME: where is the remaining space?? */
/*--- Client (peer) info -----------------------------------------------------*/
/* adev->sta_list[] is used for:
** accumulating and processing of scan results
** keeping client info in AP mode
** keeping AP info in STA mode (AP is the only one 'client')
** keeping peer info in ad-hoc mode
** non-firmware struct --> no packing necessary */
enum {
CLIENT_EMPTY_SLOT_0 = 0,
CLIENT_EXIST_1 = 1,
CLIENT_AUTHENTICATED_2 = 2,
CLIENT_ASSOCIATED_3 = 3,
CLIENT_JOIN_CANDIDATE = 4
};
struct client {
/* most frequent access first */
u8 used; /* misnamed, more like 'status' */
struct client* next;
unsigned long mtime; /* last time we heard it, in jiffies */
size_t essid_len; /* length of ESSID (without '\0') */
u32 sir; /* Standard IR */
u32 snr; /* Signal to Noise Ratio */
u16 aid; /* association ID */
u16 seq; /* from client's auth req */
u16 auth_alg; /* from client's auth req */
u16 cap_info; /* from client's assoc req */
u16 rate_cap; /* what client supports (all rates) */
u16 rate_bas; /* what client supports (basic rates) */
u16 rate_cfg; /* what is allowed (by iwconfig etc) */
u16 rate_cur; /* currently used rate mask */
u8 rate_100; /* currently used rate byte (acx100 only) */
u8 address[ETH_ALEN];
u8 bssid[ETH_ALEN]; /* ad-hoc hosts can have bssid != mac */
u8 channel;
u8 auth_step;
u8 ignore_count;
u8 fallback_count;
u8 stepup_count;
char essid[IW_ESSID_MAX_SIZE + 1]; /* ESSID and trailing '\0' */
/* FIXME: this one is too damn big */
char challenge_text[WLAN_CHALLENGE_LEN];
};
/***********************************************************************
** Hardware structures
*/
/* An opaque typesafe helper type
*
* Some hardware fields are actually pointers,
* but they have to remain u32, since using ptr instead
* (8 bytes on 64bit systems!) would disrupt the fixed descriptor
* format the acx firmware expects in the non-user area.
* Since we cannot cram an 8 byte ptr into 4 bytes, we need to
* enforce that pointed to data remains in low memory
* (address value needs to fit in 4 bytes) on 64bit systems.
*
* This is easy to get wrong, thus we are using a small struct
* and special macros to access it. Macros will check for
* attempts to overflow an acx_ptr with value > 0xffffffff.
*
* Attempts to use acx_ptr without macros result in compile-time errors */
typedef struct {
u32 v;
} ACX_PACKED acx_ptr;
#if ACX_DEBUG
#define CHECK32(n) BUG_ON(sizeof(n)>4 && (long)(n)>0xffffff00)
#else
#define CHECK32(n) ((void)0)
#endif
/* acx_ptr <-> integer conversion */
#define cpu2acx(n) ({ CHECK32(n); ((acx_ptr){ .v = cpu_to_le32(n) }); })
#define acx2cpu(a) (le32_to_cpu(a.v))
/* acx_ptr <-> pointer conversion */
#define ptr2acx(p) ({ CHECK32(p); ((acx_ptr){ .v = cpu_to_le32((u32)(long)(p)) }); })
#define acx2ptr(a) ((void*)le32_to_cpu(a.v))
/* Values for rate field (acx100 only) */
#define RATE100_1 10
#define RATE100_2 20
#define RATE100_5 55
#define RATE100_11 110
#define RATE100_22 220
/* This bit denotes use of PBCC:
** (PBCC encoding is usable with 11 and 22 Mbps speeds only) */
#define RATE100_PBCC511 0x80
/* Bit values for rate111 field */
#define RATE111_1 0x0001 /* DBPSK */
#define RATE111_2 0x0002 /* DQPSK */
#define RATE111_5 0x0004 /* CCK or PBCC */
#define RATE111_6 0x0008 /* CCK-OFDM or OFDM */
#define RATE111_9 0x0010 /* CCK-OFDM or OFDM */
#define RATE111_11 0x0020 /* CCK or PBCC */
#define RATE111_12 0x0040 /* CCK-OFDM or OFDM */
#define RATE111_18 0x0080 /* CCK-OFDM or OFDM */
#define RATE111_22 0x0100 /* PBCC */
#define RATE111_24 0x0200 /* CCK-OFDM or OFDM */
#define RATE111_36 0x0400 /* CCK-OFDM or OFDM */
#define RATE111_48 0x0800 /* CCK-OFDM or OFDM */
#define RATE111_54 0x1000 /* CCK-OFDM or OFDM */
#define RATE111_RESERVED 0x2000
#define RATE111_PBCC511 0x4000 /* PBCC mod at 5.5 or 11Mbit (else CCK) */
#define RATE111_SHORTPRE 0x8000 /* short preamble */
/* Special 'try everything' value */
#define RATE111_ALL 0x1fff
/* These bits denote acx100 compatible settings */
#define RATE111_ACX100_COMPAT 0x0127
/* These bits denote 802.11b compatible settings */
#define RATE111_80211B_COMPAT 0x0027
/* Descriptor Ctl field bits
* init value is 0x8e, "idle" value is 0x82 (in idle tx descs)
*/
#define DESC_CTL_SHORT_PREAMBLE 0x01 /* preamble type: 0 = long; 1 = short */
#define DESC_CTL_FIRSTFRAG 0x02 /* this is the 1st frag of the frame */
#define DESC_CTL_AUTODMA 0x04
#define DESC_CTL_RECLAIM 0x08 /* ready to reuse */
#define DESC_CTL_HOSTDONE 0x20 /* host has finished processing */
#define DESC_CTL_ACXDONE 0x40 /* acx has finished processing */
/* host owns the desc [has to be released last, AFTER modifying all other desc fields!] */
#define DESC_CTL_HOSTOWN 0x80
#define DESC_CTL_ACXDONE_HOSTOWN (DESC_CTL_ACXDONE | DESC_CTL_HOSTOWN)
/* Descriptor Status field
*/
#define DESC_STATUS_FULL (1 << 31)
/* NB: some bits may be interesting for Monitor mode tx (aka Raw tx): */
#define DESC_CTL2_SEQ 0x01 /* don't increase sequence field */
#define DESC_CTL2_FCS 0x02 /* don't add the FCS */
#define DESC_CTL2_MORE_FRAG 0x04
#define DESC_CTL2_RETRY 0x08 /* don't increase retry field */
#define DESC_CTL2_POWER 0x10 /* don't increase power mgmt. field */
#define DESC_CTL2_RTS 0x20 /* do RTS/CTS magic before sending */
#define DESC_CTL2_WEP 0x40 /* encrypt this frame */
#define DESC_CTL2_DUR 0x80 /* don't increase duration field */
/***********************************************************************
** PCI structures
*/
/* IRQ Constants
** (outside of "#ifdef PCI" because USB (mis)uses HOST_INT_SCAN_COMPLETE) */
#define HOST_INT_RX_DATA 0x0001
#define HOST_INT_TX_COMPLETE 0x0002
#define HOST_INT_TX_XFER 0x0004
#define HOST_INT_RX_COMPLETE 0x0008
#define HOST_INT_DTIM 0x0010
#define HOST_INT_BEACON 0x0020
#define HOST_INT_TIMER 0x0040
#define HOST_INT_KEY_NOT_FOUND 0x0080
#define HOST_INT_IV_ICV_FAILURE 0x0100
#define HOST_INT_CMD_COMPLETE 0x0200
#define HOST_INT_INFO 0x0400
#define HOST_INT_OVERFLOW 0x0800
#define HOST_INT_PROCESS_ERROR 0x1000
#define HOST_INT_SCAN_COMPLETE 0x2000
#define HOST_INT_FCS_THRESHOLD 0x4000
#define HOST_INT_UNKNOWN 0x8000
/* Outside of "#ifdef PCI" because USB needs to know sizeof()
** of txdesc and rxdesc: */
struct txdesc {
acx_ptr pNextDesc; /* pointer to next txdesc */
acx_ptr HostMemPtr; /* 0x04 */
acx_ptr AcxMemPtr; /* 0x08 */
u32 tx_time; /* 0x0c */
u16 total_length; /* 0x10 */
u16 Reserved; /* 0x12 */
/* The following 16 bytes do not change when acx100 owns the descriptor */
/* BUG: fw clears last byte of this area which is supposedly reserved
** for driver use. amd64 blew up. We dare not use it now */
u32 dummy[4];
u8 Ctl_8; /* 0x24, 8bit value */
u8 Ctl2_8; /* 0x25, 8bit value */
u8 error; /* 0x26 */
u8 ack_failures; /* 0x27 */
u8 rts_failures; /* 0x28 */
u8 rts_ok; /* 0x29 */
union {
struct {
u8 rate; /* 0x2a */
u8 queue_ctrl; /* 0x2b */
} ACX_PACKED r1;
struct {
u16 rate111; /* 0x2a */
} ACX_PACKED r2;
} ACX_PACKED u;
u32 queue_info; /* 0x2c (acx100, reserved on acx111) */
} ACX_PACKED; /* size : 48 = 0x30 */
/* NB: acx111 txdesc structure is 4 byte larger */
/* All these 4 extra bytes are reserved. tx alloc code takes them into account */
struct rxdesc {
acx_ptr pNextDesc; /* 0x00 */
acx_ptr HostMemPtr; /* 0x04 */
acx_ptr ACXMemPtr; /* 0x08 */
u32 rx_time; /* 0x0c */
u16 total_length; /* 0x10 */
u16 WEP_length; /* 0x12 */
u32 WEP_ofs; /* 0x14 */
/* the following 16 bytes do not change when acx100 owns the descriptor */
u8 driverWorkspace[16]; /* 0x18 */
u8 Ctl_8;
u8 rate;
u8 error;
u8 SNR; /* Signal-to-Noise Ratio */
u8 RxLevel;
u8 queue_ctrl;
u16 unknown;
u32 unknown2;
} ACX_PACKED; /* size 52 = 0x34 */
#ifdef ACX_PCI
/* Register I/O offsets */
#define ACX100_EEPROM_ID_OFFSET 0x380
/* please add further ACX hardware register definitions only when
it turns out you need them in the driver, and please try to use
firmware functionality instead, since using direct I/O access instead
of letting the firmware do it might confuse the firmware's state
machine */
/* ***** ABSOLUTELY ALWAYS KEEP OFFSETS IN SYNC WITH THE INITIALIZATION
** OF THE I/O ARRAYS!!!! (grep for '^IO_ACX') ***** */
enum {
IO_ACX_SOFT_RESET = 0,
IO_ACX_SLV_MEM_ADDR,
IO_ACX_SLV_MEM_DATA,
IO_ACX_SLV_MEM_CTL,
IO_ACX_SLV_END_CTL,
IO_ACX_FEMR, /* Function Event Mask */
IO_ACX_INT_TRIG,
IO_ACX_IRQ_MASK,
IO_ACX_IRQ_STATUS_NON_DES,
IO_ACX_IRQ_STATUS_CLEAR, /* CLEAR = clear on read */
IO_ACX_IRQ_ACK,
IO_ACX_HINT_TRIG,
IO_ACX_ENABLE,
IO_ACX_EEPROM_CTL,
IO_ACX_EEPROM_ADDR,
IO_ACX_EEPROM_DATA,
IO_ACX_EEPROM_CFG,
IO_ACX_PHY_ADDR,
IO_ACX_PHY_DATA,
IO_ACX_PHY_CTL,
IO_ACX_GPIO_OE,
IO_ACX_GPIO_OUT,
IO_ACX_CMD_MAILBOX_OFFS,
IO_ACX_INFO_MAILBOX_OFFS,
IO_ACX_EEPROM_INFORMATION,
IO_ACX_EE_START,
IO_ACX_SOR_CFG,
IO_ACX_ECPU_CTRL
};
/* ***** ABSOLUTELY ALWAYS KEEP OFFSETS IN SYNC WITH THE INITIALIZATION
** OF THE I/O ARRAYS!!!! (grep for '^IO_ACX') ***** */
/* Values for IO_ACX_INT_TRIG register: */
/* inform hw that rxdesc in queue needs processing */
#define INT_TRIG_RXPRC 0x08
/* inform hw that txdesc in queue needs processing */
#define INT_TRIG_TXPRC 0x04
/* ack that we received info from info mailbox */
#define INT_TRIG_INFOACK 0x02
/* inform hw that we have filled command mailbox */
#define INT_TRIG_CMD 0x01
struct txhostdesc {
acx_ptr data_phy; /* 0x00 [u8 *] */
u16 data_offset; /* 0x04 */
u16 reserved; /* 0x06 */
u16 Ctl_16; /* 16bit value, endianness!! */
u16 length; /* 0x0a */
acx_ptr desc_phy_next; /* 0x0c [txhostdesc *] */
acx_ptr pNext; /* 0x10 [txhostdesc *] */
u32 Status; /* 0x14, unused on Tx */
/* From here on you can use this area as you want (variable length, too!) */
u8 *data;
} ACX_PACKED;
struct rxhostdesc {
acx_ptr data_phy; /* 0x00 [rxbuffer_t *] */
u16 data_offset; /* 0x04 */
u16 reserved; /* 0x06 */
u16 Ctl_16; /* 0x08; 16bit value, endianness!! */
u16 length; /* 0x0a */
acx_ptr desc_phy_next; /* 0x0c [rxhostdesc_t *] */
acx_ptr pNext; /* 0x10 [rxhostdesc_t *] */
u32 Status; /* 0x14 */
/* From here on you can use this area as you want (variable length, too!) */
rxbuffer_t *data;
} ACX_PACKED;
#endif /* ACX_PCI */
/***********************************************************************
** USB structures and constants
*/
#ifdef ACX_USB
/* Used for usb_txbuffer.desc field */
#define USB_TXBUF_TXDESC 0xA
/* Size of header (everything up to data[]) */
#define USB_TXBUF_HDRSIZE 14
typedef struct usb_txbuffer {
u16 desc;
u16 mpdu_len;
u8 queue_index;
u8 rate;
u32 hostdata;
u8 ctrl1;
u8 ctrl2;
u16 data_len;
/* wlan packet content is placed here: */
u8 data[WLAN_A4FR_MAXLEN_WEP_FCS];
} ACX_PACKED usb_txbuffer_t;
/* USB returns either rx packets (see rxbuffer) or
** these "tx status" structs: */
typedef struct usb_txstatus {
u16 mac_cnt_rcvd; /* only 12 bits are len! (0xfff) */
u8 queue_index;
u8 mac_status; /* seen 0x20 on tx failure */
u32 hostdata;
u8 rate;
u8 ack_failures;
u8 rts_failures;
u8 rts_ok;
} ACX_PACKED usb_txstatus_t;
typedef struct usb_tx {
unsigned busy:1;
struct urb *urb;
acx_device_t *adev;
/* actual USB bulk output data block is here: */
usb_txbuffer_t bulkout;
} usb_tx_t;
struct usb_rx_plain {
unsigned busy:1;
struct urb *urb;
acx_device_t *adev;
rxbuffer_t bulkin;
};
typedef struct usb_rx {
unsigned busy:1;
struct urb *urb;
acx_device_t *adev;
rxbuffer_t bulkin;
/* Make entire structure 4k. Report if it breaks something. */
u8 padding[4*1024 - sizeof(struct usb_rx_plain)];
} usb_rx_t;
#endif /* ACX_USB */
/* Config Option structs */
typedef struct co_antennas {
u8 type;
u8 len;
u8 list[2];
} ACX_PACKED co_antennas_t;
typedef struct co_powerlevels {
u8 type;
u8 len;
u16 list[8];
} ACX_PACKED co_powerlevels_t;
typedef struct co_datarates {
u8 type;
u8 len;
u8 list[8];
} ACX_PACKED co_datarates_t;
typedef struct co_domains {
u8 type;
u8 len;
u8 list[6];
} ACX_PACKED co_domains_t;
typedef struct co_product_id {
u8 type;
u8 len;
u8 list[128];
} ACX_PACKED co_product_id_t;
typedef struct co_manuf_id {
u8 type;
u8 len;
u8 list[128];
} ACX_PACKED co_manuf_t;
typedef struct co_fixed {
char NVSv[8];
/* u16 NVS_vendor_offs; ACX111-only */
/* u16 unknown; ACX111-only */
u8 MAC[6]; /* ACX100-only */
u16 probe_delay; /* ACX100-only */
u32 eof_memory;
u8 dot11CCAModes;
u8 dot11Diversity;
u8 dot11ShortPreambleOption;
u8 dot11PBCCOption;
u8 dot11ChannelAgility;
u8 dot11PhyType; /* FIXME: does 802.11 call it "dot11PHYType"? */
u8 dot11TempType;
u8 table_count;
} ACX_PACKED co_fixed_t;
typedef struct acx111_ie_configoption {
u16 type;
u16 len;
/* Do not access below members directly, they are in fact variable length */
co_fixed_t fixed;
co_antennas_t antennas;
co_powerlevels_t power_levels;
co_datarates_t data_rates;
co_domains_t domains;
co_product_id_t product_id;
co_manuf_t manufacturer;
u8 _padding[4];
} ACX_PACKED acx111_ie_configoption_t;
/***********************************************************************
** Main acx per-device data structure
*/
#define ACX_STATE_FW_LOADED 0x01
#define ACX_STATE_IFACE_UP 0x02
/* MAC mode (BSS type) defines
* Note that they shouldn't be redefined, since they are also used
* during communication with firmware */
#define ACX_MODE_0_ADHOC 0
#define ACX_MODE_1_UNUSED 1
#define ACX_MODE_2_STA 2
#define ACX_MODE_3_AP 3
/* These are our own inventions. Sending these to firmware
** makes it stop emitting beacons, which is exactly what we want
** for these modes */
#define ACX_MODE_MONITOR 0xfe
#define ACX_MODE_OFF 0xff
/* 'Submode': identifies exact status of ADHOC/STA host */
#define ACX_STATUS_0_STOPPED 0
#define ACX_STATUS_1_SCANNING 1
#define ACX_STATUS_2_WAIT_AUTH 2
#define ACX_STATUS_3_AUTHENTICATED 3
#define ACX_STATUS_4_ASSOCIATED 4
/* FIXME: this should be named something like struct acx_priv (typedef'd to
* acx_priv_t) */
/* non-firmware struct, no packing necessary */
struct acx_device {
/* most frequent accesses first (dereferencing and cache line!) */
/*** Locking ***/
/* FIXME: try to convert semaphore to more efficient mutex according
to Ingo Molnar's docs (but not before driver is in mainline or
pre-mutex Linux 2.6.10 is very outdated). */
struct semaphore sem;
spinlock_t lock;
#if defined(PARANOID_LOCKING) /* Lock debugging */
const char *last_sem;
const char *last_lock;
unsigned long sem_time;
unsigned long lock_time;
#endif
/*** Linux network device ***/
struct net_device *ndev; /* pointer to linux netdevice */
/*** Device statistics ***/
struct net_device_stats stats; /* net device statistics */
#ifdef WIRELESS_EXT
struct iw_statistics wstats; /* wireless statistics */
#endif
/*** Power managment ***/
struct pm_dev *pm; /* PM crap */
/*** Management timer ***/
struct timer_list mgmt_timer;
/*** Hardware identification ***/
const char *chip_name;
u8 dev_type;
u8 chip_type;
u8 form_factor;
u8 radio_type;
u8 eeprom_version;
/*** Config retrieved from EEPROM ***/
char cfgopt_NVSv[8];
u16 cfgopt_NVS_vendor_offs;
u8 cfgopt_MAC[6];
u16 cfgopt_probe_delay;
u32 cfgopt_eof_memory;
u8 cfgopt_dot11CCAModes;
u8 cfgopt_dot11Diversity;
u8 cfgopt_dot11ShortPreambleOption;
u8 cfgopt_dot11PBCCOption;
u8 cfgopt_dot11ChannelAgility;
u8 cfgopt_dot11PhyType;
u8 cfgopt_dot11TempType;
co_antennas_t cfgopt_antennas;
co_powerlevels_t cfgopt_power_levels;
co_datarates_t cfgopt_data_rates;
co_domains_t cfgopt_domains;
co_product_id_t cfgopt_product_id;
co_manuf_t cfgopt_manufacturer;
/*** Firmware identification ***/
char firmware_version[FW_ID_SIZE+1];
u32 firmware_numver;
u32 firmware_id;
const u16 *ie_len;
const u16 *ie_len_dot11;
/*** Device state ***/
u16 dev_state_mask;
u8 led_power; /* power LED status */
u32 get_mask; /* mask of settings to fetch from the card */
u32 set_mask; /* mask of settings to write to the card */
/* Barely used in USB case */
u16 irq_status;
u8 after_interrupt_jobs; /* mini job list for doing actions after an interrupt occurred */
WORK_STRUCT after_interrupt_task; /* our task for after interrupt actions */
/*** scanning ***/
u16 scan_count; /* number of times to do channel scan */
u8 scan_mode; /* 0 == active, 1 == passive, 2 == background */
u8 scan_rate;
u16 scan_duration;
u16 scan_probe_delay;
#if WIRELESS_EXT > 15
struct iw_spy_data spy_data; /* FIXME: needs to be implemented! */
#endif
/*** Wireless network settings ***/
/* copy of the device address (ifconfig hw ether) that we actually use
** for 802.11; copied over from the network device's MAC address
** (ifconfig) when it makes sense only */
u8 dev_addr[MAX_ADDR_LEN];
u8 bssid[ETH_ALEN]; /* the BSSID after having joined */
u8 ap[ETH_ALEN]; /* The AP we want, FF:FF:FF:FF:FF:FF is any */
u16 aid; /* The Association ID sent from the AP / last used AID if we're an AP */
u16 mode; /* mode from iwconfig */
int monitor_type; /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_PRISM */
u16 status; /* 802.11 association status */
u8 essid_active; /* specific ESSID active, or select any? */
u8 essid_len; /* to avoid dozens of strlen() */
/* INCLUDES \0 termination for easy printf - but many places
** simply want the string data memcpy'd plus a length indicator!
** Keep that in mind... */
char essid[IW_ESSID_MAX_SIZE+1];
/* essid we are going to use for association, in case of "essid 'any'"
** and in case of hidden ESSID (use configured ESSID then) */
char essid_for_assoc[IW_ESSID_MAX_SIZE+1];
char nick[IW_ESSID_MAX_SIZE+1]; /* see essid! */
u8 channel;
u8 reg_dom_id; /* reg domain setting */
u16 reg_dom_chanmask;
u16 auth_or_assoc_retries;
u16 scan_retries;
unsigned long scan_start; /* YES, jiffies is defined as "unsigned long" */
/* stations known to us (if we're an ap) */
client_t sta_list[32]; /* tab is larger than list, so that */
client_t *sta_hash_tab[64]; /* hash collisions are not likely */
client_t *ap_client; /* this one is our AP (STA mode only) */
int dup_count;
int nondup_count;
unsigned long dup_msg_expiry;
u16 last_seq_ctrl; /* duplicate packet detection */
/* 802.11 power save mode */
u8 ps_wakeup_cfg;
u8 ps_listen_interval;
u8 ps_options;
u8 ps_hangover_period;
u32 ps_enhanced_transition_time;
u32 ps_beacon_rx_time;
/*** PHY settings ***/
u8 fallback_threshold;
u8 stepup_threshold;
u16 rate_basic;
u16 rate_oper;
u16 rate_bcast;
u16 rate_bcast100;
u8 rate_auto; /* false if "iwconfig rate N" (WITHOUT 'auto'!) */
u8 preamble_mode; /* 0 == Long Preamble, 1 == Short, 2 == Auto */
u8 preamble_cur;
u8 tx_disabled;
u8 tx_level_dbm;
/* u8 tx_level_val; */
/* u8 tx_level_auto; whether to do automatic power adjustment */
unsigned long recalib_time_last_success;
unsigned long recalib_time_last_attempt;
int recalib_failure_count;
int recalib_msg_ratelimit;
int retry_errors_msg_ratelimit;
unsigned long brange_time_last_state_change; /* time the power LED was last changed */
u8 brange_last_state; /* last state of the LED */
u8 brange_max_quality; /* maximum quality that equates to full speed */
u8 sensitivity;
u8 antenna; /* antenna settings */
u8 ed_threshold; /* energy detect threshold */
u8 cca; /* clear channel assessment */
u16 rts_threshold;
u16 frag_threshold;
u32 short_retry;
u32 long_retry;
u16 msdu_lifetime;
u16 listen_interval; /* given in units of beacon interval */
u32 beacon_interval;
u16 capabilities;
u8 rate_supported_len;
u8 rate_supported[13];
/*** Encryption settings (WEP) ***/
u32 auth_alg; /* used in transmit_authen1 */
u8 wep_enabled;
u8 wep_restricted;
u8 wep_current_index;
wep_key_t wep_keys[DOT11_MAX_DEFAULT_WEP_KEYS]; /* the default WEP keys */
key_struct_t wep_key_struct[10];
/*** Unknown ***/
u8 dtim_interval;
/*** Card Rx/Tx management ***/
u16 rx_config_1;
u16 rx_config_2;
u16 memblocksize;
unsigned int tx_free;
unsigned int tx_head; /* keep as close as possible to Tx stuff below (cache line) */
u16 phy_header_len;
/*************************************************************************
*** PCI/USB/... must be last or else hw agnostic code breaks horribly ***
*************************************************************************/
/* hack to let common code compile. FIXME */
dma_addr_t rxhostdesc_startphy;
/*** PCI stuff ***/
#ifdef ACX_PCI
/* pointers to tx buffers, tx host descriptors (in host memory)
** and tx descs in device memory */
unsigned int tx_tail;
u8 *txbuf_start;
txhostdesc_t *txhostdesc_start;
txdesc_t *txdesc_start; /* points to PCI-mapped memory */
dma_addr_t txbuf_startphy;
dma_addr_t txhostdesc_startphy;
/* sizes of above host memory areas */
unsigned int txbuf_area_size;
unsigned int txhostdesc_area_size;
unsigned int txdesc_size; /* size of txdesc; ACX111 = ACX100 + 4 */
client_t *txc[TX_CNT];
u16 txr[TX_CNT];
/* same for rx */
unsigned int rx_tail;
rxbuffer_t *rxbuf_start;
rxhostdesc_t *rxhostdesc_start;
rxdesc_t *rxdesc_start;
/* physical addresses of above host memory areas */
dma_addr_t rxbuf_startphy;
/* dma_addr_t rxhostdesc_startphy; */
unsigned int rxbuf_area_size;
unsigned int rxhostdesc_area_size;
u8 need_radio_fw;
u8 irqs_active; /* whether irq sending is activated */
const u16 *io; /* points to ACX100 or ACX111 PCI I/O register address set */
struct pci_dev *pdev;
unsigned long membase;
unsigned long membase2;
void __iomem *iobase;
void __iomem *iobase2;
/* command interface */
u8 __iomem *cmd_area;
u8 __iomem *info_area;
u16 irq_mask; /* interrupt types to mask out (not wanted) with many IRQs activated */
u16 irq_mask_off; /* interrupt types to mask out (not wanted) with IRQs off */
unsigned int irq_loops_this_jiffy;
unsigned long irq_last_jiffies;
#endif
/*** USB stuff ***/
#ifdef ACX_USB
struct usb_device *usbdev;
rxbuffer_t rxtruncbuf;
usb_tx_t *usb_tx;
usb_rx_t *usb_rx;
int bulkinep; /* bulk-in endpoint */
int bulkoutep; /* bulk-out endpoint */
int rxtruncsize;
#endif
};
static inline acx_device_t*
ndev2adev(struct net_device *ndev)
{
return netdev_priv(ndev);
}
/* For use with ACX1xx_IE_RXCONFIG */
/* bit description
* 13 include additional header (length etc.) *required*
* struct is defined in 'struct rxbuffer'
* is this bit acx100 only? does acx111 always put the header,
* and bit setting is irrelevant? --vda
* 10 receive frames only with SSID used in last join cmd
* 9 discard broadcast
* 8 receive packets for multicast address 1
* 7 receive packets for multicast address 0
* 6 discard all multicast packets
* 5 discard frames from foreign BSSID
* 4 discard frames with foreign destination MAC address
* 3 promiscuous mode (receive ALL frames, disable filter)
* 2 include FCS
* 1 include phy header
* 0 ???
*/
#define RX_CFG1_INCLUDE_RXBUF_HDR 0x2000 /* ACX100 only */
#define RX_CFG1_FILTER_SSID 0x0400
#define RX_CFG1_FILTER_BCAST 0x0200
#define RX_CFG1_RCV_MC_ADDR1 0x0100
#define RX_CFG1_RCV_MC_ADDR0 0x0080
#define RX_CFG1_FILTER_ALL_MULTI 0x0040
#define RX_CFG1_FILTER_BSSID 0x0020
#define RX_CFG1_FILTER_MAC 0x0010
#define RX_CFG1_RCV_PROMISCUOUS 0x0008
#define RX_CFG1_INCLUDE_FCS 0x0004
#define RX_CFG1_INCLUDE_PHY_HDR (WANT_PHY_HDR ? 0x0002 : 0)
/* bit description
* 11 receive association requests etc.
* 10 receive authentication frames
* 9 receive beacon frames
* 8 receive contention free packets
* 7 receive control frames
* 6 receive data frames
* 5 receive broken frames
* 4 receive management frames
* 3 receive probe requests
* 2 receive probe responses
* 1 receive RTS/CTS/ACK frames
* 0 receive other
*/
#define RX_CFG2_RCV_ASSOC_REQ 0x0800
#define RX_CFG2_RCV_AUTH_FRAMES 0x0400
#define RX_CFG2_RCV_BEACON_FRAMES 0x0200
#define RX_CFG2_RCV_CONTENTION_FREE 0x0100
#define RX_CFG2_RCV_CTRL_FRAMES 0x0080
#define RX_CFG2_RCV_DATA_FRAMES 0x0040
#define RX_CFG2_RCV_BROKEN_FRAMES 0x0020
#define RX_CFG2_RCV_MGMT_FRAMES 0x0010
#define RX_CFG2_RCV_PROBE_REQ 0x0008
#define RX_CFG2_RCV_PROBE_RESP 0x0004
#define RX_CFG2_RCV_ACK_FRAMES 0x0002
#define RX_CFG2_RCV_OTHER 0x0001
/* For use with ACX1xx_IE_FEATURE_CONFIG */
#define FEATURE1_80MHZ_CLOCK 0x00000040L
#define FEATURE1_4X 0x00000020L
#define FEATURE1_LOW_RX 0x00000008L
#define FEATURE1_EXTRA_LOW_RX 0x00000001L
#define FEATURE2_SNIFFER 0x00000080L
#define FEATURE2_NO_TXCRYPT 0x00000001L
/*-- get and set mask values --*/
#define GETSET_LED_POWER 0x00000001L
#define GETSET_STATION_ID 0x00000002L
#define SET_TEMPLATES 0x00000004L
#define SET_STA_LIST 0x00000008L
#define GETSET_TX 0x00000010L
#define GETSET_RX 0x00000020L
#define SET_RXCONFIG 0x00000040L
#define GETSET_ANTENNA 0x00000080L
#define GETSET_SENSITIVITY 0x00000100L
#define GETSET_TXPOWER 0x00000200L
#define GETSET_ED_THRESH 0x00000400L
#define GETSET_CCA 0x00000800L
#define GETSET_POWER_80211 0x00001000L
#define GETSET_RETRY 0x00002000L
#define GETSET_REG_DOMAIN 0x00004000L
#define GETSET_CHANNEL 0x00008000L
/* Used when ESSID changes etc and we need to scan for AP anew */
#define GETSET_RESCAN 0x00010000L
#define GETSET_MODE 0x00020000L
#define GETSET_WEP 0x00040000L
#define SET_WEP_OPTIONS 0x00080000L
#define SET_MSDU_LIFETIME 0x00100000L
#define SET_RATE_FALLBACK 0x00200000L
/* keep in sync with the above */
#define GETSET_ALL (0 \
/* GETSET_LED_POWER */ | 0x00000001L \
/* GETSET_STATION_ID */ | 0x00000002L \
/* SET_TEMPLATES */ | 0x00000004L \
/* SET_STA_LIST */ | 0x00000008L \
/* GETSET_TX */ | 0x00000010L \
/* GETSET_RX */ | 0x00000020L \
/* SET_RXCONFIG */ | 0x00000040L \
/* GETSET_ANTENNA */ | 0x00000080L \
/* GETSET_SENSITIVITY */| 0x00000100L \
/* GETSET_TXPOWER */ | 0x00000200L \
/* GETSET_ED_THRESH */ | 0x00000400L \
/* GETSET_CCA */ | 0x00000800L \
/* GETSET_POWER_80211 */| 0x00001000L \
/* GETSET_RETRY */ | 0x00002000L \
/* GETSET_REG_DOMAIN */ | 0x00004000L \
/* GETSET_CHANNEL */ | 0x00008000L \
/* GETSET_RESCAN */ | 0x00010000L \
/* GETSET_MODE */ | 0x00020000L \
/* GETSET_WEP */ | 0x00040000L \
/* SET_WEP_OPTIONS */ | 0x00080000L \
/* SET_MSDU_LIFETIME */ | 0x00100000L \
/* SET_RATE_FALLBACK */ | 0x00200000L \
)
/***********************************************************************
** Firmware loading
*/
#include <linux/firmware.h> /* request_firmware() */
#include <linux/pci.h> /* struct pci_device */
/***********************************************************************
*/
typedef struct acx100_ie_memblocksize {
u16 type;
u16 len;
u16 size;
} ACX_PACKED acx100_ie_memblocksize_t;
typedef struct acx100_ie_queueconfig {
u16 type;
u16 len;
u32 AreaSize;
u32 RxQueueStart;
u8 QueueOptions;
u8 NumTxQueues;
u8 NumRxDesc; /* for USB only */
u8 pad1;
u32 QueueEnd;
u32 HostQueueEnd; /* QueueEnd2 */
u32 TxQueueStart;
u8 TxQueuePri;
u8 NumTxDesc;
u16 pad2;
} ACX_PACKED acx100_ie_queueconfig_t;
typedef struct acx111_ie_queueconfig {
u16 type;
u16 len;
u32 tx_memory_block_address;
u32 rx_memory_block_address;
u32 rx1_queue_address;
u32 reserved1;
u32 tx1_queue_address;
u8 tx1_attributes;
u16 reserved2;
u8 reserved3;
} ACX_PACKED acx111_ie_queueconfig_t;
typedef struct acx100_ie_memconfigoption {
u16 type;
u16 len;
u32 DMA_config;
acx_ptr pRxHostDesc;
u32 rx_mem;
u32 tx_mem;
u16 RxBlockNum;
u16 TxBlockNum;
} ACX_PACKED acx100_ie_memconfigoption_t;
typedef struct acx111_ie_memoryconfig {
u16 type;
u16 len;
u16 no_of_stations;
u16 memory_block_size;
u8 tx_rx_memory_block_allocation;
u8 count_rx_queues;
u8 count_tx_queues;
u8 options;
u8 fragmentation;
u16 reserved1;
u8 reserved2;
/* start of rx1 block */
u8 rx_queue1_count_descs;
u8 rx_queue1_reserved1;
u8 rx_queue1_type; /* must be set to 7 */
u8 rx_queue1_prio; /* must be set to 0 */
acx_ptr rx_queue1_host_rx_start;
/* end of rx1 block */
/* start of tx1 block */
u8 tx_queue1_count_descs;
u8 tx_queue1_reserved1;
u8 tx_queue1_reserved2;
u8 tx_queue1_attributes;
/* end of tx1 block */
} ACX_PACKED acx111_ie_memoryconfig_t;
typedef struct acx_ie_memmap {
u16 type;
u16 len;
u32 CodeStart;
u32 CodeEnd;
u32 WEPCacheStart;
u32 WEPCacheEnd;
u32 PacketTemplateStart;
u32 PacketTemplateEnd;
u32 QueueStart;
u32 QueueEnd;
u32 PoolStart;
u32 PoolEnd;
} ACX_PACKED acx_ie_memmap_t;
typedef struct acx111_ie_feature_config {
u16 type;
u16 len;
u32 feature_options;
u32 data_flow_options;
} ACX_PACKED acx111_ie_feature_config_t;
typedef struct acx111_ie_tx_level {
u16 type;
u16 len;
u8 level;
} ACX_PACKED acx111_ie_tx_level_t;
#define PS_CFG_ENABLE 0x80
#define PS_CFG_PENDING 0x40 /* status flag when entering PS */
#define PS_CFG_WAKEUP_MODE_MASK 0x07
#define PS_CFG_WAKEUP_BY_HOST 0x03
#define PS_CFG_WAKEUP_EACH_ITVL 0x02
#define PS_CFG_WAKEUP_ON_DTIM 0x01
#define PS_CFG_WAKEUP_ALL_BEAC 0x00
/* Enhanced PS mode: sleep until Rx Beacon w/ the STA's AID bit set
** in the TIM; newer firmwares only(?) */
#define PS_OPT_ENA_ENHANCED_PS 0x04
#define PS_OPT_TX_PSPOLL 0x02 /* send PSPoll frame to fetch waiting frames from AP (on frame with matching AID) */
#define PS_OPT_STILL_RCV_BCASTS 0x01
typedef struct acx100_ie_powersave {
u16 type;
u16 len;
u8 wakeup_cfg;
u8 listen_interval; /* for EACH_ITVL: wake up every "beacon units" interval */
u8 options;
u8 hangover_period; /* remaining wake time after Tx MPDU w/ PS bit, in values of 1/1024 seconds */
u16 enhanced_ps_transition_time; /* rem. wake time for Enh. PS */
} ACX_PACKED acx100_ie_powersave_t;
typedef struct acx111_ie_powersave {
u16 type;
u16 len;
u8 wakeup_cfg;
u8 listen_interval; /* for EACH_ITVL: wake up every "beacon units" interval */
u8 options;
u8 hangover_period; /* remaining wake time after Tx MPDU w/ PS bit, in values of 1/1024 seconds */
u32 beacon_rx_time;
u32 enhanced_ps_transition_time; /* rem. wake time for Enh. PS */
} ACX_PACKED acx111_ie_powersave_t;
/***********************************************************************
** Commands and template structures
*/
/*
** SCAN command structure
**
** even though acx100 scan rates match RATE100 constants,
** acx111 ones do not match! Therefore we do not use RATE100 #defines */
#define ACX_SCAN_RATE_1 10
#define ACX_SCAN_RATE_2 20
#define ACX_SCAN_RATE_5 55
#define ACX_SCAN_RATE_11 110
#define ACX_SCAN_RATE_22 220
#define ACX_SCAN_RATE_PBCC 0x80 /* OR with this if needed */
#define ACX_SCAN_OPT_ACTIVE 0x00 /* a bit mask */
#define ACX_SCAN_OPT_PASSIVE 0x01
/* Background scan: we go into Power Save mode (by transmitting
** NULL data frame to AP with the power mgmt bit set), do the scan,
** and then exit Power Save mode. A plus is that AP buffers frames
** for us while we do background scan. Thus we avoid frame losses.
** Background scan can be active or passive, just like normal one */
#define ACX_SCAN_OPT_BACKGROUND 0x02
typedef struct acx100_scan {
u16 count; /* number of scans to do, 0xffff == continuous */
u16 start_chan;
u16 flags; /* channel list mask; 0x8000 == all channels? */
u8 max_rate; /* max. probe rate */
u8 options; /* bit mask, see defines above */
u16 chan_duration;
u16 max_probe_delay;
} ACX_PACKED acx100_scan_t; /* length 0xc */
#define ACX111_SCAN_RATE_6 0x0B
#define ACX111_SCAN_RATE_9 0x0F
#define ACX111_SCAN_RATE_12 0x0A
#define ACX111_SCAN_RATE_18 0x0E
#define ACX111_SCAN_RATE_24 0x09
#define ACX111_SCAN_RATE_36 0x0D
#define ACX111_SCAN_RATE_48 0x08
#define ACX111_SCAN_RATE_54 0x0C
#define ACX111_SCAN_OPT_5GHZ 0x04 /* else 2.4GHZ */
#define ACX111_SCAN_MOD_SHORTPRE 0x01 /* you can combine SHORTPRE and PBCC */
#define ACX111_SCAN_MOD_PBCC 0x80
#define ACX111_SCAN_MOD_OFDM 0x40
typedef struct acx111_scan {
u16 count; /* number of scans to do */
u8 channel_list_select; /* 0: scan all channels, 1: from chan_list only */
u16 reserved1;
u8 reserved2;
u8 rate; /* rate for probe requests (if active scan) */
u8 options; /* bit mask, see defines above */
u16 chan_duration; /* min time to wait for reply on one channel (in TU) */
/* (active scan only) (802.11 section 11.1.3.2.2) */
u16 max_probe_delay; /* max time to wait for reply on one channel (active scan) */
/* time to listen on a channel (passive scan) */
u8 modulation;
u8 channel_list[26]; /* bits 7:0 first byte: channels 8:1 */
/* bits 7:0 second byte: channels 16:9 */
/* 26 bytes is enough to cover 802.11a */
} ACX_PACKED acx111_scan_t;
/*
** Radio calibration command structure
*/
typedef struct acx111_cmd_radiocalib {
/* 0x80000000 == automatic calibration by firmware, according to interval;
* bits 0..3: select calibration methods to go through:
* calib based on DC, AfeDC, Tx mismatch, Tx equilization */
u32 methods;
u32 interval;
} ACX_PACKED acx111_cmd_radiocalib_t;
/*
** Packet template structures
**
** Packet templates store contents of Beacon, Probe response, Probe request,
** Null data frame, and TIM data frame. Firmware automatically transmits
** contents of template at appropriate time:
** - Beacon: when configured as AP or Ad-hoc
** - Probe response: when configured as AP or Ad-hoc, whenever
** a Probe request frame is received
** - Probe request: when host issues SCAN command (active)
** - Null data frame: when entering 802.11 power save mode
** - TIM data: at the end of Beacon frames (if no TIM template
** is configured, then transmits default TIM)
** NB:
** - size field must be set to size of actual template
** (NOT sizeof(struct) - templates are variable in length),
** size field is not itself counted.
** - members flagged with an asterisk must be initialized with host,
** rest must be zero filled.
** - variable length fields shown only in comments */
typedef struct acx_template_tim {
u16 size;
u8 tim_eid; /* 00 1 TIM IE ID * */
u8 len; /* 01 1 Length * */
u8 dtim_cnt; /* 02 1 DTIM Count */
u8 dtim_period; /* 03 1 DTIM Period */
u8 bitmap_ctrl; /* 04 1 Bitmap Control * (except bit0) */
/* 05 n Partial Virtual Bitmap * */
u8 variable[0x100 - 1-1-1-1-1];
} ACX_PACKED acx_template_tim_t;
typedef struct acx_template_probereq {
u16 size;
u16 fc; /* 00 2 fc * */
u16 dur; /* 02 2 Duration */
u8 da[6]; /* 04 6 Destination Address * */
u8 sa[6]; /* 0A 6 Source Address * */
u8 bssid[6]; /* 10 6 BSSID * */
u16 seq; /* 16 2 Sequence Control */
/* 18 n SSID * */
/* nn n Supported Rates * */
u8 variable[0x44 - 2-2-6-6-6-2];
} ACX_PACKED acx_template_probereq_t;
typedef struct acx_template_proberesp {
u16 size;
u16 fc; /* 00 2 fc * (bits [15:12] and [10:8] per 802.11 section 7.1.3.1) */
u16 dur; /* 02 2 Duration */
u8 da[6]; /* 04 6 Destination Address */
u8 sa[6]; /* 0A 6 Source Address */
u8 bssid[6]; /* 10 6 BSSID */
u16 seq; /* 16 2 Sequence Control */
u8 timestamp[8];/* 18 8 Timestamp */
u16 beacon_interval; /* 20 2 Beacon Interval * */
u16 cap; /* 22 2 Capability Information * */
/* 24 n SSID * */
/* nn n Supported Rates * */
/* nn 1 DS Parameter Set * */
u8 variable[0x54 - 2-2-6-6-6-2-8-2-2];
} ACX_PACKED acx_template_proberesp_t;
#define acx_template_beacon_t acx_template_proberesp_t
#define acx_template_beacon acx_template_proberesp
typedef struct acx_template_nullframe {
u16 size;
struct wlan_hdr_a3 hdr;
} ACX_PACKED acx_template_nullframe_t;
/*
** JOIN command structure
**
** as opposed to acx100, acx111 dtim interval is AFTER rates_basic111.
** NOTE: took me about an hour to get !@#$%^& packing right --> struct packing is eeeeevil... */
typedef struct acx_joinbss {
u8 bssid[ETH_ALEN];
u16 beacon_interval;
union {
struct {
u8 dtim_interval;
u8 rates_basic;
u8 rates_supported;
} ACX_PACKED acx100;
struct {
u16 rates_basic;
u8 dtim_interval;
} ACX_PACKED acx111;
} ACX_PACKED u;
u8 genfrm_txrate; /* generated frame (bcn, proberesp, RTS, PSpoll) tx rate */
u8 genfrm_mod_pre; /* generated frame modulation/preamble:
** bit7: PBCC, bit6: OFDM (else CCK/DQPSK/DBPSK)
** bit5: short pre */
u8 macmode; /* BSS Type, must be one of ACX_MODE_xxx */
u8 channel;
u8 essid_len;
char essid[IW_ESSID_MAX_SIZE];
} ACX_PACKED acx_joinbss_t;
#define JOINBSS_RATES_1 0x01
#define JOINBSS_RATES_2 0x02
#define JOINBSS_RATES_5 0x04
#define JOINBSS_RATES_11 0x08
#define JOINBSS_RATES_22 0x10
/* Looks like missing bits are used to indicate 11g rates!
** (it follows from the fact that constants below match 1:1 to RATE111_nn)
** This was actually seen! Look at that Assoc Request sent by acx111,
** it _does_ contain 11g rates in basic set:
01:30:20.070772 Beacon (xxx) [1.0* 2.0* 5.5* 11.0* 6.0* 9.0* 12.0* 18.0* 24.0* 36.0* 48.0* 54.0* Mbit] ESS CH: 1
01:30:20.074425 Authentication (Open System)-1: Succesful
01:30:20.076539 Authentication (Open System)-2:
01:30:20.076620 Acknowledgment
01:30:20.088546 Assoc Request (xxx) [1.0* 2.0* 5.5* 6.0* 9.0* 11.0* 12.0* 18.0* 24.0* 36.0* 48.0* 54.0* Mbit]
01:30:20.122413 Assoc Response AID(1) :: Succesful
01:30:20.122679 Acknowledgment
01:30:20.173204 Beacon (xxx) [1.0* 2.0* 5.5* 11.0* 6.0* 9.0* 12.0* 18.0* 24.0* 36.0* 48.0* 54.0* Mbit] ESS CH: 1
*/
#define JOINBSS_RATES_BASIC111_1 0x0001
#define JOINBSS_RATES_BASIC111_2 0x0002
#define JOINBSS_RATES_BASIC111_5 0x0004
#define JOINBSS_RATES_BASIC111_11 0x0020
#define JOINBSS_RATES_BASIC111_22 0x0100
/***********************************************************************
*/
typedef struct mem_read_write {
u16 addr;
u16 type; /* 0x0 int. RAM / 0xffff MAC reg. / 0x81 PHY RAM / 0x82 PHY reg.; or maybe it's actually 0x30 for MAC? Better verify it by writing and reading back and checking whether the value holds! */
u32 len;
u32 data;
} ACX_PACKED mem_read_write_t;
typedef struct firmware_image {
u32 chksum;
u32 size;
u8 data[1]; /* the byte array of the actual firmware... */
} ACX_PACKED firmware_image_t;
typedef struct acx_cmd_radioinit {
u32 offset;
u32 len;
} ACX_PACKED acx_cmd_radioinit_t;
typedef struct acx100_ie_wep_options {
u16 type;
u16 len;
u16 NumKeys; /* max # of keys */
u8 WEPOption; /* 0 == decrypt default key only, 1 == override decrypt */
u8 Pad; /* used only for acx111 */
} ACX_PACKED acx100_ie_wep_options_t;
typedef struct ie_dot11WEPDefaultKey {
u16 type;
u16 len;
u8 action;
u8 keySize;
u8 defaultKeyNum;
u8 key[29]; /* check this! was Key[19] */
} ACX_PACKED ie_dot11WEPDefaultKey_t;
typedef struct acx111WEPDefaultKey {
u8 MacAddr[ETH_ALEN];
u16 action; /* NOTE: this is a u16, NOT a u8!! */
u16 reserved;
u8 keySize;
u8 type;
u8 index;
u8 defaultKeyNum;
u8 counter[6];
u8 key[32]; /* up to 32 bytes (for TKIP!) */
} ACX_PACKED acx111WEPDefaultKey_t;
typedef struct ie_dot11WEPDefaultKeyID {
u16 type;
u16 len;
u8 KeyID;
} ACX_PACKED ie_dot11WEPDefaultKeyID_t;
typedef struct acx100_cmd_wep_mgmt {
u8 MacAddr[ETH_ALEN];
u16 Action;
u16 KeySize;
u8 Key[29]; /* 29*8 == 232bits == WEP256 */
} ACX_PACKED acx100_cmd_wep_mgmt_t;
typedef struct acx_ie_generic {
u16 type;
u16 len;
union {
/* Association ID IE: just a 16bit value: */
u16 aid;
/* generic member for quick implementation of commands */
u8 bytes[32];
} ACX_PACKED m;
} ACX_PACKED acx_ie_generic_t;
/***********************************************************************
*/
#define CHECK_SIZEOF(type,size) { \
extern void BUG_bad_size_for_##type(void); \
if (sizeof(type)!=(size)) BUG_bad_size_for_##type(); \
}
static inline void
acx_struct_size_check(void)
{
CHECK_SIZEOF(txdesc_t, 0x30);
CHECK_SIZEOF(acx100_ie_memconfigoption_t, 24);
CHECK_SIZEOF(acx100_ie_queueconfig_t, 0x20);
CHECK_SIZEOF(acx_joinbss_t, 0x30);
/* IEs need 4 bytes for (type,len) tuple */
CHECK_SIZEOF(acx111_ie_configoption_t, ACX111_IE_CONFIG_OPTIONS_LEN + 4);
}
/***********************************************************************
** Global data
*/
extern const u8 acx_bitpos2ratebyte[];
extern const u8 acx_bitpos2rate100[];
extern const u8 acx_reg_domain_ids[];
extern const char * const acx_reg_domain_strings[];
enum {
acx_reg_domain_ids_len = 8
};
extern const struct iw_handler_def acx_ioctl_handler_def;
|