Deleted Added
full compact
if_iwn.c (293179) if_iwn.c (293716)
1/*-
2 * Copyright (c) 2007-2009 Damien Bergamini <damien.bergamini@free.fr>
3 * Copyright (c) 2008 Benjamin Close <benjsc@FreeBSD.org>
4 * Copyright (c) 2008 Sam Leffler, Errno Consulting
5 * Copyright (c) 2011 Intel Corporation
6 * Copyright (c) 2013 Cedric GROSS <c.gross@kreiz-it.fr>
7 * Copyright (c) 2013 Adrian Chadd <adrian@FreeBSD.org>
8 *

--- 11 unchanged lines hidden (view full) ---

20 */
21
22/*
23 * Driver for Intel WiFi Link 4965 and 1000/5000/6000 Series 802.11 network
24 * adapters.
25 */
26
27#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2007-2009 Damien Bergamini <damien.bergamini@free.fr>
3 * Copyright (c) 2008 Benjamin Close <benjsc@FreeBSD.org>
4 * Copyright (c) 2008 Sam Leffler, Errno Consulting
5 * Copyright (c) 2011 Intel Corporation
6 * Copyright (c) 2013 Cedric GROSS <c.gross@kreiz-it.fr>
7 * Copyright (c) 2013 Adrian Chadd <adrian@FreeBSD.org>
8 *

--- 11 unchanged lines hidden (view full) ---

