aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/orinoco/main.c
diff options
context:
space:
mode:
authorDavid Kilroy <kilroyd@googlemail.com>2009-02-04 18:05:55 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-02-13 13:44:31 -0500
commit712a4342a0d89e855a03ba06fb11f7eb29456d45 (patch)
treee5b500f5e4e9f4b1e065009d7de2e19fba932ef5 /drivers/net/wireless/orinoco/main.c
parent5865d015cf85c619a51f8be93d44ec932bc90038 (diff)
orinoco: Move hardware functions into separate file
No functional change. Signed-off-by: David Kilroy <kilroyd@googlemail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/orinoco/main.c')
-rw-r--r--drivers/net/wireless/orinoco/main.c583
1 files changed, 1 insertions, 582 deletions
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index 3e20df7b6570..a340c7d75dd1 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -91,6 +91,7 @@
91 91
92#include "hermes_rid.h" 92#include "hermes_rid.h"
93#include "hermes_dld.h" 93#include "hermes_dld.h"
94#include "hw.h"
94#include "scan.h" 95#include "scan.h"
95#include "mic.h" 96#include "mic.h"
96#include "fw.h" 97#include "fw.h"
@@ -151,15 +152,11 @@ static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
151#define ORINOCO_MAX_MTU (IEEE80211_MAX_DATA_LEN - ENCAPS_OVERHEAD) 152#define ORINOCO_MAX_MTU (IEEE80211_MAX_DATA_LEN - ENCAPS_OVERHEAD)
152 153
153#define SYMBOL_MAX_VER_LEN (14) 154#define SYMBOL_MAX_VER_LEN (14)
154#define USER_BAP 0
155#define IRQ_BAP 1
156#define MAX_IRQLOOPS_PER_IRQ 10 155#define MAX_IRQLOOPS_PER_IRQ 10
157#define MAX_IRQLOOPS_PER_JIFFY (20000/HZ) /* Based on a guestimate of 156#define MAX_IRQLOOPS_PER_JIFFY (20000/HZ) /* Based on a guestimate of
158 * how many events the 157 * how many events the
159 * device could 158 * device could
160 * legitimately generate */ 159 * legitimately generate */
161#define SMALL_KEY_SIZE 5
162#define LARGE_KEY_SIZE 13
163#define TX_NICBUF_SIZE_BUG 1585 /* Bug in Symbol firmware */ 160#define TX_NICBUF_SIZE_BUG 1585 /* Bug in Symbol firmware */
164 161
165#define DUMMY_FID 0xFFFF 162#define DUMMY_FID 0xFFFF
@@ -179,31 +176,6 @@ static const struct iw_handler_def orinoco_handler_def;
179static const struct ethtool_ops orinoco_ethtool_ops; 176static const struct ethtool_ops orinoco_ethtool_ops;
180 177
181/********************************************************************/ 178/********************************************************************/
182/* Data tables */
183/********************************************************************/
184
185#define NUM_CHANNELS 14
186
187/* This tables gives the actual meanings of the bitrate IDs returned
188 * by the firmware. */
189static struct {
190 int bitrate; /* in 100s of kilobits */
191 int automatic;
192 u16 agere_txratectrl;
193 u16 intersil_txratectrl;
194} bitrate_table[] = {
195 {110, 1, 3, 15}, /* Entry 0 is the default */
196 {10, 0, 1, 1},
197 {10, 1, 1, 1},
198 {20, 0, 2, 2},
199 {20, 1, 6, 3},
200 {55, 0, 4, 4},
201 {55, 1, 7, 7},
202 {110, 0, 5, 8},
203};
204#define BITRATE_TABLE_SIZE ARRAY_SIZE(bitrate_table)
205
206/********************************************************************/
207/* Data types */ 179/* Data types */
208/********************************************************************/ 180/********************************************************************/
209 181
@@ -282,33 +254,6 @@ static inline void set_port_type(struct orinoco_private *priv)
282 } 254 }
283} 255}
284 256
285static int orinoco_get_bitratemode(int bitrate, int automatic)
286{
287 int ratemode = -1;
288 int i;
289
290 if ((bitrate != 10) && (bitrate != 20) &&
291 (bitrate != 55) && (bitrate != 110))
292 return ratemode;
293
294 for (i = 0; i < BITRATE_TABLE_SIZE; i++) {
295 if ((bitrate_table[i].bitrate == bitrate) &&
296 (bitrate_table[i].automatic == automatic)) {
297 ratemode = i;
298 break;
299 }
300 }
301 return ratemode;
302}
303
304static void orinoco_get_ratemode_cfg(int ratemode, int *bitrate, int *automatic)
305{
306 BUG_ON((ratemode < 0) || (ratemode >= BITRATE_TABLE_SIZE));
307
308 *bitrate = bitrate_table[ratemode].bitrate * 100000;
309 *automatic = bitrate_table[ratemode].automatic;
310}
311
312static inline u8 *orinoco_get_ie(u8 *data, size_t len, 257static inline u8 *orinoco_get_ie(u8 *data, size_t len,
313 enum ieee80211_eid eid) 258 enum ieee80211_eid eid)
314{ 259{
@@ -933,25 +878,6 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
933 stats->rx_dropped++; 878 stats->rx_dropped++;
934} 879}
935 880
936/* Get tsc from the firmware */
937static int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key,
938 u8 *tsc)
939{
940 hermes_t *hw = &priv->hw;
941 int err = 0;
942 u8 tsc_arr[4][IW_ENCODE_SEQ_MAX_SIZE];
943
944 if ((key < 0) || (key > 4))
945 return -EINVAL;
946
947 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_TKIP_IV,
948 sizeof(tsc_arr), NULL, &tsc_arr);
949 if (!err)
950 memcpy(tsc, &tsc_arr[key][0], sizeof(tsc_arr[0]));
951
952 return err;
953}
954
955static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) 881static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
956{ 882{
957 struct orinoco_private *priv = netdev_priv(dev); 883 struct orinoco_private *priv = netdev_priv(dev);
@@ -1790,334 +1716,6 @@ int orinoco_reinit_firmware(struct net_device *dev)
1790} 1716}
1791EXPORT_SYMBOL(orinoco_reinit_firmware); 1717EXPORT_SYMBOL(orinoco_reinit_firmware);
1792 1718
1793static int __orinoco_hw_set_bitrate(struct orinoco_private *priv)
1794{
1795 hermes_t *hw = &priv->hw;
1796 int ratemode = priv->bitratemode;
1797 int err = 0;
1798
1799 if (ratemode >= BITRATE_TABLE_SIZE) {
1800 printk(KERN_ERR "%s: BUG: Invalid bitrate mode %d\n",
1801 priv->ndev->name, ratemode);
1802 return -EINVAL;
1803 }
1804
1805 switch (priv->firmware_type) {
1806 case FIRMWARE_TYPE_AGERE:
1807 err = hermes_write_wordrec(hw, USER_BAP,
1808 HERMES_RID_CNFTXRATECONTROL,
1809 bitrate_table[ratemode].agere_txratectrl);
1810 break;
1811 case FIRMWARE_TYPE_INTERSIL:
1812 case FIRMWARE_TYPE_SYMBOL:
1813 err = hermes_write_wordrec(hw, USER_BAP,
1814 HERMES_RID_CNFTXRATECONTROL,
1815 bitrate_table[ratemode].intersil_txratectrl);
1816 break;
1817 default:
1818 BUG();
1819 }
1820
1821 return err;
1822}
1823
1824static int orinoco_hw_get_act_bitrate(struct orinoco_private *priv,
1825 int *bitrate)
1826{
1827 hermes_t *hw = &priv->hw;
1828 int i;
1829 int err = 0;
1830 u16 val;
1831
1832 err = hermes_read_wordrec(hw, USER_BAP,
1833 HERMES_RID_CURRENTTXRATE, &val);
1834 if (err)
1835 return err;
1836
1837 switch (priv->firmware_type) {
1838 case FIRMWARE_TYPE_AGERE: /* Lucent style rate */
1839 /* Note : in Lucent firmware, the return value of
1840 * HERMES_RID_CURRENTTXRATE is the bitrate in Mb/s,
1841 * and therefore is totally different from the
1842 * encoding of HERMES_RID_CNFTXRATECONTROL.
1843 * Don't forget that 6Mb/s is really 5.5Mb/s */
1844 if (val == 6)
1845 *bitrate = 5500000;
1846 else
1847 *bitrate = val * 1000000;
1848 break;
1849 case FIRMWARE_TYPE_INTERSIL: /* Intersil style rate */
1850 case FIRMWARE_TYPE_SYMBOL: /* Symbol style rate */
1851 for (i = 0; i < BITRATE_TABLE_SIZE; i++)
1852 if (bitrate_table[i].intersil_txratectrl == val)
1853 break;
1854
1855 if (i >= BITRATE_TABLE_SIZE)
1856 printk(KERN_INFO "%s: Unable to determine current bitrate (0x%04hx)\n",
1857 priv->ndev->name, val);
1858
1859 *bitrate = bitrate_table[i].bitrate * 100000;
1860 break;
1861 default:
1862 BUG();
1863 }
1864
1865 return err;
1866}
1867
1868/* Set fixed AP address */
1869static int __orinoco_hw_set_wap(struct orinoco_private *priv)
1870{
1871 int roaming_flag;
1872 int err = 0;
1873 hermes_t *hw = &priv->hw;
1874
1875 switch (priv->firmware_type) {
1876 case FIRMWARE_TYPE_AGERE:
1877 /* not supported */
1878 break;
1879 case FIRMWARE_TYPE_INTERSIL:
1880 if (priv->bssid_fixed)
1881 roaming_flag = 2;
1882 else
1883 roaming_flag = 1;
1884
1885 err = hermes_write_wordrec(hw, USER_BAP,
1886 HERMES_RID_CNFROAMINGMODE,
1887 roaming_flag);
1888 break;
1889 case FIRMWARE_TYPE_SYMBOL:
1890 err = HERMES_WRITE_RECORD(hw, USER_BAP,
1891 HERMES_RID_CNFMANDATORYBSSID_SYMBOL,
1892 &priv->desired_bssid);
1893 break;
1894 }
1895 return err;
1896}
1897
1898/* Change the WEP keys and/or the current keys. Can be called
1899 * either from __orinoco_hw_setup_enc() or directly from
1900 * orinoco_ioctl_setiwencode(). In the later case the association
1901 * with the AP is not broken (if the firmware can handle it),
1902 * which is needed for 802.1x implementations. */
1903static int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
1904{
1905 hermes_t *hw = &priv->hw;
1906 int err = 0;
1907
1908 switch (priv->firmware_type) {
1909 case FIRMWARE_TYPE_AGERE:
1910 err = HERMES_WRITE_RECORD(hw, USER_BAP,
1911 HERMES_RID_CNFWEPKEYS_AGERE,
1912 &priv->keys);
1913 if (err)
1914 return err;
1915 err = hermes_write_wordrec(hw, USER_BAP,
1916 HERMES_RID_CNFTXKEY_AGERE,
1917 priv->tx_key);
1918 if (err)
1919 return err;
1920 break;
1921 case FIRMWARE_TYPE_INTERSIL:
1922 case FIRMWARE_TYPE_SYMBOL:
1923 {
1924 int keylen;
1925 int i;
1926
1927 /* Force uniform key length to work around
1928 * firmware bugs */
1929 keylen = le16_to_cpu(priv->keys[priv->tx_key].len);
1930
1931 if (keylen > LARGE_KEY_SIZE) {
1932 printk(KERN_ERR "%s: BUG: Key %d has oversize length %d.\n",
1933 priv->ndev->name, priv->tx_key, keylen);
1934 return -E2BIG;
1935 }
1936
1937 /* Write all 4 keys */
1938 for (i = 0; i < ORINOCO_MAX_KEYS; i++) {
1939 err = hermes_write_ltv(hw, USER_BAP,
1940 HERMES_RID_CNFDEFAULTKEY0 + i,
1941 HERMES_BYTES_TO_RECLEN(keylen),
1942 priv->keys[i].data);
1943 if (err)
1944 return err;
1945 }
1946
1947 /* Write the index of the key used in transmission */
1948 err = hermes_write_wordrec(hw, USER_BAP,
1949 HERMES_RID_CNFWEPDEFAULTKEYID,
1950 priv->tx_key);
1951 if (err)
1952 return err;
1953 }
1954 break;
1955 }
1956
1957 return 0;
1958}
1959
1960static int __orinoco_hw_setup_enc(struct orinoco_private *priv)
1961{
1962 hermes_t *hw = &priv->hw;
1963 int err = 0;
1964 int master_wep_flag;
1965 int auth_flag;
1966 int enc_flag;
1967
1968 /* Setup WEP keys for WEP and WPA */
1969 if (priv->encode_alg)
1970 __orinoco_hw_setup_wepkeys(priv);
1971
1972 if (priv->wep_restrict)
1973 auth_flag = HERMES_AUTH_SHARED_KEY;
1974 else
1975 auth_flag = HERMES_AUTH_OPEN;
1976
1977 if (priv->wpa_enabled)
1978 enc_flag = 2;
1979 else if (priv->encode_alg == IW_ENCODE_ALG_WEP)
1980 enc_flag = 1;
1981 else
1982 enc_flag = 0;
1983
1984 switch (priv->firmware_type) {
1985 case FIRMWARE_TYPE_AGERE: /* Agere style WEP */
1986 if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
1987 /* Enable the shared-key authentication. */
1988 err = hermes_write_wordrec(hw, USER_BAP,
1989 HERMES_RID_CNFAUTHENTICATION_AGERE,
1990 auth_flag);
1991 }
1992 err = hermes_write_wordrec(hw, USER_BAP,
1993 HERMES_RID_CNFWEPENABLED_AGERE,
1994 enc_flag);
1995 if (err)
1996 return err;
1997
1998 if (priv->has_wpa) {
1999 /* Set WPA key management */
2000 err = hermes_write_wordrec(hw, USER_BAP,
2001 HERMES_RID_CNFSETWPAAUTHMGMTSUITE_AGERE,
2002 priv->key_mgmt);
2003 if (err)
2004 return err;
2005 }
2006
2007 break;
2008
2009 case FIRMWARE_TYPE_INTERSIL: /* Intersil style WEP */
2010 case FIRMWARE_TYPE_SYMBOL: /* Symbol style WEP */
2011 if (priv->encode_alg == IW_ENCODE_ALG_WEP) {
2012 if (priv->wep_restrict ||
2013 (priv->firmware_type == FIRMWARE_TYPE_SYMBOL))
2014 master_wep_flag = HERMES_WEP_PRIVACY_INVOKED |
2015 HERMES_WEP_EXCL_UNENCRYPTED;
2016 else
2017 master_wep_flag = HERMES_WEP_PRIVACY_INVOKED;
2018
2019 err = hermes_write_wordrec(hw, USER_BAP,
2020 HERMES_RID_CNFAUTHENTICATION,
2021 auth_flag);
2022 if (err)
2023 return err;
2024 } else
2025 master_wep_flag = 0;
2026
2027 if (priv->iw_mode == IW_MODE_MONITOR)
2028 master_wep_flag |= HERMES_WEP_HOST_DECRYPT;
2029
2030 /* Master WEP setting : on/off */
2031 err = hermes_write_wordrec(hw, USER_BAP,
2032 HERMES_RID_CNFWEPFLAGS_INTERSIL,
2033 master_wep_flag);
2034 if (err)
2035 return err;
2036
2037 break;
2038 }
2039
2040 return 0;
2041}
2042
2043/* key must be 32 bytes, including the tx and rx MIC keys.
2044 * rsc must be 8 bytes
2045 * tsc must be 8 bytes or NULL
2046 */
2047static int __orinoco_hw_set_tkip_key(hermes_t *hw, int key_idx, int set_tx,
2048 u8 *key, u8 *rsc, u8 *tsc)
2049{
2050 struct {
2051 __le16 idx;
2052 u8 rsc[IW_ENCODE_SEQ_MAX_SIZE];
2053 u8 key[TKIP_KEYLEN];
2054 u8 tx_mic[MIC_KEYLEN];
2055 u8 rx_mic[MIC_KEYLEN];
2056 u8 tsc[IW_ENCODE_SEQ_MAX_SIZE];
2057 } __attribute__ ((packed)) buf;
2058 int ret;
2059 int err;
2060 int k;
2061 u16 xmitting;
2062
2063 key_idx &= 0x3;
2064
2065 if (set_tx)
2066 key_idx |= 0x8000;
2067
2068 buf.idx = cpu_to_le16(key_idx);
2069 memcpy(buf.key, key,
2070 sizeof(buf.key) + sizeof(buf.tx_mic) + sizeof(buf.rx_mic));
2071
2072 if (rsc == NULL)
2073 memset(buf.rsc, 0, sizeof(buf.rsc));
2074 else
2075 memcpy(buf.rsc, rsc, sizeof(buf.rsc));
2076
2077 if (tsc == NULL) {
2078 memset(buf.tsc, 0, sizeof(buf.tsc));
2079 buf.tsc[4] = 0x10;
2080 } else {
2081 memcpy(buf.tsc, tsc, sizeof(buf.tsc));
2082 }
2083
2084 /* Wait upto 100ms for tx queue to empty */
2085 k = 100;
2086 do {
2087 k--;
2088 udelay(1000);
2089 ret = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_TXQUEUEEMPTY,
2090 &xmitting);
2091 if (ret)
2092 break;
2093 } while ((k > 0) && xmitting);
2094
2095 if (k == 0)
2096 ret = -ETIMEDOUT;
2097
2098 err = HERMES_WRITE_RECORD(hw, USER_BAP,
2099 HERMES_RID_CNFADDDEFAULTTKIPKEY_AGERE,
2100 &buf);
2101
2102 return ret ? ret : err;
2103}
2104
2105static int orinoco_clear_tkip_key(struct orinoco_private *priv,
2106 int key_idx)
2107{
2108 hermes_t *hw = &priv->hw;
2109 int err;
2110
2111 memset(&priv->tkip_key[key_idx], 0, sizeof(priv->tkip_key[key_idx]));
2112 err = hermes_write_wordrec(hw, USER_BAP,
2113 HERMES_RID_CNFREMDEFAULTTKIPKEY_AGERE,
2114 key_idx);
2115 if (err)
2116 printk(KERN_WARNING "%s: Error %d clearing TKIP key %d\n",
2117 priv->ndev->name, err, key_idx);
2118 return err;
2119}
2120
2121static int __orinoco_program_rids(struct net_device *dev) 1719static int __orinoco_program_rids(struct net_device *dev)
2122{ 1720{
2123 struct orinoco_private *priv = netdev_priv(dev); 1721 struct orinoco_private *priv = netdev_priv(dev);
@@ -2347,59 +1945,6 @@ static int __orinoco_program_rids(struct net_device *dev)
2347 return 0; 1945 return 0;
2348} 1946}
2349 1947
2350static int __orinoco_hw_set_multicast_list(struct orinoco_private *priv,
2351 struct dev_addr_list *mc_list,
2352 int mc_count, int promisc)
2353{
2354 hermes_t *hw = &priv->hw;
2355 int err = 0;
2356
2357 if (promisc != priv->promiscuous) {
2358 err = hermes_write_wordrec(hw, USER_BAP,
2359 HERMES_RID_CNFPROMISCUOUSMODE,
2360 promisc);
2361 if (err) {
2362 printk(KERN_ERR "%s: Error %d setting PROMISCUOUSMODE to 1.\n",
2363 priv->ndev->name, err);
2364 } else
2365 priv->promiscuous = promisc;
2366 }
2367
2368 /* If we're not in promiscuous mode, then we need to set the
2369 * group address if either we want to multicast, or if we were
2370 * multicasting and want to stop */
2371 if (!promisc && (mc_count || priv->mc_count)) {
2372 struct dev_mc_list *p = mc_list;
2373 struct hermes_multicast mclist;
2374 int i;
2375
2376 for (i = 0; i < mc_count; i++) {
2377 /* paranoia: is list shorter than mc_count? */
2378 BUG_ON(!p);
2379 /* paranoia: bad address size in list? */
2380 BUG_ON(p->dmi_addrlen != ETH_ALEN);
2381
2382 memcpy(mclist.addr[i], p->dmi_addr, ETH_ALEN);
2383 p = p->next;
2384 }
2385
2386 if (p)
2387 printk(KERN_WARNING "%s: Multicast list is "
2388 "longer than mc_count\n", priv->ndev->name);
2389
2390 err = hermes_write_ltv(hw, USER_BAP,
2391 HERMES_RID_CNFGROUPADDRESSES,
2392 HERMES_BYTES_TO_RECLEN(mc_count * ETH_ALEN),
2393 &mclist);
2394 if (err)
2395 printk(KERN_ERR "%s: Error %d setting multicast list.\n",
2396 priv->ndev->name, err);
2397 else
2398 priv->mc_count = mc_count;
2399 }
2400 return err;
2401}
2402
2403/* FIXME: return int? */ 1948/* FIXME: return int? */
2404static void 1949static void
2405__orinoco_set_multicast_list(struct net_device *dev) 1950__orinoco_set_multicast_list(struct net_device *dev)
@@ -3170,132 +2715,6 @@ EXPORT_SYMBOL(free_orinocodev);
3170/* Wireless extensions */ 2715/* Wireless extensions */
3171/********************************************************************/ 2716/********************************************************************/
3172 2717
3173/* Return : < 0 -> error code ; >= 0 -> length */
3174static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
3175 char buf[IW_ESSID_MAX_SIZE+1])
3176{
3177 hermes_t *hw = &priv->hw;
3178 int err = 0;
3179 struct hermes_idstring essidbuf;
3180 char *p = (char *)(&essidbuf.val);
3181 int len;
3182 unsigned long flags;
3183
3184 if (orinoco_lock(priv, &flags) != 0)
3185 return -EBUSY;
3186
3187 if (strlen(priv->desired_essid) > 0) {
3188 /* We read the desired SSID from the hardware rather
3189 than from priv->desired_essid, just in case the
3190 firmware is allowed to change it on us. I'm not
3191 sure about this */
3192 /* My guess is that the OWNSSID should always be whatever
3193 * we set to the card, whereas CURRENT_SSID is the one that
3194 * may change... - Jean II */
3195 u16 rid;
3196
3197 *active = 1;
3198
3199 rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID :
3200 HERMES_RID_CNFDESIREDSSID;
3201
3202 err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf),
3203 NULL, &essidbuf);
3204 if (err)
3205 goto fail_unlock;
3206 } else {
3207 *active = 0;
3208
3209 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID,
3210 sizeof(essidbuf), NULL, &essidbuf);
3211 if (err)
3212 goto fail_unlock;
3213 }
3214
3215 len = le16_to_cpu(essidbuf.len);
3216 BUG_ON(len > IW_ESSID_MAX_SIZE);
3217
3218 memset(buf, 0, IW_ESSID_MAX_SIZE);
3219 memcpy(buf, p, len);
3220 err = len;
3221
3222 fail_unlock:
3223 orinoco_unlock(priv, &flags);
3224
3225 return err;
3226}
3227
3228static int orinoco_hw_get_freq(struct orinoco_private *priv)
3229{
3230
3231 hermes_t *hw = &priv->hw;
3232 int err = 0;
3233 u16 channel;
3234 int freq = 0;
3235 unsigned long flags;
3236
3237 if (orinoco_lock(priv, &flags) != 0)
3238 return -EBUSY;
3239
3240 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_CURRENTCHANNEL,
3241 &channel);
3242 if (err)
3243 goto out;
3244
3245 /* Intersil firmware 1.3.5 returns 0 when the interface is down */
3246 if (channel == 0) {
3247 err = -EBUSY;
3248 goto out;
3249 }
3250
3251 if ((channel < 1) || (channel > NUM_CHANNELS)) {
3252 printk(KERN_WARNING "%s: Channel out of range (%d)!\n",
3253 priv->ndev->name, channel);
3254 err = -EBUSY;
3255 goto out;
3256
3257 }
3258 freq = ieee80211_dsss_chan_to_freq(channel);
3259
3260 out:
3261 orinoco_unlock(priv, &flags);
3262
3263 if (err > 0)
3264 err = -EBUSY;
3265 return err ? err : freq;
3266}
3267
3268static int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
3269 int *numrates, s32 *rates, int max)
3270{
3271 hermes_t *hw = &priv->hw;
3272 struct hermes_idstring list;
3273 unsigned char *p = (unsigned char *)&list.val;
3274 int err = 0;
3275 int num;
3276 int i;
3277 unsigned long flags;
3278
3279 if (orinoco_lock(priv, &flags) != 0)
3280 return -EBUSY;
3281
3282 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES,
3283 sizeof(list), NULL, &list);
3284 orinoco_unlock(priv, &flags);
3285
3286 if (err)
3287 return err;
3288
3289 num = le16_to_cpu(list.len);
3290 *numrates = num;
3291 num = min(num, max);
3292
3293 for (i = 0; i < num; i++)
3294 rates[i] = (p[i] & 0x7f) * 500000; /* convert to bps */
3295
3296 return 0;
3297}
3298
3299static int orinoco_ioctl_getname(struct net_device *dev, 2718static int orinoco_ioctl_getname(struct net_device *dev,
3300 struct iw_request_info *info, 2719 struct iw_request_info *info,
3301 char *name, 2720 char *name,