diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-06 09:38:14 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-06 09:38:14 -0700 |
commit | ae045e2455429c418a418a3376301a9e5753a0a8 (patch) | |
tree | b445bdeecd3f38aa0d0a29c9585cee49e4ccb0f1 /drivers/net/wireless/rsi | |
parent | f4f142ed4ef835709c7e6d12eaca10d190bcebed (diff) | |
parent | d247b6ab3ce6dd43665780865ec5fa145d9ab6bd (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller:
"Highlights:
1) Steady transitioning of the BPF instructure to a generic spot so
all kernel subsystems can make use of it, from Alexei Starovoitov.
2) SFC driver supports busy polling, from Alexandre Rames.
3) Take advantage of hash table in UDP multicast delivery, from David
Held.
4) Lighten locking, in particular by getting rid of the LRU lists, in
inet frag handling. From Florian Westphal.
5) Add support for various RFC6458 control messages in SCTP, from
Geir Ola Vaagland.
6) Allow to filter bridge forwarding database dumps by device, from
Jamal Hadi Salim.
7) virtio-net also now supports busy polling, from Jason Wang.
8) Some low level optimization tweaks in pktgen from Jesper Dangaard
Brouer.
9) Add support for ipv6 address generation modes, so that userland
can have some input into the process. From Jiri Pirko.
10) Consolidate common TCP connection request code in ipv4 and ipv6,
from Octavian Purdila.
11) New ARP packet logger in netfilter, from Pablo Neira Ayuso.
12) Generic resizable RCU hash table, with intial users in netlink and
nftables. From Thomas Graf.
13) Maintain a name assignment type so that userspace can see where a
network device name came from (enumerated by kernel, assigned
explicitly by userspace, etc.) From Tom Gundersen.
14) Automatic flow label generation on transmit in ipv6, from Tom
Herbert.
15) New packet timestamping facilities from Willem de Bruijn, meant to
assist in measuring latencies going into/out-of the packet
scheduler, latency from TCP data transmission to ACK, etc"
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1536 commits)
cxgb4 : Disable recursive mailbox commands when enabling vi
net: reduce USB network driver config options.
tg3: Modify tg3_tso_bug() to handle multiple TX rings
amd-xgbe: Perform phy connect/disconnect at dev open/stop
amd-xgbe: Use dma_set_mask_and_coherent to set DMA mask
net: sun4i-emac: fix memory leak on bad packet
sctp: fix possible seqlock seadlock in sctp_packet_transmit()
Revert "net: phy: Set the driver when registering an MDIO bus device"
cxgb4vf: Turn off SGE RX/TX Callback Timers and interrupts in PCI shutdown routine
team: Simplify return path of team_newlink
bridge: Update outdated comment on promiscuous mode
net-timestamp: ACK timestamp for bytestreams
net-timestamp: TCP timestamping
net-timestamp: SCHED timestamp on entering packet scheduler
net-timestamp: add key to disambiguate concurrent datagrams
net-timestamp: move timestamp flags out of sk_flags
net-timestamp: extend SCM_TIMESTAMPING ancillary data struct
cxgb4i : Move stray CPL definitions to cxgb4 driver
tcp: reduce spurious retransmits due to transient SACK reneging
qlcnic: Initialize dcbnl_ops before register_netdev
...
Diffstat (limited to 'drivers/net/wireless/rsi')
-rw-r--r-- | drivers/net/wireless/rsi/rsi_91x_core.c | 85 | ||||
-rw-r--r-- | drivers/net/wireless/rsi/rsi_91x_debugfs.c | 10 | ||||
-rw-r--r-- | drivers/net/wireless/rsi/rsi_91x_mac80211.c | 143 | ||||
-rw-r--r-- | drivers/net/wireless/rsi/rsi_91x_mgmt.c | 239 | ||||
-rw-r--r-- | drivers/net/wireless/rsi/rsi_91x_pkt.c | 17 | ||||
-rw-r--r-- | drivers/net/wireless/rsi/rsi_91x_sdio.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/rsi/rsi_91x_sdio_ops.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/rsi/rsi_91x_usb.c | 88 | ||||
-rw-r--r-- | drivers/net/wireless/rsi/rsi_main.h | 12 | ||||
-rw-r--r-- | drivers/net/wireless/rsi/rsi_mgmt.h | 25 | ||||
-rw-r--r-- | drivers/net/wireless/rsi/rsi_sdio.h | 8 |
11 files changed, 463 insertions, 178 deletions
diff --git a/drivers/net/wireless/rsi/rsi_91x_core.c b/drivers/net/wireless/rsi/rsi_91x_core.c index cf61d6e3eaa..f3d3995d8f6 100644 --- a/drivers/net/wireless/rsi/rsi_91x_core.c +++ b/drivers/net/wireless/rsi/rsi_91x_core.c @@ -77,6 +77,52 @@ static bool rsi_recalculate_weights(struct rsi_common *common) } /** + * rsi_get_num_pkts_dequeue() - This function determines the number of + * packets to be dequeued based on the number + * of bytes calculated using txop. + * + * @common: Pointer to the driver private structure. + * @q_num: the queue from which pkts have to be dequeued + * + * Return: pkt_num: Number of pkts to be dequeued. + */ +static u32 rsi_get_num_pkts_dequeue(struct rsi_common *common, u8 q_num) +{ + struct rsi_hw *adapter = common->priv; + struct sk_buff *skb; + u32 pkt_cnt = 0; + s16 txop = common->tx_qinfo[q_num].txop * 32; + __le16 r_txop; + struct ieee80211_rate rate; + + rate.bitrate = RSI_RATE_MCS0 * 5 * 10; /* Convert to Kbps */ + if (q_num == VI_Q) + txop = ((txop << 5) / 80); + + if (skb_queue_len(&common->tx_queue[q_num])) + skb = skb_peek(&common->tx_queue[q_num]); + else + return 0; + + do { + r_txop = ieee80211_generic_frame_duration(adapter->hw, + adapter->vifs[0], + common->band, + skb->len, &rate); + txop -= le16_to_cpu(r_txop); + pkt_cnt += 1; + /*checking if pkts are still there*/ + if (skb_queue_len(&common->tx_queue[q_num]) - pkt_cnt) + skb = skb->next; + else + break; + + } while (txop > 0); + + return pkt_cnt; +} + +/** * rsi_core_determine_hal_queue() - This function determines the queue from * which packet has to be dequeued. * @common: Pointer to the driver private structure. @@ -88,7 +134,7 @@ static u8 rsi_core_determine_hal_queue(struct rsi_common *common) bool recontend_queue = false; u32 q_len = 0; u8 q_num = INVALID_QUEUE; - u8 ii = 0, min = 0; + u8 ii = 0; if (skb_queue_len(&common->tx_queue[MGMT_SOFT_Q])) { if (!common->mgmt_q_block) @@ -96,6 +142,9 @@ static u8 rsi_core_determine_hal_queue(struct rsi_common *common) return q_num; } + if (common->hw_data_qs_blocked) + return q_num; + if (common->pkt_cnt != 0) { --common->pkt_cnt; return common->selected_qnum; @@ -106,14 +155,15 @@ get_queue_num: q_num = rsi_determine_min_weight_queue(common); - q_len = skb_queue_len(&common->tx_queue[ii]); ii = q_num; /* Selecting the queue with least back off */ for (; ii < NUM_EDCA_QUEUES; ii++) { + q_len = skb_queue_len(&common->tx_queue[ii]); if (((common->tx_qinfo[ii].pkt_contended) && - (common->tx_qinfo[ii].weight < min)) && q_len) { - min = common->tx_qinfo[ii].weight; + (common->tx_qinfo[ii].weight < common->min_weight)) && + q_len) { + common->min_weight = common->tx_qinfo[ii].weight; q_num = ii; } } @@ -140,25 +190,9 @@ get_queue_num: common->selected_qnum = q_num; q_len = skb_queue_len(&common->tx_queue[q_num]); - switch (common->selected_qnum) { - case VO_Q: - if (q_len > MAX_CONTINUOUS_VO_PKTS) - common->pkt_cnt = (MAX_CONTINUOUS_VO_PKTS - 1); - else - common->pkt_cnt = --q_len; - break; - - case VI_Q: - if (q_len > MAX_CONTINUOUS_VI_PKTS) - common->pkt_cnt = (MAX_CONTINUOUS_VI_PKTS - 1); - else - common->pkt_cnt = --q_len; - - break; - - default: - common->pkt_cnt = 0; - break; + if (q_num == VO_Q || q_num == VI_Q) { + common->pkt_cnt = rsi_get_num_pkts_dequeue(common, q_num); + common->pkt_cnt -= 1; } return q_num; @@ -252,6 +286,7 @@ void rsi_core_qos_processor(struct rsi_common *common) skb = rsi_core_dequeue_pkt(common, q_num); if (skb == NULL) { + rsi_dbg(ERR_ZONE, "skb null\n"); mutex_unlock(&common->tx_rxlock); break; } @@ -306,7 +341,8 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb) } if ((ieee80211_is_mgmt(tmp_hdr->frame_control)) || - (ieee80211_is_ctl(tmp_hdr->frame_control))) { + (ieee80211_is_ctl(tmp_hdr->frame_control)) || + (ieee80211_is_qos_nullfunc(tmp_hdr->frame_control))) { q_num = MGMT_SOFT_Q; skb->priority = q_num; } else { @@ -325,6 +361,7 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb) if ((q_num != MGMT_SOFT_Q) && ((skb_queue_len(&common->tx_queue[q_num]) + 1) >= DATA_QUEUE_WATER_MARK)) { + rsi_dbg(ERR_ZONE, "%s: sw queue full\n", __func__); if (!ieee80211_queue_stopped(adapter->hw, WME_AC(q_num))) ieee80211_stop_queue(adapter->hw, WME_AC(q_num)); rsi_set_event(&common->tx_thread.event); diff --git a/drivers/net/wireless/rsi/rsi_91x_debugfs.c b/drivers/net/wireless/rsi/rsi_91x_debugfs.c index c466246a323..828a042f903 100644 --- a/drivers/net/wireless/rsi/rsi_91x_debugfs.c +++ b/drivers/net/wireless/rsi/rsi_91x_debugfs.c @@ -145,7 +145,7 @@ static int rsi_stats_read(struct seq_file *seq, void *data) seq_printf(seq, "total_mgmt_pkt_send : %d\n", common->tx_stats.total_tx_pkt_send[MGMT_SOFT_Q]); seq_printf(seq, "total_mgmt_pkt_queued : %d\n", - skb_queue_len(&common->tx_queue[4])); + skb_queue_len(&common->tx_queue[MGMT_SOFT_Q])); seq_printf(seq, "total_mgmt_pkt_freed : %d\n", common->tx_stats.total_tx_pkt_freed[MGMT_SOFT_Q]); @@ -153,25 +153,25 @@ static int rsi_stats_read(struct seq_file *seq, void *data) seq_printf(seq, "total_data_vo_pkt_send: %8d\t", common->tx_stats.total_tx_pkt_send[VO_Q]); seq_printf(seq, "total_data_vo_pkt_queued: %8d\t", - skb_queue_len(&common->tx_queue[0])); + skb_queue_len(&common->tx_queue[VO_Q])); seq_printf(seq, "total_vo_pkt_freed: %8d\n", common->tx_stats.total_tx_pkt_freed[VO_Q]); seq_printf(seq, "total_data_vi_pkt_send: %8d\t", common->tx_stats.total_tx_pkt_send[VI_Q]); seq_printf(seq, "total_data_vi_pkt_queued: %8d\t", - skb_queue_len(&common->tx_queue[1])); + skb_queue_len(&common->tx_queue[VI_Q])); seq_printf(seq, "total_vi_pkt_freed: %8d\n", common->tx_stats.total_tx_pkt_freed[VI_Q]); seq_printf(seq, "total_data_be_pkt_send: %8d\t", common->tx_stats.total_tx_pkt_send[BE_Q]); seq_printf(seq, "total_data_be_pkt_queued: %8d\t", - skb_queue_len(&common->tx_queue[2])); + skb_queue_len(&common->tx_queue[BE_Q])); seq_printf(seq, "total_be_pkt_freed: %8d\n", common->tx_stats.total_tx_pkt_freed[BE_Q]); seq_printf(seq, "total_data_bk_pkt_send: %8d\t", common->tx_stats.total_tx_pkt_send[BK_Q]); seq_printf(seq, "total_data_bk_pkt_queued: %8d\t", - skb_queue_len(&common->tx_queue[3])); + skb_queue_len(&common->tx_queue[BK_Q])); seq_printf(seq, "total_bk_pkt_freed: %8d\n", common->tx_stats.total_tx_pkt_freed[BK_Q]); diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c index 54aaeb09deb..aeaf87bb551 100644 --- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c +++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c @@ -177,7 +177,7 @@ static void rsi_register_rates_channels(struct rsi_hw *adapter, int band) sbands->ht_cap.cap = (IEEE80211_HT_CAP_SUP_WIDTH_20_40 | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40); - sbands->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K; + sbands->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K; sbands->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE; sbands->ht_cap.mcs.rx_mask[0] = 0xff; sbands->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; @@ -185,7 +185,7 @@ static void rsi_register_rates_channels(struct rsi_hw *adapter, int band) } /** - * rsi_mac80211_attach() - This function is used to de-initialize the + * rsi_mac80211_detach() - This function is used to de-initialize the * Mac80211 stack. * @adapter: Pointer to the adapter structure. * @@ -341,6 +341,59 @@ static void rsi_mac80211_remove_interface(struct ieee80211_hw *hw, } /** + * rsi_channel_change() - This function is a performs the checks + * required for changing a channel and sets + * the channel accordingly. + * @hw: Pointer to the ieee80211_hw structure. + * + * Return: 0 on success, negative error code on failure. + */ +static int rsi_channel_change(struct ieee80211_hw *hw) +{ + struct rsi_hw *adapter = hw->priv; + struct rsi_common *common = adapter->priv; + int status = -EOPNOTSUPP; + struct ieee80211_channel *curchan = hw->conf.chandef.chan; + u16 channel = curchan->hw_value; + struct ieee80211_bss_conf *bss = &adapter->vifs[0]->bss_conf; + + rsi_dbg(INFO_ZONE, + "%s: Set channel: %d MHz type: %d channel_no %d\n", + __func__, curchan->center_freq, + curchan->flags, channel); + + if (bss->assoc) { + if (!common->hw_data_qs_blocked && + (rsi_get_connected_channel(adapter) != channel)) { + rsi_dbg(INFO_ZONE, "blk data q %d\n", channel); + if (!rsi_send_block_unblock_frame(common, true)) + common->hw_data_qs_blocked = true; + } + } + + status = rsi_band_check(common); + if (!status) + status = rsi_set_channel(adapter->priv, channel); + + if (bss->assoc) { + if (common->hw_data_qs_blocked && + (rsi_get_connected_channel(adapter) == channel)) { + rsi_dbg(INFO_ZONE, "unblk data q %d\n", channel); + if (!rsi_send_block_unblock_frame(common, false)) + common->hw_data_qs_blocked = false; + } + } else { + if (common->hw_data_qs_blocked) { + rsi_dbg(INFO_ZONE, "unblk data q %d\n", channel); + if (!rsi_send_block_unblock_frame(common, false)) + common->hw_data_qs_blocked = false; + } + } + + return status; +} + +/** * rsi_mac80211_config() - This function is a handler for configuration * requests. The stack calls this function to * change hardware configuration, e.g., channel. @@ -357,17 +410,10 @@ static int rsi_mac80211_config(struct ieee80211_hw *hw, int status = -EOPNOTSUPP; mutex_lock(&common->mutex); - if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { - struct ieee80211_channel *curchan = hw->conf.chandef.chan; - u16 channel = curchan->hw_value; - - rsi_dbg(INFO_ZONE, - "%s: Set channel: %d MHz type: %d channel_no %d\n", - __func__, curchan->center_freq, - curchan->flags, channel); - common->band = curchan->band; - status = rsi_set_channel(adapter->priv, channel); - } + + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) + status = rsi_channel_change(hw); + mutex_unlock(&common->mutex); return status; @@ -421,6 +467,15 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw, bss_conf->qos, bss_conf->aid); } + + if (changed & BSS_CHANGED_CQM) { + common->cqm_info.last_cqm_event_rssi = 0; + common->cqm_info.rssi_thold = bss_conf->cqm_rssi_thold; + common->cqm_info.rssi_hyst = bss_conf->cqm_rssi_hyst; + rsi_dbg(INFO_ZONE, "RSSI throld & hysteresis are: %d %d\n", + common->cqm_info.rssi_thold, + common->cqm_info.rssi_hyst); + } mutex_unlock(&common->mutex); } @@ -723,17 +778,17 @@ static int rsi_mac80211_set_rate_mask(struct ieee80211_hw *hw, { struct rsi_hw *adapter = hw->priv; struct rsi_common *common = adapter->priv; + enum ieee80211_band band = hw->conf.chandef.chan->band; mutex_lock(&common->mutex); + common->fixedrate_mask[band] = 0; - common->fixedrate_mask[IEEE80211_BAND_2GHZ] = 0; - - if (mask->control[IEEE80211_BAND_2GHZ].legacy == 0xfff) { - common->fixedrate_mask[IEEE80211_BAND_2GHZ] = - (mask->control[IEEE80211_BAND_2GHZ].ht_mcs[0] << 12); + if (mask->control[band].legacy == 0xfff) { + common->fixedrate_mask[band] = + (mask->control[band].ht_mcs[0] << 12); } else { - common->fixedrate_mask[IEEE80211_BAND_2GHZ] = - mask->control[IEEE80211_BAND_2GHZ].legacy; + common->fixedrate_mask[band] = + mask->control[band].legacy; } mutex_unlock(&common->mutex); @@ -741,6 +796,37 @@ static int rsi_mac80211_set_rate_mask(struct ieee80211_hw *hw, } /** + * rsi_perform_cqm() - This function performs cqm. + * @common: Pointer to the driver private structure. + * @bssid: pointer to the bssid. + * @rssi: RSSI value. + */ +static void rsi_perform_cqm(struct rsi_common *common, + u8 *bssid, + s8 rssi) +{ + struct rsi_hw *adapter = common->priv; + s8 last_event = common->cqm_info.last_cqm_event_rssi; + int thold = common->cqm_info.rssi_thold; + u32 hyst = common->cqm_info.rssi_hyst; + enum nl80211_cqm_rssi_threshold_event event; + + if (rssi < thold && (last_event == 0 || rssi < (last_event - hyst))) + event = NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW; + else if (rssi > thold && + (last_event == 0 || rssi > (last_event + hyst))) + event = NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH; + else + return; + + common->cqm_info.last_cqm_event_rssi = rssi; + rsi_dbg(INFO_ZONE, "CQM: Notifying event: %d\n", event); + ieee80211_cqm_rssi_notify(adapter->vifs[0], event, GFP_KERNEL); + + return; +} + +/** * rsi_fill_rx_status() - This function fills rx status in * ieee80211_rx_status structure. * @hw: Pointer to the ieee80211_hw structure. @@ -755,6 +841,7 @@ static void rsi_fill_rx_status(struct ieee80211_hw *hw, struct rsi_common *common, struct ieee80211_rx_status *rxs) { + struct ieee80211_bss_conf *bss = &common->priv->vifs[0]->bss_conf; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct skb_info *rx_params = (struct skb_info *)info->driver_data; struct ieee80211_hdr *hdr; @@ -770,10 +857,7 @@ static void rsi_fill_rx_status(struct ieee80211_hw *hw, rxs->signal = -(rssi); - if (channel <= 14) - rxs->band = IEEE80211_BAND_2GHZ; - else - rxs->band = IEEE80211_BAND_5GHZ; + rxs->band = common->band; freq = ieee80211_channel_to_frequency(channel, rxs->band); @@ -792,6 +876,14 @@ static void rsi_fill_rx_status(struct ieee80211_hw *hw, rxs->flag |= RX_FLAG_DECRYPTED; rxs->flag |= RX_FLAG_IV_STRIPPED; } + + /* CQM only for connected AP beacons, the RSSI is a weighted avg */ + if (bss->assoc && !(memcmp(bss->bssid, hdr->addr2, ETH_ALEN))) { + if (ieee80211_is_beacon(hdr->frame_control)) + rsi_perform_cqm(common, hdr->addr2, rxs->signal); + } + + return; } /** @@ -983,6 +1075,7 @@ int rsi_mac80211_attach(struct rsi_common *common) hw->max_tx_aggregation_subframes = 6; rsi_register_rates_channels(adapter, IEEE80211_BAND_2GHZ); + rsi_register_rates_channels(adapter, IEEE80211_BAND_5GHZ); hw->rate_control_algorithm = "AARF"; SET_IEEE80211_PERM_ADDR(hw, common->mac_addr); @@ -1000,6 +1093,8 @@ int rsi_mac80211_attach(struct rsi_common *common) wiphy->available_antennas_tx = 1; wiphy->bands[IEEE80211_BAND_2GHZ] = &adapter->sbands[IEEE80211_BAND_2GHZ]; + wiphy->bands[IEEE80211_BAND_5GHZ] = + &adapter->sbands[IEEE80211_BAND_5GHZ]; status = ieee80211_register_hw(hw); if (status) diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c index 2eefbf159bc..8d110fd9eba 100644 --- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c +++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c @@ -217,6 +217,7 @@ static void rsi_set_default_parameters(struct rsi_common *common) common->min_rate = 0xffff; common->fsm_state = FSM_CARD_NOT_READY; common->iface_down = true; + common->endpoint = EP_2GHZ_20MHZ; } /** @@ -276,7 +277,6 @@ static int rsi_load_radio_caps(struct rsi_common *common) { struct rsi_radio_caps *radio_caps; struct rsi_hw *adapter = common->priv; - struct ieee80211_hw *hw = adapter->hw; u16 inx = 0; u8 ii; u8 radio_id = 0; @@ -285,7 +285,6 @@ static int rsi_load_radio_caps(struct rsi_common *common) 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0}; - struct ieee80211_conf *conf = &hw->conf; struct sk_buff *skb; rsi_dbg(INFO_ZONE, "%s: Sending rate symbol req frame\n", __func__); @@ -307,29 +306,36 @@ static int rsi_load_radio_caps(struct rsi_common *common) if (common->channel_width == BW_40MHZ) { radio_caps->desc_word[7] |= cpu_to_le16(RSI_LMAC_CLOCK_80MHZ); radio_caps->desc_word[7] |= cpu_to_le16(RSI_ENABLE_40MHZ); - if (common->channel_width) { - radio_caps->desc_word[5] = - cpu_to_le16(common->channel_width << 12); - radio_caps->desc_word[5] |= cpu_to_le16(FULL40M_ENABLE); - } - if (conf_is_ht40_minus(conf)) { - radio_caps->desc_word[5] = 0; - radio_caps->desc_word[5] |= - cpu_to_le16(LOWER_20_ENABLE); - radio_caps->desc_word[5] |= - cpu_to_le16(LOWER_20_ENABLE >> 12); - } - - if (conf_is_ht40_plus(conf)) { - radio_caps->desc_word[5] = 0; - radio_caps->desc_word[5] |= - cpu_to_le16(UPPER_20_ENABLE); - radio_caps->desc_word[5] |= - cpu_to_le16(UPPER_20_ENABLE >> 12); + if (common->fsm_state == FSM_MAC_INIT_DONE) { + struct ieee80211_hw *hw = adapter->hw; + struct ieee80211_conf *conf = &hw->conf; + if (conf_is_ht40_plus(conf)) { + radio_caps->desc_word[5] = + cpu_to_le16(LOWER_20_ENABLE); + radio_caps->desc_word[5] |= + cpu_to_le16(LOWER_20_ENABLE >> 12); + } else if (conf_is_ht40_minus(conf)) { + radio_caps->desc_word[5] = + cpu_to_le16(UPPER_20_ENABLE); + radio_caps->desc_word[5] |= + cpu_to_le16(UPPER_20_ENABLE >> 12); + } else { + radio_caps->desc_word[5] = + cpu_to_le16(BW_40MHZ << 12); + radio_caps->desc_word[5] |= + cpu_to_le16(FULL40M_ENABLE); + } } } + radio_caps->sifs_tx_11n = cpu_to_le16(SIFS_TX_11N_VALUE); + radio_caps->sifs_tx_11b = cpu_to_le16(SIFS_TX_11B_VALUE); + radio_caps->slot_rx_11n = cpu_to_le16(SHORT_SLOT_VALUE); + radio_caps->ofdm_ack_tout = cpu_to_le16(OFDM_ACK_TOUT_VALUE); + radio_caps->cck_ack_tout = cpu_to_le16(CCK_ACK_TOUT_VALUE); + radio_caps->preamble_type = cpu_to_le16(LONG_PREAMBLE); + radio_caps->desc_word[7] |= cpu_to_le16(radio_id << 8); for (ii = 0; ii < MAX_HW_QUEUES; ii++) { @@ -588,7 +594,7 @@ static int rsi_program_bb_rf(struct rsi_common *common) mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12); mgmt_frame->desc_word[1] = cpu_to_le16(BBP_PROG_IN_TA); - mgmt_frame->desc_word[4] = cpu_to_le16(common->endpoint << 8); + mgmt_frame->desc_word[4] = cpu_to_le16(common->endpoint); if (common->rf_reset) { mgmt_frame->desc_word[7] = cpu_to_le16(RF_RESET_ENABLE); @@ -615,6 +621,9 @@ int rsi_set_vap_capabilities(struct rsi_common *common, enum opmode mode) { struct sk_buff *skb = NULL; struct rsi_vap_caps *vap_caps; + struct rsi_hw *adapter = common->priv; + struct ieee80211_hw *hw = adapter->hw; + struct ieee80211_conf *conf = &hw->conf; u16 vap_id = 0; rsi_dbg(MGMT_TX_ZONE, "%s: Sending VAP capabilities frame\n", __func__); @@ -644,13 +653,24 @@ int rsi_set_vap_capabilities(struct rsi_common *common, enum opmode mode) vap_caps->frag_threshold = cpu_to_le16(IEEE80211_MAX_FRAG_THRESHOLD); vap_caps->rts_threshold = cpu_to_le16(common->rts_threshold); - vap_caps->default_mgmt_rate = 0; - if (conf_is_ht40(&common->priv->hw->conf)) { - vap_caps->default_ctrl_rate = - cpu_to_le32(RSI_RATE_6 | FULL40M_ENABLE << 16); - } else { + vap_caps->default_mgmt_rate = cpu_to_le32(RSI_RATE_6); + + if (common->band == IEEE80211_BAND_5GHZ) { vap_caps->default_ctrl_rate = cpu_to_le32(RSI_RATE_6); + if (conf_is_ht40(&common->priv->hw->conf)) { + vap_caps->default_ctrl_rate |= + cpu_to_le32(FULL40M_ENABLE << 16); + } + } else { + vap_caps->default_ctrl_rate = cpu_to_le32(RSI_RATE_1); + if (conf_is_ht40_minus(conf)) + vap_caps->default_ctrl_rate |= + cpu_to_le32(UPPER_20_ENABLE << 16); + else if (conf_is_ht40_plus(conf)) + vap_caps->default_ctrl_rate |= + cpu_to_le32(LOWER_20_ENABLE << 16); } + vap_caps->default_data_rate = 0; vap_caps->beacon_interval = cpu_to_le16(200); vap_caps->dtim_period = cpu_to_le16(4); @@ -827,6 +847,63 @@ static int rsi_send_reset_mac(struct rsi_common *common) } /** + * rsi_band_check() - This function programs the band + * @common: Pointer to the driver private structure. + * + * Return: 0 on success, corresponding error code on failure. + */ +int rsi_band_check(struct rsi_common *common) +{ + struct rsi_hw *adapter = common->priv; + struct ieee80211_hw *hw = adapter->hw; + u8 prev_bw = common->channel_width; + u8 prev_ep = common->endpoint; + struct ieee80211_channel *curchan = hw->conf.chandef.chan; + int status = 0; + + if (common->band != curchan->band) { + common->rf_reset = 1; + common->band = curchan->band; + } + + if ((hw->conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) || + (hw->conf.chandef.width == NL80211_CHAN_WIDTH_20)) + common->channel_width = BW_20MHZ; + else + common->channel_width = BW_40MHZ; + + if (common->band == IEEE80211_BAND_2GHZ) { + if (common->channel_width) + common->endpoint = EP_2GHZ_40MHZ; + else + common->endpoint = EP_2GHZ_20MHZ; + } else { + if (common->channel_width) + common->endpoint = EP_5GHZ_40MHZ; + else + common->endpoint = EP_5GHZ_20MHZ; + } + + if (common->endpoint != prev_ep) { + status = rsi_program_bb_rf(common); + if (status) + return status; + } + + if (common->channel_width != prev_bw) { + status = rsi_load_bootup_params(common); + if (status) + return status; + + status = rsi_load_radio_caps(common); + if (status) + return status; + } + + return status; +} + +/** * rsi_set_channel() - This function programs the channel. * @common: Pointer to the driver private structure. * @channel: Channel value to be set. @@ -841,23 +918,6 @@ int rsi_set_channel(struct rsi_common *common, u16 channel) rsi_dbg(MGMT_TX_ZONE, "%s: Sending scan req frame\n", __func__); - if (common->band == IEEE80211_BAND_5GHZ) { - if ((channel >= 36) && (channel <= 64)) - channel = ((channel - 32) / 4); - else if ((channel > 64) && (channel <= 140)) - channel = ((channel - 102) / 4) + 8; - else if (channel >= 149) - channel = ((channel - 151) / 4) + 18; - else - return -EINVAL; - } else { - if (channel > 14) { - rsi_dbg(ERR_ZONE, "%s: Invalid chno %d, band = %d\n", - __func__, channel, common->band); - return -EINVAL; - } - } - skb = dev_alloc_skb(FRAME_DESC_SZ); if (!skb) { rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n", @@ -877,6 +937,7 @@ int rsi_set_channel(struct rsi_common *common, u16 channel) (RSI_RF_TYPE << 4)); mgmt_frame->desc_word[5] = cpu_to_le16(0x01); + mgmt_frame->desc_word[6] = cpu_to_le16(0x12); if (common->channel_width == BW_40MHZ) mgmt_frame->desc_word[5] |= cpu_to_le16(0x1 << 8); @@ -950,7 +1011,7 @@ static int rsi_send_auto_rate_request(struct rsi_common *common) struct ieee80211_hw *hw = common->priv->hw; u8 band = hw->conf.chandef.chan->band; u8 num_supported_rates = 0; - u8 rate_offset = 0; + u8 rate_table_offset, rate_offset = 0; u32 rate_bitmap = common->bitrate_mask[band]; u16 *selected_rates, min_rate; @@ -986,14 +1047,19 @@ static int rsi_send_auto_rate_request(struct rsi_common *common) if (common->channel_width == BW_40MHZ) auto_rate->desc_word[7] |= cpu_to_le16(1); - if (band == IEEE80211_BAND_2GHZ) - min_rate = STD_RATE_01; - else - min_rate = STD_RATE_06; + if (band == IEEE80211_BAND_2GHZ) { + min_rate = RSI_RATE_1; + rate_table_offset = 0; + } else { + min_rate = RSI_RATE_6; + rate_table_offset = 4; + } - for (ii = 0, jj = 0; ii < ARRAY_SIZE(rsi_rates); ii++) { + for (ii = 0, jj = 0; + ii < (ARRAY_SIZE(rsi_rates) - rate_table_offset); ii++) { if (rate_bitmap & BIT(ii)) { - selected_rates[jj++] = (rsi_rates[ii].bitrate / 5); + selected_rates[jj++] = + (rsi_rates[ii + rate_table_offset].bitrate / 5); rate_offset++; } } @@ -1006,13 +1072,6 @@ static int rsi_send_auto_rate_request(struct rsi_common *common) rate_offset += ARRAY_SIZE(mcs); } - if (rate_offset < (RSI_TBL_SZ / 2) - 1) { - for (ii = jj; ii < (RSI_TBL_SZ / 2); ii++) { - selected_rates[jj++] = min_rate; - rate_offset++; - } - } - sort(selected_rates, jj, sizeof(u16), &rsi_compare, NULL); /* mapping the rates to RSI rates */ @@ -1028,25 +1087,25 @@ static int rsi_send_auto_rate_request(struct rsi_common *common) /* loading HT rates in the bottom half of the auto rate table */ if (common->vif_info[0].is_ht) { - if (common->vif_info[0].sgi) - auto_rate->supported_rates[rate_offset++] = - cpu_to_le16(RSI_RATE_MCS7_SG); - for (ii = rate_offset, kk = ARRAY_SIZE(rsi_mcsrates) - 1; ii < rate_offset + 2 * ARRAY_SIZE(rsi_mcsrates); ii++) { - if (common->vif_info[0].sgi) + if (common->vif_info[0].sgi || + conf_is_ht40(&common->priv->hw->conf)) auto_rate->supported_rates[ii++] = cpu_to_le16(rsi_mcsrates[kk] | BIT(9)); auto_rate->supported_rates[ii] = cpu_to_le16(rsi_mcsrates[kk--]); } - for (; ii < RSI_TBL_SZ; ii++) { + for (; ii < (RSI_TBL_SZ - 1); ii++) { auto_rate->supported_rates[ii] = cpu_to_le16(rsi_mcsrates[0]); } } + for (; ii < RSI_TBL_SZ; ii++) + auto_rate->supported_rates[ii] = cpu_to_le16(min_rate); + auto_rate->num_supported_rates = cpu_to_le16(num_supported_rates * 2); auto_rate->moderate_rate_inx = cpu_to_le16(num_supported_rates / 2); auto_rate->desc_word[7] |= cpu_to_le16(0 << 8); @@ -1141,6 +1200,49 @@ static int rsi_eeprom_read(struct rsi_common *common) } /** + * This function sends a frame to block/unblock + * data queues in the firmware + * + * @param common Pointer to the driver private structure. + * @param block event - block if true, unblock if false + * @return 0 on success, -1 on failure. + */ +int rsi_send_block_unblock_frame(struct rsi_common *common, bool block_event) +{ + struct rsi_mac_frame *mgmt_frame; + struct sk_buff *skb; + + rsi_dbg(MGMT_TX_ZONE, "%s: Sending block/unblock frame\n", __func__); + + skb = dev_alloc_skb(FRAME_DESC_SZ); + if (!skb) { + rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n", + __func__); + return -ENOMEM; + } + + memset(skb->data, 0, FRAME_DESC_SZ); + mgmt_frame = (struct rsi_mac_frame *)skb->data; + + mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12); + mgmt_frame->desc_word[1] = cpu_to_le16(BLOCK_HW_QUEUE); + + if (block_event == true) { + rsi_dbg(INFO_ZONE, "blocking the data qs\n"); + mgmt_frame->desc_word[4] = cpu_to_le16(0xf); + } else { + rsi_dbg(INFO_ZONE, "unblocking the data qs\n"); + mgmt_frame->desc_word[5] = cpu_to_le16(0xf); + } + + skb_put(skb, FRAME_DESC_SZ); + + return rsi_send_internal_mgmt_frame(common, skb); + +} + + +/** * rsi_handle_ta_confirm_type() - This function handles the confirm frames. * @common: Pointer to the driver private structure. * @msg: Pointer to received packet. @@ -1164,7 +1266,7 @@ static int rsi_handle_ta_confirm_type(struct rsi_common *common, common->fsm_state = FSM_EEPROM_READ_MAC_ADDR; } } else { - rsi_dbg(ERR_ZONE, + rsi_dbg(INFO_ZONE, "%s: Received bootup params cfm in %d state\n", __func__, common->fsm_state); return 0; @@ -1227,7 +1329,7 @@ static int rsi_handle_ta_confirm_type(struct rsi_common *common, __func__); } } else { - rsi_dbg(ERR_ZONE, + rsi_dbg(INFO_ZONE, "%s: Received radio caps cfm in %d state\n", __func__, common->fsm_state); return 0; @@ -1245,7 +1347,10 @@ static int rsi_handle_ta_confirm_type(struct rsi_common *common, return rsi_mac80211_attach(common); } } else { - goto out; + rsi_dbg(INFO_ZONE, + "%s: Received bbb_rf cfm in %d state\n", + __func__, common->fsm_state); + return 0; } break; diff --git a/drivers/net/wireless/rsi/rsi_91x_pkt.c b/drivers/net/wireless/rsi/rsi_91x_pkt.c index 8e48e72bae2..702593f1999 100644 --- a/drivers/net/wireless/rsi/rsi_91x_pkt.c +++ b/drivers/net/wireless/rsi/rsi_91x_pkt.c @@ -81,6 +81,16 @@ int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb) /* Send fixed rate */ frame_desc[3] = cpu_to_le16(RATE_INFO_ENABLE); frame_desc[4] = cpu_to_le16(common->min_rate); + + if (conf_is_ht40(&common->priv->hw->conf)) + frame_desc[5] = cpu_to_le16(FULL40M_ENABLE); + + if (common->vif_info[0].sgi) { + if (common->min_rate & 0x100) /* Only MCS rates */ + frame_desc[4] |= + cpu_to_le16(ENABLE_SHORTGI_RATE); + } + } frame_desc[6] |= cpu_to_le16(seq_num & 0xfff); @@ -116,6 +126,8 @@ int rsi_send_mgmt_pkt(struct rsi_common *common, struct ieee80211_hdr *wh = NULL; struct ieee80211_tx_info *info; struct ieee80211_bss_conf *bss = NULL; + struct ieee80211_hw *hw = adapter->hw; + struct ieee80211_conf *conf = &hw->conf; struct skb_info *tx_params; int status = -E2BIG; __le16 *msg = NULL; @@ -175,6 +187,11 @@ int rsi_send_mgmt_pkt(struct rsi_common *common, else msg[4] = cpu_to_le16((RSI_RATE_6 & 0x0f) | RSI_11G_MODE); + if (conf_is_ht40(conf)) { + msg[4] = cpu_to_le16(0xB | RSI_11G_MODE); + msg[5] = cpu_to_le16(0x6); + } + /* Indicate to firmware to give cfm */ if ((skb->data[16] == IEEE80211_STYPE_PROBE_REQ) && (!bss->assoc)) { msg[1] |= cpu_to_le16(BIT(10)); diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio.c b/drivers/net/wireless/rsi/rsi_91x_sdio.c index 46e7af446f0..8428858204a 100644 --- a/drivers/net/wireless/rsi/rsi_91x_sdio.c +++ b/drivers/net/wireless/rsi/rsi_91x_sdio.c @@ -820,9 +820,11 @@ static struct sdio_driver rsi_driver = { */ static int rsi_module_init(void) { - sdio_register_driver(&rsi_driver); + int ret; + + ret = sdio_register_driver(&rsi_driver); rsi_dbg(INIT_ZONE, "%s: Registering driver\n", __func__); - return 0; + return ret; } /** diff --git a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c index 20d11ccfffe..4834a9abc17 100644 --- a/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c +++ b/drivers/net/wireless/rsi/rsi_91x_sdio_ops.c @@ -401,14 +401,16 @@ void rsi_interrupt_handler(struct rsi_hw *adapter) case BUFFER_AVAILABLE: dev->rx_info.watch_bufferfull_count = 0; dev->rx_info.buffer_full = false; + dev->rx_info.semi_buffer_full = false; dev->rx_info.mgmt_buffer_full = false; rsi_sdio_ack_intr(common->priv, (1 << PKT_BUFF_AVAILABLE)); - rsi_set_event((&common->tx_thread.event)); + rsi_set_event(&common->tx_thread.event); + rsi_dbg(ISR_ZONE, - "%s: ==> BUFFER_AVILABLE <==\n", + "%s: ==> BUFFER_AVAILABLE <==\n", __func__); - dev->rx_info.buf_avilable_counter++; + dev->rx_info.buf_available_counter++; break; case FIRMWARE_ASSERT_IND: diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c index 4c46e5631e2..ef5d394f185 100644 --- a/drivers/net/wireless/rsi/rsi_91x_usb.c +++ b/drivers/net/wireless/rsi/rsi_91x_usb.c @@ -25,7 +25,7 @@ * @len: Length to be written. * @endpoint: Type of endpoint. * - * Return: status: 0 on success, -1 on failure. + * Return: status: 0 on success, a negative error code on failure. */ static int rsi_usb_card_write(struct rsi_hw *adapter, void *buf, @@ -60,7 +60,7 @@ static int rsi_usb_card_write(struct rsi_hw *adapter, * @data: Pointer to the data that has to be written. * @count: Number of multiple bytes to be written. * - * Return: 0 on success, -1 on failure. + * Return: 0 on success, a negative error code on failure. */ static int rsi_write_multiple(struct rsi_hw *adapter, u8 endpoint, @@ -147,7 +147,7 @@ static int rsi_find_bulk_in_and_out_endpoints(struct usb_interface *interface, * @value: Value to be read. * @len: length of data to be read. * - * Return: status: 0 on success, -1 on failure. + * Return: status: 0 on success, a negative error code on failure. */ static int rsi_usb_reg_read(struct usb_device *usbdev, u32 reg, @@ -189,7 +189,7 @@ static int rsi_usb_reg_read(struct usb_device *usbdev, * @value: Value to write. * @len: Length of data to be written. * - * Return: status: 0 on success, -1 on failure. + * Return: status: 0 on success, a negative error code on failure. */ static int rsi_usb_reg_write(struct usb_device *usbdev, u32 reg, @@ -249,7 +249,7 @@ static void rsi_rx_done_handler(struct urb *urb) * rsi_rx_urb_submit() - This function submits the given URB to the USB stack. * @adapter: Pointer to the adapter structure. * - * Return: 0 on success, -1 on failure. + * Return: 0 on success, a negative error code on failure. */ static int rsi_rx_urb_submit(struct rsi_hw *adapter) { @@ -281,7 +281,7 @@ static int rsi_rx_urb_submit(struct rsi_hw *adapter) * @data: Pointer to the data that has to be written. * @count: Number of multiple bytes to be written on to the registers. * - * Return: status: 0 on success, -1 on failure. + * Return: status: 0 on success, a negative error code on failure. */ int rsi_usb_write_register_multiple(struct rsi_hw *adapter, u32 addr, @@ -331,7 +331,7 @@ int rsi_usb_write_register_multiple(struct rsi_hw *adapter, * @pkt: Pointer to the data to be written on to the card. * @len: Length of the data to be written on to the card. * - * Return: 0 on success, -1 on failure. + * Return: 0 on success, a negative error code on failure. */ static int rsi_usb_host_intf_write_pkt(struct rsi_hw *adapter, u8 *pkt, @@ -359,6 +359,7 @@ static void rsi_deinit_usb_interface(struct rsi_hw *adapter) struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; rsi_kill_thread(&dev->rx_thread); + usb_free_urb(dev->rx_usb_urb[0]); kfree(adapter->priv->rx_data_pkt); kfree(dev->tx_buffer); } @@ -368,7 +369,7 @@ static void rsi_deinit_usb_interface(struct rsi_hw *adapter) * @adapter: Pointer to the adapter structure. * @pfunction: Pointer to USB interface structure. * - * Return: 0 on success, -1 on failure. + * Return: 0 on success, a negative error code on failure. */ static int rsi_init_usb_interface(struct rsi_hw *adapter, struct usb_interface *pfunction) @@ -397,8 +398,16 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter, return -ENOMEM; } - rsi_dev->tx_buffer = kmalloc(2048, GFP_ATOMIC); + rsi_dev->tx_buffer = kmalloc(2048, GFP_KERNEL); + if (!rsi_dev->tx_buffer) { + status = -ENOMEM; + goto fail_tx; + } rsi_dev->rx_usb_urb[0] = usb_alloc_urb(0, GFP_KERNEL); + if (!rsi_dev->rx_usb_urb[0]) { + status = -ENOMEM; + goto fail_rx; + } rsi_dev->rx_usb_urb[0]->transfer_buffer = adapter->priv->rx_data_pkt; rsi_dev->tx_blk_size = 252; @@ -413,7 +422,7 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter, rsi_usb_rx_thread, "RX-Thread"); if (status) { rsi_dbg(ERR_ZONE, "%s: Unable to init rx thrd\n", __func__); - goto fail; + goto fail_thread; } #ifdef CONFIG_RSI_DEBUGFS @@ -424,8 +433,11 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter, rsi_dbg(INIT_ZONE, "%s: Enabled the interface\n", __func__); return 0; -fail: +fail_thread: + usb_free_urb(rsi_dev->rx_usb_urb[0]); +fail_rx: kfree(rsi_dev->tx_buffer); +fail_tx: kfree(common->rx_data_pkt); return status; } @@ -437,7 +449,7 @@ fail: * @pfunction: Pointer to the USB interface structure. * @id: Pointer to the usb_device_id structure. * - * Return: 0 on success, -1 on failure. + * Return: 0 on success, a negative error code on failure. */ static int rsi_probe(struct usb_interface *pfunction, const struct usb_device_id *id) @@ -445,6 +457,7 @@ static int rsi_probe(struct usb_interface *pfunction, struct rsi_hw *adapter; struct rsi_91x_usbdev *dev; u16 fw_status; + int status; rsi_dbg(INIT_ZONE, "%s: Init function called\n", __func__); @@ -452,10 +465,11 @@ static int rsi_probe(struct usb_interface *pfunction, if (!adapter) { rsi_dbg(ERR_ZONE, "%s: Failed to init os intf ops\n", __func__); - return 1; + return -ENOMEM; } - if (rsi_init_usb_interface(adapter, pfunction)) { + status = rsi_init_usb_interface(adapter, pfunction); + if (status) { rsi_dbg(ERR_ZONE, "%s: Failed to init usb interface\n", __func__); goto err; @@ -465,26 +479,30 @@ static int rsi_probe(struct usb_interface *pfunction, dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; - if (rsi_usb_reg_read(dev->usbdev, FW_STATUS_REG, &fw_status, 2) < 0) + status = rsi_usb_reg_read(dev->usbdev, FW_STATUS_REG, &fw_status, 2); + if (status) goto err1; else fw_status &= 1; if (!fw_status) { - if (rsi_usb_device_init(adapter->priv)) { + status = rsi_usb_device_init(adapter->priv); + if (status) { rsi_dbg(ERR_ZONE, "%s: Failed in device init\n", __func__); goto err1; } - if (rsi_usb_reg_write(dev->usbdev, - USB_INTERNAL_REG_1, - RSI_USB_READY_MAGIC_NUM, 1) < 0) + status = rsi_usb_reg_write(dev->usbdev, + USB_INTERNAL_REG_1, + RSI_USB_READY_MAGIC_NUM, 1); + if (status) goto err1; rsi_dbg(INIT_ZONE, "%s: Performed device init\n", __func__); } - if (rsi_rx_urb_submit(adapter)) + status = rsi_rx_urb_submit(adapter); + if (status) goto err1; return 0; @@ -493,7 +511,7 @@ err1: err: rsi_91x_deinit(adapter); rsi_dbg(ERR_ZONE, "%s: Failed in probe...Exiting\n", __func__); - return 1; + return status; } /** @@ -550,33 +568,7 @@ static struct usb_driver rsi_driver = { #endif }; -/** - * rsi_module_init() - This function registers the client driver. - * @void: Void. - * - * Return: 0 on success. - */ -static int rsi_module_init(void) -{ - usb_register(&rsi_driver); - rsi_dbg(INIT_ZONE, "%s: Registering driver\n", __func__); - return 0; -} - -/** - * rsi_module_exit() - This function unregisters the client driver. - * @void: Void. - * - * Return: None. - */ -static void rsi_module_exit(void) -{ - usb_deregister(&rsi_driver); - rsi_dbg(INFO_ZONE, "%s: Unregistering driver\n", __func__); -} - -module_init(rsi_module_init); -module_exit(rsi_module_exit); +module_usb_driver(rsi_driver); MODULE_AUTHOR("Redpine Signals Inc"); MODULE_DESCRIPTION("Common USB layer for RSI drivers"); diff --git a/drivers/net/wireless/rsi/rsi_main.h b/drivers/net/wireless/rsi/rsi_main.h index 2cb73e7edb9..5baed945f60 100644 --- a/drivers/net/wireless/rsi/rsi_main.h +++ b/drivers/net/wireless/rsi/rsi_main.h @@ -115,6 +115,7 @@ struct wmm_qinfo { s32 weight; s32 wme_params; s32 pkt_contended; + s32 txop; }; struct transmit_q_stats { @@ -141,6 +142,12 @@ struct rsi_thread { atomic_t thread_done; }; +struct cqm_info { + s8 last_cqm_event_rssi; + int rssi_thold; + u32 rssi_hyst; +}; + struct rsi_hw; struct rsi_common { @@ -192,6 +199,11 @@ struct rsi_common { u8 selected_qnum; u32 pkt_cnt; u8 min_weight; + + /* bgscan related */ + struct cqm_info cqm_info; + + bool hw_data_qs_blocked; }; struct rsi_hw { diff --git a/drivers/net/wireless/rsi/rsi_mgmt.h b/drivers/net/wireless/rsi/rsi_mgmt.h index 225215a3b8b..3741173fd3a 100644 --- a/drivers/net/wireless/rsi/rsi_mgmt.h +++ b/drivers/net/wireless/rsi/rsi_mgmt.h @@ -69,6 +69,7 @@ #define RSI_LMAC_CLOCK_80MHZ 0x1 #define RSI_ENABLE_40MHZ (0x1 << 3) +#define ENABLE_SHORTGI_RATE BIT(9) #define RX_BA_INDICATION 1 #define RSI_TBL_SZ 40 @@ -123,6 +124,20 @@ #define BW_20MHZ 0 #define BW_40MHZ 1 +#define EP_2GHZ_20MHZ 0 +#define EP_2GHZ_40MHZ 1 +#define EP_5GHZ_20MHZ 2 +#define EP_5GHZ_40MHZ 3 + +#define SIFS_TX_11N_VALUE 580 +#define SIFS_TX_11B_VALUE 346 +#define SHORT_SLOT_VALUE 360 +#define LONG_SLOT_VALUE 640 +#define OFDM_ACK_TOUT_VALUE 2720 +#define CCK_ACK_TOUT_VALUE 9440 +#define LONG_PREAMBLE 0x0000 +#define SHORT_PREAMBLE 0x0001 + #define RSI_SUPP_FILTERS (FIF_ALLMULTI | FIF_PROBE_REQ |\ FIF_BCN_PRBRESP_PROMISC) enum opmode { @@ -153,7 +168,7 @@ enum cmd_frame_type { SCAN_REQUEST, TSF_UPDATE, PEER_NOTIFY, - BLOCK_UNBLOCK, + BLOCK_HW_QUEUE, SET_KEY_REQ, AUTO_RATE_IND, BOOTUP_PARAMS_REQUEST, @@ -238,6 +253,12 @@ struct rsi_radio_caps { u8 num_11n_rates; u8 num_11ac_rates; __le16 gcpd_per_rate[20]; + __le16 sifs_tx_11n; + __le16 sifs_tx_11b; + __le16 slot_rx_11n; + __le16 ofdm_ack_tout; + __le16 cck_ack_tout; + __le16 preamble_type; } __packed; static inline u32 rsi_get_queueno(u8 *addr, u16 offset) @@ -272,6 +293,7 @@ int rsi_send_aggregation_params_frame(struct rsi_common *common, u16 tid, int rsi_hal_load_key(struct rsi_common *common, u8 *data, u16 key_len, u8 key_type, u8 key_id, u32 cipher); int rsi_set_channel(struct rsi_common *common, u16 chno); +int rsi_send_block_unblock_frame(struct rsi_common *common, bool event); void rsi_inform_bss_status(struct rsi_common *common, u8 status, const u8 *bssid, u8 qos_enable, u16 aid); void rsi_indicate_pkt_to_os(struct rsi_common *common, struct sk_buff *skb); @@ -283,4 +305,5 @@ void rsi_core_qos_processor(struct rsi_common *common); void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb); int rsi_send_mgmt_pkt(struct rsi_common *common, struct sk_buff *skb); int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb); +int rsi_band_check(struct rsi_common *common); #endif diff --git a/drivers/net/wireless/rsi/rsi_sdio.h b/drivers/net/wireless/rsi/rsi_sdio.h index df4b5e20e05..c7e8f2be790 100644 --- a/drivers/net/wireless/rsi/rsi_sdio.h +++ b/drivers/net/wireless/rsi/rsi_sdio.h @@ -30,7 +30,7 @@ enum sdio_interrupt_type { BUFFER_FULL = 0x0, - BUFFER_AVAILABLE = 0x1, + BUFFER_AVAILABLE = 0x2, FIRMWARE_ASSERT_IND = 0x3, MSDU_PACKET_PENDING = 0x4, UNKNOWN_INT = 0XE @@ -42,7 +42,7 @@ enum sdio_interrupt_type { #define PKT_MGMT_BUFF_FULL 2 #define MSDU_PKT_PENDING 3 /* Interrupt Bit Related Macros */ -#define PKT_BUFF_AVAILABLE 0 +#define PKT_BUFF_AVAILABLE 1 #define FW_ASSERT_IND 2 #define RSI_DEVICE_BUFFER_STATUS_REGISTER 0xf3 @@ -84,7 +84,7 @@ enum sdio_interrupt_type { #define TA_HOLD_THREAD_VALUE cpu_to_le32(0xF) #define TA_RELEASE_THREAD_VALUE cpu_to_le32(0xF) #define TA_BASE_ADDR 0x2200 -#define MISC_CFG_BASE_ADDR 0x4150 +#define MISC_CFG_BASE_ADDR 0x4105 struct receive_info { bool buffer_full; @@ -98,7 +98,7 @@ struct receive_info { u32 total_sdio_msdu_pending_intr; u32 total_sdio_unknown_intr; u32 buf_full_counter; - u32 buf_avilable_counter; + u32 buf_available_counter; }; struct rsi_91x_sdiodev { |