20 */
21
22/*
23 * Driver for Intel WiFi Link 4965 and 1000/5000/6000 Series 802.11 network
24 * adapters.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/dev/iwn/if_iwn.c 293179 2016-01-04 21:11:27Z avos $");
28__FBSDID("$FreeBSD: head/sys/dev/iwn/if_iwn.c 293716 2016-01-12 00:24:40Z avos $");
29
30#include "opt_wlan.h"
31#include "opt_iwn.h"
32
33#include <sys/param.h>
34#include <sys/sockio.h>
35#include <sys/sysctl.h>
36#include <sys/mbuf.h>

--- 135 unchanged lines hidden (view full) ---

172static int iwn_read_eeprom(struct iwn_softc *,
173 uint8_t macaddr[IEEE80211_ADDR_LEN]);
174static void iwn4965_read_eeprom(struct iwn_softc *);
175#ifdef IWN_DEBUG
176static void iwn4965_print_power_group(struct iwn_softc *, int);
177#endif
178static void iwn5000_read_eeprom(struct iwn_softc *);
179static uint32_t iwn_eeprom_channel_flags(struct iwn_eeprom_chan *);
29
30#include "opt_wlan.h"
31#include "opt_iwn.h"
32
33#include <sys/param.h>
34#include <sys/sockio.h>
35#include <sys/sysctl.h>
36#include <sys/mbuf.h>

--- 135 unchanged lines hidden (view full) ---

172static int iwn_read_eeprom(struct iwn_softc *,
173 uint8_t macaddr[IEEE80211_ADDR_LEN]);
174static void iwn4965_read_eeprom(struct iwn_softc *);
175#ifdef IWN_DEBUG
176static void iwn4965_print_power_group(struct iwn_softc *, int);
177#endif
178static void iwn5000_read_eeprom(struct iwn_softc *);
179static uint32_t iwn_eeprom_channel_flags(struct iwn_eeprom_chan *);
180static void iwn_read_eeprom_band(struct iwn_softc *, int);
181static void iwn_read_eeprom_ht40(struct iwn_softc *, int);
180static void iwn_read_eeprom_band(struct iwn_softc *, int, int, int *,
181 struct ieee80211_channel[]);
182static void iwn_read_eeprom_ht40(struct iwn_softc *, int, int, int *,
183 struct ieee80211_channel[]);
182static void iwn_read_eeprom_channels(struct iwn_softc *, int, uint32_t);
183static struct iwn_eeprom_chan *iwn_find_eeprom_channel(struct iwn_softc *,
184 struct ieee80211_channel *);
184static void iwn_read_eeprom_channels(struct iwn_softc *, int, uint32_t);
185static struct iwn_eeprom_chan *iwn_find_eeprom_channel(struct iwn_softc *,
186 struct ieee80211_channel *);
187static void iwn_getradiocaps(struct ieee80211com *, int, int *,
188 struct ieee80211_channel[]);
185static int iwn_setregdomain(struct ieee80211com *,
186 struct ieee80211_regdomain *, int,
187 struct ieee80211_channel[]);
188static void iwn_read_eeprom_enhinfo(struct iwn_softc *);
189static struct ieee80211_node *iwn_node_alloc(struct ieee80211vap *,
190 const uint8_t mac[IEEE80211_ADDR_LEN]);
191static void iwn_newassoc(struct ieee80211_node *, int);
192static int iwn_media_change(struct ifnet *);

--- 468 unchanged lines hidden (view full) ---

661 ic->ic_newassoc = iwn_newassoc;
662 ic->ic_wme.wme_update = iwn_updateedca;
663 ic->ic_update_mcast = iwn_update_mcast;
664 ic->ic_scan_start = iwn_scan_start;
665 ic->ic_scan_end = iwn_scan_end;
666 ic->ic_set_channel = iwn_set_channel;
667 ic->ic_scan_curchan = iwn_scan_curchan;
668 ic->ic_scan_mindwell = iwn_scan_mindwell;
189static int iwn_setregdomain(struct ieee80211com *,
190 struct ieee80211_regdomain *, int,
191 struct ieee80211_channel[]);
192static void iwn_read_eeprom_enhinfo(struct iwn_softc *);
193static struct ieee80211_node *iwn_node_alloc(struct ieee80211vap *,
194 const uint8_t mac[IEEE80211_ADDR_LEN]);
195static void iwn_newassoc(struct ieee80211_node *, int);
196static int iwn_media_change(struct ifnet *);

--- 468 unchanged lines hidden (view full) ---

665 ic->ic_newassoc = iwn_newassoc;
666 ic->ic_wme.wme_update = iwn_updateedca;
667 ic->ic_update_mcast = iwn_update_mcast;
668 ic->ic_scan_start = iwn_scan_start;
669 ic->ic_scan_end = iwn_scan_end;
670 ic->ic_set_channel = iwn_set_channel;
671 ic->ic_scan_curchan = iwn_scan_curchan;
672 ic->ic_scan_mindwell = iwn_scan_mindwell;
673 ic->ic_getradiocaps = iwn_getradiocaps;
669 ic->ic_setregdomain = iwn_setregdomain;
670
671 iwn_radiotap_attach(sc);
672
673 callout_init_mtx(&sc->calib_to, &sc->sc_mtx, 0);
674 callout_init_mtx(&sc->watchdog_to, &sc->sc_mtx, 0);
675 TASK_INIT(&sc->sc_reinit_task, 0, iwn_hw_reset, sc);
676 TASK_INIT(&sc->sc_radioon_task, 0, iwn_radio_on, sc);

--- 1689 unchanged lines hidden (view full) ---

2366 /* XXX apparently IBSS may still be marked */
2367 nflags |= IEEE80211_CHAN_NOADHOC;
2368 }
2369
2370 return nflags;
2371}
2372
2373static void
674 ic->ic_setregdomain = iwn_setregdomain;
675
676 iwn_radiotap_attach(sc);
677
678 callout_init_mtx(&sc->calib_to, &sc->sc_mtx, 0);
679 callout_init_mtx(&sc->watchdog_to, &sc->sc_mtx, 0);
680 TASK_INIT(&sc->sc_reinit_task, 0, iwn_hw_reset, sc);
681 TASK_INIT(&sc->sc_radioon_task, 0, iwn_radio_on, sc);

--- 1689 unchanged lines hidden (view full) ---

