Lines 169-174
Link Here
|
169 |
struct ieee80211_regdomain *, int, |
169 |
struct ieee80211_regdomain *, int, |
170 |
struct ieee80211_channel[]); |
170 |
struct ieee80211_channel[]); |
171 |
static int wpi_read_eeprom_group(struct wpi_softc *, int); |
171 |
static int wpi_read_eeprom_group(struct wpi_softc *, int); |
|
|
172 |
static int wpi_add_node_entry_adhoc(struct wpi_softc *); |
172 |
static void wpi_node_free(struct ieee80211_node *); |
173 |
static void wpi_node_free(struct ieee80211_node *); |
173 |
static struct ieee80211_node *wpi_node_alloc(struct ieee80211vap *, |
174 |
static struct ieee80211_node *wpi_node_alloc(struct ieee80211vap *, |
174 |
const uint8_t mac[IEEE80211_ADDR_LEN]); |
175 |
const uint8_t mac[IEEE80211_ADDR_LEN]); |
Lines 384-391
Link Here
|
384 |
|
385 |
|
385 |
WPI_LOCK_INIT(sc); |
386 |
WPI_LOCK_INIT(sc); |
386 |
|
387 |
|
387 |
sc->sc_unr = new_unrhdr(WPI_ID_IBSS_MIN, WPI_ID_IBSS_MAX, &sc->sc_mtx); |
|
|
388 |
|
389 |
/* Allocate DMA memory for firmware transfers. */ |
388 |
/* Allocate DMA memory for firmware transfers. */ |
390 |
if ((error = wpi_alloc_fwmem(sc)) != 0) { |
389 |
if ((error = wpi_alloc_fwmem(sc)) != 0) { |
391 |
device_printf(dev, |
390 |
device_printf(dev, |
Lines 679-686
Link Here
|
679 |
if (ifp != NULL) |
678 |
if (ifp != NULL) |
680 |
if_free(ifp); |
679 |
if_free(ifp); |
681 |
|
680 |
|
682 |
delete_unrhdr(sc->sc_unr); |
|
|
683 |
|
684 |
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END, __func__); |
681 |
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_END, __func__); |
685 |
WPI_LOCK_DESTROY(sc); |
682 |
WPI_LOCK_DESTROY(sc); |
686 |
return 0; |
683 |
return 0; |
Lines 1514-1519
Link Here
|
1514 |
return 0; |
1511 |
return 0; |
1515 |
} |
1512 |
} |
1516 |
|
1513 |
|
|
|
1514 |
static int |
1515 |
wpi_add_node_entry_adhoc(struct wpi_softc *sc) |
1516 |
{ |
1517 |
int newid = WPI_ID_IBSS_MIN; |
1518 |
|
1519 |
for (; newid <= WPI_ID_IBSS_MAX; newid++) { |
1520 |
if ((sc->nodesmsk & (1 << newid)) == 0) { |
1521 |
sc->nodesmsk |= 1 << newid; |
1522 |
return newid; |
1523 |
} |
1524 |
} |
1525 |
|
1526 |
return WPI_ID_UNDEFINED; |
1527 |
} |
1528 |
|
1529 |
static __inline int |
1530 |
wpi_check_node_entry(struct wpi_softc *sc, uint8_t id) |
1531 |
{ |
1532 |
if (id == WPI_ID_UNDEFINED) |
1533 |
return 0; |
1534 |
|
1535 |
return (sc->nodesmsk >> id) & 1; |
1536 |
} |
1537 |
|
1538 |
static __inline void |
1539 |
wpi_clear_node_table(struct wpi_softc *sc) |
1540 |
{ |
1541 |
sc->nodesmsk = 0; |
1542 |
} |
1543 |
|
1544 |
static __inline void |
1545 |
wpi_del_node_entry(struct wpi_softc *sc, uint8_t id) |
1546 |
{ |
1547 |
sc->nodesmsk &= ~(1 << id); |
1548 |
} |
1549 |
|
1517 |
static struct ieee80211_node * |
1550 |
static struct ieee80211_node * |
1518 |
wpi_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN]) |
1551 |
wpi_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN]) |
1519 |
{ |
1552 |
{ |
Lines 1538-1548
Link Here
|
1538 |
struct wpi_node *wn = WPI_NODE(ni); |
1571 |
struct wpi_node *wn = WPI_NODE(ni); |
1539 |
|
1572 |
|
1540 |
if (wn->id >= WPI_ID_IBSS_MIN && wn->id <= WPI_ID_IBSS_MAX) { |
1573 |
if (wn->id >= WPI_ID_IBSS_MIN && wn->id <= WPI_ID_IBSS_MAX) { |
1541 |
free_unr(sc->sc_unr, wn->id); |
|
|
1542 |
|
1543 |
WPI_LOCK(sc); |
1574 |
WPI_LOCK(sc); |
1544 |
if (sc->rxon.filter & htole32(WPI_FILTER_BSS)) |
1575 |
if (wpi_check_node_entry(sc, wn->id)) { |
|
|
1576 |
wpi_del_node_entry(sc, wn->id); |
1545 |
wpi_del_node(sc, ni); |
1577 |
wpi_del_node(sc, ni); |
|
|
1578 |
} |
1546 |
WPI_UNLOCK(sc); |
1579 |
WPI_UNLOCK(sc); |
1547 |
} |
1580 |
} |
1548 |
|
1581 |
|
Lines 2050-2055
Link Here
|
2050 |
le32toh(*status)); |
2083 |
le32toh(*status)); |
2051 |
|
2084 |
|
2052 |
if (le32toh(*status) & 1) { |
2085 |
if (le32toh(*status) & 1) { |
|
|
2086 |
wpi_clear_node_table(sc); |
2053 |
ieee80211_runtask(ic, &sc->sc_radiooff_task); |
2087 |
ieee80211_runtask(ic, &sc->sc_radiooff_task); |
2054 |
return; |
2088 |
return; |
2055 |
} |
2089 |
} |
Lines 3001-3006
Link Here
|
3001 |
wpi_add_ibss_node(struct wpi_softc *sc, struct ieee80211_node *ni) |
3035 |
wpi_add_ibss_node(struct wpi_softc *sc, struct ieee80211_node *ni) |
3002 |
{ |
3036 |
{ |
3003 |
struct wpi_node *wn = WPI_NODE(ni); |
3037 |
struct wpi_node *wn = WPI_NODE(ni); |
|
|
3038 |
int error; |
3004 |
|
3039 |
|
3005 |
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_DOING, __func__); |
3040 |
DPRINTF(sc, WPI_DEBUG_TRACE, TRACE_STR_DOING, __func__); |
3006 |
|
3041 |
|
Lines 3007-3018
Link Here
|
3007 |
if (wn->id != WPI_ID_UNDEFINED) |
3042 |
if (wn->id != WPI_ID_UNDEFINED) |
3008 |
return EINVAL; |
3043 |
return EINVAL; |
3009 |
|
3044 |
|
3010 |
wn->id = alloc_unrl(sc->sc_unr); |
3045 |
if ((wn->id = wpi_add_node_entry_adhoc(sc)) == WPI_ID_UNDEFINED) { |
|
|
3046 |
device_printf(sc->sc_dev, "%s: h/w table is full\n", __func__); |
3047 |
return ENOMEM; |
3048 |
} |
3011 |
|
3049 |
|
3012 |
if (wn->id == (uint8_t)-1) |
3050 |
if ((error = wpi_add_node(sc, ni)) != 0) { |
3013 |
return ENOBUFS; |
3051 |
wpi_del_node_entry(sc, wn->id); |
|
|
3052 |
wn->id = WPI_ID_UNDEFINED; |
3053 |
return error; |
3054 |
} |
3014 |
|
3055 |
|
3015 |
return wpi_add_node(sc, ni); |
3056 |
return 0; |
3016 |
} |
3057 |
} |
3017 |
|
3058 |
|
3018 |
static void |
3059 |
static void |
Lines 3404-3409
Link Here
|
3404 |
} else { |
3445 |
} else { |
3405 |
error = wpi_cmd(sc, WPI_CMD_RXON, &sc->rxon, |
3446 |
error = wpi_cmd(sc, WPI_CMD_RXON, &sc->rxon, |
3406 |
sizeof (struct wpi_rxon), async); |
3447 |
sizeof (struct wpi_rxon), async); |
|
|
3448 |
|
3449 |
wpi_clear_node_table(sc); |
3407 |
} |
3450 |
} |
3408 |
if (error != 0) { |
3451 |
if (error != 0) { |
3409 |
device_printf(sc->sc_dev, "RXON command failed, error %d\n", |
3452 |
device_printf(sc->sc_dev, "RXON command failed, error %d\n", |