From 64b92f26916f8b57e7e9a8f75664c652c4bcb80f Mon Sep 17 00:00:00 2001 From: Andriy Voskoboinyk Date: Sat, 25 Mar 2017 15:57:47 +0000 Subject: iwn: do not try to update node configuration when the node does not exist. Firmware will just respond with status '0x8' (node does not exist) or will hang -> cause 'device timeout's (sometimes). --- sys/dev/iwn/if_iwn.c | 20 +++++++++++++++++++- sys/dev/iwn/if_iwnreg.h | 6 ++++-- 2 files changed, 23 insertions(+), 3 deletions(-) (limited to 'sys/dev/iwn') diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c index 5afe64e30e28..7572bd560ca1 100644 --- a/sys/dev/iwn/if_iwn.c +++ b/sys/dev/iwn/if_iwn.c @@ -2651,7 +2651,15 @@ iwn_read_eeprom_enhinfo(struct iwn_softc *sc) static struct ieee80211_node * iwn_node_alloc(struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN]) { - return malloc(sizeof (struct iwn_node), M_80211_NODE,M_NOWAIT | M_ZERO); + struct iwn_node *wn; + + wn = malloc(sizeof (struct iwn_node), M_80211_NODE, M_NOWAIT | M_ZERO); + if (wn == NULL) + return (NULL); + + wn->id = IWN_ID_UNDEFINED; + + return (&wn->ni); } static __inline int @@ -7355,6 +7363,9 @@ iwn_ampdu_rx_start(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap, tid = MS(le16toh(baparamset), IEEE80211_BAPS_TID); ssn = MS(le16toh(baseqctl), IEEE80211_BASEQ_START); + if (wn->id == IWN_ID_UNDEFINED) + return (ENOENT); + memset(&node, 0, sizeof node); node.id = wn->id; node.control = IWN_NODE_UPDATE; @@ -7386,6 +7397,9 @@ iwn_ampdu_rx_stop(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap) DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__); + if (wn->id == IWN_ID_UNDEFINED) + goto end; + /* XXX: tid as an argument */ for (tid = 0; tid < WME_NUM_TID; tid++) { if (&ni->ni_rx_ampdu[tid] == rap) @@ -7399,6 +7413,7 @@ iwn_ampdu_rx_stop(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap) node.delba_tid = tid; DPRINTF(sc, IWN_DEBUG_RECV, "DELBA RA=%d TID=%d\n", wn->id, tid); (void)ops->add_node(sc, &node, 1); +end: sc->sc_ampdu_rx_stop(ni, rap); } @@ -7473,6 +7488,9 @@ iwn_ampdu_tx_start(struct ieee80211com *ic, struct ieee80211_node *ni, DPRINTF(sc, IWN_DEBUG_TRACE, "->Doing %s\n", __func__); + if (wn->id == IWN_ID_UNDEFINED) + return (0); + /* Enable TX for the specified RA/TID. */ wn->disable_tid &= ~(1 << tid); memset(&node, 0, sizeof node); diff --git a/sys/dev/iwn/if_iwnreg.h b/sys/dev/iwn/if_iwnreg.h index 5081c50206c2..c95e47551357 100644 --- a/sys/dev/iwn/if_iwnreg.h +++ b/sys/dev/iwn/if_iwnreg.h @@ -690,13 +690,15 @@ struct iwn_node_info { uint8_t macaddr[IEEE80211_ADDR_LEN]; uint16_t reserved2; uint8_t id; -#define IWN_ID_BSS 0 +#define IWN_ID_BSS 0 #define IWN_STA_ID 1 -#define IWN_PAN_ID_BCAST 14 +#define IWN_PAN_ID_BCAST 14 #define IWN5000_ID_BROADCAST 15 #define IWN4965_ID_BROADCAST 31 +#define IWN_ID_UNDEFINED (uint8_t)-1 + uint8_t flags; #define IWN_FLAG_SET_KEY (1 << 0) #define IWN_FLAG_SET_DISABLE_TID (1 << 1) -- cgit v1.2.3