2371 /* XXX apparently IBSS may still be marked */
2372 nflags |= IEEE80211_CHAN_NOADHOC;
2373 }
2374
2375 return nflags;
2376}
2377
2378static void
2374iwn_read_eeprom_band(struct iwn_softc *sc, int n)
2379iwn_read_eeprom_band(struct iwn_softc *sc, int n, int maxchans, int *nchans,
2380 struct ieee80211_channel chans[])
2375{
2381{
2376 struct ieee80211com *ic = &sc->sc_ic;
2377 struct iwn_eeprom_chan *channels = sc->eeprom_channels[n];
2378 const struct iwn_chan_band *band = &iwn_bands[n];
2379 struct ieee80211_channel *c;
2380 uint8_t chan;
2381 int i, nflags;
2382
2383 DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);
2384
2385 for (i = 0; i < band->nchan; i++) {
2386 if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID)) {
2387 DPRINTF(sc, IWN_DEBUG_RESET,
2388 "skip chan %d flags 0x%x maxpwr %d\n",
2389 band->chan[i], channels[i].flags,
2390 channels[i].maxpwr);
2391 continue;
2392 }
2382 struct iwn_eeprom_chan *channels = sc->eeprom_channels[n];
2383 const struct iwn_chan_band *band = &iwn_bands[n];
2384 struct ieee80211_channel *c;
2385 uint8_t chan;
2386 int i, nflags;
2387
2388 DPRINTF(sc, IWN_DEBUG_TRACE, "->%s begin\n", __func__);
2389
2390 for (i = 0; i < band->nchan; i++) {
2391 if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID)) {
2392 DPRINTF(sc, IWN_DEBUG_RESET,
2393 "skip chan %d flags 0x%x maxpwr %d\n",
2394 band->chan[i], channels[i].flags,
2395 channels[i].maxpwr);
2396 continue;
2397 }
2398
2399 if (*nchans >= maxchans)
2400 break;
2401
2393 chan = band->chan[i];
2394 nflags = iwn_eeprom_channel_flags(&channels[i]);
2395
2402 chan = band->chan[i];
2403 nflags = iwn_eeprom_channel_flags(&channels[i]);
2404
2396 c = &ic->ic_channels[ic->ic_nchans++];
2405 c = &chans[(*nchans)++];
2397 c->ic_ieee = chan;
2398 c->ic_maxregpower = channels[i].maxpwr;
2399 c->ic_maxpower = 2*c->ic_maxregpower;
2400
2401 if (n == 0) { /* 2GHz band */
2402 c->ic_freq = ieee80211_ieee2mhz(chan, IEEE80211_CHAN_G);
2403 /* G =>'s B is supported */
2404 c->ic_flags = IEEE80211_CHAN_B | nflags;
2406 c->ic_ieee = chan;
2407 c->ic_maxregpower = channels[i].maxpwr;
2408 c->ic_maxpower = 2*c->ic_maxregpower;
2409
2410 if (n == 0) { /* 2GHz band */
2411 c->ic_freq = ieee80211_ieee2mhz(chan, IEEE80211_CHAN_G);
2412 /* G =>'s B is supported */
2413 c->ic_flags = IEEE80211_CHAN_B | nflags;
2405 c = &ic->ic_channels[ic->ic_nchans++];
2414
2415 if (*nchans >= maxchans)
2416 break;
2417
2418 c = &chans[(*nchans)++];
2406 c[0] = c[-1];
2407 c->ic_flags = IEEE80211_CHAN_G | nflags;
2408 } else { /* 5GHz band */
2409 c->ic_freq = ieee80211_ieee2mhz(chan, IEEE80211_CHAN_A);
2410 c->ic_flags = IEEE80211_CHAN_A | nflags;
2411 }
2412
2413 /* Save maximum allowed TX power for this channel. */
2414 sc->maxpwr[chan] = channels[i].maxpwr;
2415
2416 DPRINTF(sc, IWN_DEBUG_RESET,
2417 "add chan %d flags 0x%x maxpwr %d\n", chan,
2418 channels[i].flags, channels[i].maxpwr);
2419
2420 if (sc->sc_flags & IWN_FLAG_HAS_11N) {
2419 c[0] = c[-1];
2420 c->ic_flags = IEEE80211_CHAN_G | nflags;
2421 } else { /* 5GHz band */
2422 c->ic_freq = ieee80211_ieee2mhz(chan, IEEE80211_CHAN_A);
2423 c->ic_flags = IEEE80211_CHAN_A | nflags;
2424 }
2425
2426 /* Save maximum allowed TX power for this channel. */
2427 sc->maxpwr[chan] = channels[i].maxpwr;
2428
2429 DPRINTF(sc, IWN_DEBUG_RESET,
2430 "add chan %d flags 0x%x maxpwr %d\n", chan,
2431 channels[i].flags, channels[i].maxpwr);
2432
2433 if (sc->sc_flags & IWN_FLAG_HAS_11N) {
2434 if (*nchans >= maxchans)
2435 break;
2436
2421 /* add HT20, HT40 added separately */
2437 /* add HT20, HT40 added separately */
2422 c = &ic->ic_channels[ic->ic_nchans++];
2438 c = &chans[(*nchans)++];
2423 c[0] = c[-1];
2424 c->ic_flags |= IEEE80211_CHAN_HT20;
2425 }
2426 }
2427
2428 DPRINTF(sc, IWN_DEBUG_TRACE, "->%s end\n", __func__);
2429
2430}
2431
2432static void
2439 c[0] = c[-1];
2440 c->ic_flags |= IEEE80211_CHAN_HT20;
2441 }
2442 }
2443
2444 DPRINTF(sc, IWN_DEBUG_TRACE, "->%s end\n", __func__);
2445
2446}
2447
2448static void
2433iwn_read_eeprom_ht40(struct iwn_softc *sc, int n)
2449iwn_read_eeprom_ht40(struct iwn_softc *sc, int n, int maxchans, int *nchans,
2450 struct ieee80211_channel chans[])
2434{
2435 struct ieee80211com *ic = &sc->sc_ic;
2436 struct iwn_eeprom_chan *channels = sc->eeprom_channels[n];
2437 const struct iwn_chan_band *band = &iwn_bands[n];
2438 struct ieee80211_channel *c, *cent, *extc;
2439 uint8_t chan;
2440 int i, nflags;
2441

--- 7 unchanged lines hidden (view full) ---

2449 for (i = 0; i < band->nchan; i++) {
2450 if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID)) {
2451 DPRINTF(sc, IWN_DEBUG_RESET,
2452 "skip chan %d flags 0x%x maxpwr %d\n",
2453 band->chan[i], channels[i].flags,
2454 channels[i].maxpwr);
2455 continue;
2456 }
2451{
2452 struct ieee80211com *ic = &sc->sc_ic;
2453 struct iwn_eeprom_chan *channels = sc->eeprom_channels[n];
2454 const struct iwn_chan_band *band = &iwn_bands[n];
2455 struct ieee80211_channel *c, *cent, *extc;
2456 uint8_t chan;
2457 int i, nflags;
2458

--- 7 unchanged lines hidden (view full) ---

2466 for (i = 0; i < band->nchan; i++) {
2467 if (!(channels[i].flags & IWN_EEPROM_CHAN_VALID)) {
2468 DPRINTF(sc, IWN_DEBUG_RESET,
2469 "skip chan %d flags 0x%x maxpwr %d\n",
2470 band->chan[i], channels[i].flags,
2471 channels[i].maxpwr);
2472 continue;
2473 }
2474
2475 if (*nchans + 1 >= maxchans)
2476 break;
2477
2457 chan = band->chan[i];
2458 nflags = iwn_eeprom_channel_flags(&channels[i]);
2459
2460 /*
2461 * Each entry defines an HT40 channel pair; find the
2462 * center channel, then the extension channel above.
2463 */
2464 cent = ieee80211_find_channel_byieee(ic, chan,

--- 11 unchanged lines hidden (view full) ---

2476 __func__, chan);
2477 continue;
2478 }
2479
2480 DPRINTF(sc, IWN_DEBUG_RESET,
2481 "add ht40 chan %d flags 0x%x maxpwr %d\n",
2482 chan, channels[i].flags, channels[i].maxpwr);
2483
2478 chan = band->chan[i];
2479 nflags = iwn_eeprom_channel_flags(&channels[i]);
2480
2481 /*
2482 * Each entry defines an HT40 channel pair; find the
2483 * center channel, then the extension channel above.
2484 */
2485 cent = ieee80211_find_channel_byieee(ic, chan,

--- 11 unchanged lines hidden (view full) ---

2497 __func__, chan);
2498 continue;
2499 }
2500
2501 DPRINTF(sc, IWN_DEBUG_RESET,
2502 "add ht40 chan %d flags 0x%x maxpwr %d\n",
2503 chan, channels[i].flags, channels[i].maxpwr);
2504
2484 c = &ic->ic_channels[ic->ic_nchans++];
2505 c = &chans[(*nchans)++];
2485 c[0] = cent[0];
2486 c->ic_extieee = extc->ic_ieee;
2487 c->ic_flags &= ~IEEE80211_CHAN_HT;
2488 c->ic_flags |= IEEE80211_CHAN_HT40U | nflags;
2506 c[0] = cent[0];
2507 c->ic_extieee = extc->ic_ieee;
2508 c->ic_flags &= ~IEEE80211_CHAN_HT;
2509 c->ic_flags |= IEEE80211_CHAN_HT40U | nflags;
2489 c = &ic->ic_channels[ic->ic_nchans++];
2510 c = &chans[(*nchans)++];
2490 c[0] = extc[0];
2491 c->ic_extieee = cent->ic_ieee;
2492 c->ic_flags &= ~IEEE80211_CHAN_HT;
2493 c->ic_flags |= IEEE80211_CHAN_HT40D | nflags;
2494 }
2495
2496 DPRINTF(sc, IWN_DEBUG_TRACE, "->%s end\n", __func__);
2497
2498}
2499
2500static void
2501iwn_read_eeprom_channels(struct iwn_softc *sc, int n, uint32_t addr)
2502{
2503 struct ieee80211com *ic = &sc->sc_ic;
2504
2505 iwn_read_prom_data(sc, addr, &sc->eeprom_channels[n],
2506 iwn_bands[n].nchan * sizeof (struct iwn_eeprom_chan));
2507
2511 c[0] = extc[0];
2512 c->ic_extieee = cent->ic_ieee;
2513 c->ic_flags &= ~IEEE80211_CHAN_HT;
2514 c->ic_flags |= IEEE80211_CHAN_HT40D | nflags;
2515 }
2516
2517 DPRINTF(sc, IWN_DEBUG_TRACE, "->%s end\n", __func__);
2518
2519}
2520
2521static void
2522iwn_read_eeprom_channels(struct iwn_softc *sc, int n, uint32_t addr)
2523{
2524 struct ieee80211com *ic = &sc->sc_ic;
2525
2526 iwn_read_prom_data(sc, addr, &sc->eeprom_channels[n],
2527 iwn_bands[n].nchan * sizeof (struct iwn_eeprom_chan));
2528
2508 if (n < 5)
2509 iwn_read_eeprom_band(sc, n);
2510 else
2511 iwn_read_eeprom_ht40(sc, n);
2529 if (n < 5) {
2530 iwn_read_eeprom_band(sc, n, IEEE80211_CHAN_MAX, &ic->ic_nchans,
2531 ic->ic_channels);
2532 } else {
2533 iwn_read_eeprom_ht40(sc, n, IEEE80211_CHAN_MAX, &ic->ic_nchans,
2534 ic->ic_channels);
2535 }
2512 ieee80211_sort_channels(ic->ic_channels, ic->ic_nchans);
2513}
2514
2515static struct iwn_eeprom_chan *
2516iwn_find_eeprom_channel(struct iwn_softc *sc, struct ieee80211_channel *c)
2517{
2518 int band, chan, i, j;
2519

--- 13 unchanged lines hidden (view full) ---

2533 if (iwn_bands[j].chan[i] == c->ic_ieee)
2534 return &sc->eeprom_channels[j][i];
2535 }
2536 }
2537 }
2538 return NULL;
2539}
2540
2536 ieee80211_sort_channels(ic->ic_channels, ic->ic_nchans);
2537}
2538
2539static struct iwn_eeprom_chan *
2540iwn_find_eeprom_channel(struct iwn_softc *sc, struct ieee80211_channel *c)
2541{
2542 int band, chan, i, j;
2543

--- 13 unchanged lines hidden (view full) ---

2557 if (iwn_bands[j].chan[i] == c->ic_ieee)
2558 return &sc->eeprom_channels[j][i];
2559 }
2560 }
2561 }
2562 return NULL;
2563}
2564
2565static void
2566iwn_getradiocaps(struct ieee80211com *ic,
2567 int maxchans, int *nchans, struct ieee80211_channel chans[])
2568{
2569 struct iwn_softc *sc = ic->ic_softc;
2570 int i;
2571
2572 /* Parse the list of authorized channels. */
2573 for (i = 0; i < 5 && *nchans < maxchans; i++)
2574 iwn_read_eeprom_band(sc, i, maxchans, nchans, chans);
2575 for (i = 5; i < IWN_NBANDS - 1 && *nchans < maxchans; i++)
2576 iwn_read_eeprom_ht40(sc, i, maxchans, nchans, chans);
2577}
2578
2541/*
2542 * Enforce flags read from EEPROM.
2543 */
2544static int
2545iwn_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd,
2546 int nchan, struct ieee80211_channel chans[])
2547{
2548 struct iwn_softc *sc = ic->ic_softc;

--- 6435 unchanged lines hidden ---
2579/*
2580 * Enforce flags read from EEPROM.
2581 */
2582static int
2583iwn_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd,
2584 int nchan, struct ieee80211_channel chans[])
2585{
2586 struct iwn_softc *sc = ic->ic_softc;

--- 6435 unchanged lines hidden ---