diff options
Diffstat (limited to 'drivers')
98 files changed, 1556 insertions, 1895 deletions
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c index 2c1798e38abd..12da68ec48ba 100644 --- a/drivers/bcma/main.c +++ b/drivers/bcma/main.c @@ -136,17 +136,17 @@ static bool bcma_is_core_needed_early(u16 core_id) return false; } -static struct device_node *bcma_of_find_child_device(struct platform_device *parent, +static struct device_node *bcma_of_find_child_device(struct device *parent, struct bcma_device *core) { struct device_node *node; u64 size; const __be32 *reg; - if (!parent || !parent->dev.of_node) + if (!parent->of_node) return NULL; - for_each_child_of_node(parent->dev.of_node, node) { + for_each_child_of_node(parent->of_node, node) { reg = of_get_address(node, 0, &size, NULL); if (!reg) continue; @@ -156,7 +156,7 @@ static struct device_node *bcma_of_find_child_device(struct platform_device *par return NULL; } -static int bcma_of_irq_parse(struct platform_device *parent, +static int bcma_of_irq_parse(struct device *parent, struct bcma_device *core, struct of_phandle_args *out_irq, int num) { @@ -169,7 +169,7 @@ static int bcma_of_irq_parse(struct platform_device *parent, return rc; } - out_irq->np = parent->dev.of_node; + out_irq->np = parent->of_node; out_irq->args_count = 1; out_irq->args[0] = num; @@ -177,13 +177,13 @@ static int bcma_of_irq_parse(struct platform_device *parent, return of_irq_parse_raw(laddr, out_irq); } -static unsigned int bcma_of_get_irq(struct platform_device *parent, +static unsigned int bcma_of_get_irq(struct device *parent, struct bcma_device *core, int num) { struct of_phandle_args out_irq; int ret; - if (!IS_ENABLED(CONFIG_OF_IRQ) || !parent || !parent->dev.of_node) + if (!IS_ENABLED(CONFIG_OF_IRQ) || !parent->of_node) return 0; ret = bcma_of_irq_parse(parent, core, &out_irq, num); @@ -196,7 +196,7 @@ static unsigned int bcma_of_get_irq(struct platform_device *parent, return irq_create_of_mapping(&out_irq); } -static void bcma_of_fill_device(struct platform_device *parent, +static void bcma_of_fill_device(struct device *parent, struct bcma_device *core) { struct device_node *node; @@ -227,7 +227,7 @@ unsigned int bcma_core_irq(struct bcma_device *core, int num) return mips_irq <= 4 ? mips_irq + 2 : 0; } if (bus->host_pdev) - return bcma_of_get_irq(bus->host_pdev, core, num); + return bcma_of_get_irq(&bus->host_pdev->dev, core, num); return 0; case BCMA_HOSTTYPE_SDIO: return 0; @@ -253,7 +253,8 @@ void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core) if (IS_ENABLED(CONFIG_OF) && bus->host_pdev) { core->dma_dev = &bus->host_pdev->dev; core->dev.parent = &bus->host_pdev->dev; - bcma_of_fill_device(bus->host_pdev, core); + if (core->dev.parent) + bcma_of_fill_device(core->dev.parent, core); } else { core->dev.dma_mask = &core->dev.coherent_dma_mask; core->dma_dev = &core->dev; @@ -633,8 +634,11 @@ static int bcma_device_probe(struct device *dev) drv); int err = 0; + get_device(dev); if (adrv->probe) err = adrv->probe(core); + if (err) + put_device(dev); return err; } @@ -647,6 +651,7 @@ static int bcma_device_remove(struct device *dev) if (adrv->remove) adrv->remove(core); + put_device(dev); return 0; } diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c index 72139b579b18..5bc2ba214735 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c @@ -1104,6 +1104,7 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = { BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4339), BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43430), BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4345), + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43455), BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354), BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4356), { /* end: all zeroes */ } diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h index e21f7600122b..76693df34742 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h @@ -218,9 +218,6 @@ int brcmf_bus_get_memdump(struct brcmf_bus *bus, void *data, size_t len) * interface functions from common layer */ -bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, struct sk_buff *pkt, - int prec); - /* Receive frame for delivery to OS. Callee disposes of rxp. */ void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp, bool handle_event); /* Receive async event packet from firmware. Callee disposes of rxp. */ @@ -241,13 +238,12 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success); /* Configure the "global" bus state used by upper layers */ void brcmf_bus_change_state(struct brcmf_bus *bus, enum brcmf_bus_state state); -int brcmf_bus_start(struct device *dev); +int brcmf_bus_started(struct device *dev); s32 brcmf_iovar_data_set(struct device *dev, char *name, void *data, u32 len); void brcmf_bus_add_txhdrlen(struct device *dev, uint len); #ifdef CONFIG_BRCMFMAC_SDIO void brcmf_sdio_exit(void); -void brcmf_sdio_init(void); void brcmf_sdio_register(void); #endif #ifdef CONFIG_BRCMFMAC_USB diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 15eaf722b54b..0e28d0710af5 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -138,7 +138,6 @@ static struct ieee80211_rate __wl_rates[] = { .band = NL80211_BAND_2GHZ, \ .center_freq = (_freq), \ .hw_value = (_channel), \ - .flags = IEEE80211_CHAN_DISABLED, \ .max_antenna_gain = 0, \ .max_power = 30, \ } @@ -147,7 +146,6 @@ static struct ieee80211_rate __wl_rates[] = { .band = NL80211_BAND_5GHZ, \ .center_freq = 5000 + (5 * (_channel)), \ .hw_value = (_channel), \ - .flags = IEEE80211_CHAN_DISABLED, \ .max_antenna_gain = 0, \ .max_power = 30, \ } @@ -328,7 +326,7 @@ u16 channel_to_chanspec(struct brcmu_d11inf *d11inf, * triples, returning a pointer to the substring whose first element * matches tag */ -const struct brcmf_tlv * +static const struct brcmf_tlv * brcmf_parse_tlvs(const void *buf, int buflen, uint key) { const struct brcmf_tlv *elt = buf; @@ -3332,7 +3330,6 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp, goto out_err; } - data += sizeof(struct brcmf_pno_scanresults_le); netinfo_start = brcmf_get_netinfo_array(pfn_result); for (i = 0; i < result_count; i++) { @@ -3480,8 +3477,7 @@ brcmf_wowl_nd_results(struct brcmf_if *ifp, const struct brcmf_event_msg *e, return -EINVAL; } - data += sizeof(struct brcmf_pno_scanresults_le); - netinfo = (struct brcmf_pno_net_info_le *)data; + netinfo = brcmf_get_netinfo_array(pfn_result); memcpy(cfg->wowl.nd->ssid.ssid, netinfo->SSID, netinfo->SSID_len); cfg->wowl.nd->ssid.ssid_len = netinfo->SSID_len; cfg->wowl.nd->n_channels = 1; @@ -5071,6 +5067,29 @@ static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy, return ret; } +static int +brcmf_cfg80211_update_conn_params(struct wiphy *wiphy, + struct net_device *ndev, + struct cfg80211_connect_params *sme, + u32 changed) +{ + struct brcmf_if *ifp; + int err; + + if (!(changed & UPDATE_ASSOC_IES)) + return 0; + + ifp = netdev_priv(ndev); + err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG, + sme->ie, sme->ie_len); + if (err) + brcmf_err("Set Assoc REQ IE Failed\n"); + else + brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n"); + + return err; +} + #ifdef CONFIG_PM static int brcmf_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *ndev, @@ -5138,6 +5157,7 @@ static struct cfg80211_ops brcmf_cfg80211_ops = { .crit_proto_start = brcmf_cfg80211_crit_proto_start, .crit_proto_stop = brcmf_cfg80211_crit_proto_stop, .tdls_oper = brcmf_cfg80211_tdls_oper, + .update_connect_params = brcmf_cfg80211_update_conn_params, }; struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, @@ -5825,7 +5845,6 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, u32 i, j; u32 total; u32 chaninfo; - u32 index; pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL); @@ -5873,33 +5892,36 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, ch.bw == BRCMU_CHAN_BW_80) continue; - channel = band->channels; - index = band->n_channels; + channel = NULL; for (j = 0; j < band->n_channels; j++) { - if (channel[j].hw_value == ch.control_ch_num) { - index = j; + if (band->channels[j].hw_value == ch.control_ch_num) { + channel = &band->channels[j]; break; } } - channel[index].center_freq = - ieee80211_channel_to_frequency(ch.control_ch_num, - band->band); - channel[index].hw_value = ch.control_ch_num; + if (!channel) { + /* It seems firmware supports some channel we never + * considered. Something new in IEEE standard? + */ + brcmf_err("Ignoring unexpected firmware channel %d\n", + ch.control_ch_num); + continue; + } /* assuming the chanspecs order is HT20, * HT40 upper, HT40 lower, and VHT80. */ if (ch.bw == BRCMU_CHAN_BW_80) { - channel[index].flags &= ~IEEE80211_CHAN_NO_80MHZ; + channel->flags &= ~IEEE80211_CHAN_NO_80MHZ; } else if (ch.bw == BRCMU_CHAN_BW_40) { - brcmf_update_bw40_channel_flag(&channel[index], &ch); + brcmf_update_bw40_channel_flag(channel, &ch); } else { /* enable the channel and disable other bandwidths * for now as mentioned order assure they are enabled * for subsequent chanspecs. */ - channel[index].flags = IEEE80211_CHAN_NO_HT40 | - IEEE80211_CHAN_NO_80MHZ; + channel->flags = IEEE80211_CHAN_NO_HT40 | + IEEE80211_CHAN_NO_80MHZ; ch.bw = BRCMU_CHAN_BW_20; cfg->d11inf.encchspec(&ch); chaninfo = ch.chspec; @@ -5907,11 +5929,11 @@ static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, &chaninfo); if (!err) { if (chaninfo & WL_CHAN_RADAR) - channel[index].flags |= + channel->flags |= (IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR); if (chaninfo & WL_CHAN_PASSIVE) - channel[index].flags |= + channel->flags |= IEEE80211_CHAN_NO_IR; } } @@ -6341,7 +6363,7 @@ static void brcmf_wiphy_pno_params(struct wiphy *wiphy) } #ifdef CONFIG_PM -static struct wiphy_wowlan_support brcmf_wowlan_support = { +static const struct wiphy_wowlan_support brcmf_wowlan_support = { .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT, .n_patterns = BRCMF_WOWL_MAXPATTERNS, .pattern_max_len = BRCMF_WOWL_MAXPATTERNSIZE, @@ -6354,19 +6376,29 @@ static void brcmf_wiphy_wowl_params(struct wiphy *wiphy, struct brcmf_if *ifp) { #ifdef CONFIG_PM struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct wiphy_wowlan_support *wowl; + + wowl = kmemdup(&brcmf_wowlan_support, sizeof(brcmf_wowlan_support), + GFP_KERNEL); + if (!wowl) { + brcmf_err("only support basic wowlan features\n"); + wiphy->wowlan = &brcmf_wowlan_support; + return; + } if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) { if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ND)) { - brcmf_wowlan_support.flags |= WIPHY_WOWLAN_NET_DETECT; + wowl->flags |= WIPHY_WOWLAN_NET_DETECT; + wowl->max_nd_match_sets = BRCMF_PNO_MAX_PFN_COUNT; init_waitqueue_head(&cfg->wowl.nd_data_wait); } } if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) { - brcmf_wowlan_support.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY; - brcmf_wowlan_support.flags |= WIPHY_WOWLAN_GTK_REKEY_FAILURE; + wowl->flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY; + wowl->flags |= WIPHY_WOWLAN_GTK_REKEY_FAILURE; } - wiphy->wowlan = &brcmf_wowlan_support; + wiphy->wowlan = wowl; #endif } @@ -6477,8 +6509,7 @@ static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp) wiphy->bands[NL80211_BAND_5GHZ] = band; } } - err = brcmf_setup_wiphybands(wiphy); - return err; + return 0; } static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) @@ -6748,6 +6779,10 @@ static void brcmf_free_wiphy(struct wiphy *wiphy) kfree(wiphy->bands[NL80211_BAND_5GHZ]->channels); kfree(wiphy->bands[NL80211_BAND_5GHZ]); } +#if IS_ENABLED(CONFIG_PM) + if (wiphy->wowlan != &brcmf_wowlan_support) + kfree(wiphy->wowlan); +#endif wiphy_free(wiphy); } @@ -6843,6 +6878,12 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr, goto priv_out; } + err = brcmf_setup_wiphybands(wiphy); + if (err) { + brcmf_err("Setting wiphy bands failed (%d)\n", err); + goto wiphy_unreg_out; + } + /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(), * setup 40MHz in 2GHz band and enable OBSS scanning. */ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h index 0c9a7081fca9..8f19d95d4175 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h @@ -396,8 +396,6 @@ void brcmf_free_vif(struct brcmf_cfg80211_vif *vif); s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, const u8 *vndr_ie_buf, u32 vndr_ie_len); s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif); -const struct brcmf_tlv * -brcmf_parse_tlvs(const void *buf, int buflen, uint key); u16 channel_to_chanspec(struct brcmu_d11inf *d11inf, struct ieee80211_channel *ch); bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg, diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c index 3e15d64c6481..f7c8c2e80349 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c @@ -74,7 +74,7 @@ module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR); MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine"); #ifdef DEBUG -/* always succeed brcmf_bus_start() */ +/* always succeed brcmf_bus_started() */ static int brcmf_ignore_probe_fail; module_param_named(ignore_probe_fail, brcmf_ignore_probe_fail, int, 0); MODULE_PARM_DESC(ignore_probe_fail, "always succeed probe for debugging"); @@ -299,11 +299,9 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev, } } } - if ((bus_type == BRCMF_BUSTYPE_SDIO) && (!found)) { - /* No platform data for this device. In case of SDIO try OF - * (Open Firwmare) Device Tree. - */ - brcmf_of_probe(dev, &settings->bus.sdio); + if (!found) { + /* No platform data for this device, try OF (Open Firwmare) */ + brcmf_of_probe(dev, bus_type, settings); } return settings; } diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h index bd095abca393..a62f8e70b320 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h @@ -65,6 +65,8 @@ struct brcmf_mp_device { } bus; }; +void brcmf_c_set_joinpref_default(struct brcmf_if *ifp); + struct brcmf_mp_device *brcmf_get_module_param(struct device *dev, enum brcmf_bus_type bus_type, u32 chip, u32 chiprev); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index 9e6f60a0ec3e..b73a55b00fa7 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -966,7 +966,7 @@ static int brcmf_revinfo_read(struct seq_file *s, void *data) return 0; } -int brcmf_bus_start(struct device *dev) +int brcmf_bus_started(struct device *dev) { int ret = -1; struct brcmf_bus *bus_if = dev_get_drvdata(dev); @@ -1075,16 +1075,6 @@ void brcmf_bus_add_txhdrlen(struct device *dev, uint len) } } -static void brcmf_bus_detach(struct brcmf_pub *drvr) -{ - brcmf_dbg(TRACE, "Enter\n"); - - if (drvr) { - /* Stop the bus module */ - brcmf_bus_stop(drvr->bus_if); - } -} - void brcmf_dev_reset(struct device *dev) { struct brcmf_bus *bus_if = dev_get_drvdata(dev); @@ -1131,7 +1121,7 @@ void brcmf_detach(struct device *dev) brcmf_fws_deinit(drvr); - brcmf_bus_detach(drvr); + brcmf_bus_stop(drvr->bus_if); brcmf_proto_detach(drvr); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h index c94dcab260d0..de3197be5491 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h @@ -216,7 +216,6 @@ void brcmf_txflowblock_if(struct brcmf_if *ifp, void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success); void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb); void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on); -void brcmf_c_set_joinpref_default(struct brcmf_if *ifp); int __init brcmf_core_init(void); void __exit brcmf_core_exit(void); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c index 425c41dc0a59..aee6e5937c41 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c @@ -23,14 +23,17 @@ #include "common.h" #include "of.h" -void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio) +void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, + struct brcmf_mp_device *settings) { + struct brcmfmac_sdio_pd *sdio = &settings->bus.sdio; struct device_node *np = dev->of_node; int irq; u32 irqf; u32 val; - if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac")) + if (!np || bus_type != BRCMF_BUSTYPE_SDIO || + !of_device_is_compatible(np, "brcm,bcm4329-fmac")) return; if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h index a9d94c15d0f5..95b7032d54b1 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h @@ -14,9 +14,11 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #ifdef CONFIG_OF -void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio); +void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, + struct brcmf_mp_device *settings); #else -static void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio) +static void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, + struct brcmf_mp_device *settings) { } #endif /* CONFIG_OF */ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c index 048027f2085b..6fae4cf3f6ab 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c @@ -601,7 +601,6 @@ static void brcmf_pcie_attach(struct brcmf_pciedev_info *devinfo) { u32 config; - brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); /* BAR1 window may not be sized properly */ brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2); brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR, 0x4e0); @@ -1572,7 +1571,7 @@ static int brcmf_pcie_attach_bus(struct brcmf_pciedev_info *devinfo) if (ret) { brcmf_err("brcmf_attach failed\n"); } else { - ret = brcmf_bus_start(&devinfo->pdev->dev); + ret = brcmf_bus_started(&devinfo->pdev->dev); if (ret) brcmf_err("dongle is not responding\n"); } diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index dfb0658713d9..c5744b45ec8f 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -1661,7 +1661,7 @@ static u8 brcmf_sdio_rxglom(struct brcmf_sdio *bus, u8 rxseq) pfirst->len, pfirst->next, pfirst->prev); skb_unlink(pfirst, &bus->glom); - if (brcmf_sdio_fromevntchan(pfirst->data)) + if (brcmf_sdio_fromevntchan(&dptr[SDPCM_HWHDR_LEN])) brcmf_rx_event(bus->sdiodev->dev, pfirst); else brcmf_rx_frame(bus->sdiodev->dev, pfirst, @@ -4065,7 +4065,7 @@ static void brcmf_sdio_firmware_callback(struct device *dev, sdio_release_host(sdiodev->func[1]); - err = brcmf_bus_start(dev); + err = brcmf_bus_started(dev); if (err != 0) { brcmf_err("dongle is not responding\n"); goto fail; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c index 2f978a39b58a..d93ebbdc7737 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c @@ -1148,7 +1148,7 @@ static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo) if (ret) goto fail; - ret = brcmf_bus_start(devinfo->dev); + ret = brcmf_bus_started(devinfo->dev); if (ret) goto fail; diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c index affe760c8c22..376c79337a0e 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/debugfs.c @@ -2310,7 +2310,7 @@ static ssize_t iwl_dbgfs_fw_restart_write(struct file *file, { struct iwl_priv *priv = file->private_data; bool restart_fw = iwlwifi_mod_params.restart_fw; - int ret; + int __maybe_unused ret; iwlwifi_mod_params.restart_fw = true; diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c index 8c0719468d00..2a04d0cd71ae 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/mac80211.c @@ -163,7 +163,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, REGULATORY_DISABLE_BEACON_HINTS; #ifdef CONFIG_PM_SLEEP - if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len && + if (priv->fw->img[IWL_UCODE_WOWLAN].num_sec && priv->trans->ops->d3_suspend && priv->trans->ops->d3_resume && device_can_wakeup(priv->trans->dev)) { diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/rs.c b/drivers/net/wireless/intel/iwlwifi/dvm/rs.c index b95c2d76db33..710dbbefd551 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/rs.c @@ -364,7 +364,7 @@ static void rs_program_fix_rate(struct iwl_priv *priv, /* get the traffic load value for tid */ -static u32 rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid) +static void rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid) { u32 curr_time = jiffies_to_msecs(jiffies); u32 time_diff; @@ -372,14 +372,14 @@ static u32 rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid) struct iwl_traffic_load *tl = NULL; if (tid >= IWL_MAX_TID_COUNT) - return 0; + return; tl = &(lq_data->load[tid]); curr_time -= curr_time % TID_ROUND_VALUE; if (!(tl->queue_count)) - return 0; + return; time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time); index = time_diff / TID_QUEUE_CELL_SPACING; @@ -388,8 +388,6 @@ static u32 rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid) /* TID_MAX_TIME_DIFF */ if (index >= TID_QUEUE_MAX_SIZE) rs_tl_rm_old_stats(tl, curr_time); - - return tl->total; } static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, @@ -397,7 +395,6 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, struct ieee80211_sta *sta) { int ret = -EAGAIN; - u32 load; /* * Don't create TX aggregation sessions when in high @@ -410,7 +407,7 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, return ret; } - load = rs_tl_get_load(lq_data, tid); + rs_tl_get_load(lq_data, tid); IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", sta->addr, tid); diff --git a/drivers/net/wireless/intel/iwlwifi/dvm/ucode.c b/drivers/net/wireless/intel/iwlwifi/dvm/ucode.c index c7509c51e9d9..d6013bfe991c 100644 --- a/drivers/net/wireless/intel/iwlwifi/dvm/ucode.c +++ b/drivers/net/wireless/intel/iwlwifi/dvm/ucode.c @@ -407,7 +407,7 @@ int iwl_run_init_ucode(struct iwl_priv *priv) lockdep_assert_held(&priv->mutex); /* No init ucode required? Curious, but maybe ok */ - if (!priv->fw->img[IWL_UCODE_INIT].sec[0].len) + if (!priv->fw->img[IWL_UCODE_INIT].num_sec) return 0; iwl_init_notification_wait(&priv->notif_wait, &calib_wait, diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-6000.c b/drivers/net/wireless/intel/iwlwifi/iwl-6000.c index 0b9f6a7bc834..39335b7b0c16 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-6000.c @@ -371,4 +371,4 @@ const struct iwl_cfg iwl6000_3agn_cfg = { MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX)); MODULE_FIRMWARE(IWL6005_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); -MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2B_UCODE_API_MAX)); +MODULE_FIRMWARE(IWL6030_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX)); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-7000.c b/drivers/net/wireless/intel/iwlwifi/iwl-7000.c index d4b73dedf89b..a72e58623d3a 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-7000.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-7000.c @@ -73,8 +73,8 @@ /* Highest firmware API version supported */ #define IWL7260_UCODE_API_MAX 17 #define IWL7265_UCODE_API_MAX 17 -#define IWL7265D_UCODE_API_MAX 26 -#define IWL3168_UCODE_API_MAX 26 +#define IWL7265D_UCODE_API_MAX 28 +#define IWL3168_UCODE_API_MAX 28 /* Lowest firmware API version supported */ #define IWL7260_UCODE_API_MIN 17 diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-8000.c b/drivers/net/wireless/intel/iwlwifi/iwl-8000.c index d02ca1491d16..df0fc24e99e1 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-8000.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-8000.c @@ -70,8 +70,8 @@ #include "iwl-agn-hw.h" /* Highest firmware API version supported */ -#define IWL8000_UCODE_API_MAX 26 -#define IWL8265_UCODE_API_MAX 26 +#define IWL8000_UCODE_API_MAX 28 +#define IWL8265_UCODE_API_MAX 28 /* Lowest firmware API version supported */ #define IWL8000_UCODE_API_MIN 17 diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-9000.c b/drivers/net/wireless/intel/iwlwifi/iwl-9000.c index ff850410d897..a5f0c0bf85ec 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-9000.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-9000.c @@ -55,7 +55,7 @@ #include "iwl-agn-hw.h" /* Highest firmware API version supported */ -#define IWL9000_UCODE_API_MAX 26 +#define IWL9000_UCODE_API_MAX 28 /* Lowest firmware API version supported */ #define IWL9000_UCODE_API_MIN 17 diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-a000.c b/drivers/net/wireless/intel/iwlwifi/iwl-a000.c index ea1618525878..82f18d967c40 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-a000.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-a000.c @@ -55,7 +55,7 @@ #include "iwl-agn-hw.h" /* Highest firmware API version supported */ -#define IWL_A000_UCODE_API_MAX 26 +#define IWL_A000_UCODE_API_MAX 28 /* Lowest firmware API version supported */ #define IWL_A000_UCODE_API_MIN 24 diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index 45b2f679e4d8..d22821501676 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -166,8 +166,9 @@ static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc) static void iwl_free_fw_img(struct iwl_drv *drv, struct fw_img *img) { int i; - for (i = 0; i < IWL_UCODE_SECTION_MAX; i++) + for (i = 0; i < img->num_sec; i++) iwl_free_fw_desc(drv, &img->sec[i]); + kfree(img->sec); } static void iwl_dealloc_ucode(struct iwl_drv *drv) @@ -179,8 +180,7 @@ static void iwl_dealloc_ucode(struct iwl_drv *drv) kfree(drv->fw.dbg_conf_tlv[i]); for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_trigger_tlv); i++) kfree(drv->fw.dbg_trigger_tlv[i]); - for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_mem_tlv); i++) - kfree(drv->fw.dbg_mem_tlv[i]); + kfree(drv->fw.dbg_mem_tlv); for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) iwl_free_fw_img(drv, drv->fw.img + i); @@ -241,7 +241,7 @@ static int iwl_request_firmware(struct iwl_drv *drv, bool first) } struct fw_img_parsing { - struct fw_sec sec[IWL_UCODE_SECTION_MAX]; + struct fw_sec *sec; int sec_counter; }; @@ -276,7 +276,8 @@ struct iwl_firmware_pieces { size_t dbg_conf_tlv_len[FW_DBG_CONF_MAX]; struct iwl_fw_dbg_trigger_tlv *dbg_trigger_tlv[FW_DBG_TRIGGER_MAX]; size_t dbg_trigger_tlv_len[FW_DBG_TRIGGER_MAX]; - struct iwl_fw_dbg_mem_seg_tlv *dbg_mem_tlv[FW_DBG_MEM_MAX]; + struct iwl_fw_dbg_mem_seg_tlv *dbg_mem_tlv; + size_t n_dbg_mem_tlv; }; /* @@ -290,11 +291,33 @@ static struct fw_sec *get_sec(struct iwl_firmware_pieces *pieces, return &pieces->img[type].sec[sec]; } +static void alloc_sec_data(struct iwl_firmware_pieces *pieces, + enum iwl_ucode_type type, + int sec) +{ + struct fw_img_parsing *img = &pieces->img[type]; + struct fw_sec *sec_memory; + int size = sec + 1; + size_t alloc_size = sizeof(*img->sec) * size; + + if (img->sec && img->sec_counter >= size) + return; + + sec_memory = krealloc(img->sec, alloc_size, GFP_KERNEL); + if (!sec_memory) + return; + + img->sec = sec_memory; + img->sec_counter = size; +} + static void set_sec_data(struct iwl_firmware_pieces *pieces, enum iwl_ucode_type type, int sec, const void *data) { + alloc_sec_data(pieces, type, sec); + pieces->img[type].sec[sec].data = data; } @@ -303,6 +326,8 @@ static void set_sec_size(struct iwl_firmware_pieces *pieces, int sec, size_t size) { + alloc_sec_data(pieces, type, sec); + pieces->img[type].sec[sec].size = size; } @@ -318,6 +343,8 @@ static void set_sec_offset(struct iwl_firmware_pieces *pieces, int sec, u32 offset) { + alloc_sec_data(pieces, type, sec); + pieces->img[type].sec[sec].offset = offset; } @@ -383,6 +410,7 @@ static int iwl_store_ucode_sec(struct iwl_firmware_pieces *pieces, struct fw_img_parsing *img; struct fw_sec *sec; struct fw_sec_parsing *sec_parse; + size_t alloc_size; if (WARN_ON(!pieces || !data || type >= IWL_UCODE_TYPE_MAX)) return -1; @@ -390,6 +418,13 @@ static int iwl_store_ucode_sec(struct iwl_firmware_pieces *pieces, sec_parse = (struct fw_sec_parsing *)data; img = &pieces->img[type]; + + alloc_size = sizeof(*img->sec) * (img->sec_counter + 1); + sec = krealloc(img->sec, alloc_size, GFP_KERNEL); + if (!sec) + return -ENOMEM; + img->sec = sec; + sec = &img->sec[img->sec_counter]; sec->offset = le32_to_cpu(sec_parse->offset); @@ -1009,31 +1044,37 @@ static int iwl_parse_tlv_firmware(struct iwl_drv *drv, struct iwl_fw_dbg_mem_seg_tlv *dbg_mem = (void *)tlv_data; u32 type; + size_t size; + struct iwl_fw_dbg_mem_seg_tlv *n; if (tlv_len != (sizeof(*dbg_mem))) goto invalid_tlv_len; type = le32_to_cpu(dbg_mem->data_type); - drv->fw.dbg_dynamic_mem = true; - if (type >= ARRAY_SIZE(drv->fw.dbg_mem_tlv)) { - IWL_ERR(drv, - "Skip unknown dbg mem segment: %u\n", - dbg_mem->data_type); - break; - } + IWL_DEBUG_INFO(drv, "Found debug memory segment: %u\n", + dbg_mem->data_type); - if (pieces->dbg_mem_tlv[type]) { - IWL_ERR(drv, - "Ignore duplicate mem segment: %u\n", - dbg_mem->data_type); + switch (type & FW_DBG_MEM_TYPE_MASK) { + case FW_DBG_MEM_TYPE_REGULAR: + case FW_DBG_MEM_TYPE_PRPH: + /* we know how to handle these */ break; + default: + IWL_ERR(drv, + "Found debug memory segment with invalid type: 0x%x\n", + type); + return -EINVAL; } - IWL_DEBUG_INFO(drv, "Found debug memory segment: %u\n", - dbg_mem->data_type); - - pieces->dbg_mem_tlv[type] = dbg_mem; + size = sizeof(*pieces->dbg_mem_tlv) * + (pieces->n_dbg_mem_tlv + 1); + n = krealloc(pieces->dbg_mem_tlv, size, GFP_KERNEL); + if (!n) + return -ENOMEM; + pieces->dbg_mem_tlv = n; + pieces->dbg_mem_tlv[pieces->n_dbg_mem_tlv] = *dbg_mem; + pieces->n_dbg_mem_tlv++; break; } default: @@ -1083,12 +1124,18 @@ static int iwl_alloc_ucode(struct iwl_drv *drv, enum iwl_ucode_type type) { int i; - for (i = 0; - i < IWL_UCODE_SECTION_MAX && get_sec_size(pieces, type, i); - i++) - if (iwl_alloc_fw_desc(drv, &(drv->fw.img[type].sec[i]), - get_sec(pieces, type, i))) + struct fw_desc *sec; + + sec = kcalloc(pieces->img[type].sec_counter, sizeof(*sec), GFP_KERNEL); + if (!sec) + return -ENOMEM; + drv->fw.img[type].sec = sec; + drv->fw.img[type].num_sec = pieces->img[type].sec_counter; + + for (i = 0; i < pieces->img[type].sec_counter; i++) + if (iwl_alloc_fw_desc(drv, &sec[i], get_sec(pieces, type, i))) return -ENOMEM; + return 0; } @@ -1345,19 +1392,12 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) } } - for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_mem_tlv); i++) { - if (pieces->dbg_mem_tlv[i]) { - drv->fw.dbg_mem_tlv[i] = - kmemdup(pieces->dbg_mem_tlv[i], - sizeof(*drv->fw.dbg_mem_tlv[i]), - GFP_KERNEL); - if (!drv->fw.dbg_mem_tlv[i]) - goto out_free_fw; - } - } - /* Now that we can no longer fail, copy information */ + drv->fw.dbg_mem_tlv = pieces->dbg_mem_tlv; + pieces->dbg_mem_tlv = NULL; + drv->fw.n_dbg_mem_tlv = pieces->n_dbg_mem_tlv; + /* * The (size - 16) / 12 formula is based on the information recorded * for each event, which is of mode 1 (including timestamp) for all @@ -1441,25 +1481,27 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) op->name, err); #endif } - kfree(pieces); - return; + goto free; try_again: /* try next, if any */ release_firmware(ucode_raw); if (iwl_request_firmware(drv, false)) goto out_unbind; - kfree(pieces); - return; + goto free; out_free_fw: IWL_ERR(drv, "failed to allocate pci memory\n"); iwl_dealloc_ucode(drv); release_firmware(ucode_raw); out_unbind: - kfree(pieces); complete(&drv->request_firmware_complete); device_release_driver(drv->trans->dev); + free: + for (i = 0; i < ARRAY_SIZE(pieces->img); i++) + kfree(pieces->img[i].sec); + kfree(pieces->dbg_mem_tlv); + kfree(pieces); } struct iwl_drv *iwl_drv_start(struct iwl_trans *trans, diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h index 84813b550ef1..d01701ee4777 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-fw-file.h @@ -379,7 +379,6 @@ enum iwl_ucode_tlv_capa { * For 16.0 uCode and above, there is no differentiation between sections, * just an offset to the HW address. */ -#define IWL_UCODE_SECTION_MAX 16 #define CPU1_CPU2_SEPARATOR_SECTION 0xFFFFCCCC #define PAGING_SEPARATOR_SECTION 0xAAAABBBB @@ -489,25 +488,22 @@ enum iwl_fw_dbg_monitor_mode { }; /** - * enum iwl_fw_mem_seg_type - data types for dumping on error - * - * @FW_DBG_MEM_SMEM: the data type is SMEM - * @FW_DBG_MEM_DCCM_LMAC: the data type is DCCM_LMAC - * @FW_DBG_MEM_DCCM_UMAC: the data type is DCCM_UMAC + * enum iwl_fw_mem_seg_type - memory segment type + * @FW_DBG_MEM_TYPE_MASK: mask for the type indication + * @FW_DBG_MEM_TYPE_REGULAR: regular memory + * @FW_DBG_MEM_TYPE_PRPH: periphery memory (requires special reading) */ -enum iwl_fw_dbg_mem_seg_type { - FW_DBG_MEM_DCCM_LMAC = 0, - FW_DBG_MEM_DCCM_UMAC, - FW_DBG_MEM_SMEM, - - /* Must be last */ - FW_DBG_MEM_MAX, +enum iwl_fw_mem_seg_type { + FW_DBG_MEM_TYPE_MASK = 0xff000000, + FW_DBG_MEM_TYPE_REGULAR = 0x00000000, + FW_DBG_MEM_TYPE_PRPH = 0x01000000, }; /** * struct iwl_fw_dbg_mem_seg_tlv - configures the debug data memory segments * - * @data_type: enum %iwl_fw_mem_seg_type + * @data_type: the memory segment type to record, see &enum iwl_fw_mem_seg_type + * for what we care about * @ofs: the memory segment offset * @len: the memory segment length, in bytes * diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-fw.h b/drivers/net/wireless/intel/iwlwifi/iwl-fw.h index 5f229556339a..d323b70b510a 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-fw.h +++ b/drivers/net/wireless/intel/iwlwifi/iwl-fw.h @@ -132,7 +132,8 @@ struct fw_desc { }; struct fw_img { - struct fw_desc sec[IWL_UCODE_SECTION_MAX]; + struct fw_desc *sec; + int num_sec; bool is_dual_cpus; u32 paging_mem_size; }; @@ -295,8 +296,8 @@ struct iwl_fw { struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX]; size_t dbg_conf_tlv_len[FW_DBG_CONF_MAX]; struct iwl_fw_dbg_trigger_tlv *dbg_trigger_tlv[FW_DBG_TRIGGER_MAX]; - struct iwl_fw_dbg_mem_seg_tlv *dbg_mem_tlv[FW_DBG_MEM_MAX]; - bool dbg_dynamic_mem; + struct iwl_fw_dbg_mem_seg_tlv *dbg_mem_tlv; + size_t n_dbg_mem_tlv; size_t dbg_trigger_tlv_len[FW_DBG_TRIGGER_MAX]; u8 dbg_dest_reg_num; struct iwl_gscan_capabilities gscan_capa; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c index b88e2048ae0b..207d8ae1e116 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c @@ -1262,12 +1262,15 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw, iwl_trans_d3_suspend(mvm->trans, test, !unified_image); out: if (ret < 0) { - iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); - if (mvm->restart_fw > 0) { - mvm->restart_fw--; - ieee80211_restart_hw(mvm->hw); - } iwl_mvm_free_nd(mvm); + + if (!unified_image) { + iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); + if (mvm->restart_fw > 0) { + mvm->restart_fw--; + ieee80211_restart_hw(mvm->hw); + } + } } out_noreset: mutex_unlock(&mvm->mutex); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c index 7b7d2a146e30..a260cd503200 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs.c @@ -798,7 +798,7 @@ static ssize_t iwl_dbgfs_drv_rx_stats_read(struct file *file, static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf, size_t count, loff_t *ppos) { - int ret; + int __maybe_unused ret; mutex_lock(&mvm->mutex); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h index ae12badc0c2a..567597c26115 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h @@ -2075,7 +2075,7 @@ struct iwl_mu_group_mgmt_notif { * @system_time: system time on air rise * @tsf: TSF on air rise * @beacon_timestamp: beacon on air rise - * @phy_flags: general phy flags: band, modulation, etc. + * @band: band, matches &RX_RES_PHY_FLAGS_BAND_24 definition * @channel: channel this beacon was received on * @rates: rate in ucode internal format * @byte_count: frame's byte count @@ -2084,12 +2084,12 @@ struct iwl_stored_beacon_notif { __le32 system_time; __le64 tsf; __le32 beacon_timestamp; - __le16 phy_flags; + __le16 band; __le16 channel; __le32 rates; __le32 byte_count; u8 data[MAX_STORED_BEACON_SIZE]; -} __packed; /* WOWLAN_STROED_BEACON_INFO_S_VER_1 */ +} __packed; /* WOWLAN_STROED_BEACON_INFO_S_VER_2 */ #define LQM_NUMBER_OF_STATIONS_IN_REPORT 16 diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c index 2e8e3e8e30a3..e7b3b712d778 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c @@ -406,46 +406,63 @@ static const struct iwl_prph_range iwl_prph_dump_addr_9000[] = { { .start = 0x00a02400, .end = 0x00a02758 }, }; -static u32 iwl_dump_prph(struct iwl_trans *trans, - struct iwl_fw_error_dump_data **data, - const struct iwl_prph_range *iwl_prph_dump_addr, - u32 range_len) +static void _iwl_read_prph_block(struct iwl_trans *trans, u32 start, + u32 len_bytes, __le32 *data) +{ + u32 i; + + for (i = 0; i < len_bytes; i += 4) + *data++ = cpu_to_le32(iwl_read_prph_no_grab(trans, start + i)); +} + +static bool iwl_read_prph_block(struct iwl_trans *trans, u32 start, + u32 len_bytes, __le32 *data) +{ + unsigned long flags; + bool success = false; + + if (iwl_trans_grab_nic_access(trans, &flags)) { + success = true; + _iwl_read_prph_block(trans, start, len_bytes, data); + iwl_trans_release_nic_access(trans, &flags); + } + + return success; +} + +static void iwl_dump_prph(struct iwl_trans *trans, + struct iwl_fw_error_dump_data **data, + const struct iwl_prph_range *iwl_prph_dump_addr, + u32 range_len) { struct iwl_fw_error_dump_prph *prph; unsigned long flags; - u32 prph_len = 0, i; + u32 i; if (!iwl_trans_grab_nic_access(trans, &flags)) - return 0; + return; for (i = 0; i < range_len; i++) { /* The range includes both boundaries */ int num_bytes_in_chunk = iwl_prph_dump_addr[i].end - iwl_prph_dump_addr[i].start + 4; - int reg; - __le32 *val; - - prph_len += sizeof(**data) + sizeof(*prph) + num_bytes_in_chunk; (*data)->type = cpu_to_le32(IWL_FW_ERROR_DUMP_PRPH); (*data)->len = cpu_to_le32(sizeof(*prph) + num_bytes_in_chunk); prph = (void *)(*data)->data; prph->prph_start = cpu_to_le32(iwl_prph_dump_addr[i].start); - val = (void *)prph->data; - for (reg = iwl_prph_dump_addr[i].start; - reg <= iwl_prph_dump_addr[i].end; - reg += 4) - *val++ = cpu_to_le32(iwl_read_prph_no_grab(trans, - reg)); + _iwl_read_prph_block(trans, iwl_prph_dump_addr[i].start, + /* our range is inclusive, hence + 4 */ + iwl_prph_dump_addr[i].end - + iwl_prph_dump_addr[i].start + 4, + (void *)prph->data); *data = iwl_fw_error_next_data(*data); } iwl_trans_release_nic_access(trans, &flags); - - return prph_len; } /* @@ -495,11 +512,10 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) struct iwl_mvm_dump_ptrs *fw_error_dump; struct scatterlist *sg_dump_data; u32 sram_len, sram_ofs; - struct iwl_fw_dbg_mem_seg_tlv * const *fw_dbg_mem = - mvm->fw->dbg_mem_tlv; + const struct iwl_fw_dbg_mem_seg_tlv *fw_dbg_mem = mvm->fw->dbg_mem_tlv; u32 file_len, fifo_data_len = 0, prph_len = 0, radio_len = 0; - u32 smem_len = mvm->fw->dbg_dynamic_mem ? 0 : mvm->cfg->smem_len; - u32 sram2_len = mvm->fw->dbg_dynamic_mem ? 0 : mvm->cfg->dccm2_len; + u32 smem_len = mvm->fw->n_dbg_mem_tlv ? 0 : mvm->cfg->smem_len; + u32 sram2_len = mvm->fw->n_dbg_mem_tlv ? 0 : mvm->cfg->dccm2_len; bool monitor_dump_only = false; int i; @@ -624,10 +640,9 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) file_len += sizeof(*dump_data) + sizeof(*dump_mem) + sram2_len; /* Make room for MEM segments */ - for (i = 0; i < ARRAY_SIZE(mvm->fw->dbg_mem_tlv); i++) { - if (fw_dbg_mem[i]) - file_len += sizeof(*dump_data) + sizeof(*dump_mem) + - le32_to_cpu(fw_dbg_mem[i]->len); + for (i = 0; i < mvm->fw->n_dbg_mem_tlv; i++) { + file_len += sizeof(*dump_data) + sizeof(*dump_mem) + + le32_to_cpu(fw_dbg_mem[i].len); } /* Make room for fw's virtual image pages, if it exists */ @@ -656,7 +671,7 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) file_len += sizeof(*dump_data) + sizeof(*dump_trig) + mvm->fw_dump_desc->len; - if (!mvm->fw->dbg_dynamic_mem) + if (!mvm->fw->n_dbg_mem_tlv) file_len += sram_len + sizeof(*dump_mem); dump_file = vzalloc(file_len); @@ -708,7 +723,7 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) if (monitor_dump_only) goto dump_trans_data; - if (!mvm->fw->dbg_dynamic_mem) { + if (!mvm->fw->n_dbg_mem_tlv) { dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM); dump_data->len = cpu_to_le32(sram_len + sizeof(*dump_mem)); dump_mem = (void *)dump_data->data; @@ -719,22 +734,39 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) dump_data = iwl_fw_error_next_data(dump_data); } - for (i = 0; i < ARRAY_SIZE(mvm->fw->dbg_mem_tlv); i++) { - if (fw_dbg_mem[i]) { - u32 len = le32_to_cpu(fw_dbg_mem[i]->len); - u32 ofs = le32_to_cpu(fw_dbg_mem[i]->ofs); - - dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM); - dump_data->len = cpu_to_le32(len + - sizeof(*dump_mem)); - dump_mem = (void *)dump_data->data; - dump_mem->type = fw_dbg_mem[i]->data_type; - dump_mem->offset = cpu_to_le32(ofs); + for (i = 0; i < mvm->fw->n_dbg_mem_tlv; i++) { + u32 len = le32_to_cpu(fw_dbg_mem[i].len); + u32 ofs = le32_to_cpu(fw_dbg_mem[i].ofs); + bool success; + + dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_MEM); + dump_data->len = cpu_to_le32(len + sizeof(*dump_mem)); + dump_mem = (void *)dump_data->data; + dump_mem->type = fw_dbg_mem[i].data_type; + dump_mem->offset = cpu_to_le32(ofs); + + switch (dump_mem->type & cpu_to_le32(FW_DBG_MEM_TYPE_MASK)) { + case cpu_to_le32(FW_DBG_MEM_TYPE_REGULAR): iwl_trans_read_mem_bytes(mvm->trans, ofs, dump_mem->data, len); - dump_data = iwl_fw_error_next_data(dump_data); + success = true; + break; + case cpu_to_le32(FW_DBG_MEM_TYPE_PRPH): + success = iwl_read_prph_block(mvm->trans, ofs, len, + (void *)dump_mem->data); + break; + default: + /* + * shouldn't get here, we ignored this kind + * of TLV earlier during the TLV parsing?! + */ + WARN_ON(1); + success = false; } + + if (success) + dump_data = iwl_fw_error_next_data(dump_data); } if (smem_len) { @@ -816,11 +848,12 @@ dump_trans_data: sg_nents(sg_dump_data), fw_error_dump->op_mode_ptr, fw_error_dump->op_mode_len, 0); - sg_pcopy_from_buffer(sg_dump_data, - sg_nents(sg_dump_data), - fw_error_dump->trans_ptr->data, - fw_error_dump->trans_ptr->len, - fw_error_dump->op_mode_len); + if (fw_error_dump->trans_ptr) + sg_pcopy_from_buffer(sg_dump_data, + sg_nents(sg_dump_data), + fw_error_dump->trans_ptr->data, + fw_error_dump->trans_ptr->len, + fw_error_dump->op_mode_len); dev_coredumpsg(mvm->trans->dev, sg_dump_data, file_len, GFP_KERNEL); } diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 872066317fa5..b278e44e97ad 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c @@ -190,7 +190,7 @@ static int iwl_fill_paging_mem(struct iwl_mvm *mvm, const struct fw_img *image) * CPU2 paging CSS * CPU2 paging image (including instruction and data) */ - for (sec_idx = 0; sec_idx < IWL_UCODE_SECTION_MAX; sec_idx++) { + for (sec_idx = 0; sec_idx < image->num_sec; sec_idx++) { if (image->sec[sec_idx].offset == PAGING_SEPARATOR_SECTION) { sec_idx++; break; @@ -201,7 +201,7 @@ static int iwl_fill_paging_mem(struct iwl_mvm *mvm, const struct fw_img *image) * If paging is enabled there should be at least 2 more sections left * (one for CSS and one for Paging data) */ - if (sec_idx >= ARRAY_SIZE(image->sec) - 1) { + if (sec_idx >= image->num_sec - 1) { IWL_ERR(mvm, "Paging: Missing CSS and/or paging sections\n"); iwl_free_fw_paging(mvm); return -EINVAL; @@ -259,9 +259,7 @@ static int iwl_alloc_fw_paging_mem(struct iwl_mvm *mvm, { struct page *block; dma_addr_t phys = 0; - int blk_idx = 0; - int order, num_of_pages; - int dma_enabled; + int blk_idx, order, num_of_pages, size, dma_enabled; if (mvm->fw_paging_db[0].fw_paging_block) return 0; @@ -272,9 +270,8 @@ static int iwl_alloc_fw_paging_mem(struct iwl_mvm *mvm, BUILD_BUG_ON(BIT(BLOCK_2_EXP_SIZE) != PAGING_BLOCK_SIZE); num_of_pages = image->paging_mem_size / FW_PAGING_SIZE; - mvm->num_of_paging_blk = ((num_of_pages - 1) / - NUM_OF_PAGE_PER_GROUP) + 1; - + mvm->num_of_paging_blk = + DIV_ROUND_UP(num_of_pages, NUM_OF_PAGE_PER_GROUP); mvm->num_of_pages_in_last_blk = num_of_pages - NUM_OF_PAGE_PER_GROUP * (mvm->num_of_paging_blk - 1); @@ -284,46 +281,13 @@ static int iwl_alloc_fw_paging_mem(struct iwl_mvm *mvm, mvm->num_of_paging_blk, mvm->num_of_pages_in_last_blk); - /* allocate block of 4Kbytes for paging CSS */ - order = get_order(FW_PAGING_SIZE); - block = alloc_pages(GFP_KERNEL, order); - if (!block) { - /* free all the previous pages since we failed */ - iwl_free_fw_paging(mvm); - return -ENOMEM; - } - - mvm->fw_paging_db[blk_idx].fw_paging_block = block; - mvm->fw_paging_db[blk_idx].fw_paging_size = FW_PAGING_SIZE; - - if (dma_enabled) { - phys = dma_map_page(mvm->trans->dev, block, 0, - PAGE_SIZE << order, DMA_BIDIRECTIONAL); - if (dma_mapping_error(mvm->trans->dev, phys)) { - /* - * free the previous pages and the current one since - * we failed to map_page. - */ - iwl_free_fw_paging(mvm); - return -ENOMEM; - } - mvm->fw_paging_db[blk_idx].fw_paging_phys = phys; - } else { - mvm->fw_paging_db[blk_idx].fw_paging_phys = PAGING_ADDR_SIG | - blk_idx << BLOCK_2_EXP_SIZE; - } - - IWL_DEBUG_FW(mvm, - "Paging: allocated 4K(CSS) bytes (order %d) for firmware paging.\n", - order); - /* - * allocate blocks in dram. - * since that CSS allocated in fw_paging_db[0] loop start from index 1 + * Allocate CSS and paging blocks in dram. */ - for (blk_idx = 1; blk_idx < mvm->num_of_paging_blk + 1; blk_idx++) { - /* allocate block of PAGING_BLOCK_SIZE (32K) */ - order = get_order(PAGING_BLOCK_SIZE); + for (blk_idx = 0; blk_idx < mvm->num_of_paging_blk + 1; blk_idx++) { + /* For CSS allocate 4KB, for others PAGING_BLOCK_SIZE (32K) */ + size = blk_idx ? PAGING_BLOCK_SIZE : FW_PAGING_SIZE; + order = get_order(size); block = alloc_pages(GFP_KERNEL, order); if (!block) { /* free all the previous pages since we failed */ @@ -332,7 +296,7 @@ static int iwl_alloc_fw_paging_mem(struct iwl_mvm *mvm, } mvm->fw_paging_db[blk_idx].fw_paging_block = block; - mvm->fw_paging_db[blk_idx].fw_paging_size = PAGING_BLOCK_SIZE; + mvm->fw_paging_db[blk_idx].fw_paging_size = size; if (dma_enabled) { phys = dma_map_page(mvm->trans->dev, block, 0, @@ -353,9 +317,14 @@ static int iwl_alloc_fw_paging_mem(struct iwl_mvm *mvm, blk_idx << BLOCK_2_EXP_SIZE; } - IWL_DEBUG_FW(mvm, - "Paging: allocated 32K bytes (order %d) for firmware paging.\n", - order); + if (!blk_idx) + IWL_DEBUG_FW(mvm, + "Paging: allocated 4K(CSS) bytes (order %d) for firmware paging.\n", + order); + else + IWL_DEBUG_FW(mvm, + "Paging: allocated 32K bytes (order %d) for firmware paging.\n", + order); } return 0; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c index 4a0874e40731..ebf6c071eb36 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c @@ -1565,7 +1565,7 @@ void iwl_mvm_rx_stored_beacon_notif(struct iwl_mvm *mvm, rx_status.flag |= RX_FLAG_MACTIME_PLCP_START; rx_status.device_timestamp = le32_to_cpu(sb->system_time); rx_status.band = - (sb->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_BAND_24)) ? + (sb->band & cpu_to_le16(RX_RES_PHY_FLAGS_BAND_24)) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ; rx_status.freq = ieee80211_channel_to_frequency(le16_to_cpu(sb->channel), diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 45122dafe922..71f9aa9f7c7d 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -463,6 +463,13 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) IEEE80211_RADIOTAP_MCS_HAVE_STBC; hw->radiotap_vht_details |= IEEE80211_RADIOTAP_VHT_KNOWN_STBC | IEEE80211_RADIOTAP_VHT_KNOWN_BEAMFORMED; + + hw->radiotap_timestamp.units_pos = + IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US | + IEEE80211_RADIOTAP_TIMESTAMP_SPOS_PLCP_SIG_ACQ; + /* this is the case for CCK frames, it's better (only 8) for OFDM */ + hw->radiotap_timestamp.accuracy = 22; + hw->rate_control_algorithm = "iwl-mvm-rs"; hw->uapsd_queues = IWL_MVM_UAPSD_QUEUES; hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP; @@ -670,7 +677,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) hw->wiphy->wowlan = &mvm->wowlan; } - if (mvm->fw->img[IWL_UCODE_WOWLAN].sec[0].len && + if (mvm->fw->img[IWL_UCODE_WOWLAN].num_sec && mvm->trans->ops->d3_suspend && mvm->trans->ops->d3_resume && device_can_wakeup(mvm->trans->dev)) { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h index 4a9cb76b7611..a672aa71c656 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h @@ -1657,8 +1657,8 @@ void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue, * Disable a TXQ. * Note that in non-DQA mode the %mac80211_queue and %tid params are ignored. */ -void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue, - u8 tid, u8 flags); +int iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue, + u8 tid, u8 flags); int iwl_mvm_find_free_queue(struct iwl_mvm *mvm, u8 sta_id, u8 minq, u8 maxq); /* Return a bitmask with all the hw supported queues, except for the diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c index 227c5ed9cbe6..80f99c365b6a 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rs.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rs.c @@ -161,9 +161,6 @@ static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, struct rs_rate *rate, const struct rs_tx_column *next_col) { - struct iwl_mvm_sta *mvmsta; - struct iwl_mvm_vif *mvmvif; - if (!sta->ht_cap.ht_supported) return false; @@ -176,9 +173,6 @@ static bool rs_mimo_allow(struct iwl_mvm *mvm, struct ieee80211_sta *sta, if (!iwl_mvm_bt_coex_is_mimo_allowed(mvm, sta)) return false; - mvmsta = iwl_mvm_sta_from_mac80211(sta); - mvmvif = iwl_mvm_vif_from_mac80211(mvmsta->vif); - if (mvm->nvm_data->sku_cap_mimo_disabled) return false; @@ -3071,7 +3065,7 @@ static void iwl_mvm_reset_frame_stats(struct iwl_mvm *mvm) void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg) { - u8 nss = 0, mcs = 0; + u8 nss = 0; spin_lock(&mvm->drv_stats_lock); @@ -3099,11 +3093,9 @@ void iwl_mvm_update_frame_stats(struct iwl_mvm *mvm, u32 rate, bool agg) if (rate & RATE_MCS_HT_MSK) { mvm->drv_rx_stats.ht_frames++; - mcs = rate & RATE_HT_MCS_RATE_CODE_MSK; nss = ((rate & RATE_HT_MCS_NSS_MSK) >> RATE_HT_MCS_NSS_POS) + 1; } else if (rate & RATE_MCS_VHT_MSK) { mvm->drv_rx_stats.vht_frames++; - mcs = rate & RATE_VHT_MCS_RATE_CODE_MSK; nss = ((rate & RATE_VHT_MCS_NSS_MSK) >> RATE_VHT_MCS_NSS_POS) + 1; } else { diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c index 0e60e38b2acf..e16687d5afaa 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rx.c @@ -621,12 +621,10 @@ void iwl_mvm_handle_rx_statistics(struct iwl_mvm *mvm, }; int expected_size = iwl_mvm_has_new_rx_api(mvm) ? sizeof(*stats) : sizeof(struct iwl_notif_statistics_v10); - u32 temperature; if (iwl_rx_packet_payload_len(pkt) != expected_size) goto invalid; - temperature = le32_to_cpu(stats->general.radio_temperature); data.mac_id = stats->rx.general.mac_id; data.beacon_filter_average_energy = stats->general.beacon_filter_average_energy; diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c index 636c8b03e318..40e7fc5f1f1f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c @@ -454,13 +454,6 @@ static int iwl_mvm_remove_sta_queue_marking(struct iwl_mvm *mvm, int queue) rcu_read_unlock(); - spin_lock_bh(&mvm->queue_info_lock); - /* Unmap MAC queues and TIDs from this queue */ - mvm->queue_info[queue].hw_queue_to_mac80211 = 0; - mvm->queue_info[queue].hw_queue_refcount = 0; - mvm->queue_info[queue].tid_bitmap = 0; - spin_unlock_bh(&mvm->queue_info_lock); - return disable_agg_tids; } @@ -755,28 +748,22 @@ static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm, * first */ if (using_inactive_queue) { - struct iwl_scd_txq_cfg_cmd cmd = { - .scd_queue = queue, - .action = SCD_CFG_DISABLE_QUEUE, - }; - u8 txq_curr_ac; - - disable_agg_tids = iwl_mvm_remove_sta_queue_marking(mvm, queue); + u8 txq_curr_ac, sta_id; spin_lock_bh(&mvm->queue_info_lock); txq_curr_ac = mvm->queue_info[queue].mac80211_ac; - cmd.sta_id = mvm->queue_info[queue].ra_sta_id; - cmd.tx_fifo = iwl_mvm_ac_to_tx_fifo[txq_curr_ac]; - cmd.tid = mvm->queue_info[queue].txq_tid; + sta_id = mvm->queue_info[queue].ra_sta_id; spin_unlock_bh(&mvm->queue_info_lock); + disable_agg_tids = iwl_mvm_remove_sta_queue_marking(mvm, queue); /* Disable the queue */ if (disable_agg_tids) iwl_mvm_invalidate_sta_queue(mvm, queue, disable_agg_tids, false); - iwl_trans_txq_disable(mvm->trans, queue, false); - ret = iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, sizeof(cmd), - &cmd); + + ret = iwl_mvm_disable_txq(mvm, queue, + mvmsta->vif->hw_queue[txq_curr_ac], + tid, 0); if (ret) { IWL_ERR(mvm, "Failed to free inactive queue %d (ret=%d)\n", @@ -791,7 +778,7 @@ static int iwl_mvm_sta_alloc_queue(struct iwl_mvm *mvm, } /* If TXQ is allocated to another STA, update removal in FW */ - if (cmd.sta_id != mvmsta->sta_id) + if (sta_id != mvmsta->sta_id) iwl_mvm_invalidate_sta_queue(mvm, queue, 0, true); } @@ -868,7 +855,6 @@ static void iwl_mvm_change_queue_owner(struct iwl_mvm *mvm, int queue) .scd_queue = queue, .action = SCD_CFG_UPDATE_QUEUE_TID, }; - s8 sta_id; int tid; unsigned long tid_bitmap; int ret; @@ -876,7 +862,6 @@ static void iwl_mvm_change_queue_owner(struct iwl_mvm *mvm, int queue) lockdep_assert_held(&mvm->mutex); spin_lock_bh(&mvm->queue_info_lock); - sta_id = mvm->queue_info[queue].ra_sta_id; tid_bitmap = mvm->queue_info[queue].tid_bitmap; spin_unlock_bh(&mvm->queue_info_lock); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 66957ac12ca4..2b2db38eee3e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c @@ -102,14 +102,13 @@ iwl_mvm_bar_check_trigger(struct iwl_mvm *mvm, const u8 *addr, #define OPT_HDR(type, skb, off) \ (type *)(skb_network_header(skb) + (off)) -static void iwl_mvm_tx_csum(struct iwl_mvm *mvm, struct sk_buff *skb, - struct ieee80211_hdr *hdr, - struct ieee80211_tx_info *info, - struct iwl_tx_cmd *tx_cmd) +static u16 iwl_mvm_tx_csum(struct iwl_mvm *mvm, struct sk_buff *skb, + struct ieee80211_hdr *hdr, + struct ieee80211_tx_info *info) { + u16 offload_assist = 0; #if IS_ENABLED(CONFIG_INET) u16 mh_len = ieee80211_hdrlen(hdr->frame_control); - u16 offload_assist = le16_to_cpu(tx_cmd->offload_assist); u8 protocol = 0; /* @@ -117,7 +116,7 @@ static void iwl_mvm_tx_csum(struct iwl_mvm *mvm, struct sk_buff *skb, * compute it */ if (skb->ip_summed != CHECKSUM_PARTIAL || IWL_MVM_SW_TX_CSUM_OFFLOAD) - return; + goto out; /* We do not expect to be requested to csum stuff we do not support */ if (WARN_ONCE(!(mvm->hw->netdev_features & IWL_TX_CSUM_NETIF_FLAGS) || @@ -125,7 +124,7 @@ static void iwl_mvm_tx_csum(struct iwl_mvm *mvm, struct sk_buff *skb, skb->protocol != htons(ETH_P_IPV6)), "No support for requested checksum\n")) { skb_checksum_help(skb); - return; + goto out; } if (skb->protocol == htons(ETH_P_IP)) { @@ -145,7 +144,7 @@ static void iwl_mvm_tx_csum(struct iwl_mvm *mvm, struct sk_buff *skb, protocol != NEXTHDR_HOP && protocol != NEXTHDR_DEST) { skb_checksum_help(skb); - return; + goto out; } hp = OPT_HDR(struct ipv6_opt_hdr, skb, off); @@ -159,7 +158,7 @@ static void iwl_mvm_tx_csum(struct iwl_mvm *mvm, struct sk_buff *skb, if (protocol != IPPROTO_TCP && protocol != IPPROTO_UDP) { WARN_ON_ONCE(1); skb_checksum_help(skb); - return; + goto out; } /* enable L4 csum */ @@ -191,8 +190,9 @@ static void iwl_mvm_tx_csum(struct iwl_mvm *mvm, struct sk_buff *skb, mh_len /= 2; offload_assist |= mh_len << TX_CMD_OFFLD_MH_SIZE; - tx_cmd->offload_assist = cpu_to_le16(offload_assist); +out: #endif + return offload_assist; } /* @@ -295,7 +295,52 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, !(tx_cmd->offload_assist & cpu_to_le16(BIT(TX_CMD_OFFLD_AMSDU)))) tx_cmd->offload_assist |= cpu_to_le16(BIT(TX_CMD_OFFLD_PAD)); - iwl_mvm_tx_csum(mvm, skb, hdr, info, tx_cmd); + tx_cmd->offload_assist |= + cpu_to_le16(iwl_mvm_tx_csum(mvm, skb, hdr, info)); +} + +static u32 iwl_mvm_get_tx_rate(struct iwl_mvm *mvm, + struct ieee80211_tx_info *info, + struct ieee80211_sta *sta) +{ + int rate_idx; + u8 rate_plcp; + u32 rate_flags; + + /* HT rate doesn't make sense for a non data frame */ + WARN_ONCE(info->control.rates[0].flags & IEEE80211_TX_RC_MCS, + "Got an HT rate (flags:0x%x/mcs:%d) for a non data frame\n", + info->control.rates[0].flags, + info->control.rates[0].idx); + + rate_idx = info->control.rates[0].idx; + /* if the rate isn't a well known legacy rate, take the lowest one */ + if (rate_idx < 0 || rate_idx >= IWL_RATE_COUNT_LEGACY) + rate_idx = rate_lowest_index( + &mvm->nvm_data->bands[info->band], sta); + + /* For 5 GHZ band, remap mac80211 rate indices into driver indices */ + if (info->band == NL80211_BAND_5GHZ) + rate_idx += IWL_FIRST_OFDM_RATE; + + /* For 2.4 GHZ band, check that there is no need to remap */ + BUILD_BUG_ON(IWL_FIRST_CCK_RATE != 0); + + /* Get PLCP rate for tx_cmd->rate_n_flags */ + rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx); + + if (info->band == NL80211_BAND_2GHZ && + !iwl_mvm_bt_coex_is_shared_ant_avail(mvm)) + rate_flags = mvm->cfg->non_shared_ant << RATE_MCS_ANT_POS; + else + rate_flags = + BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS; + + /* Set CCK flag as needed */ + if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE)) + rate_flags |= RATE_MCS_CCK_MSK; + + return (u32)rate_plcp | rate_flags; } /* @@ -305,10 +350,6 @@ void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, struct iwl_tx_cmd *tx_cmd, struct ieee80211_tx_info *info, struct ieee80211_sta *sta, __le16 fc) { - u32 rate_flags; - int rate_idx; - u8 rate_plcp; - /* Set retry limit on RTS packets */ tx_cmd->rts_retry_limit = IWL_RTS_DFAULT_RETRY_LIMIT; @@ -337,46 +378,12 @@ void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm, struct iwl_tx_cmd *tx_cmd, cpu_to_le32(TX_CMD_FLG_ACK | TX_CMD_FLG_BAR); } - /* HT rate doesn't make sense for a non data frame */ - WARN_ONCE(info->control.rates[0].flags & IEEE80211_TX_RC_MCS, - "Got an HT rate (flags:0x%x/mcs:%d) for a non data frame (fc:0x%x)\n", - info->control.rates[0].flags, - info->control.rates[0].idx, - le16_to_cpu(fc)); - - rate_idx = info->control.rates[0].idx; - /* if the rate isn't a well known legacy rate, take the lowest one */ - if (rate_idx < 0 || rate_idx >= IWL_RATE_COUNT_LEGACY) - rate_idx = rate_lowest_index( - &mvm->nvm_data->bands[info->band], sta); - - /* For 5 GHZ band, remap mac80211 rate indices into driver indices */ - if (info->band == NL80211_BAND_5GHZ) - rate_idx += IWL_FIRST_OFDM_RATE; - - /* For 2.4 GHZ band, check that there is no need to remap */ - BUILD_BUG_ON(IWL_FIRST_CCK_RATE != 0); - - /* Get PLCP rate for tx_cmd->rate_n_flags */ - rate_plcp = iwl_mvm_mac80211_idx_to_hwrate(rate_idx); - mvm->mgmt_last_antenna_idx = iwl_mvm_next_antenna(mvm, iwl_mvm_get_valid_tx_ant(mvm), mvm->mgmt_last_antenna_idx); - if (info->band == NL80211_BAND_2GHZ && - !iwl_mvm_bt_coex_is_shared_ant_avail(mvm)) - rate_flags = mvm->cfg->non_shared_ant << RATE_MCS_ANT_POS; - else - rate_flags = - BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS; - - /* Set CCK flag as needed */ - if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE)) - rate_flags |= RATE_MCS_CCK_MSK; - /* Set the rate in the TX cmd */ - tx_cmd->rate_n_flags = cpu_to_le32((u32)rate_plcp | rate_flags); + tx_cmd->rate_n_flags = cpu_to_le32(iwl_mvm_get_tx_rate(mvm, info, sta)); } static inline void iwl_mvm_set_tx_cmd_pn(struct ieee80211_tx_info *info, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c index d04babd99b53..26b853ef195f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/utils.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/utils.c @@ -693,10 +693,6 @@ void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue, .tid = cfg->tid, }; - /* Set sta_id in the command, if it exists */ - if (iwl_mvm_is_dqa_supported(mvm)) - cmd.sta_id = cfg->sta_id; - iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, NULL, wdg_timeout); WARN(iwl_mvm_send_cmd_pdu(mvm, SCD_QUEUE_CFG, 0, sizeof(cmd), @@ -706,8 +702,8 @@ void iwl_mvm_enable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue, } } -void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue, - u8 tid, u8 flags) +int iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue, + u8 tid, u8 flags) { struct iwl_scd_txq_cfg_cmd cmd = { .scd_queue = queue, @@ -720,7 +716,7 @@ void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue, if (WARN_ON(mvm->queue_info[queue].hw_queue_refcount == 0)) { spin_unlock_bh(&mvm->queue_info_lock); - return; + return 0; } mvm->queue_info[queue].tid_bitmap &= ~BIT(tid); @@ -760,7 +756,7 @@ void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue, /* If the queue is still enabled - nothing left to do in this func */ if (cmd.action == SCD_CFG_ENABLE_QUEUE) { spin_unlock_bh(&mvm->queue_info_lock); - return; + return 0; } cmd.sta_id = mvm->queue_info[queue].ra_sta_id; @@ -791,6 +787,8 @@ void iwl_mvm_disable_txq(struct iwl_mvm *mvm, int queue, int mac80211_queue, if (ret) IWL_ERR(mvm, "Failed to disable queue %d (ret=%d)\n", queue, ret); + + return ret; } /** diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index b10e3633df1a..c1d99d15796d 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c @@ -805,7 +805,7 @@ static int iwl_pcie_load_cpu_sections_8000(struct iwl_trans *trans, (*first_ucode_section)++; } - for (i = *first_ucode_section; i < IWL_UCODE_SECTION_MAX; i++) { + for (i = *first_ucode_section; i < image->num_sec; i++) { last_read_idx = i; /* @@ -868,19 +868,15 @@ static int iwl_pcie_load_cpu_sections(struct iwl_trans *trans, int cpu, int *first_ucode_section) { - int shift_param; int i, ret = 0; u32 last_read_idx = 0; - if (cpu == 1) { - shift_param = 0; + if (cpu == 1) *first_ucode_section = 0; - } else { - shift_param = 16; + else (*first_ucode_section)++; - } - for (i = *first_ucode_section; i < IWL_UCODE_SECTION_MAX; i++) { + for (i = *first_ucode_section; i < image->num_sec; i++) { last_read_idx = i; /* @@ -1066,6 +1062,20 @@ static int iwl_pcie_load_given_ucode_8000(struct iwl_trans *trans, &first_ucode_section); } +static bool iwl_trans_check_hw_rf_kill(struct iwl_trans *trans) +{ + bool hw_rfkill = iwl_is_rfkill_set(trans); + + if (hw_rfkill) + set_bit(STATUS_RFKILL, &trans->status); + else + clear_bit(STATUS_RFKILL, &trans->status); + + iwl_trans_pcie_rf_kill(trans, hw_rfkill); + + return hw_rfkill; +} + static void _iwl_trans_pcie_stop_device(struct iwl_trans *trans, bool low_power) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -1208,12 +1218,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, mutex_lock(&trans_pcie->mutex); /* If platform's RF_KILL switch is NOT set to KILL */ - hw_rfkill = iwl_is_rfkill_set(trans); - if (hw_rfkill) - set_bit(STATUS_RFKILL, &trans->status); - else - clear_bit(STATUS_RFKILL, &trans->status); - iwl_trans_pcie_rf_kill(trans, hw_rfkill); + hw_rfkill = iwl_trans_check_hw_rf_kill(trans); if (hw_rfkill && !run_in_rfkill) { ret = -ERFKILL; goto out; @@ -1261,13 +1266,7 @@ static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, ret = iwl_pcie_load_given_ucode(trans, fw); /* re-check RF-Kill state since we may have missed the interrupt */ - hw_rfkill = iwl_is_rfkill_set(trans); - if (hw_rfkill) - set_bit(STATUS_RFKILL, &trans->status); - else - clear_bit(STATUS_RFKILL, &trans->status); - - iwl_trans_pcie_rf_kill(trans, hw_rfkill); + hw_rfkill = iwl_trans_check_hw_rf_kill(trans); if (hw_rfkill && !run_in_rfkill) ret = -ERFKILL; @@ -1659,7 +1658,6 @@ static int iwl_pcie_init_msix_handler(struct pci_dev *pdev, static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); - bool hw_rfkill; int err; lockdep_assert_held(&trans_pcie->mutex); @@ -1683,13 +1681,8 @@ static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power) /* Set is_down to false here so that...*/ trans_pcie->is_down = false; - hw_rfkill = iwl_is_rfkill_set(trans); - if (hw_rfkill) - set_bit(STATUS_RFKILL, &trans->status); - else - clear_bit(STATUS_RFKILL, &trans->status); - /* ... rfkill can call stop_device and set it false if needed */ - iwl_trans_pcie_rf_kill(trans, hw_rfkill); + /* ...rfkill can call stop_device and set it false if needed */ + iwl_trans_check_hw_rf_kill(trans); /* Make sure we sync here, because we'll need full access later */ if (low_power) diff --git a/drivers/net/wireless/marvell/libertas/cmd.c b/drivers/net/wireless/marvell/libertas/cmd.c index 301170cccfff..033ff881c751 100644 --- a/drivers/net/wireless/marvell/libertas/cmd.c +++ b/drivers/net/wireless/marvell/libertas/cmd.c @@ -305,7 +305,7 @@ int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action, } lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret); - return 0; + return ret; } static int lbs_wait_for_ds_awake(struct lbs_private *priv) diff --git a/drivers/net/wireless/marvell/mwifiex/11n_aggr.c b/drivers/net/wireless/marvell/mwifiex/11n_aggr.c index c47d6366875d..a75013ac84d7 100644 --- a/drivers/net/wireless/marvell/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/marvell/mwifiex/11n_aggr.c @@ -101,13 +101,6 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv, { struct txpd *local_tx_pd; struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb); - unsigned int pad; - int headroom = (priv->adapter->iface_type == - MWIFIEX_USB) ? 0 : INTF_HEADER_LEN; - - pad = ((void *)skb->data - sizeof(*local_tx_pd) - - headroom - NULL) & (MWIFIEX_DMA_ALIGN_SZ - 1); - skb_push(skb, pad); skb_push(skb, sizeof(*local_tx_pd)); @@ -121,12 +114,10 @@ mwifiex_11n_form_amsdu_txpd(struct mwifiex_private *priv, local_tx_pd->bss_num = priv->bss_num; local_tx_pd->bss_type = priv->bss_type; /* Always zero as the data is followed by struct txpd */ - local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd) + - pad); + local_tx_pd->tx_pkt_offset = cpu_to_le16(sizeof(struct txpd)); local_tx_pd->tx_pkt_type = cpu_to_le16(PKT_TYPE_AMSDU); local_tx_pd->tx_pkt_length = cpu_to_le16(skb->len - - sizeof(*local_tx_pd) - - pad); + sizeof(*local_tx_pd)); if (tx_info->flags & MWIFIEX_BUF_FLAG_TDLS_PKT) local_tx_pd->flags |= MWIFIEX_TXPD_FLAGS_TDLS_PACKET; @@ -190,7 +181,11 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, ra_list_flags); return -1; } - skb_reserve(skb_aggr, MWIFIEX_MIN_DATA_HEADER_LEN); + + /* skb_aggr->data already 64 byte align, just reserve bus interface + * header and txpd. + */ + skb_reserve(skb_aggr, headroom + sizeof(struct txpd)); tx_info_aggr = MWIFIEX_SKB_TXCB(skb_aggr); memset(tx_info_aggr, 0, sizeof(*tx_info_aggr)); diff --git a/drivers/net/wireless/marvell/mwifiex/debugfs.c b/drivers/net/wireless/marvell/mwifiex/debugfs.c index b9284b533294..ae2b69db5994 100644 --- a/drivers/net/wireless/marvell/mwifiex/debugfs.c +++ b/drivers/net/wireless/marvell/mwifiex/debugfs.c @@ -114,7 +114,8 @@ mwifiex_info_read(struct file *file, char __user *ubuf, if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) { p += sprintf(p, "multicast_count=\"%d\"\n", netdev_mc_count(netdev)); - p += sprintf(p, "essid=\"%s\"\n", info.ssid.ssid); + p += sprintf(p, "essid=\"%.*s\"\n", info.ssid.ssid_len, + info.ssid.ssid); p += sprintf(p, "bssid=\"%pM\"\n", info.bssid); p += sprintf(p, "channel=\"%d\"\n", (int) info.bss_chan); p += sprintf(p, "country_code = \"%s\"\n", info.country_code); diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h index 55db158fd156..cb6a1a81d44e 100644 --- a/drivers/net/wireless/marvell/mwifiex/fw.h +++ b/drivers/net/wireless/marvell/mwifiex/fw.h @@ -550,6 +550,7 @@ enum mwifiex_channel_flags { #define EVENT_TX_DATA_PAUSE 0x00000055 #define EVENT_EXT_SCAN_REPORT 0x00000058 #define EVENT_RXBA_SYNC 0x00000059 +#define EVENT_UNKNOWN_DEBUG 0x00000063 #define EVENT_BG_SCAN_STOPPED 0x00000065 #define EVENT_REMAIN_ON_CHAN_EXPIRED 0x0000005f #define EVENT_MULTI_CHAN_INFO 0x0000006a diff --git a/drivers/net/wireless/marvell/mwifiex/init.c b/drivers/net/wireless/marvell/mwifiex/init.c index 0e89ccfa244e..756948385b60 100644 --- a/drivers/net/wireless/marvell/mwifiex/init.c +++ b/drivers/net/wireless/marvell/mwifiex/init.c @@ -409,8 +409,6 @@ static void mwifiex_free_lock_list(struct mwifiex_adapter *adapter) static void mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter) { - int idx; - if (!adapter) { pr_err("%s: adapter is NULL\n", __func__); return; @@ -428,23 +426,6 @@ mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter) mwifiex_dbg(adapter, INFO, "info: free cmd buffer\n"); mwifiex_free_cmd_buffer(adapter); - for (idx = 0; idx < adapter->num_mem_types; idx++) { - struct memory_type_mapping *entry = - &adapter->mem_type_mapping_tbl[idx]; - - if (entry->mem_ptr) { - vfree(entry->mem_ptr); - entry->mem_ptr = NULL; - } - entry->mem_size = 0; - } - - if (adapter->drv_info_dump) { - vfree(adapter->drv_info_dump); - adapter->drv_info_dump = NULL; - adapter->drv_info_size = 0; - } - if (adapter->sleep_cfm) dev_kfree_skb_any(adapter->sleep_cfm); } @@ -657,10 +638,9 @@ void mwifiex_free_priv(struct mwifiex_private *priv) * - Free the adapter * - Notify completion */ -int +void mwifiex_shutdown_drv(struct mwifiex_adapter *adapter) { - int ret = -EINPROGRESS; struct mwifiex_private *priv; s32 i; unsigned long flags; @@ -668,15 +648,7 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter) /* mwifiex already shutdown */ if (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY) - return 0; - - adapter->hw_status = MWIFIEX_HW_STATUS_CLOSING; - /* wait for mwifiex_process to complete */ - if (adapter->mwifiex_processing) { - mwifiex_dbg(adapter, WARN, - "main process is still running\n"); - return ret; - } + return; /* cancel current command */ if (adapter->curr_cmd) { @@ -727,11 +699,7 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter) mwifiex_adapter_cleanup(adapter); spin_unlock(&adapter->mwifiex_lock); - - /* Notify completion */ - ret = mwifiex_shutdown_fw_complete(adapter); - - return ret; + adapter->hw_status = MWIFIEX_HW_STATUS_NOT_READY; } /* diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c index e5c3a8aa3929..9d80180a5519 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -248,15 +248,14 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter) if (adapter->mwifiex_processing || adapter->main_locked) { adapter->more_task_flag = true; spin_unlock_irqrestore(&adapter->main_proc_lock, flags); - goto exit_main_proc; + return 0; } else { adapter->mwifiex_processing = true; spin_unlock_irqrestore(&adapter->main_proc_lock, flags); } process_start: do { - if ((adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING) || - (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY)) + if (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY) break; /* For non-USB interfaces, If we process interrupts first, it @@ -464,9 +463,6 @@ process_start: adapter->mwifiex_processing = false; spin_unlock_irqrestore(&adapter->main_proc_lock, flags); -exit_main_proc: - if (adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING) - mwifiex_shutdown_drv(adapter); return ret; } EXPORT_SYMBOL_GPL(mwifiex_main_process); @@ -645,16 +641,14 @@ err_dnld_fw: if (adapter->if_ops.unregister_dev) adapter->if_ops.unregister_dev(adapter); + adapter->surprise_removed = true; + mwifiex_terminate_workqueue(adapter); + if (adapter->hw_status == MWIFIEX_HW_STATUS_READY) { pr_debug("info: %s: shutdown mwifiex\n", __func__); - adapter->init_wait_q_woken = false; - - if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS) - wait_event_interruptible(adapter->init_wait_q, - adapter->init_wait_q_woken); + mwifiex_shutdown_drv(adapter); } - adapter->surprise_removed = true; - mwifiex_terminate_workqueue(adapter); + init_failed = true; done: if (adapter->cal_data) { @@ -1032,7 +1026,7 @@ void mwifiex_multi_chan_resync(struct mwifiex_adapter *adapter) } EXPORT_SYMBOL_GPL(mwifiex_multi_chan_resync); -void mwifiex_drv_info_dump(struct mwifiex_adapter *adapter) +int mwifiex_drv_info_dump(struct mwifiex_adapter *adapter, void **drv_info) { void *p; char drv_version[64]; @@ -1042,21 +1036,17 @@ void mwifiex_drv_info_dump(struct mwifiex_adapter *adapter) int i, idx; struct netdev_queue *txq; struct mwifiex_debug_info *debug_info; - - if (adapter->drv_info_dump) { - vfree(adapter->drv_info_dump); - adapter->drv_info_dump = NULL; - adapter->drv_info_size = 0; - } + void *drv_info_dump; mwifiex_dbg(adapter, MSG, "===mwifiex driverinfo dump start===\n"); - adapter->drv_info_dump = vzalloc(MWIFIEX_DRV_INFO_SIZE_MAX); + /* memory allocate here should be free in mwifiex_upload_device_dump*/ + drv_info_dump = vzalloc(MWIFIEX_DRV_INFO_SIZE_MAX); - if (!adapter->drv_info_dump) - return; + if (!drv_info_dump) + return 0; - p = (char *)(adapter->drv_info_dump); + p = (char *)(drv_info_dump); p += sprintf(p, "driver_name = " "\"mwifiex\"\n"); mwifiex_drv_get_driver_version(adapter, drv_version, @@ -1140,18 +1130,20 @@ void mwifiex_drv_info_dump(struct mwifiex_adapter *adapter) kfree(debug_info); } - adapter->drv_info_size = p - adapter->drv_info_dump; mwifiex_dbg(adapter, MSG, "===mwifiex driverinfo dump end===\n"); + *drv_info = drv_info_dump; + return p - drv_info_dump; } EXPORT_SYMBOL_GPL(mwifiex_drv_info_dump); -void mwifiex_upload_device_dump(struct mwifiex_adapter *adapter) +void mwifiex_upload_device_dump(struct mwifiex_adapter *adapter, void *drv_info, + int drv_info_size) { u8 idx, *dump_data, *fw_dump_ptr; u32 dump_len; dump_len = (strlen("========Start dump driverinfo========\n") + - adapter->drv_info_size + + drv_info_size + strlen("\n========End dump========\n")); for (idx = 0; idx < adapter->num_mem_types; idx++) { @@ -1181,8 +1173,8 @@ void mwifiex_upload_device_dump(struct mwifiex_adapter *adapter) strcpy(fw_dump_ptr, "========Start dump driverinfo========\n"); fw_dump_ptr += strlen("========Start dump driverinfo========\n"); - memcpy(fw_dump_ptr, adapter->drv_info_dump, adapter->drv_info_size); - fw_dump_ptr += adapter->drv_info_size; + memcpy(fw_dump_ptr, drv_info, drv_info_size); + fw_dump_ptr += drv_info_size; strcpy(fw_dump_ptr, "\n========End dump========\n"); fw_dump_ptr += strlen("\n========End dump========\n"); @@ -1220,18 +1212,12 @@ done: struct memory_type_mapping *entry = &adapter->mem_type_mapping_tbl[idx]; - if (entry->mem_ptr) { - vfree(entry->mem_ptr); - entry->mem_ptr = NULL; - } + vfree(entry->mem_ptr); + entry->mem_ptr = NULL; entry->mem_size = 0; } - if (adapter->drv_info_dump) { - vfree(adapter->drv_info_dump); - adapter->drv_info_dump = NULL; - adapter->drv_info_size = 0; - } + vfree(drv_info); } EXPORT_SYMBOL_GPL(mwifiex_upload_device_dump); @@ -1362,7 +1348,7 @@ static void mwifiex_main_work_queue(struct work_struct *work) * This function gets called during PCIe function level reset. Required * code is extracted from mwifiex_remove_card() */ -static int +int mwifiex_shutdown_sw(struct mwifiex_adapter *adapter) { struct mwifiex_private *priv; @@ -1399,11 +1385,8 @@ mwifiex_shutdown_sw(struct mwifiex_adapter *adapter) } mwifiex_dbg(adapter, CMD, "cmd: calling mwifiex_shutdown_drv...\n"); - adapter->init_wait_q_woken = false; - if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS) - wait_event_interruptible(adapter->init_wait_q, - adapter->init_wait_q_woken); + mwifiex_shutdown_drv(adapter); if (adapter->if_ops.down_dev) adapter->if_ops.down_dev(adapter); @@ -1434,24 +1417,18 @@ mwifiex_shutdown_sw(struct mwifiex_adapter *adapter) exit_return: return 0; } +EXPORT_SYMBOL_GPL(mwifiex_shutdown_sw); /* This function gets called during PCIe function level reset. Required * code is extracted from mwifiex_add_card() */ -static int -mwifiex_reinit_sw(struct mwifiex_adapter *adapter, struct completion *fw_done, - struct mwifiex_if_ops *if_ops, u8 iface_type) +int +mwifiex_reinit_sw(struct mwifiex_adapter *adapter) { - char fw_name[32]; - struct pcie_service_card *card = adapter->card; - mwifiex_init_lock_list(adapter); if (adapter->if_ops.up_dev) adapter->if_ops.up_dev(adapter); - adapter->iface_type = iface_type; - adapter->fw_done = fw_done; - adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING; adapter->surprise_removed = false; init_waitqueue_head(&adapter->init_wait_q); @@ -1488,18 +1465,12 @@ mwifiex_reinit_sw(struct mwifiex_adapter *adapter, struct completion *fw_done, * mwifiex_register_dev() */ mwifiex_dbg(adapter, INFO, "%s, mwifiex_init_hw_fw()...\n", __func__); - strcpy(fw_name, adapter->fw_name); - strcpy(adapter->fw_name, PCIE8997_DEFAULT_WIFIFW_NAME); - adapter->tx_buf_size = card->pcie.tx_buf_size; - adapter->ext_scan = card->pcie.can_ext_scan; if (mwifiex_init_hw_fw(adapter, false)) { - strcpy(adapter->fw_name, fw_name); mwifiex_dbg(adapter, ERROR, "%s: firmware init failed\n", __func__); goto err_init_fw; } - strcpy(adapter->fw_name, fw_name); mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__); complete_all(adapter->fw_done); @@ -1509,43 +1480,22 @@ err_init_fw: mwifiex_dbg(adapter, ERROR, "info: %s: unregister device\n", __func__); if (adapter->if_ops.unregister_dev) adapter->if_ops.unregister_dev(adapter); + +err_kmalloc: + adapter->surprise_removed = true; + mwifiex_terminate_workqueue(adapter); if (adapter->hw_status == MWIFIEX_HW_STATUS_READY) { mwifiex_dbg(adapter, ERROR, "info: %s: shutdown mwifiex\n", __func__); - adapter->init_wait_q_woken = false; - - if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS) - wait_event_interruptible(adapter->init_wait_q, - adapter->init_wait_q_woken); + mwifiex_shutdown_drv(adapter); } -err_kmalloc: - mwifiex_terminate_workqueue(adapter); - adapter->surprise_removed = true; complete_all(adapter->fw_done); mwifiex_dbg(adapter, INFO, "%s, error\n", __func__); return -1; } - -/* This function processes pre and post PCIe function level resets. - * It performs software cleanup without touching PCIe specific code. - * Also, during initialization PCIe stuff is skipped. - */ -void mwifiex_do_flr(struct mwifiex_adapter *adapter, bool prepare) -{ - struct mwifiex_if_ops if_ops; - - if (!prepare) { - mwifiex_reinit_sw(adapter, adapter->fw_done, &if_ops, - adapter->iface_type); - } else { - memcpy(&if_ops, &adapter->if_ops, - sizeof(struct mwifiex_if_ops)); - mwifiex_shutdown_sw(adapter); - } -} -EXPORT_SYMBOL_GPL(mwifiex_do_flr); +EXPORT_SYMBOL_GPL(mwifiex_reinit_sw); static irqreturn_t mwifiex_irq_wakeup_handler(int irq, void *priv) { @@ -1681,17 +1631,13 @@ err_init_fw: pr_debug("info: %s: unregister device\n", __func__); if (adapter->if_ops.unregister_dev) adapter->if_ops.unregister_dev(adapter); - if (adapter->hw_status == MWIFIEX_HW_STATUS_READY) { - pr_debug("info: %s: shutdown mwifiex\n", __func__); - adapter->init_wait_q_woken = false; - - if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS) - wait_event_interruptible(adapter->init_wait_q, - adapter->init_wait_q_woken); - } err_registerdev: adapter->surprise_removed = true; mwifiex_terminate_workqueue(adapter); + if (adapter->hw_status == MWIFIEX_HW_STATUS_READY) { + pr_debug("info: %s: shutdown mwifiex\n", __func__); + mwifiex_shutdown_drv(adapter); + } err_kmalloc: mwifiex_free_adapter(adapter); @@ -1741,11 +1687,8 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter) mwifiex_dbg(adapter, CMD, "cmd: calling mwifiex_shutdown_drv...\n"); - adapter->init_wait_q_woken = false; - if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS) - wait_event_interruptible(adapter->init_wait_q, - adapter->init_wait_q_woken); + mwifiex_shutdown_drv(adapter); mwifiex_dbg(adapter, CMD, "cmd: mwifiex_shutdown_drv done\n"); if (atomic_read(&adapter->rx_pending) || diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h index d552a9d104d0..5c8297207f33 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.h +++ b/drivers/net/wireless/marvell/mwifiex/main.h @@ -248,7 +248,6 @@ enum MWIFIEX_HARDWARE_STATUS { MWIFIEX_HW_STATUS_INITIALIZING, MWIFIEX_HW_STATUS_INIT_DONE, MWIFIEX_HW_STATUS_RESET, - MWIFIEX_HW_STATUS_CLOSING, MWIFIEX_HW_STATUS_NOT_READY }; @@ -995,8 +994,6 @@ struct mwifiex_adapter { u8 key_api_major_ver, key_api_minor_ver; struct memory_type_mapping *mem_type_mapping_tbl; u8 num_mem_types; - void *drv_info_dump; - u32 drv_info_size; bool scan_chan_gap_enabled; struct sk_buff_head rx_data_q; bool mfg_mode; @@ -1041,9 +1038,7 @@ int mwifiex_init_fw(struct mwifiex_adapter *adapter); int mwifiex_init_fw_complete(struct mwifiex_adapter *adapter); -int mwifiex_shutdown_drv(struct mwifiex_adapter *adapter); - -int mwifiex_shutdown_fw_complete(struct mwifiex_adapter *adapter); +void mwifiex_shutdown_drv(struct mwifiex_adapter *adapter); int mwifiex_dnld_fw(struct mwifiex_adapter *, struct mwifiex_fw_image *); @@ -1644,8 +1639,9 @@ void mwifiex_hist_data_add(struct mwifiex_private *priv, u8 mwifiex_adjust_data_rate(struct mwifiex_private *priv, u8 rx_rate, u8 ht_info); -void mwifiex_drv_info_dump(struct mwifiex_adapter *adapter); -void mwifiex_upload_device_dump(struct mwifiex_adapter *adapter); +int mwifiex_drv_info_dump(struct mwifiex_adapter *adapter, void **drv_info); +void mwifiex_upload_device_dump(struct mwifiex_adapter *adapter, void *drv_info, + int drv_info_size); void *mwifiex_alloc_dma_align_buf(int rx_len, gfp_t flags); void mwifiex_queue_main_work(struct mwifiex_adapter *adapter); int mwifiex_get_wakeup_reason(struct mwifiex_private *priv, u16 action, @@ -1670,5 +1666,6 @@ void mwifiex_debugfs_remove(void); void mwifiex_dev_debugfs_init(struct mwifiex_private *priv); void mwifiex_dev_debugfs_remove(struct mwifiex_private *priv); #endif -void mwifiex_do_flr(struct mwifiex_adapter *adapter, bool prepare); +int mwifiex_reinit_sw(struct mwifiex_adapter *adapter); +int mwifiex_shutdown_sw(struct mwifiex_adapter *adapter); #endif /* !_MWIFIEX_MAIN_H_ */ diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c index 4db07da81d8d..a0d918094889 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie.c +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c @@ -31,8 +31,6 @@ #define PCIE_VERSION "1.0" #define DRV_NAME "Marvell mwifiex PCIe" -static u8 user_rmmod; - static struct mwifiex_if_ops pcie_ops; static const struct of_device_id mwifiex_pcie_of_match_table[] = { @@ -51,6 +49,8 @@ static int mwifiex_pcie_probe_of(struct device *dev) return 0; } +static void mwifiex_pcie_work(struct work_struct *work); + static int mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb, size_t size, int flags) @@ -79,6 +79,42 @@ static void mwifiex_unmap_pci_memory(struct mwifiex_adapter *adapter, } /* + * This function writes data into PCIE card register. + */ +static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data) +{ + struct pcie_service_card *card = adapter->card; + + iowrite32(data, card->pci_mmap1 + reg); + + return 0; +} + +/* This function reads data from PCIE card register. + */ +static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data) +{ + struct pcie_service_card *card = adapter->card; + + *data = ioread32(card->pci_mmap1 + reg); + if (*data == 0xffffffff) + return 0xffffffff; + + return 0; +} + +/* This function reads u8 data from PCIE card register. */ +static int mwifiex_read_reg_byte(struct mwifiex_adapter *adapter, + int reg, u8 *data) +{ + struct pcie_service_card *card = adapter->card; + + *data = ioread8(card->pci_mmap1 + reg); + + return 0; +} + +/* * This function reads sleep cookie and checks if FW is ready */ static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter) @@ -219,6 +255,7 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev, card->pcie.mem_type_mapping_tbl = data->mem_type_mapping_tbl; card->pcie.num_mem_types = data->num_mem_types; card->pcie.can_ext_scan = data->can_ext_scan; + INIT_WORK(&card->work, mwifiex_pcie_work); } /* device tree node parsing and platform specific configuration*/ @@ -245,6 +282,9 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev) struct pcie_service_card *card; struct mwifiex_adapter *adapter; struct mwifiex_private *priv; + const struct mwifiex_pcie_card_reg *reg; + u32 fw_status; + int ret; card = pci_get_drvdata(pdev); @@ -254,7 +294,15 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev) if (!adapter || !adapter->priv_num) return; - if (user_rmmod && !adapter->mfg_mode) { + cancel_work_sync(&card->work); + + reg = card->pcie.reg; + if (reg) + ret = mwifiex_read_reg(adapter, reg->fw_status, &fw_status); + else + fw_status = -1; + + if (fw_status == FIRMWARE_READY_PCIE && !adapter->mfg_mode) { mwifiex_deauthenticate_all(adapter); priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); @@ -269,7 +317,6 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev) static void mwifiex_pcie_shutdown(struct pci_dev *pdev) { - user_rmmod = 1; mwifiex_pcie_remove(pdev); return; @@ -330,7 +377,7 @@ static void mwifiex_pcie_reset_notify(struct pci_dev *pdev, bool prepare) * Cleanup all software without cleaning anything related to * PCIe and HW. */ - mwifiex_do_flr(adapter, prepare); + mwifiex_shutdown_sw(adapter); adapter->surprise_removed = true; } else { /* Kernel stores and restores PCIe function context before and @@ -338,7 +385,7 @@ static void mwifiex_pcie_reset_notify(struct pci_dev *pdev, bool prepare) * and firmware including firmware redownload */ adapter->surprise_removed = false; - mwifiex_do_flr(adapter, prepare); + mwifiex_reinit_sw(adapter); } mwifiex_dbg(adapter, INFO, "%s, successful\n", __func__); } @@ -369,43 +416,6 @@ static struct pci_driver __refdata mwifiex_pcie = { }; /* - * This function writes data into PCIE card register. - */ -static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data) -{ - struct pcie_service_card *card = adapter->card; - - iowrite32(data, card->pci_mmap1 + reg); - - return 0; -} - -/* - * This function reads data from PCIE card register. - */ -static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data) -{ - struct pcie_service_card *card = adapter->card; - - *data = ioread32(card->pci_mmap1 + reg); - if (*data == 0xffffffff) - return 0xffffffff; - - return 0; -} - -/* This function reads u8 data from PCIE card register. */ -static int mwifiex_read_reg_byte(struct mwifiex_adapter *adapter, - int reg, u8 *data) -{ - struct pcie_service_card *card = adapter->card; - - *data = ioread8(card->pci_mmap1 + reg); - - return 0; -} - -/* * This function adds delay loop to ensure FW is awake before proceeding. */ static void mwifiex_pcie_dev_wakeup_delay(struct mwifiex_adapter *adapter) @@ -429,16 +439,25 @@ static void mwifiex_delay_for_sleep_cookie(struct mwifiex_adapter *adapter, struct pcie_service_card *card = adapter->card; u8 *buffer; u32 sleep_cookie, count; + struct sk_buff *cmdrsp = card->cmdrsp_buf; for (count = 0; count < max_delay_loop_cnt; count++) { - buffer = card->cmdrsp_buf->data - INTF_HEADER_LEN; - sleep_cookie = *(u32 *)buffer; + pci_dma_sync_single_for_cpu(card->dev, + MWIFIEX_SKB_DMA_ADDR(cmdrsp), + sizeof(sleep_cookie), + PCI_DMA_FROMDEVICE); + buffer = cmdrsp->data; + sleep_cookie = READ_ONCE(*(u32 *)buffer); if (sleep_cookie == MWIFIEX_DEF_SLEEP_COOKIE) { mwifiex_dbg(adapter, INFO, "sleep cookie found at count %d\n", count); break; } + pci_dma_sync_single_for_device(card->dev, + MWIFIEX_SKB_DMA_ADDR(cmdrsp), + sizeof(sleep_cookie), + PCI_DMA_FROMDEVICE); usleep_range(20, 30); } @@ -450,7 +469,6 @@ static void mwifiex_delay_for_sleep_cookie(struct mwifiex_adapter *adapter, /* This function wakes up the card by reading fw_status register. */ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter) { - u32 fw_status; struct pcie_service_card *card = adapter->card; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; @@ -460,10 +478,10 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter) if (reg->sleep_cookie) mwifiex_pcie_dev_wakeup_delay(adapter); - /* Reading fw_status register will wakeup device */ - if (mwifiex_read_reg(adapter, reg->fw_status, &fw_status)) { + /* Accessing fw_status register will wakeup device */ + if (mwifiex_write_reg(adapter, reg->fw_status, FIRMWARE_READY_PCIE)) { mwifiex_dbg(adapter, ERROR, - "Reading fw_status register failed\n"); + "Writing fw_status register failed\n"); return -1; } @@ -1681,7 +1699,13 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) mwifiex_dbg(adapter, CMD, "info: Rx CMD Response\n"); - mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_FROMDEVICE); + if (adapter->curr_cmd) + mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_FROMDEVICE); + else + pci_dma_sync_single_for_cpu(card->dev, + MWIFIEX_SKB_DMA_ADDR(skb), + MWIFIEX_UPLD_SIZE, + PCI_DMA_FROMDEVICE); /* Unmap the command as a response has been received. */ if (card->cmd_buf) { @@ -1694,10 +1718,13 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) rx_len = le16_to_cpu(pkt_len); skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len); skb_trim(skb, rx_len); - skb_pull(skb, INTF_HEADER_LEN); if (!adapter->curr_cmd) { if (adapter->ps_state == PS_STATE_SLEEP_CFM) { + pci_dma_sync_single_for_device(card->dev, + MWIFIEX_SKB_DMA_ADDR(skb), + MWIFIEX_SLEEP_COOKIE_SIZE, + PCI_DMA_FROMDEVICE); if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT, CPU_INTR_SLEEP_CFM_DONE)) { @@ -1707,6 +1734,9 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) } mwifiex_delay_for_sleep_cookie(adapter, MWIFIEX_MAX_DELAY_COUNT); + mwifiex_unmap_pci_memory(adapter, skb, + PCI_DMA_FROMDEVICE); + skb_pull(skb, INTF_HEADER_LEN); while (reg->sleep_cookie && (count++ < 10) && mwifiex_pcie_ok_to_access_hw(adapter)) usleep_range(50, 60); @@ -1724,6 +1754,7 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) PCI_DMA_FROMDEVICE)) return -1; } else if (mwifiex_pcie_ok_to_access_hw(adapter)) { + skb_pull(skb, INTF_HEADER_LEN); adapter->curr_cmd->resp_skb = skb; adapter->cmd_resp_received = true; /* Take the pointer and set it to CMD node and will @@ -2325,79 +2356,41 @@ static int mwifiex_process_pcie_int(struct mwifiex_adapter *adapter) } } } - while (pcie_ireg & HOST_INTR_MASK) { - if (pcie_ireg & HOST_INTR_DNLD_DONE) { - pcie_ireg &= ~HOST_INTR_DNLD_DONE; - mwifiex_dbg(adapter, INTR, - "info: TX DNLD Done\n"); - ret = mwifiex_pcie_send_data_complete(adapter); - if (ret) - return ret; - } - if (pcie_ireg & HOST_INTR_UPLD_RDY) { - pcie_ireg &= ~HOST_INTR_UPLD_RDY; - mwifiex_dbg(adapter, INTR, - "info: Rx DATA\n"); - ret = mwifiex_pcie_process_recv_data(adapter); - if (ret) - return ret; - } - if (pcie_ireg & HOST_INTR_EVENT_RDY) { - pcie_ireg &= ~HOST_INTR_EVENT_RDY; - mwifiex_dbg(adapter, INTR, - "info: Rx EVENT\n"); - ret = mwifiex_pcie_process_event_ready(adapter); - if (ret) - return ret; - } - - if (pcie_ireg & HOST_INTR_CMD_DONE) { - pcie_ireg &= ~HOST_INTR_CMD_DONE; - if (adapter->cmd_sent) { - mwifiex_dbg(adapter, INTR, - "info: CMD sent Interrupt\n"); - adapter->cmd_sent = false; - } - /* Handle command response */ - ret = mwifiex_pcie_process_cmd_complete(adapter); - if (ret) - return ret; - if (adapter->hs_activated) - return ret; - } - - if (card->msi_enable) { - spin_lock_irqsave(&adapter->int_lock, flags); - adapter->int_status = 0; - spin_unlock_irqrestore(&adapter->int_lock, flags); - } - - if (mwifiex_pcie_ok_to_access_hw(adapter)) { - if (mwifiex_read_reg(adapter, PCIE_HOST_INT_STATUS, - &pcie_ireg)) { - mwifiex_dbg(adapter, ERROR, - "Read register failed\n"); - return -1; - } - - if ((pcie_ireg != 0xFFFFFFFF) && (pcie_ireg)) { - if (mwifiex_write_reg(adapter, - PCIE_HOST_INT_STATUS, - ~pcie_ireg)) { - mwifiex_dbg(adapter, ERROR, - "Write register failed\n"); - return -1; - } - } + if (pcie_ireg & HOST_INTR_DNLD_DONE) { + pcie_ireg &= ~HOST_INTR_DNLD_DONE; + mwifiex_dbg(adapter, INTR, "info: TX DNLD Done\n"); + ret = mwifiex_pcie_send_data_complete(adapter); + if (ret) + return ret; + } + if (pcie_ireg & HOST_INTR_UPLD_RDY) { + pcie_ireg &= ~HOST_INTR_UPLD_RDY; + mwifiex_dbg(adapter, INTR, "info: Rx DATA\n"); + ret = mwifiex_pcie_process_recv_data(adapter); + if (ret) + return ret; + } + if (pcie_ireg & HOST_INTR_EVENT_RDY) { + pcie_ireg &= ~HOST_INTR_EVENT_RDY; + mwifiex_dbg(adapter, INTR, "info: Rx EVENT\n"); + ret = mwifiex_pcie_process_event_ready(adapter); + if (ret) + return ret; + } + if (pcie_ireg & HOST_INTR_CMD_DONE) { + pcie_ireg &= ~HOST_INTR_CMD_DONE; + if (adapter->cmd_sent) { + mwifiex_dbg(adapter, INTR, + "info: CMD sent Interrupt\n"); + adapter->cmd_sent = false; } - if (!card->msi_enable) { - spin_lock_irqsave(&adapter->int_lock, flags); - pcie_ireg |= adapter->int_status; - adapter->int_status = 0; - spin_unlock_irqrestore(&adapter->int_lock, flags); - } + /* Handle command response */ + ret = mwifiex_pcie_process_cmd_complete(adapter); + if (ret) + return ret; } + mwifiex_dbg(adapter, INTR, "info: cmd_sent=%d data_sent=%d\n", adapter->cmd_sent, adapter->data_sent); @@ -2715,31 +2708,35 @@ static void mwifiex_pcie_fw_dump(struct mwifiex_adapter *adapter) static void mwifiex_pcie_device_dump_work(struct mwifiex_adapter *adapter) { - mwifiex_drv_info_dump(adapter); + int drv_info_size; + void *drv_info; + + drv_info_size = mwifiex_drv_info_dump(adapter, &drv_info); mwifiex_pcie_fw_dump(adapter); - mwifiex_upload_device_dump(adapter); + mwifiex_upload_device_dump(adapter, drv_info, drv_info_size); } -static unsigned long iface_work_flags; -static struct mwifiex_adapter *save_adapter; static void mwifiex_pcie_work(struct work_struct *work) { + struct pcie_service_card *card = + container_of(work, struct pcie_service_card, work); + if (test_and_clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, - &iface_work_flags)) - mwifiex_pcie_device_dump_work(save_adapter); + &card->work_flags)) + mwifiex_pcie_device_dump_work(card->adapter); } -static DECLARE_WORK(pcie_work, mwifiex_pcie_work); /* This function dumps FW information */ static void mwifiex_pcie_device_dump(struct mwifiex_adapter *adapter) { - save_adapter = adapter; - if (test_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &iface_work_flags)) + struct pcie_service_card *card = adapter->card; + + if (test_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags)) return; - set_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &iface_work_flags); + set_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags); - schedule_work(&pcie_work); + schedule_work(&card->work); } /* @@ -2752,7 +2749,7 @@ static void mwifiex_pcie_device_dump(struct mwifiex_adapter *adapter) * - Allocate command response ring buffer * - Allocate sleep cookie buffer */ -static int mwifiex_pcie_init(struct mwifiex_adapter *adapter) +static int mwifiex_init_pcie(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; int ret; @@ -2861,13 +2858,16 @@ err_enable_dev: * - Command response ring buffer * - Sleep cookie buffer */ -static void mwifiex_pcie_cleanup(struct mwifiex_adapter *adapter) +static void mwifiex_cleanup_pcie(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; struct pci_dev *pdev = card->dev; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; + int ret; + u32 fw_status; - if (user_rmmod) { + ret = mwifiex_read_reg(adapter, reg->fw_status, &fw_status); + if (fw_status == FIRMWARE_READY_PCIE) { mwifiex_dbg(adapter, INFO, "Clearing driver ready signature\n"); if (mwifiex_write_reg(adapter, reg->drv_rdy, 0x00000000)) @@ -3058,7 +3058,7 @@ static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter) * - Allocate event BD ring buffers * - Allocate command response ring buffer * - Allocate sleep cookie buffer - * Part of mwifiex_pcie_init(), not reset the PCIE registers + * Part of mwifiex_init_pcie(), not reset the PCIE registers */ static void mwifiex_pcie_up_dev(struct mwifiex_adapter *adapter) { @@ -3067,6 +3067,17 @@ static void mwifiex_pcie_up_dev(struct mwifiex_adapter *adapter) struct pci_dev *pdev = card->dev; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; + /* Bluetooth is not on pcie interface. Download Wifi only firmware + * during pcie FLR, so that bluetooth part of firmware which is + * already running doesn't get affected. + */ + strcpy(adapter->fw_name, PCIE8997_DEFAULT_WIFIFW_NAME); + + /* tx_buf_size might be changed to 3584 by firmware during + * data transfer, we should reset it to default size. + */ + adapter->tx_buf_size = card->pcie.tx_buf_size; + card->cmdrsp_buf = NULL; ret = mwifiex_pcie_create_txbd_ring(adapter); if (ret) { @@ -3128,7 +3139,6 @@ static void mwifiex_pcie_down_dev(struct mwifiex_adapter *adapter) mwifiex_dbg(adapter, ERROR, "Failed to write driver not-ready signature\n"); adapter->seq_num = 0; - adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K; if (reg->sleep_cookie) mwifiex_pcie_delete_sleep_cookie_buf(adapter); @@ -3141,8 +3151,8 @@ static void mwifiex_pcie_down_dev(struct mwifiex_adapter *adapter) } static struct mwifiex_if_ops pcie_ops = { - .init_if = mwifiex_pcie_init, - .cleanup_if = mwifiex_pcie_cleanup, + .init_if = mwifiex_init_pcie, + .cleanup_if = mwifiex_cleanup_pcie, .check_fw_status = mwifiex_check_fw_status, .check_winner_status = mwifiex_check_winner_status, .prog_fw = mwifiex_prog_fw_w_helper, @@ -3168,49 +3178,7 @@ static struct mwifiex_if_ops pcie_ops = { .up_dev = mwifiex_pcie_up_dev, }; -/* - * This function initializes the PCIE driver module. - * - * This registers the device with PCIE bus. - */ -static int mwifiex_pcie_init_module(void) -{ - int ret; - - pr_debug("Marvell PCIe Driver\n"); - - /* Clear the flag in case user removes the card. */ - user_rmmod = 0; - - ret = pci_register_driver(&mwifiex_pcie); - if (ret) - pr_err("Driver register failed!\n"); - else - pr_debug("info: Driver registered successfully!\n"); - - return ret; -} - -/* - * This function cleans up the PCIE driver. - * - * The following major steps are followed for cleanup - - * - Resume the device if its suspended - * - Disconnect the device if connected - * - Shutdown the firmware - * - Unregister the device from PCIE bus. - */ -static void mwifiex_pcie_cleanup_module(void) -{ - /* Set the flag as user is removing this module. */ - user_rmmod = 1; - - cancel_work_sync(&pcie_work); - pci_unregister_driver(&mwifiex_pcie); -} - -module_init(mwifiex_pcie_init_module); -module_exit(mwifiex_pcie_cleanup_module); +module_pci_driver(mwifiex_pcie); MODULE_AUTHOR("Marvell International Ltd."); MODULE_DESCRIPTION("Marvell WiFi-Ex PCI-Express Driver version " PCIE_VERSION); diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.h b/drivers/net/wireless/marvell/mwifiex/pcie.h index ae3365d1c34e..00e8ee5ad4a8 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie.h +++ b/drivers/net/wireless/marvell/mwifiex/pcie.h @@ -116,6 +116,7 @@ /* FW awake cookie after FW ready */ #define FW_AWAKE_COOKIE (0xAA55AA55) #define MWIFIEX_DEF_SLEEP_COOKIE 0xBEEFBEEF +#define MWIFIEX_SLEEP_COOKIE_SIZE 4 #define MWIFIEX_MAX_DELAY_COUNT 100 struct mwifiex_pcie_card_reg { @@ -386,6 +387,8 @@ struct pcie_service_card { #endif struct mwifiex_msix_context msix_ctx[MWIFIEX_NUM_MSIX_VECTORS]; struct mwifiex_msix_context share_irq_ctx; + struct work_struct work; + unsigned long work_flags; }; static inline int diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c index 43facba641bf..a4b356d267f9 100644 --- a/drivers/net/wireless/marvell/mwifiex/sdio.c +++ b/drivers/net/wireless/marvell/mwifiex/sdio.c @@ -31,23 +31,9 @@ #define SDIO_VERSION "1.0" -/* The mwifiex_sdio_remove() callback function is called when - * user removes this module from kernel space or ejects - * the card from the slot. The driver handles these 2 cases - * differently. - * If the user is removing the module, the few commands (FUNC_SHUTDOWN, - * HS_CANCEL etc.) are sent to the firmware. - * If the card is removed, there is no need to send these command. - * - * The variable 'user_rmmod' is used to distinguish these two - * scenarios. This flag is initialized as FALSE in case the card - * is removed, and will be set to TRUE for module removal when - * module_exit function is called. - */ -static u8 user_rmmod; +static void mwifiex_sdio_work(struct work_struct *work); static struct mwifiex_if_ops sdio_ops; -static unsigned long iface_work_flags; static struct memory_type_mapping generic_mem_type_map[] = { {"DUMP", NULL, 0, 0xDD}, @@ -116,7 +102,6 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) init_completion(&card->fw_done); card->func = func; - card->device_id = id; func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; @@ -136,6 +121,7 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) card->fw_dump_enh = data->fw_dump_enh; card->can_auto_tdls = data->can_auto_tdls; card->can_ext_scan = data->can_ext_scan; + INIT_WORK(&card->work, mwifiex_sdio_work); } sdio_claim_host(func); @@ -212,6 +198,171 @@ static int mwifiex_sdio_resume(struct device *dev) return 0; } +/* Write data into SDIO card register. Caller claims SDIO device. */ +static int +mwifiex_write_reg_locked(struct sdio_func *func, u32 reg, u8 data) +{ + int ret = -1; + + sdio_writeb(func, data, reg, &ret); + return ret; +} + +/* This function writes data into SDIO card register. + */ +static int +mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u8 data) +{ + struct sdio_mmc_card *card = adapter->card; + int ret; + + sdio_claim_host(card->func); + ret = mwifiex_write_reg_locked(card->func, reg, data); + sdio_release_host(card->func); + + return ret; +} + +/* This function reads data from SDIO card register. + */ +static int +mwifiex_read_reg(struct mwifiex_adapter *adapter, u32 reg, u8 *data) +{ + struct sdio_mmc_card *card = adapter->card; + int ret = -1; + u8 val; + + sdio_claim_host(card->func); + val = sdio_readb(card->func, reg, &ret); + sdio_release_host(card->func); + + *data = val; + + return ret; +} + +/* This function writes multiple data into SDIO card memory. + * + * This does not work in suspended mode. + */ +static int +mwifiex_write_data_sync(struct mwifiex_adapter *adapter, + u8 *buffer, u32 pkt_len, u32 port) +{ + struct sdio_mmc_card *card = adapter->card; + int ret; + u8 blk_mode = + (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE; + u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1; + u32 blk_cnt = + (blk_mode == + BLOCK_MODE) ? (pkt_len / + MWIFIEX_SDIO_BLOCK_SIZE) : pkt_len; + u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK); + + if (adapter->is_suspended) { + mwifiex_dbg(adapter, ERROR, + "%s: not allowed while suspended\n", __func__); + return -1; + } + + sdio_claim_host(card->func); + + ret = sdio_writesb(card->func, ioport, buffer, blk_cnt * blk_size); + + sdio_release_host(card->func); + + return ret; +} + +/* This function reads multiple data from SDIO card memory. + */ +static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *buffer, + u32 len, u32 port, u8 claim) +{ + struct sdio_mmc_card *card = adapter->card; + int ret; + u8 blk_mode = (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE + : BLOCK_MODE; + u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1; + u32 blk_cnt = (blk_mode == BLOCK_MODE) ? (len / MWIFIEX_SDIO_BLOCK_SIZE) + : len; + u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK); + + if (claim) + sdio_claim_host(card->func); + + ret = sdio_readsb(card->func, buffer, ioport, blk_cnt * blk_size); + + if (claim) + sdio_release_host(card->func); + + return ret; +} + +/* This function reads the firmware status. + */ +static int +mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat) +{ + struct sdio_mmc_card *card = adapter->card; + const struct mwifiex_sdio_card_reg *reg = card->reg; + u8 fws0, fws1; + + if (mwifiex_read_reg(adapter, reg->status_reg_0, &fws0)) + return -1; + + if (mwifiex_read_reg(adapter, reg->status_reg_1, &fws1)) + return -1; + + *dat = (u16)((fws1 << 8) | fws0); + return 0; +} + +/* This function checks the firmware status in card. + */ +static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter, + u32 poll_num) +{ + int ret = 0; + u16 firmware_stat; + u32 tries; + + for (tries = 0; tries < poll_num; tries++) { + ret = mwifiex_sdio_read_fw_status(adapter, &firmware_stat); + if (ret) + continue; + if (firmware_stat == FIRMWARE_READY_SDIO) { + ret = 0; + break; + } + + msleep(100); + ret = -1; + } + + return ret; +} + +/* This function checks if WLAN is the winner. + */ +static int mwifiex_check_winner_status(struct mwifiex_adapter *adapter) +{ + int ret = 0; + u8 winner = 0; + struct sdio_mmc_card *card = adapter->card; + + if (mwifiex_read_reg(adapter, card->reg->status_reg_0, &winner)) + return -1; + + if (winner) + adapter->winner = 0; + else + adapter->winner = 1; + + return ret; +} + /* * SDIO remove. * @@ -223,6 +374,8 @@ mwifiex_sdio_remove(struct sdio_func *func) struct sdio_mmc_card *card; struct mwifiex_adapter *adapter; struct mwifiex_private *priv; + int ret = 0; + u16 firmware_stat; card = sdio_get_drvdata(func); if (!card) @@ -234,9 +387,12 @@ mwifiex_sdio_remove(struct sdio_func *func) if (!adapter || !adapter->priv_num) return; + cancel_work_sync(&card->work); + mwifiex_dbg(adapter, INFO, "info: SDIO func num=%d\n", func->num); - if (user_rmmod && !adapter->mfg_mode) { + ret = mwifiex_sdio_read_fw_status(adapter, &firmware_stat); + if (firmware_stat == FIRMWARE_READY_SDIO && !adapter->mfg_mode) { mwifiex_deauthenticate_all(adapter); priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); @@ -364,111 +520,6 @@ static struct sdio_driver mwifiex_sdio = { } }; -/* Write data into SDIO card register. Caller claims SDIO device. */ -static int -mwifiex_write_reg_locked(struct sdio_func *func, u32 reg, u8 data) -{ - int ret = -1; - sdio_writeb(func, data, reg, &ret); - return ret; -} - -/* - * This function writes data into SDIO card register. - */ -static int -mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u8 data) -{ - struct sdio_mmc_card *card = adapter->card; - int ret; - - sdio_claim_host(card->func); - ret = mwifiex_write_reg_locked(card->func, reg, data); - sdio_release_host(card->func); - - return ret; -} - -/* - * This function reads data from SDIO card register. - */ -static int -mwifiex_read_reg(struct mwifiex_adapter *adapter, u32 reg, u8 *data) -{ - struct sdio_mmc_card *card = adapter->card; - int ret = -1; - u8 val; - - sdio_claim_host(card->func); - val = sdio_readb(card->func, reg, &ret); - sdio_release_host(card->func); - - *data = val; - - return ret; -} - -/* - * This function writes multiple data into SDIO card memory. - * - * This does not work in suspended mode. - */ -static int -mwifiex_write_data_sync(struct mwifiex_adapter *adapter, - u8 *buffer, u32 pkt_len, u32 port) -{ - struct sdio_mmc_card *card = adapter->card; - int ret; - u8 blk_mode = - (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE; - u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1; - u32 blk_cnt = - (blk_mode == - BLOCK_MODE) ? (pkt_len / - MWIFIEX_SDIO_BLOCK_SIZE) : pkt_len; - u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK); - - if (adapter->is_suspended) { - mwifiex_dbg(adapter, ERROR, - "%s: not allowed while suspended\n", __func__); - return -1; - } - - sdio_claim_host(card->func); - - ret = sdio_writesb(card->func, ioport, buffer, blk_cnt * blk_size); - - sdio_release_host(card->func); - - return ret; -} - -/* - * This function reads multiple data from SDIO card memory. - */ -static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *buffer, - u32 len, u32 port, u8 claim) -{ - struct sdio_mmc_card *card = adapter->card; - int ret; - u8 blk_mode = (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE - : BLOCK_MODE; - u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1; - u32 blk_cnt = (blk_mode == BLOCK_MODE) ? (len / MWIFIEX_SDIO_BLOCK_SIZE) - : len; - u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK); - - if (claim) - sdio_claim_host(card->func); - - ret = sdio_readsb(card->func, buffer, ioport, blk_cnt * blk_size); - - if (claim) - sdio_release_host(card->func); - - return ret; -} - /* * This function wakes up the card. * @@ -755,27 +806,6 @@ mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits) } /* - * This function reads the firmware status. - */ -static int -mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat) -{ - struct sdio_mmc_card *card = adapter->card; - const struct mwifiex_sdio_card_reg *reg = card->reg; - u8 fws0, fws1; - - if (mwifiex_read_reg(adapter, reg->status_reg_0, &fws0)) - return -1; - - if (mwifiex_read_reg(adapter, reg->status_reg_1, &fws1)) - return -1; - - *dat = (u16) ((fws1 << 8) | fws0); - - return 0; -} - -/* * This function disables the host interrupt. * * The host interrupt mask is read, the disable bit is reset and @@ -1080,51 +1110,6 @@ done: } /* - * This function checks the firmware status in card. - */ -static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter, - u32 poll_num) -{ - int ret = 0; - u16 firmware_stat; - u32 tries; - - for (tries = 0; tries < poll_num; tries++) { - ret = mwifiex_sdio_read_fw_status(adapter, &firmware_stat); - if (ret) - continue; - if (firmware_stat == FIRMWARE_READY_SDIO) { - ret = 0; - break; - } else { - msleep(100); - ret = -1; - } - } - - return ret; -} - -/* This function checks if WLAN is the winner. - */ -static int mwifiex_check_winner_status(struct mwifiex_adapter *adapter) -{ - int ret = 0; - u8 winner = 0; - struct sdio_mmc_card *card = adapter->card; - - if (mwifiex_read_reg(adapter, card->reg->status_reg_0, &winner)) - return -1; - - if (winner) - adapter->winner = 0; - else - adapter->winner = 1; - - return ret; -} - -/* * This function decode sdio aggreation pkt. * * Based on the the data block size and pkt_len, @@ -2204,33 +2189,12 @@ mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port) port, card->mp_data_port_mask); } -static void mwifiex_recreate_adapter(struct sdio_mmc_card *card) +static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter) { + struct sdio_mmc_card *card = adapter->card; struct sdio_func *func = card->func; - const struct sdio_device_id *device_id = card->device_id; - - /* TODO mmc_hw_reset does not require destroying and re-probing the - * whole adapter. Hence there was no need to for this rube-goldberg - * design to reload the fw from an external workqueue. If we don't - * destroy the adapter we could reload the fw from - * mwifiex_main_work_queue directly. - * The real difficulty with fw reset is to restore all the user - * settings applied through ioctl. By destroying and recreating the - * adapter, we take the easy way out, since we rely on user space to - * restore them. We assume that user space will treat the new - * incarnation of the adapter(interfaces) as if they had been just - * discovered and initializes them from scratch. - */ - mwifiex_sdio_remove(func); - - /* - * Normally, we would let the driver core take care of releasing these. - * But we're not letting the driver core handle this one. See above - * TODO. - */ - sdio_set_drvdata(func, NULL); - devm_kfree(&func->dev, card); + mwifiex_shutdown_sw(adapter); /* power cycle the adapter */ sdio_claim_host(func); @@ -2240,24 +2204,10 @@ static void mwifiex_recreate_adapter(struct sdio_mmc_card *card) /* Previous save_adapter won't be valid after this. We will cancel * pending work requests. */ - clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &iface_work_flags); - clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &iface_work_flags); - - mwifiex_sdio_probe(func, device_id); -} - -static struct mwifiex_adapter *save_adapter; -static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter) -{ - struct sdio_mmc_card *card = adapter->card; + clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags); + clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags); - /* TODO card pointer is unprotected. If the adapter is removed - * physically, sdio core might trigger mwifiex_sdio_remove, before this - * workqueue is run, which will destroy the adapter struct. When this - * workqueue eventually exceutes it will dereference an invalid adapter - * pointer - */ - mwifiex_recreate_adapter(card); + mwifiex_reinit_sw(adapter); } /* This function read/write firmware */ @@ -2548,47 +2498,53 @@ done: static void mwifiex_sdio_device_dump_work(struct mwifiex_adapter *adapter) { struct sdio_mmc_card *card = adapter->card; + int drv_info_size; + void *drv_info; - mwifiex_drv_info_dump(adapter); + drv_info_size = mwifiex_drv_info_dump(adapter, &drv_info); if (card->fw_dump_enh) mwifiex_sdio_generic_fw_dump(adapter); else mwifiex_sdio_fw_dump(adapter); - mwifiex_upload_device_dump(adapter); + mwifiex_upload_device_dump(adapter, drv_info, drv_info_size); } static void mwifiex_sdio_work(struct work_struct *work) { + struct sdio_mmc_card *card = + container_of(work, struct sdio_mmc_card, work); + if (test_and_clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, - &iface_work_flags)) - mwifiex_sdio_device_dump_work(save_adapter); + &card->work_flags)) + mwifiex_sdio_device_dump_work(card->adapter); if (test_and_clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, - &iface_work_flags)) - mwifiex_sdio_card_reset_work(save_adapter); + &card->work_flags)) + mwifiex_sdio_card_reset_work(card->adapter); } -static DECLARE_WORK(sdio_work, mwifiex_sdio_work); /* This function resets the card */ static void mwifiex_sdio_card_reset(struct mwifiex_adapter *adapter) { - save_adapter = adapter; - if (test_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &iface_work_flags)) + struct sdio_mmc_card *card = adapter->card; + + if (test_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags)) return; - set_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &iface_work_flags); + set_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags); - schedule_work(&sdio_work); + schedule_work(&card->work); } /* This function dumps FW information */ static void mwifiex_sdio_device_dump(struct mwifiex_adapter *adapter) { - save_adapter = adapter; - if (test_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &iface_work_flags)) + struct sdio_mmc_card *card = adapter->card; + + if (test_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags)) return; - set_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &iface_work_flags); - schedule_work(&sdio_work); + set_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags); + schedule_work(&card->work); } /* Function to dump SDIO function registers and SDIO scratch registers in case @@ -2684,6 +2640,33 @@ mwifiex_sdio_reg_dump(struct mwifiex_adapter *adapter, char *drv_buf) return p - drv_buf; } +/* sdio device/function initialization, code is extracted + * from init_if handler and register_dev handler. + */ +static void mwifiex_sdio_up_dev(struct mwifiex_adapter *adapter) +{ + struct sdio_mmc_card *card = adapter->card; + u8 sdio_ireg; + + sdio_claim_host(card->func); + sdio_enable_func(card->func); + sdio_set_block_size(card->func, MWIFIEX_SDIO_BLOCK_SIZE); + sdio_release_host(card->func); + + /* tx_buf_size might be changed to 3584 by firmware during + * data transfer, we will reset to default size. + */ + adapter->tx_buf_size = card->tx_buf_size; + + /* Read the host_int_status_reg for ACK the first interrupt got + * from the bootloader. If we don't do this we get a interrupt + * as soon as we register the irq. + */ + mwifiex_read_reg(adapter, card->reg->host_int_status_reg, &sdio_ireg); + + mwifiex_init_sdio_ioport(adapter); +} + static struct mwifiex_if_ops sdio_ops = { .init_if = mwifiex_init_sdio, .cleanup_if = mwifiex_cleanup_sdio, @@ -2709,43 +2692,10 @@ static struct mwifiex_if_ops sdio_ops = { .reg_dump = mwifiex_sdio_reg_dump, .device_dump = mwifiex_sdio_device_dump, .deaggr_pkt = mwifiex_deaggr_sdio_pkt, + .up_dev = mwifiex_sdio_up_dev, }; -/* - * This function initializes the SDIO driver. - * - * This registers the device with SDIO bus. - */ -static int -mwifiex_sdio_init_module(void) -{ - /* Clear the flag in case user removes the card. */ - user_rmmod = 0; - - return sdio_register_driver(&mwifiex_sdio); -} - -/* - * This function cleans up the SDIO driver. - * - * The following major steps are followed for cleanup - - * - Resume the device if its suspended - * - Disconnect the device if connected - * - Shutdown the firmware - * - Unregister the device from SDIO bus. - */ -static void -mwifiex_sdio_cleanup_module(void) -{ - /* Set the flag as user is removing this module. */ - user_rmmod = 1; - cancel_work_sync(&sdio_work); - - sdio_unregister_driver(&mwifiex_sdio); -} - -module_init(mwifiex_sdio_init_module); -module_exit(mwifiex_sdio_cleanup_module); +module_driver(mwifiex_sdio, sdio_register_driver, sdio_unregister_driver); MODULE_AUTHOR("Marvell International Ltd."); MODULE_DESCRIPTION("Marvell WiFi-Ex SDIO Driver version " SDIO_VERSION); diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.h b/drivers/net/wireless/marvell/mwifiex/sdio.h index cdbf3a3ac7f9..dccf7fd1aef3 100644 --- a/drivers/net/wireless/marvell/mwifiex/sdio.h +++ b/drivers/net/wireless/marvell/mwifiex/sdio.h @@ -268,8 +268,8 @@ struct sdio_mmc_card { struct mwifiex_sdio_mpa_tx mpa_tx; struct mwifiex_sdio_mpa_rx mpa_rx; - /* needed for card reset */ - const struct sdio_device_id *device_id; + struct work_struct work; + unsigned long work_flags; }; struct mwifiex_sdio_device { diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c index 9df0c4dc06ed..96503d3d053f 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_event.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c @@ -1009,6 +1009,10 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) adapter->event_skb->len - sizeof(eventcause)); break; + /* Debugging event; not used, but let's not print an ERROR for it. */ + case EVENT_UNKNOWN_DEBUG: + mwifiex_dbg(adapter, EVENT, "event: debug\n"); + break; default: mwifiex_dbg(adapter, ERROR, "event: unknown event id: %#x\n", eventcause); diff --git a/drivers/net/wireless/marvell/mwifiex/usb.c b/drivers/net/wireless/marvell/mwifiex/usb.c index c563160b3b6b..9cf3334adf4d 100644 --- a/drivers/net/wireless/marvell/mwifiex/usb.c +++ b/drivers/net/wireless/marvell/mwifiex/usb.c @@ -22,7 +22,6 @@ #define USB_VERSION "1.0" -static u8 user_rmmod; static struct mwifiex_if_ops usb_ops; static struct usb_device_id mwifiex_usb_table[] = { @@ -618,7 +617,7 @@ static void mwifiex_usb_disconnect(struct usb_interface *intf) if (!adapter || !adapter->priv_num) return; - if (user_rmmod && !adapter->mfg_mode) { + if (card->udev->state != USB_STATE_NOTATTACHED && !adapter->mfg_mode) { mwifiex_deauthenticate_all(adapter); mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter, @@ -1201,43 +1200,7 @@ static struct mwifiex_if_ops usb_ops = { .is_port_ready = mwifiex_usb_is_port_ready, }; -/* This function initializes the USB driver module. - * - * This registers the device with USB bus. - */ -static int mwifiex_usb_init_module(void) -{ - int ret; - - pr_debug("Marvell USB8797 Driver\n"); - - ret = usb_register(&mwifiex_usb_driver); - if (ret) - pr_err("Driver register failed!\n"); - else - pr_debug("info: Driver registered successfully!\n"); - - return ret; -} - -/* This function cleans up the USB driver. - * - * The following major steps are followed in .disconnect for cleanup: - * - Resume the device if its suspended - * - Disconnect the device if connected - * - Shutdown the firmware - * - Unregister the device from USB bus. - */ -static void mwifiex_usb_cleanup_module(void) -{ - /* set the flag as user is removing this module */ - user_rmmod = 1; - - usb_deregister(&mwifiex_usb_driver); -} - -module_init(mwifiex_usb_init_module); -module_exit(mwifiex_usb_cleanup_module); +module_usb_driver(mwifiex_usb_driver); MODULE_AUTHOR("Marvell International Ltd."); MODULE_DESCRIPTION("Marvell WiFi-Ex USB Driver version" USB_VERSION); diff --git a/drivers/net/wireless/marvell/mwifiex/util.c b/drivers/net/wireless/marvell/mwifiex/util.c index 18fbb96a46e9..b1ab8da121dd 100644 --- a/drivers/net/wireless/marvell/mwifiex/util.c +++ b/drivers/net/wireless/marvell/mwifiex/util.c @@ -146,21 +146,6 @@ int mwifiex_init_fw_complete(struct mwifiex_adapter *adapter) } /* - * Firmware shutdown complete callback handler. - * - * This function sets the hardware status to not ready and wakes up - * the function waiting on the init wait queue for the firmware - * shutdown to complete. - */ -int mwifiex_shutdown_fw_complete(struct mwifiex_adapter *adapter) -{ - adapter->hw_status = MWIFIEX_HW_STATUS_NOT_READY; - adapter->init_wait_q_woken = true; - wake_up_interruptible(&adapter->init_wait_q); - return 0; -} - -/* * This function sends init/shutdown command * to firmware. */ diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800.h b/drivers/net/wireless/ralink/rt2x00/rt2800.h index ec622a08a486..256496bfbafb 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h @@ -72,6 +72,7 @@ #define RF5592 0x000f #define RF3070 0x3070 #define RF3290 0x3290 +#define RF5350 0x5350 #define RF5360 0x5360 #define RF5362 0x5362 #define RF5370 0x5370 @@ -2286,6 +2287,8 @@ struct mac_iveiv_entry { #define RFCSR30_RX_H20M FIELD8(0x04) #define RFCSR30_RX_VCM FIELD8(0x18) #define RFCSR30_RF_CALIBRATION FIELD8(0x80) +#define RF3322_RFCSR30_TX_H20M FIELD8(0x01) +#define RF3322_RFCSR30_RX_H20M FIELD8(0x02) /* * RFCSR 31: @@ -2301,6 +2304,12 @@ struct mac_iveiv_entry { #define RFCSR36_RF_BS FIELD8(0x80) /* + * RFCSR 34: + */ +#define RFCSR34_TX0_EXT_PA FIELD8(0x04) +#define RFCSR34_TX1_EXT_PA FIELD8(0x08) + +/* * RFCSR 38: */ #define RFCSR38_RX_LO1_EN FIELD8(0x20) @@ -2312,6 +2321,18 @@ struct mac_iveiv_entry { #define RFCSR39_RX_LO2_EN FIELD8(0x80) /* + * RFCSR 41: + */ +#define RFCSR41_BIT1 FIELD8(0x01) +#define RFCSR41_BIT4 FIELD8(0x08) + +/* + * RFCSR 42: + */ +#define RFCSR42_BIT1 FIELD8(0x01) +#define RFCSR42_BIT4 FIELD8(0x08) + +/* * RFCSR 49: */ #define RFCSR49_TX FIELD8(0x3f) @@ -2324,6 +2345,8 @@ struct mac_iveiv_entry { * RFCSR 50: */ #define RFCSR50_TX FIELD8(0x3f) +#define RFCSR50_TX0_EXT_PA FIELD8(0x02) +#define RFCSR50_TX1_EXT_PA FIELD8(0x10) #define RFCSR50_EP FIELD8(0xc0) /* bits for RT3593 */ #define RFCSR50_TX_LO1_EN FIELD8(0x20) @@ -2471,6 +2494,8 @@ enum rt2800_eeprom_word { * INTERNAL_TX_ALC: 0: disable, 1: enable * BT_COEXIST: 0: disable, 1: enable * DAC_TEST: 0: disable, 1: enable + * EXTERNAL_TX0_PA: 0: disable, 1: enable (only on RT3352) + * EXTERNAL_TX1_PA: 0: disable, 1: enable (only on RT3352) */ #define EEPROM_NIC_CONF1_HW_RADIO FIELD16(0x0001) #define EEPROM_NIC_CONF1_EXTERNAL_TX_ALC FIELD16(0x0002) @@ -2487,6 +2512,8 @@ enum rt2800_eeprom_word { #define EEPROM_NIC_CONF1_INTERNAL_TX_ALC FIELD16(0x2000) #define EEPROM_NIC_CONF1_BT_COEXIST FIELD16(0x4000) #define EEPROM_NIC_CONF1_DAC_TEST FIELD16(0x8000) +#define EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352 FIELD16(0x4000) +#define EEPROM_NIC_CONF1_EXTERNAL_TX1_PA_3352 FIELD16(0x8000) /* * EEPROM frequency diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c index 5436cdb07937..572cdea4ca25 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c @@ -373,9 +373,6 @@ static int rt2800_enable_wlan_rt3290(struct rt2x00_dev *rt2x00dev) int i, count; rt2800_register_read(rt2x00dev, WLAN_FUN_CTRL, ®); - if (rt2x00_get_field32(reg, WLAN_EN)) - return 0; - rt2x00_set_field32(®, WLAN_GPIO_OUT_OE_BIT_ALL, 0xff); rt2x00_set_field32(®, FRC_WL_ANT_SET, 1); rt2x00_set_field32(®, WLAN_CLK_EN, 0); @@ -967,8 +964,6 @@ static void rt2800_update_beacons_setup(struct rt2x00_dev *rt2x00dev) bcn_num++; } - WARN_ON_ONCE(bcn_num != rt2x00dev->intf_beaconing); - rt2800_register_write(rt2x00dev, BCN_OFFSET0, (u32) reg); rt2800_register_write(rt2x00dev, BCN_OFFSET1, (u32) (reg >> 32)); @@ -1937,6 +1932,11 @@ static void rt2800_config_lna_gain(struct rt2x00_dev *rt2x00dev, rt2x00dev->lna_gain = lna_gain; } +static inline bool rt2800_clk_is_20mhz(struct rt2x00_dev *rt2x00dev) +{ + return clk_get_rate(rt2x00dev->clk) == 20000000; +} + #define FREQ_OFFSET_BOUND 0x5f static void rt2800_freq_cal_mode1(struct rt2x00_dev *rt2x00dev) @@ -2760,6 +2760,13 @@ static void rt2800_config_channel_rf53xx(struct rt2x00_dev *rt2x00dev, rt2800_rfcsr_write(rt2x00dev, 59, r59_non_bt[idx]); + } else if (rt2x00_rt(rt2x00dev, RT5350)) { + static const char r59_non_bt[] = {0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, + 0x0a, 0x09, 0x08, 0x07, 0x07, 0x06}; + + rt2800_rfcsr_write(rt2x00dev, 59, + r59_non_bt[idx]); } } } @@ -3197,6 +3204,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info); break; case RF3070: + case RF5350: case RF5360: case RF5362: case RF5370: @@ -3215,6 +3223,7 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, if (rt2x00_rf(rt2x00dev, RF3070) || rt2x00_rf(rt2x00dev, RF3290) || rt2x00_rf(rt2x00dev, RF3322) || + rt2x00_rf(rt2x00dev, RF5350) || rt2x00_rf(rt2x00dev, RF5360) || rt2x00_rf(rt2x00dev, RF5362) || rt2x00_rf(rt2x00dev, RF5370) || @@ -3222,8 +3231,17 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, rt2x00_rf(rt2x00dev, RF5390) || rt2x00_rf(rt2x00dev, RF5392)) { rt2800_rfcsr_read(rt2x00dev, 30, &rfcsr); - rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, 0); - rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, 0); + if (rt2x00_rf(rt2x00dev, RF3322)) { + rt2x00_set_field8(&rfcsr, RF3322_RFCSR30_TX_H20M, + conf_is_ht40(conf)); + rt2x00_set_field8(&rfcsr, RF3322_RFCSR30_RX_H20M, + conf_is_ht40(conf)); + } else { + rt2x00_set_field8(&rfcsr, RFCSR30_TX_H20M, + conf_is_ht40(conf)); + rt2x00_set_field8(&rfcsr, RFCSR30_RX_H20M, + conf_is_ht40(conf)); + } rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); rt2800_rfcsr_read(rt2x00dev, 3, &rfcsr); @@ -3234,11 +3252,18 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, /* * Change BBP settings */ + if (rt2x00_rt(rt2x00dev, RT3352)) { + rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); + rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); + rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); + rt2800_bbp_write(rt2x00dev, 27, 0x0); rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain); rt2800_bbp_write(rt2x00dev, 27, 0x20); rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain); + rt2800_bbp_write(rt2x00dev, 86, 0x38); + rt2800_bbp_write(rt2x00dev, 83, 0x6a); } else if (rt2x00_rt(rt2x00dev, RT3593)) { if (rf->channel > 14) { /* Disable CCK Packet detection on 5GHz */ @@ -3456,7 +3481,8 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, /* * Clear update flag */ - if (rt2x00_rt(rt2x00dev, RT3352)) { + if (rt2x00_rt(rt2x00dev, RT3352) || + rt2x00_rt(rt2x00dev, RT5350)) { rt2800_bbp_read(rt2x00dev, 49, &bbp); rt2x00_set_field8(&bbp, BBP49_UPDATE_FLAG, 0); rt2800_bbp_write(rt2x00dev, 49, bbp); @@ -4337,6 +4363,7 @@ void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev) case RF3053: case RF3070: case RF3290: + case RF5350: case RF5360: case RF5362: case RF5370: @@ -4719,6 +4746,8 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); + } else if (rt2x00_rt(rt2x00dev, RT5350)) { + rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404); } else { rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000); rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606); @@ -4743,15 +4772,16 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_read(rt2x00dev, MAX_LEN_CFG, ®); rt2x00_set_field32(®, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE); - if (rt2x00_rt_rev_gte(rt2x00dev, RT2872, REV_RT2872E) || - rt2x00_rt(rt2x00dev, RT2883) || - rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070E)) { + if (rt2x00_is_usb(rt2x00dev)) { + drv_data->max_psdu = 3; + } else if (rt2x00_rt_rev_gte(rt2x00dev, RT2872, REV_RT2872E) || + rt2x00_rt(rt2x00dev, RT2883) || + rt2x00_rt_rev_lt(rt2x00dev, RT3070, REV_RT3070E)) { drv_data->max_psdu = 2; - rt2x00_set_field32(®, MAX_LEN_CFG_MAX_PSDU, 2); } else { drv_data->max_psdu = 1; - rt2x00_set_field32(®, MAX_LEN_CFG_MAX_PSDU, 1); } + rt2x00_set_field32(®, MAX_LEN_CFG_MAX_PSDU, drv_data->max_psdu); rt2x00_set_field32(®, MAX_LEN_CFG_MIN_PSDU, 10); rt2x00_set_field32(®, MAX_LEN_CFG_MIN_MPDU, 10); rt2800_register_write(rt2x00dev, MAX_LEN_CFG, reg); @@ -4769,8 +4799,8 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_write(rt2x00dev, PBF_MAX_PCNT, 0x1f3fbf9f); rt2800_register_read(rt2x00dev, TX_RTY_CFG, ®); - rt2x00_set_field32(®, TX_RTY_CFG_SHORT_RTY_LIMIT, 15); - rt2x00_set_field32(®, TX_RTY_CFG_LONG_RTY_LIMIT, 31); + rt2x00_set_field32(®, TX_RTY_CFG_SHORT_RTY_LIMIT, 2); + rt2x00_set_field32(®, TX_RTY_CFG_LONG_RTY_LIMIT, 2); rt2x00_set_field32(®, TX_RTY_CFG_LONG_RTY_THRE, 2000); rt2x00_set_field32(®, TX_RTY_CFG_NON_AGG_RTY_MODE, 0); rt2x00_set_field32(®, TX_RTY_CFG_AGG_RTY_MODE, 0); @@ -4902,10 +4932,10 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev) rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, reg); rt2800_register_read(rt2x00dev, TX_RTS_CFG, ®); - rt2x00_set_field32(®, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 32); + rt2x00_set_field32(®, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 7); rt2x00_set_field32(®, TX_RTS_CFG_RTS_THRES, IEEE80211_MAX_RTS_THRESHOLD); - rt2x00_set_field32(®, TX_RTS_CFG_RTS_FBK_EN, 0); + rt2x00_set_field32(®, TX_RTS_CFG_RTS_FBK_EN, 1); rt2800_register_write(rt2x00dev, TX_RTS_CFG, reg); rt2800_register_write(rt2x00dev, EXP_ACK_TIME, 0x002400ca); @@ -5363,9 +5393,13 @@ static void rt2800_init_bbp_3352(struct rt2x00_dev *rt2x00dev) rt2800_bbp_write(rt2x00dev, 82, 0x62); - rt2800_bbp_write(rt2x00dev, 83, 0x6a); - - rt2800_bbp_write(rt2x00dev, 84, 0x99); + if (rt2x00_rt(rt2x00dev, RT5350)) { + rt2800_bbp_write(rt2x00dev, 83, 0x7a); + rt2800_bbp_write(rt2x00dev, 84, 0x9a); + } else { + rt2800_bbp_write(rt2x00dev, 83, 0x6a); + rt2800_bbp_write(rt2x00dev, 84, 0x99); + } rt2800_bbp_write(rt2x00dev, 86, 0x38); @@ -5379,9 +5413,13 @@ static void rt2800_init_bbp_3352(struct rt2x00_dev *rt2x00dev) rt2800_bbp_write(rt2x00dev, 104, 0x92); - rt2800_bbp_write(rt2x00dev, 105, 0x34); - - rt2800_bbp_write(rt2x00dev, 106, 0x05); + if (rt2x00_rt(rt2x00dev, RT5350)) { + rt2800_bbp_write(rt2x00dev, 105, 0x3c); + rt2800_bbp_write(rt2x00dev, 106, 0x03); + } else { + rt2800_bbp_write(rt2x00dev, 105, 0x34); + rt2800_bbp_write(rt2x00dev, 106, 0x05); + } rt2800_bbp_write(rt2x00dev, 120, 0x50); @@ -5406,6 +5444,16 @@ static void rt2800_init_bbp_3352(struct rt2x00_dev *rt2x00dev) rt2800_bbp_write(rt2x00dev, 143, 0xa2); rt2800_bbp_write(rt2x00dev, 148, 0xc8); + + if (rt2x00_rt(rt2x00dev, RT5350)) { + /* Antenna Software OFDM */ + rt2800_bbp_write(rt2x00dev, 150, 0x40); + /* Antenna Software CCK */ + rt2800_bbp_write(rt2x00dev, 151, 0x30); + rt2800_bbp_write(rt2x00dev, 152, 0xa3); + /* Clear previously selected antenna */ + rt2800_bbp_write(rt2x00dev, 154, 0); + } } static void rt2800_init_bbp_3390(struct rt2x00_dev *rt2x00dev) @@ -5706,6 +5754,7 @@ static void rt2800_init_bbp(struct rt2x00_dev *rt2x00dev) rt2800_init_bbp_3290(rt2x00dev); break; case RT3352: + case RT5350: rt2800_init_bbp_3352(rt2x00dev); break; case RT3390: @@ -6179,6 +6228,12 @@ static void rt2800_init_rfcsr_3290(struct rt2x00_dev *rt2x00dev) static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev) { + int tx0_int_pa = test_bit(CAPABILITY_INTERNAL_PA_TX0, + &rt2x00dev->cap_flags); + int tx1_int_pa = test_bit(CAPABILITY_INTERNAL_PA_TX1, + &rt2x00dev->cap_flags); + u8 rfcsr; + rt2800_rf_init_calibration(rt2x00dev, 30); rt2800_rfcsr_write(rt2x00dev, 0, 0xf0); @@ -6214,15 +6269,30 @@ static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 31, 0x80); rt2800_rfcsr_write(rt2x00dev, 32, 0x80); rt2800_rfcsr_write(rt2x00dev, 33, 0x00); - rt2800_rfcsr_write(rt2x00dev, 34, 0x01); + rfcsr = 0x01; + if (!tx0_int_pa) + rt2x00_set_field8(&rfcsr, RFCSR34_TX0_EXT_PA, 1); + if (!tx1_int_pa) + rt2x00_set_field8(&rfcsr, RFCSR34_TX1_EXT_PA, 1); + rt2800_rfcsr_write(rt2x00dev, 34, rfcsr); rt2800_rfcsr_write(rt2x00dev, 35, 0x03); rt2800_rfcsr_write(rt2x00dev, 36, 0xbd); rt2800_rfcsr_write(rt2x00dev, 37, 0x3c); rt2800_rfcsr_write(rt2x00dev, 38, 0x5f); rt2800_rfcsr_write(rt2x00dev, 39, 0xc5); rt2800_rfcsr_write(rt2x00dev, 40, 0x33); - rt2800_rfcsr_write(rt2x00dev, 41, 0x5b); - rt2800_rfcsr_write(rt2x00dev, 42, 0x5b); + rfcsr = 0x52; + if (tx0_int_pa) { + rt2x00_set_field8(&rfcsr, RFCSR41_BIT1, 1); + rt2x00_set_field8(&rfcsr, RFCSR41_BIT4, 1); + } + rt2800_rfcsr_write(rt2x00dev, 41, rfcsr); + rfcsr = 0x52; + if (tx1_int_pa) { + rt2x00_set_field8(&rfcsr, RFCSR42_BIT1, 1); + rt2x00_set_field8(&rfcsr, RFCSR42_BIT4, 1); + } + rt2800_rfcsr_write(rt2x00dev, 42, rfcsr); rt2800_rfcsr_write(rt2x00dev, 43, 0xdb); rt2800_rfcsr_write(rt2x00dev, 44, 0xdb); rt2800_rfcsr_write(rt2x00dev, 45, 0xdb); @@ -6230,15 +6300,20 @@ static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev) rt2800_rfcsr_write(rt2x00dev, 47, 0x0d); rt2800_rfcsr_write(rt2x00dev, 48, 0x14); rt2800_rfcsr_write(rt2x00dev, 49, 0x00); - rt2800_rfcsr_write(rt2x00dev, 50, 0x2d); - rt2800_rfcsr_write(rt2x00dev, 51, 0x7f); - rt2800_rfcsr_write(rt2x00dev, 52, 0x00); - rt2800_rfcsr_write(rt2x00dev, 53, 0x52); - rt2800_rfcsr_write(rt2x00dev, 54, 0x1b); - rt2800_rfcsr_write(rt2x00dev, 55, 0x7f); - rt2800_rfcsr_write(rt2x00dev, 56, 0x00); - rt2800_rfcsr_write(rt2x00dev, 57, 0x52); - rt2800_rfcsr_write(rt2x00dev, 58, 0x1b); + rfcsr = 0x2d; + if (!tx0_int_pa) + rt2x00_set_field8(&rfcsr, RFCSR50_TX0_EXT_PA, 1); + if (!tx1_int_pa) + rt2x00_set_field8(&rfcsr, RFCSR50_TX1_EXT_PA, 1); + rt2800_rfcsr_write(rt2x00dev, 50, rfcsr); + rt2800_rfcsr_write(rt2x00dev, 51, (tx0_int_pa ? 0x7f : 0x52)); + rt2800_rfcsr_write(rt2x00dev, 52, (tx0_int_pa ? 0x00 : 0xc0)); + rt2800_rfcsr_write(rt2x00dev, 53, (tx0_int_pa ? 0x52 : 0xd2)); + rt2800_rfcsr_write(rt2x00dev, 54, (tx0_int_pa ? 0x1b : 0xc0)); + rt2800_rfcsr_write(rt2x00dev, 55, (tx1_int_pa ? 0x7f : 0x52)); + rt2800_rfcsr_write(rt2x00dev, 56, (tx1_int_pa ? 0x00 : 0xc0)); + rt2800_rfcsr_write(rt2x00dev, 57, (tx0_int_pa ? 0x52 : 0x49)); + rt2800_rfcsr_write(rt2x00dev, 58, (tx1_int_pa ? 0x1b : 0xc0)); rt2800_rfcsr_write(rt2x00dev, 59, 0x00); rt2800_rfcsr_write(rt2x00dev, 60, 0x00); rt2800_rfcsr_write(rt2x00dev, 61, 0x00); @@ -6490,6 +6565,76 @@ static void rt2800_init_rfcsr_3593(struct rt2x00_dev *rt2x00dev) /* TODO: enable stream mode support */ } +static void rt2800_init_rfcsr_5350(struct rt2x00_dev *rt2x00dev) +{ + rt2800_rfcsr_write(rt2x00dev, 0, 0xf0); + rt2800_rfcsr_write(rt2x00dev, 1, 0x23); + rt2800_rfcsr_write(rt2x00dev, 2, 0x50); + rt2800_rfcsr_write(rt2x00dev, 3, 0x08); + rt2800_rfcsr_write(rt2x00dev, 4, 0x49); + rt2800_rfcsr_write(rt2x00dev, 5, 0x10); + rt2800_rfcsr_write(rt2x00dev, 6, 0xe0); + rt2800_rfcsr_write(rt2x00dev, 7, 0x00); + rt2800_rfcsr_write(rt2x00dev, 8, 0xf1); + rt2800_rfcsr_write(rt2x00dev, 9, 0x02); + rt2800_rfcsr_write(rt2x00dev, 10, 0x53); + rt2800_rfcsr_write(rt2x00dev, 11, 0x4a); + rt2800_rfcsr_write(rt2x00dev, 12, 0x46); + if (rt2800_clk_is_20mhz(rt2x00dev)) + rt2800_rfcsr_write(rt2x00dev, 13, 0x1f); + else + rt2800_rfcsr_write(rt2x00dev, 13, 0x9f); + rt2800_rfcsr_write(rt2x00dev, 14, 0x00); + rt2800_rfcsr_write(rt2x00dev, 15, 0x00); + rt2800_rfcsr_write(rt2x00dev, 16, 0xc0); + rt2800_rfcsr_write(rt2x00dev, 18, 0x03); + rt2800_rfcsr_write(rt2x00dev, 19, 0x00); + rt2800_rfcsr_write(rt2x00dev, 20, 0x00); + rt2800_rfcsr_write(rt2x00dev, 21, 0x00); + rt2800_rfcsr_write(rt2x00dev, 22, 0x20); + rt2800_rfcsr_write(rt2x00dev, 23, 0x00); + rt2800_rfcsr_write(rt2x00dev, 24, 0x00); + rt2800_rfcsr_write(rt2x00dev, 25, 0x80); + rt2800_rfcsr_write(rt2x00dev, 26, 0x00); + rt2800_rfcsr_write(rt2x00dev, 27, 0x03); + rt2800_rfcsr_write(rt2x00dev, 28, 0x00); + rt2800_rfcsr_write(rt2x00dev, 29, 0xd0); + rt2800_rfcsr_write(rt2x00dev, 30, 0x10); + rt2800_rfcsr_write(rt2x00dev, 31, 0x80); + rt2800_rfcsr_write(rt2x00dev, 32, 0x80); + rt2800_rfcsr_write(rt2x00dev, 33, 0x00); + rt2800_rfcsr_write(rt2x00dev, 34, 0x07); + rt2800_rfcsr_write(rt2x00dev, 35, 0x12); + rt2800_rfcsr_write(rt2x00dev, 36, 0x00); + rt2800_rfcsr_write(rt2x00dev, 37, 0x08); + rt2800_rfcsr_write(rt2x00dev, 38, 0x85); + rt2800_rfcsr_write(rt2x00dev, 39, 0x1b); + rt2800_rfcsr_write(rt2x00dev, 40, 0x0b); + rt2800_rfcsr_write(rt2x00dev, 41, 0xbb); + rt2800_rfcsr_write(rt2x00dev, 42, 0xd5); + rt2800_rfcsr_write(rt2x00dev, 43, 0x9b); + rt2800_rfcsr_write(rt2x00dev, 44, 0x0c); + rt2800_rfcsr_write(rt2x00dev, 45, 0xa6); + rt2800_rfcsr_write(rt2x00dev, 46, 0x73); + rt2800_rfcsr_write(rt2x00dev, 47, 0x00); + rt2800_rfcsr_write(rt2x00dev, 48, 0x10); + rt2800_rfcsr_write(rt2x00dev, 49, 0x80); + rt2800_rfcsr_write(rt2x00dev, 50, 0x00); + rt2800_rfcsr_write(rt2x00dev, 51, 0x00); + rt2800_rfcsr_write(rt2x00dev, 52, 0x38); + rt2800_rfcsr_write(rt2x00dev, 53, 0x00); + rt2800_rfcsr_write(rt2x00dev, 54, 0x38); + rt2800_rfcsr_write(rt2x00dev, 55, 0x43); + rt2800_rfcsr_write(rt2x00dev, 56, 0x82); + rt2800_rfcsr_write(rt2x00dev, 57, 0x00); + rt2800_rfcsr_write(rt2x00dev, 58, 0x39); + rt2800_rfcsr_write(rt2x00dev, 59, 0x0b); + rt2800_rfcsr_write(rt2x00dev, 60, 0x45); + rt2800_rfcsr_write(rt2x00dev, 61, 0xd1); + rt2800_rfcsr_write(rt2x00dev, 62, 0x00); + rt2800_rfcsr_write(rt2x00dev, 63, 0x00); +} + static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev) { rt2800_rf_init_calibration(rt2x00dev, 2); @@ -6727,6 +6872,9 @@ static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) case RT3593: rt2800_init_rfcsr_3593(rt2x00dev); break; + case RT5350: + rt2800_init_rfcsr_5350(rt2x00dev); + break; case RT5390: rt2800_init_rfcsr_5390(rt2x00dev); break; @@ -7104,6 +7252,10 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) rt2x00_rt(rt2x00dev, RT5390) || rt2x00_rt(rt2x00dev, RT5392)) rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf); + else if (rt2x00_rt(rt2x00dev, RT3352)) + rf = RF3322; + else if (rt2x00_rt(rt2x00dev, RT5350)) + rf = RF5350; else rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE); @@ -7122,6 +7274,7 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) case RF3290: case RF3320: case RF3322: + case RF5350: case RF5360: case RF5362: case RF5370: @@ -7193,7 +7346,8 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) /* * Detect if this device has Bluetooth co-existence. */ - if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) + if (!rt2x00_rt(rt2x00dev, RT3352) && + rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_BT_COEXIST)) __set_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags); /* @@ -7222,6 +7376,22 @@ static int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev) EIRP_MAX_TX_POWER_LIMIT) __set_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags); + /* + * Detect if device uses internal or external PA + */ + rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1, &eeprom); + + if (rt2x00_rt(rt2x00dev, RT3352)) { + if (!rt2x00_get_field16(eeprom, + EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352)) + __set_bit(CAPABILITY_INTERNAL_PA_TX0, + &rt2x00dev->cap_flags); + if (!rt2x00_get_field16(eeprom, + EEPROM_NIC_CONF1_EXTERNAL_TX1_PA_3352)) + __set_bit(CAPABILITY_INTERNAL_PA_TX1, + &rt2x00dev->cap_flags); + } + return 0; } @@ -7366,6 +7536,27 @@ static const struct rf_channel rf_vals_3x[] = { {173, 0x61, 0, 9}, }; +/* + * RF value list for rt3xxx with Xtal20MHz + * Supports: 2.4 GHz (all) (RF3322) + */ +static const struct rf_channel rf_vals_3x_xtal20[] = { + {1, 0xE2, 2, 0x14}, + {2, 0xE3, 2, 0x14}, + {3, 0xE4, 2, 0x14}, + {4, 0xE5, 2, 0x14}, + {5, 0xE6, 2, 0x14}, + {6, 0xE7, 2, 0x14}, + {7, 0xE8, 2, 0x14}, + {8, 0xE9, 2, 0x14}, + {9, 0xEA, 2, 0x14}, + {10, 0xEB, 2, 0x14}, + {11, 0xEC, 2, 0x14}, + {12, 0xED, 2, 0x14}, + {13, 0xEE, 2, 0x14}, + {14, 0xF0, 2, 0x18}, +}; + static const struct rf_channel rf_vals_5592_xtal20[] = { /* Channel, N, K, mod, R */ {1, 482, 4, 10, 3}, @@ -7514,6 +7705,13 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) rt2x00dev->hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; /* + * Change default retry settings to values corresponding more closely + * to rate[0].count setting of minstrel rate control algorithm. + */ + rt2x00dev->hw->wiphy->retry_short = 2; + rt2x00dev->hw->wiphy->retry_long = 2; + + /* * Initialize all hw fields. */ ieee80211_hw_set(rt2x00dev->hw, REPORTS_TX_ACK_STATUS); @@ -7580,6 +7778,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) case RF3290: case RF3320: case RF3322: + case RF5350: case RF5360: case RF5362: case RF5370: @@ -7587,7 +7786,10 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) case RF5390: case RF5392: spec->num_channels = 14; - spec->channels = rf_vals_3x; + if (rt2800_clk_is_20mhz(rt2x00dev)) + spec->channels = rf_vals_3x_xtal20; + else + spec->channels = rf_vals_3x; break; case RF3052: @@ -7713,6 +7915,7 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) case RF3053: case RF3070: case RF3290: + case RF5350: case RF5360: case RF5362: case RF5370: @@ -7753,6 +7956,7 @@ static int rt2800_probe_rt(struct rt2x00_dev *rt2x00dev) case RT3390: case RT3572: case RT3593: + case RT5350: case RT5390: case RT5392: case RT5592: diff --git a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c index f38c44061b5b..205a7b8ac8a7 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c @@ -123,7 +123,7 @@ static inline bool rt2800usb_entry_txstatus_timeout(struct queue_entry *entry) if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) return false; - tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(100)); + tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(500)); if (unlikely(tout)) rt2x00_dbg(entry->queue->rt2x00dev, "TX status timeout for entry %d in queue %d\n", @@ -436,47 +436,6 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev, } /* - * Watchdog handlers - */ -static void rt2800usb_watchdog(struct rt2x00_dev *rt2x00dev) -{ - unsigned int i; - u32 reg; - - rt2x00usb_register_read(rt2x00dev, TXRXQ_PCNT, ®); - if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) { - rt2x00_warn(rt2x00dev, "TX HW queue 0 timed out, invoke forced kick\n"); - - rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40012); - - for (i = 0; i < 10; i++) { - udelay(10); - if (!rt2x00_get_field32(reg, TXRXQ_PCNT_TX0Q)) - break; - } - - rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40006); - } - - rt2x00usb_register_read(rt2x00dev, TXRXQ_PCNT, ®); - if (rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) { - rt2x00_warn(rt2x00dev, "TX HW queue 1 timed out, invoke forced kick\n"); - - rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf4000a); - - for (i = 0; i < 10; i++) { - udelay(10); - if (!rt2x00_get_field32(reg, TXRXQ_PCNT_TX1Q)) - break; - } - - rt2x00usb_register_write(rt2x00dev, PBF_CFG, 0xf40006); - } - - rt2x00usb_watchdog(rt2x00dev); -} - -/* * TX descriptor initialization */ static __le32 *rt2800usb_get_txwi(struct queue_entry *entry) @@ -643,10 +602,9 @@ static void rt2800usb_txdone_nostatus(struct rt2x00_dev *rt2x00dev) !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) break; - if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags) || + rt2800usb_entry_txstatus_timeout(entry)) rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); - else if (rt2800usb_entry_txstatus_timeout(entry)) - rt2x00lib_txdone_noinfo(entry, TXDONE_UNKNOWN); else break; } @@ -877,7 +835,6 @@ static const struct rt2x00lib_ops rt2800usb_rt2x00_ops = { .link_tuner = rt2800_link_tuner, .gain_calibration = rt2800_gain_calibration, .vco_calibration = rt2800_vco_calibration, - .watchdog = rt2800usb_watchdog, .start_queue = rt2800usb_start_queue, .kick_queue = rt2x00usb_kick_queue, .stop_queue = rt2800usb_stop_queue, diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00.h b/drivers/net/wireless/ralink/rt2x00/rt2x00.h index 034a07273038..ea299c4e7ada 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h @@ -39,6 +39,7 @@ #include <linux/hrtimer.h> #include <linux/average.h> #include <linux/usb.h> +#include <linux/clk.h> #include <net/mac80211.h> @@ -169,6 +170,7 @@ struct rt2x00_chip { #define RT3572 0x3572 #define RT3593 0x3593 #define RT3883 0x3883 /* WSOC */ +#define RT5350 0x5350 /* WSOC 2.4GHz */ #define RT5390 0x5390 /* 2.4GHz */ #define RT5392 0x5392 /* 2.4GHz */ #define RT5592 0x5592 @@ -716,6 +718,8 @@ enum rt2x00_capability_flags { CAPABILITY_DOUBLE_ANTENNA, CAPABILITY_BT_COEXIST, CAPABILITY_VCO_RECALIBRATION, + CAPABILITY_INTERNAL_PA_TX0, + CAPABILITY_INTERNAL_PA_TX1, }; /* @@ -1009,6 +1013,9 @@ struct rt2x00_dev { unsigned int extra_tx_headroom; struct usb_anchor *anchor; + + /* Clock for System On Chip devices. */ + struct clk *clk; }; struct rt2x00_bar_list_entry { diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00config.c b/drivers/net/wireless/ralink/rt2x00/rt2x00config.c index 6a1f508d472f..350507458ddc 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00config.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00config.c @@ -249,6 +249,22 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, */ rt2x00dev->ops->lib->config(rt2x00dev, &libconf, ieee80211_flags); + if (conf->flags & IEEE80211_CONF_PS) + set_bit(CONFIG_POWERSAVING, &rt2x00dev->flags); + else + clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags); + + if (conf->flags & IEEE80211_CONF_MONITOR) + set_bit(CONFIG_MONITORING, &rt2x00dev->flags); + else + clear_bit(CONFIG_MONITORING, &rt2x00dev->flags); + + rt2x00dev->curr_band = conf->chandef.chan->band; + rt2x00dev->curr_freq = conf->chandef.chan->center_freq; + rt2x00dev->tx_power = conf->power_level; + rt2x00dev->short_retry = conf->short_frame_max_tx_count; + rt2x00dev->long_retry = conf->long_frame_max_tx_count; + /* * Some configuration changes affect the link quality * which means we need to reset the link tuner. @@ -271,20 +287,4 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, &rt2x00dev->autowakeup_work, autowake_timeout - 15); } - - if (conf->flags & IEEE80211_CONF_PS) - set_bit(CONFIG_POWERSAVING, &rt2x00dev->flags); - else - clear_bit(CONFIG_POWERSAVING, &rt2x00dev->flags); - - if (conf->flags & IEEE80211_CONF_MONITOR) - set_bit(CONFIG_MONITORING, &rt2x00dev->flags); - else - clear_bit(CONFIG_MONITORING, &rt2x00dev->flags); - - rt2x00dev->curr_band = conf->chandef.chan->band; - rt2x00dev->curr_freq = conf->chandef.chan->center_freq; - rt2x00dev->tx_power = conf->power_level; - rt2x00dev->short_retry = conf->short_frame_max_tx_count; - rt2x00dev->long_retry = conf->long_frame_max_tx_count; } diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c index 3cc1384ed2fc..ecc96312a370 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c @@ -743,7 +743,8 @@ void rt2x00mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif, return; tx_queue_for_each(rt2x00dev, queue) - rt2x00queue_flush_queue(queue, drop); + if (!rt2x00queue_empty(queue)) + rt2x00queue_flush_queue(queue, drop); } EXPORT_SYMBOL_GPL(rt2x00mac_flush); diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00mmio.c b/drivers/net/wireless/ralink/rt2x00/rt2x00mmio.c index f0178fd4fe5f..da38d254c26f 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00mmio.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mmio.c @@ -101,7 +101,7 @@ void rt2x00mmio_flush_queue(struct data_queue *queue, bool drop) unsigned int i; for (i = 0; !rt2x00queue_empty(queue) && i < 10; i++) - msleep(10); + msleep(50); } EXPORT_SYMBOL_GPL(rt2x00mmio_flush_queue); diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c b/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c index 69a0cdadb07f..29250f79c4a4 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c @@ -93,6 +93,10 @@ int rt2x00soc_probe(struct platform_device *pdev, const struct rt2x00_ops *ops) rt2x00dev->irq = platform_get_irq(pdev, 0); rt2x00dev->name = pdev->dev.driver->name; + rt2x00dev->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(rt2x00dev->clk)) + rt2x00dev->clk = NULL; + rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_SOC); retval = rt2x00soc_alloc_reg(rt2x00dev); diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c index 6005e14213ca..838ca58d2dd6 100644 --- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c @@ -517,7 +517,7 @@ void rt2x00usb_flush_queue(struct data_queue *queue, bool drop) * Wait for a little while to give the driver * the oppurtunity to recover itself. */ - msleep(10); + msleep(50); } } EXPORT_SYMBOL_GPL(rt2x00usb_flush_queue); diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h index df551b2b56eb..95e3993d8a33 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com> + * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com> * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c index f9e2050812ab..a41a29612582 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192c.c @@ -1,7 +1,7 @@ /* * RTL8XXXU mac80211 USB driver - 8188c/8188r/8192c specific subdriver * - * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com> + * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com> * * Portions, notably calibration code: * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c index a1178c5d6ad8..80fee699f58a 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8192e.c @@ -1,7 +1,7 @@ /* * RTL8XXXU mac80211 USB driver - 8192e specific subdriver * - * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com> + * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com> * * Portions, notably calibration code: * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c index aef373028155..174631132b96 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723a.c @@ -1,7 +1,7 @@ /* * RTL8XXXU mac80211 USB driver - 8723a specific subdriver * - * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com> + * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com> * * Portions, notably calibration code: * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c index 02b8ddd98a95..c4b86a84a721 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c @@ -1,7 +1,7 @@ /* * RTL8XXXU mac80211 USB driver - 8723b specific subdriver * - * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com> + * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com> * * Portions, notably calibration code: * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c index 3a86675020a2..e544dd1d618c 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c @@ -1,7 +1,7 @@ /* * RTL8XXXU mac80211 USB driver * - * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com> + * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com> * * Portions, notably calibration code: * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved. @@ -48,7 +48,7 @@ static bool rtl8xxxu_dma_aggregation; static int rtl8xxxu_dma_agg_timeout = -1; static int rtl8xxxu_dma_agg_pages = -1; -MODULE_AUTHOR("Jes Sorensen <Jes.Sorensen@redhat.com>"); +MODULE_AUTHOR("Jes Sorensen <Jes.Sorensen@gmail.com>"); MODULE_DESCRIPTION("RTL8XXXu USB mac80211 Wireless LAN Driver"); MODULE_LICENSE("GPL"); MODULE_FIRMWARE("rtlwifi/rtl8723aufw_A.bin"); @@ -6000,6 +6000,7 @@ static int rtl8xxxu_probe(struct usb_interface *interface, case 0x8176: case 0x8178: case 0x817f: + case 0x818b: untested = 0; break; } @@ -6196,6 +6197,12 @@ static struct usb_device_id dev_table[] = { .driver_info = (unsigned long)&rtl8723au_fops}, {USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x818b, 0xff, 0xff, 0xff), .driver_info = (unsigned long)&rtl8192eu_fops}, +/* TP-Link TL-WN822N v4 */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0108, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, +/* D-Link DWA-131 rev E1, tested by David Patiño */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x3319, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, /* Tested by Myckel Habets */ {USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0109, 0xff, 0xff, 0xff), .driver_info = (unsigned long)&rtl8192eu_fops}, @@ -6347,6 +6354,13 @@ static struct usb_device_id dev_table[] = { .driver_info = (unsigned long)&rtl8192cu_fops}, {USB_DEVICE_AND_INTERFACE_INFO(0x7392, 0x7822, 0xff, 0xff, 0xff), .driver_info = (unsigned long)&rtl8192cu_fops}, +/* found in rtl8192eu vendor driver */ +{USB_DEVICE_AND_INTERFACE_INFO(0x2357, 0x0107, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(0x2019, 0xab33, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, +{USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_REALTEK, 0x818c, 0xff, 0xff, 0xff), + .driver_info = (unsigned long)&rtl8192eu_fops}, #endif { } }; diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h index 315ccfb2dff5..3d3e2e1ada6f 100644 --- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h +++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_regs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 - 2016 Jes Sorensen <Jes.Sorensen@redhat.com> + * Copyright (c) 2014 - 2017 Jes Sorensen <Jes.Sorensen@gmail.com> * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c index 13325e15929e..01cf0a9aa31b 100644 --- a/drivers/net/wireless/realtek/rtlwifi/base.c +++ b/drivers/net/wireless/realtek/rtlwifi/base.c @@ -2083,65 +2083,6 @@ void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len) } EXPORT_SYMBOL_GPL(rtl_recognize_peer); -/********************************************************* - * - * sysfs functions - * - *********************************************************/ -static ssize_t rtl_show_debug_level(struct device *d, - struct device_attribute *attr, char *buf) -{ - struct ieee80211_hw *hw = dev_get_drvdata(d); - struct rtl_priv *rtlpriv = rtl_priv(hw); - - return sprintf(buf, "0x%08X\n", rtlpriv->dbg.global_debuglevel); -} - -static ssize_t rtl_store_debug_level(struct device *d, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct ieee80211_hw *hw = dev_get_drvdata(d); - struct rtl_priv *rtlpriv = rtl_priv(hw); - unsigned long val; - int ret; - - ret = kstrtoul(buf, 0, &val); - if (ret) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG, - "%s is not in hex or decimal form.\n", buf); - } else { - rtlpriv->dbg.global_debuglevel = val; - RT_TRACE(rtlpriv, COMP_ERR, DBG_DMESG, - "debuglevel:%x\n", - rtlpriv->dbg.global_debuglevel); - } - - return strnlen(buf, count); -} - -static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO, - rtl_show_debug_level, rtl_store_debug_level); - -static struct attribute *rtl_sysfs_entries[] = { - - &dev_attr_debug_level.attr, - - NULL -}; - -/* - * "name" is folder name witch will be - * put in device directory like : - * sys/devices/pci0000:00/0000:00:1c.4/ - * 0000:06:00.0/rtl_sysfs - */ -struct attribute_group rtl_attribute_group = { - .name = "rtlsysfs", - .attrs = rtl_sysfs_entries, -}; -EXPORT_SYMBOL_GPL(rtl_attribute_group); - MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>"); MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>"); MODULE_AUTHOR("Larry Finger <Larry.FInger@lwfinger.net>"); diff --git a/drivers/net/wireless/realtek/rtlwifi/base.h b/drivers/net/wireless/realtek/rtlwifi/base.h index 74233d601a90..6c770aecebe7 100644 --- a/drivers/net/wireless/realtek/rtlwifi/base.h +++ b/drivers/net/wireless/realtek/rtlwifi/base.h @@ -148,7 +148,6 @@ int rtl_send_smps_action(struct ieee80211_hw *hw, u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie); void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len); u8 rtl_tid_to_ac(u8 tid); -extern struct attribute_group rtl_attribute_group; void rtl_easy_concurrent_retrytimer_callback(unsigned long data); extern struct rtl_global_var rtl_global_var; void rtl_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation); diff --git a/drivers/net/wireless/realtek/rtlwifi/debug.c b/drivers/net/wireless/realtek/rtlwifi/debug.c index 33905bbacad2..7ecac6116d5d 100644 --- a/drivers/net/wireless/realtek/rtlwifi/debug.c +++ b/drivers/net/wireless/realtek/rtlwifi/debug.c @@ -26,35 +26,32 @@ #include <linux/moduleparam.h> -void rtl_dbgp_flag_init(struct ieee80211_hw *hw) +#ifdef CONFIG_RTLWIFI_DEBUG +void _rtl_dbg_trace(struct rtl_priv *rtlpriv, int comp, int level, + const char *fmt, ...) { - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 i; + if (unlikely((comp & rtlpriv->cfg->mod_params->debug_mask) && + (level <= rtlpriv->cfg->mod_params->debug_level))) { + struct va_format vaf; + va_list args; - rtlpriv->dbg.global_debugcomponents = - COMP_ERR | COMP_FW | COMP_INIT | COMP_RECV | COMP_SEND | - COMP_MLME | COMP_SCAN | COMP_INTR | COMP_LED | COMP_SEC | - COMP_BEACON | COMP_RATE | COMP_RXDESC | COMP_DIG | COMP_TXAGC | - COMP_POWER | COMP_POWER_TRACKING | COMP_BB_POWERSAVING | COMP_SWAS | - COMP_RF | COMP_TURBO | COMP_RATR | COMP_CMD | - COMP_EFUSE | COMP_QOS | COMP_MAC80211 | COMP_REGD | COMP_CHAN | - COMP_EASY_CONCURRENT | COMP_EFUSE | COMP_QOS | COMP_MAC80211 | - COMP_REGD | COMP_CHAN | COMP_BT_COEXIST; + va_start(args, fmt); + vaf.fmt = fmt; + vaf.va = &args; - for (i = 0; i < DBGP_TYPE_MAX; i++) - rtlpriv->dbg.dbgp_type[i] = 0; + pr_info(":<%lx> %pV", in_interrupt(), &vaf); - /*Init Debug flag enable condition */ + va_end(args); + } } -EXPORT_SYMBOL_GPL(rtl_dbgp_flag_init); +EXPORT_SYMBOL_GPL(_rtl_dbg_trace); -#ifdef CONFIG_RTLWIFI_DEBUG -void _rtl_dbg_trace(struct rtl_priv *rtlpriv, int comp, int level, - const char *modname, const char *fmt, ...) +void _rtl_dbg_print(struct rtl_priv *rtlpriv, u64 comp, int level, + const char *fmt, ...) { - if (unlikely((comp & rtlpriv->dbg.global_debugcomponents) && - (level <= rtlpriv->dbg.global_debuglevel))) { + if (unlikely((comp & rtlpriv->cfg->mod_params->debug_mask) && + (level <= rtlpriv->cfg->mod_params->debug_level))) { struct va_format vaf; va_list args; @@ -63,13 +60,25 @@ void _rtl_dbg_trace(struct rtl_priv *rtlpriv, int comp, int level, vaf.fmt = fmt; vaf.va = &args; - printk(KERN_DEBUG "%s:%ps:<%lx-%x> %pV", - modname, __builtin_return_address(0), - in_interrupt(), in_atomic(), - &vaf); + pr_info("%pV", &vaf); va_end(args); } } -EXPORT_SYMBOL_GPL(_rtl_dbg_trace); +EXPORT_SYMBOL_GPL(_rtl_dbg_print); + +void _rtl_dbg_print_data(struct rtl_priv *rtlpriv, u64 comp, int level, + const char *titlestring, + const void *hexdata, int hexdatalen) +{ + if (unlikely(((comp) & rtlpriv->cfg->mod_params->debug_mask) && + ((level) <= rtlpriv->cfg->mod_params->debug_level))) { + pr_info("In process \"%s\" (pid %i): %s\n", + current->comm, current->pid, titlestring); + print_hex_dump_bytes("", DUMP_PREFIX_NONE, + hexdata, hexdatalen); + } +} +EXPORT_SYMBOL_GPL(_rtl_dbg_print_data); + #endif diff --git a/drivers/net/wireless/realtek/rtlwifi/debug.h b/drivers/net/wireless/realtek/rtlwifi/debug.h index a6cc3ca05c5e..bf5339f1c1bc 100644 --- a/drivers/net/wireless/realtek/rtlwifi/debug.h +++ b/drivers/net/wireless/realtek/rtlwifi/debug.h @@ -168,34 +168,29 @@ enum dbgp_flag_e { struct rtl_priv; -__printf(5, 6) +__printf(4, 5) void _rtl_dbg_trace(struct rtl_priv *rtlpriv, int comp, int level, - const char *modname, const char *fmt, ...); + const char *fmt, ...); + +__printf(4, 5) +void _rtl_dbg_print(struct rtl_priv *rtlpriv, u64 comp, int level, + const char *fmt, ...); + +void _rtl_dbg_print_data(struct rtl_priv *rtlpriv, u64 comp, int level, + const char *titlestring, + const void *hexdata, int hexdatalen); #define RT_TRACE(rtlpriv, comp, level, fmt, ...) \ _rtl_dbg_trace(rtlpriv, comp, level, \ - KBUILD_MODNAME, fmt, ##__VA_ARGS__) + fmt, ##__VA_ARGS__) #define RTPRINT(rtlpriv, dbgtype, dbgflag, fmt, ...) \ -do { \ - if (unlikely(rtlpriv->dbg.dbgp_type[dbgtype] & dbgflag)) { \ - printk(KERN_DEBUG KBUILD_MODNAME ": " fmt, \ - ##__VA_ARGS__); \ - } \ -} while (0) + _rtl_dbg_print(rtlpriv, dbgtype, dbgflag, fmt, ##__VA_ARGS__) #define RT_PRINT_DATA(rtlpriv, _comp, _level, _titlestring, _hexdata, \ _hexdatalen) \ -do { \ - if (unlikely(((_comp) & rtlpriv->dbg.global_debugcomponents) && \ - (_level <= rtlpriv->dbg.global_debuglevel))) { \ - printk(KERN_DEBUG "%s: In process \"%s\" (pid %i): %s\n", \ - KBUILD_MODNAME, current->comm, current->pid, \ - _titlestring); \ - print_hex_dump_bytes("", DUMP_PREFIX_NONE, \ - _hexdata, _hexdatalen); \ - } \ -} while (0) + _rtl_dbg_print_data(rtlpriv, _comp, _level, \ + _titlestring, _hexdata, _hexdatalen) #else @@ -223,6 +218,4 @@ static inline void RT_PRINT_DATA(struct rtl_priv *rtlpriv, } #endif - -void rtl_dbgp_flag_init(struct ieee80211_hw *hw); #endif diff --git a/drivers/net/wireless/realtek/rtlwifi/efuse.c b/drivers/net/wireless/realtek/rtlwifi/efuse.c index afc7550e8e41..eb58633e674a 100644 --- a/drivers/net/wireless/realtek/rtlwifi/efuse.c +++ b/drivers/net/wireless/realtek/rtlwifi/efuse.c @@ -31,6 +31,9 @@ static const u8 MAX_PGPKT_SIZE = 9; static const u8 PGPKT_DATA_SIZE = 8; static const int EFUSE_MAX_SIZE = 512; +#define START_ADDRESS 0x1000 +#define REG_MCUFWDL 0x0080 + static const struct efuse_map RTL8712_SDIO_EFUSE_TABLE[] = { {0, 0, 0, 2}, {0, 1, 0, 2}, @@ -1320,3 +1323,45 @@ int rtl_get_hwinfo(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv, return 0; } EXPORT_SYMBOL_GPL(rtl_get_hwinfo); + +void rtl_fw_block_write(struct ieee80211_hw *hw, const u8 *buffer, u32 size) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 *pu4byteptr = (u8 *)buffer; + u32 i; + + for (i = 0; i < size; i++) + rtl_write_byte(rtlpriv, (START_ADDRESS + i), *(pu4byteptr + i)); +} +EXPORT_SYMBOL_GPL(rtl_fw_block_write); + +void rtl_fw_page_write(struct ieee80211_hw *hw, u32 page, const u8 *buffer, + u32 size) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u8 value8; + u8 u8page = (u8)(page & 0x07); + + value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page; + + rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8); + rtl_fw_block_write(hw, buffer, size); +} +EXPORT_SYMBOL_GPL(rtl_fw_page_write); + +void rtl_fill_dummy(u8 *pfwbuf, u32 *pfwlen) +{ + u32 fwlen = *pfwlen; + u8 remain = (u8)(fwlen % 4); + + remain = (remain == 0) ? 0 : (4 - remain); + + while (remain > 0) { + pfwbuf[fwlen] = 0; + fwlen++; + remain--; + } + + *pfwlen = fwlen; +} +EXPORT_SYMBOL_GPL(rtl_fill_dummy); diff --git a/drivers/net/wireless/realtek/rtlwifi/efuse.h b/drivers/net/wireless/realtek/rtlwifi/efuse.h index 51aa1210def5..1338ae63fe54 100644 --- a/drivers/net/wireless/realtek/rtlwifi/efuse.h +++ b/drivers/net/wireless/realtek/rtlwifi/efuse.h @@ -111,5 +111,9 @@ void efuse_force_write_vendor_Id(struct ieee80211_hw *hw); void efuse_re_pg_section(struct ieee80211_hw *hw, u8 section_idx); int rtl_get_hwinfo(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv, int max_size, u8 *hwinfo, int *params); +void rtl_fill_dummy(u8 *pfwbuf, u32 *pfwlen); +void rtl_fw_page_write(struct ieee80211_hw *hw, u32 page, const u8 *buffer, + u32 size); +void rtl_fw_block_write(struct ieee80211_hw *hw, const u8 *buffer, u32 size); #endif diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c index 81ac0b393304..b402f438b1af 100644 --- a/drivers/net/wireless/realtek/rtlwifi/pci.c +++ b/drivers/net/wireless/realtek/rtlwifi/pci.c @@ -2212,16 +2212,6 @@ int rtl_pci_probe(struct pci_dev *pdev, rtlpriv->intf_ops = &rtl_pci_ops; rtlpriv->glb_var = &rtl_global_var; - /* - *init dbgp flags before all - *other functions, because we will - *use it in other funtions like - *RT_TRACE/RT_PRINT/RTL_PRINT_DATA - *you can not use these macro - *before this - */ - rtl_dbgp_flag_init(hw); - /* MEM map */ err = pci_request_regions(pdev, KBUILD_MODNAME); if (err) { @@ -2299,12 +2289,6 @@ int rtl_pci_probe(struct pci_dev *pdev, } rtlpriv->mac80211.mac80211_registered = 1; - err = sysfs_create_group(&pdev->dev.kobj, &rtl_attribute_group); - if (err) { - pr_err("failed to create sysfs device attributes\n"); - goto fail3; - } - /*init rfkill */ rtl_init_rfkill(hw); /* Init PCI sw */ @@ -2354,8 +2338,6 @@ void rtl_pci_disconnect(struct pci_dev *pdev) wait_for_completion(&rtlpriv->firmware_loading_complete); clear_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); - sysfs_remove_group(&pdev->dev.kobj, &rtl_attribute_group); - /*ieee80211_unregister_hw will call ops_stop */ if (rtlmac->mac80211_registered == 1) { ieee80211_unregister_hw(hw); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.c index afa784a46634..21ed9ad3be7a 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/fw.c @@ -27,6 +27,7 @@ #include "../pci.h" #include "../base.h" #include "../core.h" +#include "../efuse.h" #include "reg.h" #include "def.h" #include "fw.h" @@ -53,63 +54,6 @@ static void _rtl88e_enable_fw_download(struct ieee80211_hw *hw, bool enable) } } -static void _rtl88e_fw_block_write(struct ieee80211_hw *hw, - const u8 *buffer, u32 size) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 blocksize = sizeof(u32); - u8 *bufferptr = (u8 *)buffer; - u32 *pu4BytePtr = (u32 *)buffer; - u32 i, offset, blockcount, remainsize; - - blockcount = size / blocksize; - remainsize = size % blocksize; - - for (i = 0; i < blockcount; i++) { - offset = i * blocksize; - rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset), - *(pu4BytePtr + i)); - } - - if (remainsize) { - offset = blockcount * blocksize; - bufferptr += offset; - for (i = 0; i < remainsize; i++) { - rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS + - offset + i), *(bufferptr + i)); - } - } -} - -static void _rtl88e_fw_page_write(struct ieee80211_hw *hw, - u32 page, const u8 *buffer, u32 size) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 value8; - u8 u8page = (u8) (page & 0x07); - - value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page; - - rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8); - _rtl88e_fw_block_write(hw, buffer, size); -} - -static void _rtl88e_fill_dummy(u8 *pfwbuf, u32 *pfwlen) -{ - u32 fwlen = *pfwlen; - u8 remain = (u8) (fwlen % 4); - - remain = (remain == 0) ? 0 : (4 - remain); - - while (remain > 0) { - pfwbuf[fwlen] = 0; - fwlen++; - remain--; - } - - *pfwlen = fwlen; -} - static void _rtl88e_write_fw(struct ieee80211_hw *hw, enum version_8188e version, u8 *buffer, u32 size) { @@ -120,7 +64,7 @@ static void _rtl88e_write_fw(struct ieee80211_hw *hw, RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "FW size is %d bytes,\n", size); - _rtl88e_fill_dummy(bufferptr, &size); + rtl_fill_dummy(bufferptr, &size); pagenums = size / FW_8192C_PAGE_SIZE; remainsize = size % FW_8192C_PAGE_SIZE; @@ -130,15 +74,14 @@ static void _rtl88e_write_fw(struct ieee80211_hw *hw, for (page = 0; page < pagenums; page++) { offset = page * FW_8192C_PAGE_SIZE; - _rtl88e_fw_page_write(hw, page, (bufferptr + offset), - FW_8192C_PAGE_SIZE); + rtl_fw_page_write(hw, page, (bufferptr + offset), + FW_8192C_PAGE_SIZE); } if (remainsize) { offset = pagenums * FW_8192C_PAGE_SIZE; page = pagenums; - _rtl88e_fw_page_write(hw, page, (bufferptr + offset), - remainsize); + rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize); } } diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c index 276c74539fb3..7661cfa53032 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c @@ -131,8 +131,6 @@ int rtl88e_init_sw_vars(struct ieee80211_hw *hw) rtlpci->irq_mask[1] = (u32) (IMR_RXFOVW | 0); rtlpci->sys_irq_mask = (u32) (HSIMR_PDN_INT_EN | HSIMR_RON_INT_EN); - /* for debug level */ - rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug; /* for LPS & IPS */ rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; @@ -276,7 +274,8 @@ static struct rtl_mod_params rtl88ee_mod_params = { .swctrl_lps = false, .fwctrl_lps = false, .msi_support = true, - .debug = 0, + .debug_level = 0, + .debug_mask = 0, }; static const struct rtl_hal_cfg rtl88ee_hal_cfg = { @@ -392,7 +391,8 @@ MODULE_DESCRIPTION("Realtek 8188E 802.11n PCI wireless"); MODULE_FIRMWARE("rtlwifi/rtl8188efw.bin"); module_param_named(swenc, rtl88ee_mod_params.sw_crypto, bool, 0444); -module_param_named(debug, rtl88ee_mod_params.debug, int, 0444); +module_param_named(debug_level, rtl88ee_mod_params.debug_level, int, 0644); +module_param_named(debug_mask, rtl88ee_mod_params.debug_mask, ullong, 0644); module_param_named(ips, rtl88ee_mod_params.inactiveps, bool, 0444); module_param_named(swlps, rtl88ee_mod_params.swctrl_lps, bool, 0444); module_param_named(fwlps, rtl88ee_mod_params.fwctrl_lps, bool, 0444); @@ -404,7 +404,8 @@ MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n"); -MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)"); MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n"); static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.c index 433ab7f33acf..c7a77467b20e 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192c/fw_common.c @@ -27,6 +27,7 @@ #include "../pci.h" #include "../base.h" #include "../core.h" +#include "../efuse.h" #include "../rtl8192ce/reg.h" #include "../rtl8192ce/def.h" #include "fw_common.h" @@ -68,63 +69,6 @@ static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable) } } -static void _rtl92c_fw_block_write(struct ieee80211_hw *hw, - const u8 *buffer, u32 size) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 blocksize = sizeof(u32); - u8 *bufferptr = (u8 *)buffer; - u32 *pu4byteptr = (u32 *)buffer; - u32 i, offset, blockcount, remainsize; - - blockcount = size / blocksize; - remainsize = size % blocksize; - - for (i = 0; i < blockcount; i++) { - offset = i * blocksize; - rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset), - *(pu4byteptr + i)); - } - - if (remainsize) { - offset = blockcount * blocksize; - bufferptr += offset; - for (i = 0; i < remainsize; i++) { - rtl_write_byte(rtlpriv, (FW_8192C_START_ADDRESS + - offset + i), *(bufferptr + i)); - } - } -} - -static void _rtl92c_fw_page_write(struct ieee80211_hw *hw, - u32 page, const u8 *buffer, u32 size) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 value8; - u8 u8page = (u8) (page & 0x07); - - value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page; - - rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8); - _rtl92c_fw_block_write(hw, buffer, size); -} - -static void _rtl92c_fill_dummy(u8 *pfwbuf, u32 *pfwlen) -{ - u32 fwlen = *pfwlen; - u8 remain = (u8) (fwlen % 4); - - remain = (remain == 0) ? 0 : (4 - remain); - - while (remain > 0) { - pfwbuf[fwlen] = 0; - fwlen++; - remain--; - } - - *pfwlen = fwlen; -} - static void _rtl92c_write_fw(struct ieee80211_hw *hw, enum version_8192c version, u8 *buffer, u32 size) { @@ -140,7 +84,7 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw, u32 page, offset; if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192CE) - _rtl92c_fill_dummy(bufferptr, &size); + rtl_fill_dummy(bufferptr, &size); pageNums = size / FW_8192C_PAGE_SIZE; remainsize = size % FW_8192C_PAGE_SIZE; @@ -150,18 +94,18 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw, for (page = 0; page < pageNums; page++) { offset = page * FW_8192C_PAGE_SIZE; - _rtl92c_fw_page_write(hw, page, (bufferptr + offset), - FW_8192C_PAGE_SIZE); + rtl_fw_page_write(hw, page, (bufferptr + offset), + FW_8192C_PAGE_SIZE); } if (remainsize) { offset = pageNums * FW_8192C_PAGE_SIZE; page = pageNums; - _rtl92c_fw_page_write(hw, page, (bufferptr + offset), - remainsize); + rtl_fw_page_write(hw, page, (bufferptr + offset), + remainsize); } } else { - _rtl92c_fw_block_write(hw, buffer, size); + rtl_fw_block_write(hw, buffer, size); } } diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c index 9bd2bff6212a..efedd918d10a 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/sw.c @@ -130,8 +130,6 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD | 0); - /* for debug level */ - rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug; /* for LPS & IPS */ rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; @@ -247,7 +245,8 @@ static struct rtl_mod_params rtl92ce_mod_params = { .inactiveps = true, .swctrl_lps = false, .fwctrl_lps = true, - .debug = 0, + .debug_level = 0, + .debug_mask = 0, }; static const struct rtl_hal_cfg rtl92ce_hal_cfg = { @@ -364,7 +363,8 @@ MODULE_FIRMWARE("rtlwifi/rtl8192cfwU.bin"); MODULE_FIRMWARE("rtlwifi/rtl8192cfwU_B.bin"); module_param_named(swenc, rtl92ce_mod_params.sw_crypto, bool, 0444); -module_param_named(debug, rtl92ce_mod_params.debug, int, 0444); +module_param_named(debug_level, rtl92ce_mod_params.debug_level, int, 0644); +module_param_named(debug_mask, rtl92ce_mod_params.debug_mask, ullong, 0644); module_param_named(ips, rtl92ce_mod_params.inactiveps, bool, 0444); module_param_named(swlps, rtl92ce_mod_params.swctrl_lps, bool, 0444); module_param_named(fwlps, rtl92ce_mod_params.fwctrl_lps, bool, 0444); @@ -372,7 +372,8 @@ MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n"); MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); -MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)"); static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c index 935e8308e2e6..96c923b3feb4 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c @@ -61,7 +61,6 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->dm.dm_flag = 0; rtlpriv->dm.disable_framebursting = false; rtlpriv->dm.thermalvalue = 0; - rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug; rtlpriv->cfg->mod_params->sw_crypto = rtlpriv->cfg->mod_params->sw_crypto; @@ -157,13 +156,16 @@ static struct rtl_hal_ops rtl8192cu_hal_ops = { static struct rtl_mod_params rtl92cu_mod_params = { .sw_crypto = 0, - .debug = 0, + .debug_level = 0, + .debug_mask = 0, }; module_param_named(swenc, rtl92cu_mod_params.sw_crypto, bool, 0444); -module_param_named(debug, rtl92cu_mod_params.debug, int, 0444); +module_param_named(debug_level, rtl92cu_mod_params.debug_level, int, 0644); +module_param_named(debug_mask, rtl92cu_mod_params.debug_mask, ullong, 0644); MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n"); -MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)"); static struct rtl_hal_usbint_cfg rtl92cu_interface_cfg = { /* rx */ diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c index 6da6e2acfbec..1611e42479d9 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.c @@ -477,14 +477,14 @@ static void _rtl_fill_usb_tx_desc(u8 *txdesc) */ static void _rtl_tx_desc_checksum(u8 *txdesc) { - u16 *ptr = (u16 *)txdesc; + __le16 *ptr = (__le16 *)txdesc; u16 checksum = 0; u32 index; /* Clear first */ SET_TX_DESC_TX_DESC_CHECKSUM(txdesc, 0); for (index = 0; index < 16; index++) - checksum = checksum ^ (*(ptr + index)); + checksum = checksum ^ le16_to_cpu(*(ptr + index)); SET_TX_DESC_TX_DESC_CHECKSUM(txdesc, checksum); } diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.h b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.h index df88e39301c2..487eec89bc29 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/trx.h @@ -92,129 +92,107 @@ struct rx_drv_info_92c { u8 reserve:4; } __packed; -/* Define a macro that takes a le32 word, converts it to host ordering, - * right shifts by a specified count, creates a mask of the specified - * bit count, and extracts that number of bits. - */ - -#define SHIFT_AND_MASK_LE(__pdesc, __shift, __bits) \ - ((le32_to_cpu(*(((__le32 *)(__pdesc)))) >> (__shift)) & \ - BIT_LEN_MASK_32(__bits)) - -/* Define a macro that clears a bit field in an le32 word and - * sets the specified value into that bit field. The resulting - * value remains in le32 ordering; however, it is properly converted - * to host ordering for the clear and set operations before conversion - * back to le32. - */ - -#define SET_BITS_OFFSET_LE(__pdesc, __shift, __len, __val) \ - (*(__le32 *)(__pdesc) = \ - (cpu_to_le32((le32_to_cpu(*((__le32 *)(__pdesc))) & \ - (~(BIT_OFFSET_LEN_MASK_32((__shift), __len)))) | \ - (((u32)(__val) & BIT_LEN_MASK_32(__len)) << (__shift))))); - /* macros to read various fields in RX descriptor */ /* DWORD 0 */ #define GET_RX_DESC_PKT_LEN(__rxdesc) \ - SHIFT_AND_MASK_LE((__rxdesc), 0, 14) + LE_BITS_TO_4BYTE((__rxdesc), 0, 14) #define GET_RX_DESC_CRC32(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc, 14, 1) + LE_BITS_TO_4BYTE(__rxdesc, 14, 1) #define GET_RX_DESC_ICV(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc, 15, 1) + LE_BITS_TO_4BYTE(__rxdesc, 15, 1) #define GET_RX_DESC_DRVINFO_SIZE(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc, 16, 4) + LE_BITS_TO_4BYTE(__rxdesc, 16, 4) #define GET_RX_DESC_SECURITY(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc, 20, 3) + LE_BITS_TO_4BYTE(__rxdesc, 20, 3) #define GET_RX_DESC_QOS(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc, 23, 1) + LE_BITS_TO_4BYTE(__rxdesc, 23, 1) #define GET_RX_DESC_SHIFT(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc, 24, 2) + LE_BITS_TO_4BYTE(__rxdesc, 24, 2) #define GET_RX_DESC_PHY_STATUS(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc, 26, 1) + LE_BITS_TO_4BYTE(__rxdesc, 26, 1) #define GET_RX_DESC_SWDEC(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc, 27, 1) + LE_BITS_TO_4BYTE(__rxdesc, 27, 1) #define GET_RX_DESC_LAST_SEG(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc, 28, 1) + LE_BITS_TO_4BYTE(__rxdesc, 28, 1) #define GET_RX_DESC_FIRST_SEG(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc, 29, 1) + LE_BITS_TO_4BYTE(__rxdesc, 29, 1) #define GET_RX_DESC_EOR(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc, 30, 1) + LE_BITS_TO_4BYTE(__rxdesc, 30, 1) #define GET_RX_DESC_OWN(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc, 31, 1) + LE_BITS_TO_4BYTE(__rxdesc, 31, 1) /* DWORD 1 */ #define GET_RX_DESC_MACID(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+4, 0, 5) + LE_BITS_TO_4BYTE(__rxdesc + 4, 0, 5) #define GET_RX_DESC_TID(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+4, 5, 4) + LE_BITS_TO_4BYTE(__rxdesc + 4, 5, 4) #define GET_RX_DESC_PAGGR(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+4, 14, 1) + LE_BITS_TO_4BYTE(__rxdesc + 4, 14, 1) #define GET_RX_DESC_FAGGR(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+4, 15, 1) + LE_BITS_TO_4BYTE(__rxdesc + 4, 15, 1) #define GET_RX_DESC_A1_FIT(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+4, 16, 4) + LE_BITS_TO_4BYTE(__rxdesc + 4, 16, 4) #define GET_RX_DESC_A2_FIT(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+4, 20, 4) + LE_BITS_TO_4BYTE(__rxdesc + 4, 20, 4) #define GET_RX_DESC_PAM(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+4, 24, 1) + LE_BITS_TO_4BYTE(__rxdesc + 4, 24, 1) #define GET_RX_DESC_PWR(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+4, 25, 1) + LE_BITS_TO_4BYTE(__rxdesc + 4, 25, 1) #define GET_RX_DESC_MORE_DATA(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+4, 26, 1) + LE_BITS_TO_4BYTE(__rxdesc + 4, 26, 1) #define GET_RX_DESC_MORE_FRAG(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+4, 27, 1) + LE_BITS_TO_4BYTE(__rxdesc + 4, 27, 1) #define GET_RX_DESC_TYPE(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+4, 28, 2) + LE_BITS_TO_4BYTE(__rxdesc + 4, 28, 2) #define GET_RX_DESC_MC(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+4, 30, 1) + LE_BITS_TO_4BYTE(__rxdesc + 4, 30, 1) #define GET_RX_DESC_BC(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+4, 31, 1) + LE_BITS_TO_4BYTE(__rxdesc + 4, 31, 1) /* DWORD 2 */ #define GET_RX_DESC_SEQ(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+8, 0, 12) + LE_BITS_TO_4BYTE(__rxdesc + 8, 0, 12) #define GET_RX_DESC_FRAG(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+8, 12, 4) + LE_BITS_TO_4BYTE(__rxdesc + 8, 12, 4) #define GET_RX_DESC_USB_AGG_PKTNUM(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+8, 16, 8) + LE_BITS_TO_4BYTE(__rxdesc + 8, 16, 8) #define GET_RX_DESC_NEXT_IND(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+8, 30, 1) + LE_BITS_TO_4BYTE(__rxdesc + 8, 30, 1) /* DWORD 3 */ #define GET_RX_DESC_RX_MCS(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+12, 0, 6) + LE_BITS_TO_4BYTE(__rxdesc + 12, 0, 6) #define GET_RX_DESC_RX_HT(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+12, 6, 1) + LE_BITS_TO_4BYTE(__rxdesc + 12, 6, 1) #define GET_RX_DESC_AMSDU(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+12, 7, 1) + LE_BITS_TO_4BYTE(__rxdesc + 12, 7, 1) #define GET_RX_DESC_SPLCP(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+12, 8, 1) + LE_BITS_TO_4BYTE(__rxdesc + 12, 8, 1) #define GET_RX_DESC_BW(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+12, 9, 1) + LE_BITS_TO_4BYTE(__rxdesc + 12, 9, 1) #define GET_RX_DESC_HTC(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+12, 10, 1) + LE_BITS_TO_4BYTE(__rxdesc + 12, 10, 1) #define GET_RX_DESC_TCP_CHK_RPT(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+12, 11, 1) + LE_BITS_TO_4BYTE(__rxdesc + 12, 11, 1) #define GET_RX_DESC_IP_CHK_RPT(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+12, 12, 1) + LE_BITS_TO_4BYTE(__rxdesc + 12, 12, 1) #define GET_RX_DESC_TCP_CHK_VALID(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+12, 13, 1) + LE_BITS_TO_4BYTE(__rxdesc + 12, 13, 1) #define GET_RX_DESC_HWPC_ERR(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+12, 14, 1) + LE_BITS_TO_4BYTE(__rxdesc + 12, 14, 1) #define GET_RX_DESC_HWPC_IND(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+12, 15, 1) + LE_BITS_TO_4BYTE(__rxdesc + 12, 15, 1) #define GET_RX_DESC_IV0(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+12, 16, 16) + LE_BITS_TO_4BYTE(__rxdesc + 12, 16, 16) /* DWORD 4 */ #define GET_RX_DESC_IV1(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+16, 0, 32) + LE_BITS_TO_4BYTE(__rxdesc + 16, 0, 32) /* DWORD 5 */ #define GET_RX_DESC_TSFL(__rxdesc) \ - SHIFT_AND_MASK_LE(__rxdesc+20, 0, 32) + LE_BITS_TO_4BYTE(__rxdesc + 20, 0, 32) /*======================= tx desc ============================================*/ @@ -222,182 +200,182 @@ struct rx_drv_info_92c { /* Dword 0 */ #define SET_TX_DESC_PKT_SIZE(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc, 0, 16, __value) + SET_BITS_TO_LE_4BYTE(__txdesc, 0, 16, __value) #define SET_TX_DESC_OFFSET(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc, 16, 8, __value) + SET_BITS_TO_LE_4BYTE(__txdesc, 16, 8, __value) #define SET_TX_DESC_BMC(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc, 24, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc, 24, 1, __value) #define SET_TX_DESC_HTC(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc, 25, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc, 25, 1, __value) #define SET_TX_DESC_LAST_SEG(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc, 26, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc, 26, 1, __value) #define SET_TX_DESC_FIRST_SEG(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc, 27, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc, 27, 1, __value) #define SET_TX_DESC_LINIP(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc, 28, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc, 28, 1, __value) #define SET_TX_DESC_NO_ACM(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc, 29, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc, 29, 1, __value) #define SET_TX_DESC_GF(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc, 30, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc, 30, 1, __value) #define SET_TX_DESC_OWN(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc, 31, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc, 31, 1, __value) /* Dword 1 */ #define SET_TX_DESC_MACID(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+4, 0, 5, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 4, 0, 5, __value) #define SET_TX_DESC_AGG_ENABLE(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+4, 5, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 4, 5, 1, __value) #define SET_TX_DESC_AGG_BREAK(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+4, 6, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 4, 6, 1, __value) #define SET_TX_DESC_RDG_ENABLE(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+4, 7, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 4, 7, 1, __value) #define SET_TX_DESC_QUEUE_SEL(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+4, 8, 5, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 4, 8, 5, __value) #define SET_TX_DESC_RDG_NAV_EXT(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+4, 13, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 4, 13, 1, __value) #define SET_TX_DESC_LSIG_TXOP_EN(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+4, 14, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 4, 14, 1, __value) #define SET_TX_DESC_PIFS(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+4, 15, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 4, 15, 1, __value) #define SET_TX_DESC_RATE_ID(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+4, 16, 4, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 4, 16, 4, __value) #define SET_TX_DESC_RA_BRSR_ID(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+4, 16, 4, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 4, 16, 4, __value) #define SET_TX_DESC_NAV_USE_HDR(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+4, 20, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 4, 20, 1, __value) #define SET_TX_DESC_EN_DESC_ID(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+4, 21, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 4, 21, 1, __value) #define SET_TX_DESC_SEC_TYPE(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+4, 22, 2, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 4, 22, 2, __value) #define SET_TX_DESC_PKT_OFFSET(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+4, 26, 5, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 4, 26, 5, __value) /* Dword 2 */ #define SET_TX_DESC_RTS_RC(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+8, 0, 6, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 8, 0, 6, __value) #define SET_TX_DESC_DATA_RC(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+8, 6, 6, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 8, 6, 6, __value) #define SET_TX_DESC_BAR_RTY_TH(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+8, 14, 2, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 8, 14, 2, __value) #define SET_TX_DESC_MORE_FRAG(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+8, 17, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 8, 17, 1, __value) #define SET_TX_DESC_RAW(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+8, 18, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 8, 18, 1, __value) #define SET_TX_DESC_CCX(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+8, 19, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 8, 19, 1, __value) #define SET_TX_DESC_AMPDU_DENSITY(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+8, 20, 3, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 8, 20, 3, __value) #define SET_TX_DESC_ANTSEL_A(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+8, 24, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 8, 24, 1, __value) #define SET_TX_DESC_ANTSEL_B(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+8, 25, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 8, 25, 1, __value) #define SET_TX_DESC_TX_ANT_CCK(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+8, 26, 2, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 8, 26, 2, __value) #define SET_TX_DESC_TX_ANTL(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+8, 28, 2, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 8, 28, 2, __value) #define SET_TX_DESC_TX_ANT_HT(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+8, 30, 2, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 8, 30, 2, __value) /* Dword 3 */ #define SET_TX_DESC_NEXT_HEAP_PAGE(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+12, 0, 8, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 12, 0, 8, __value) #define SET_TX_DESC_TAIL_PAGE(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+12, 8, 8, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 12, 8, 8, __value) #define SET_TX_DESC_SEQ(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+12, 16, 12, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 12, 16, 12, __value) #define SET_TX_DESC_PKT_ID(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+12, 28, 4, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 12, 28, 4, __value) /* Dword 4 */ #define SET_TX_DESC_RTS_RATE(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+16, 0, 5, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 16, 0, 5, __value) #define SET_TX_DESC_AP_DCFE(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+16, 5, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 16, 5, 1, __value) #define SET_TX_DESC_QOS(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+16, 6, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 16, 6, 1, __value) #define SET_TX_DESC_HWSEQ_EN(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+16, 7, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 16, 7, 1, __value) #define SET_TX_DESC_USE_RATE(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+16, 8, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 16, 8, 1, __value) #define SET_TX_DESC_DISABLE_RTS_FB(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+16, 9, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 16, 9, 1, __value) #define SET_TX_DESC_DISABLE_FB(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+16, 10, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 16, 10, 1, __value) #define SET_TX_DESC_CTS2SELF(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+16, 11, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 16, 11, 1, __value) #define SET_TX_DESC_RTS_ENABLE(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+16, 12, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 16, 12, 1, __value) #define SET_TX_DESC_HW_RTS_ENABLE(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+16, 13, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 16, 13, 1, __value) #define SET_TX_DESC_WAIT_DCTS(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+16, 18, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 16, 18, 1, __value) #define SET_TX_DESC_CTS2AP_EN(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+16, 19, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 16, 19, 1, __value) #define SET_TX_DESC_DATA_SC(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+16, 20, 2, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 16, 20, 2, __value) #define SET_TX_DESC_DATA_STBC(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+16, 22, 2, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 16, 22, 2, __value) #define SET_TX_DESC_DATA_SHORT(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+16, 24, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 16, 24, 1, __value) #define SET_TX_DESC_DATA_BW(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+16, 25, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 16, 25, 1, __value) #define SET_TX_DESC_RTS_SHORT(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+16, 26, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 16, 26, 1, __value) #define SET_TX_DESC_RTS_BW(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+16, 27, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 16, 27, 1, __value) #define SET_TX_DESC_RTS_SC(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+16, 28, 2, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 16, 28, 2, __value) #define SET_TX_DESC_RTS_STBC(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+16, 30, 2, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 16, 30, 2, __value) /* Dword 5 */ #define SET_TX_DESC_TX_RATE(__pdesc, __val) \ - SET_BITS_OFFSET_LE(__pdesc+20, 0, 6, __val) + SET_BITS_TO_LE_4BYTE(__pdesc + 20, 0, 6, __val) #define SET_TX_DESC_DATA_SHORTGI(__pdesc, __val) \ - SET_BITS_OFFSET_LE(__pdesc+20, 6, 1, __val) + SET_BITS_TO_LE_4BYTE(__pdesc + 20, 6, 1, __val) #define SET_TX_DESC_CCX_TAG(__pdesc, __val) \ - SET_BITS_OFFSET_LE(__pdesc+20, 7, 1, __val) + SET_BITS_TO_LE_4BYTE(__pdesc + 20, 7, 1, __val) #define SET_TX_DESC_DATA_RATE_FB_LIMIT(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+20, 8, 5, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 20, 8, 5, __value) #define SET_TX_DESC_RTS_RATE_FB_LIMIT(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+20, 13, 4, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 20, 13, 4, __value) #define SET_TX_DESC_RETRY_LIMIT_ENABLE(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+20, 17, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 20, 17, 1, __value) #define SET_TX_DESC_DATA_RETRY_LIMIT(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+20, 18, 6, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 20, 18, 6, __value) #define SET_TX_DESC_USB_TXAGG_NUM(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+20, 24, 8, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 20, 24, 8, __value) /* Dword 6 */ #define SET_TX_DESC_TXAGC_A(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+24, 0, 5, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 24, 0, 5, __value) #define SET_TX_DESC_TXAGC_B(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+24, 5, 5, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 24, 5, 5, __value) #define SET_TX_DESC_USB_MAX_LEN(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+24, 10, 1, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 24, 10, 1, __value) #define SET_TX_DESC_MAX_AGG_NUM(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+24, 11, 5, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 24, 11, 5, __value) #define SET_TX_DESC_MCSG1_MAX_LEN(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+24, 16, 4, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 24, 16, 4, __value) #define SET_TX_DESC_MCSG2_MAX_LEN(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+24, 20, 4, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 24, 20, 4, __value) #define SET_TX_DESC_MCSG3_MAX_LEN(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+24, 24, 4, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 24, 24, 4, __value) #define SET_TX_DESC_MCSG7_MAX_LEN(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+24, 28, 4, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 24, 28, 4, __value) /* Dword 7 */ #define SET_TX_DESC_TX_DESC_CHECKSUM(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+28, 0, 16, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 28, 0, 16, __value) #define SET_TX_DESC_MCSG4_MAX_LEN(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+28, 16, 4, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 28, 16, 4, __value) #define SET_TX_DESC_MCSG5_MAX_LEN(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+28, 20, 4, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 28, 20, 4, __value) #define SET_TX_DESC_MCSG6_MAX_LEN(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+28, 24, 4, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 28, 24, 4, __value) #define SET_TX_DESC_MCSG15_MAX_LEN(__txdesc, __value) \ - SET_BITS_OFFSET_LE(__txdesc+28, 28, 4, __value) + SET_BITS_TO_LE_4BYTE(__txdesc + 28, 28, 4, __value) int rtl8192cu_endpoint_mapping(struct ieee80211_hw *hw); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.c index aa1e51c871df..88faeab2574f 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/fw.c @@ -26,6 +26,7 @@ #include "../wifi.h" #include "../pci.h" #include "../base.h" +#include "../efuse.h" #include "reg.h" #include "def.h" #include "fw.h" @@ -59,84 +60,31 @@ static void _rtl92d_enable_fw_download(struct ieee80211_hw *hw, bool enable) } } -static void _rtl92d_fw_block_write(struct ieee80211_hw *hw, - const u8 *buffer, u32 size) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 blocksize = sizeof(u32); - u8 *bufferptr = (u8 *) buffer; - u32 *pu4BytePtr = (u32 *) buffer; - u32 i, offset, blockCount, remainSize; - - blockCount = size / blocksize; - remainSize = size % blocksize; - for (i = 0; i < blockCount; i++) { - offset = i * blocksize; - rtl_write_dword(rtlpriv, (FW_8192D_START_ADDRESS + offset), - *(pu4BytePtr + i)); - } - if (remainSize) { - offset = blockCount * blocksize; - bufferptr += offset; - for (i = 0; i < remainSize; i++) { - rtl_write_byte(rtlpriv, (FW_8192D_START_ADDRESS + - offset + i), *(bufferptr + i)); - } - } -} - -static void _rtl92d_fw_page_write(struct ieee80211_hw *hw, - u32 page, const u8 *buffer, u32 size) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 value8; - u8 u8page = (u8) (page & 0x07); - - value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page; - rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8); - _rtl92d_fw_block_write(hw, buffer, size); -} - -static void _rtl92d_fill_dummy(u8 *pfwbuf, u32 *pfwlen) -{ - u32 fwlen = *pfwlen; - u8 remain = (u8) (fwlen % 4); - - remain = (remain == 0) ? 0 : (4 - remain); - while (remain > 0) { - pfwbuf[fwlen] = 0; - fwlen++; - remain--; - } - *pfwlen = fwlen; -} - static void _rtl92d_write_fw(struct ieee80211_hw *hw, enum version_8192d version, u8 *buffer, u32 size) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - u8 *bufferPtr = buffer; - u32 pagenums, remainSize; + u8 *bufferptr = buffer; + u32 pagenums, remainsize; u32 page, offset; RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size); if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE) - _rtl92d_fill_dummy(bufferPtr, &size); + rtl_fill_dummy(bufferptr, &size); pagenums = size / FW_8192D_PAGE_SIZE; - remainSize = size % FW_8192D_PAGE_SIZE; + remainsize = size % FW_8192D_PAGE_SIZE; if (pagenums > 8) pr_err("Page numbers should not greater then 8\n"); for (page = 0; page < pagenums; page++) { offset = page * FW_8192D_PAGE_SIZE; - _rtl92d_fw_page_write(hw, page, (bufferPtr + offset), - FW_8192D_PAGE_SIZE); + rtl_fw_page_write(hw, page, (bufferptr + offset), + FW_8192D_PAGE_SIZE); } - if (remainSize) { + if (remainsize) { offset = pagenums * FW_8192D_PAGE_SIZE; page = pagenums; - _rtl92d_fw_page_write(hw, page, (bufferPtr + offset), - remainSize); + rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize); } } @@ -323,7 +271,6 @@ int rtl92d_download_fw(struct ieee80211_hw *hw) spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags); if (err) pr_err("fw is not ready to run!\n"); - goto exit; exit: err = _rtl92d_fw_init(hw); return err; diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c index 51463d7b130a..16132c66e5e1 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192de/sw.c @@ -140,8 +140,6 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) rtlpci->irq_mask[1] = (u32) (IMR_CPWM | IMR_C2HCMD); - /* for debug level */ - rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug; /* for LPS & IPS */ rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; @@ -254,7 +252,8 @@ static struct rtl_mod_params rtl92de_mod_params = { .inactiveps = true, .swctrl_lps = true, .fwctrl_lps = false, - .debug = 0, + .debug_level = 0, + .debug_mask = 0, }; static const struct rtl_hal_cfg rtl92de_hal_cfg = { @@ -364,15 +363,17 @@ MODULE_DESCRIPTION("Realtek 8192DE 802.11n Dual Mac PCI wireless"); MODULE_FIRMWARE("rtlwifi/rtl8192defw.bin"); module_param_named(swenc, rtl92de_mod_params.sw_crypto, bool, 0444); -module_param_named(debug, rtl92de_mod_params.debug, int, 0444); +module_param_named(debug_level, rtl92de_mod_params.debug_level, int, 0644); module_param_named(ips, rtl92de_mod_params.inactiveps, bool, 0444); module_param_named(swlps, rtl92de_mod_params.swctrl_lps, bool, 0444); module_param_named(fwlps, rtl92de_mod_params.fwctrl_lps, bool, 0444); +module_param_named(debug_mask, rtl92de_mod_params.debug_mask, ullong, 0644); MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n"); MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 1)\n"); MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 0)\n"); -MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)"); static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c index 78ee6e1d1850..9d7a16c9e74e 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/fw.c @@ -27,6 +27,7 @@ #include "../pci.h" #include "../base.h" #include "../core.h" +#include "../efuse.h" #include "reg.h" #include "def.h" #include "fw.h" @@ -48,64 +49,6 @@ static void _rtl92ee_enable_fw_download(struct ieee80211_hw *hw, bool enable) } } -static void _rtl92ee_fw_block_write(struct ieee80211_hw *hw, - const u8 *buffer, u32 size) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 blocksize = sizeof(u32); - u8 *bufferptr = (u8 *)buffer; - u32 *pu4byteptr = (u32 *)buffer; - u32 i, offset, blockcount, remainsize; - - blockcount = size / blocksize; - remainsize = size % blocksize; - - for (i = 0; i < blockcount; i++) { - offset = i * blocksize; - rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset), - *(pu4byteptr + i)); - } - - if (remainsize) { - offset = blockcount * blocksize; - bufferptr += offset; - for (i = 0; i < remainsize; i++) { - rtl_write_byte(rtlpriv, - (FW_8192C_START_ADDRESS + offset + i), - *(bufferptr + i)); - } - } -} - -static void _rtl92ee_fw_page_write(struct ieee80211_hw *hw, u32 page, - const u8 *buffer, u32 size) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 value8; - u8 u8page = (u8)(page & 0x07); - - value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page; - rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8); - - _rtl92ee_fw_block_write(hw, buffer, size); -} - -static void _rtl92ee_fill_dummy(u8 *pfwbuf, u32 *pfwlen) -{ - u32 fwlen = *pfwlen; - u8 remain = (u8)(fwlen % 4); - - remain = (remain == 0) ? 0 : (4 - remain); - - while (remain > 0) { - pfwbuf[fwlen] = 0; - fwlen++; - remain--; - } - - *pfwlen = fwlen; -} - static void _rtl92ee_write_fw(struct ieee80211_hw *hw, enum version_8192e version, u8 *buffer, u32 size) @@ -117,7 +60,7 @@ static void _rtl92ee_write_fw(struct ieee80211_hw *hw, RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD , "FW size is %d bytes,\n", size); - _rtl92ee_fill_dummy(bufferptr, &size); + rtl_fill_dummy(bufferptr, &size); pagenums = size / FW_8192C_PAGE_SIZE; remainsize = size % FW_8192C_PAGE_SIZE; @@ -127,16 +70,15 @@ static void _rtl92ee_write_fw(struct ieee80211_hw *hw, for (page = 0; page < pagenums; page++) { offset = page * FW_8192C_PAGE_SIZE; - _rtl92ee_fw_page_write(hw, page, (bufferptr + offset), - FW_8192C_PAGE_SIZE); + rtl_fw_page_write(hw, page, (bufferptr + offset), + FW_8192C_PAGE_SIZE); udelay(2); } if (remainsize) { offset = pagenums * FW_8192C_PAGE_SIZE; page = pagenums; - _rtl92ee_fw_page_write(hw, page, (bufferptr + offset), - remainsize); + rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize); } } diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c index eddc704b3ee3..554f2dc86bc5 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/sw.c @@ -133,8 +133,6 @@ int rtl92ee_init_sw_vars(struct ieee80211_hw *hw) 0); rtlpci->irq_mask[1] = (u32)(IMR_RXFOVW | 0); - /* for debug level */ - rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug; /* for LPS & IPS */ rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; @@ -258,7 +256,8 @@ static struct rtl_mod_params rtl92ee_mod_params = { .swctrl_lps = false, .fwctrl_lps = true, .msi_support = true, - .debug = 0, + .debug_level = 0, + .debug_mask = 0, }; static const struct rtl_hal_cfg rtl92ee_hal_cfg = { @@ -368,7 +367,8 @@ MODULE_DESCRIPTION("Realtek 8192EE 802.11n PCI wireless"); MODULE_FIRMWARE("rtlwifi/rtl8192eefw.bin"); module_param_named(swenc, rtl92ee_mod_params.sw_crypto, bool, 0444); -module_param_named(debug, rtl92ee_mod_params.debug, int, 0444); +module_param_named(debug_level, rtl92ee_mod_params.debug_level, int, 0644); +module_param_named(debug_mask, rtl92ee_mod_params.debug_mask, ullong, 0644); module_param_named(ips, rtl92ee_mod_params.inactiveps, bool, 0444); module_param_named(swlps, rtl92ee_mod_params.swctrl_lps, bool, 0444); module_param_named(fwlps, rtl92ee_mod_params.fwctrl_lps, bool, 0444); @@ -380,7 +380,8 @@ MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n"); -MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)"); MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n"); static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c index 3c66d00abbac..2006b09ea74f 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c @@ -178,8 +178,6 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) rtlpci->first_init = true; - /* for debug level */ - rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug; /* for LPS & IPS */ rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; @@ -297,7 +295,8 @@ static struct rtl_mod_params rtl92se_mod_params = { .inactiveps = true, .swctrl_lps = true, .fwctrl_lps = false, - .debug = 0, + .debug_level = 0, + .debug_mask = 0, }; /* Because memory R/W bursting will cause system hang/crash @@ -416,7 +415,8 @@ MODULE_DESCRIPTION("Realtek 8192S/8191S 802.11n PCI wireless"); MODULE_FIRMWARE("rtlwifi/rtl8192sefw.bin"); module_param_named(swenc, rtl92se_mod_params.sw_crypto, bool, 0444); -module_param_named(debug, rtl92se_mod_params.debug, int, 0444); +module_param_named(debug_level, rtl92se_mod_params.debug_level, int, 0644); +module_param_named(debug_mask, rtl92se_mod_params.debug_mask, ullong, 0644); module_param_named(ips, rtl92se_mod_params.inactiveps, bool, 0444); module_param_named(swlps, rtl92se_mod_params.swctrl_lps, bool, 0444); module_param_named(fwlps, rtl92se_mod_params.fwctrl_lps, bool, 0444); @@ -424,7 +424,8 @@ MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n"); MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 1)\n"); MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 0)\n"); -MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)"); static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c index 401f54266f15..7bf9f2557920 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723ae/sw.c @@ -145,8 +145,6 @@ int rtl8723e_init_sw_vars(struct ieee80211_hw *hw) (u32)(PHIMR_RXFOVW | 0); - /* for debug level */ - rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug; /* for LPS & IPS */ rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; @@ -268,7 +266,8 @@ static struct rtl_mod_params rtl8723e_mod_params = { .inactiveps = true, .swctrl_lps = false, .fwctrl_lps = true, - .debug = 0, + .debug_level = 0, + .debug_mask = 0, .msi_support = false, .disable_watchdog = false, }; @@ -382,7 +381,8 @@ MODULE_DESCRIPTION("Realtek 8723E 802.11n PCI wireless"); MODULE_FIRMWARE("rtlwifi/rtl8723efw.bin"); module_param_named(swenc, rtl8723e_mod_params.sw_crypto, bool, 0444); -module_param_named(debug, rtl8723e_mod_params.debug, int, 0444); +module_param_named(debug_level, rtl8723e_mod_params.debug_level, int, 0644); +module_param_named(debug_mask, rtl8723e_mod_params.debug_mask, ullong, 0644); module_param_named(ips, rtl8723e_mod_params.inactiveps, bool, 0444); module_param_named(swlps, rtl8723e_mod_params.swctrl_lps, bool, 0444); module_param_named(fwlps, rtl8723e_mod_params.fwctrl_lps, bool, 0444); @@ -394,7 +394,8 @@ MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 0)\n"); -MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)"); MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n"); static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c index dd42c1a6d986..e571b876f0af 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c @@ -144,8 +144,6 @@ int rtl8723be_init_sw_vars(struct ieee80211_hw *hw) HSIMR_RON_INT_EN | 0); - /* for debug level */ - rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug; /* for LPS & IPS */ rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; @@ -271,7 +269,8 @@ static struct rtl_mod_params rtl8723be_mod_params = { .fwctrl_lps = true, .msi_support = false, .disable_watchdog = false, - .debug = 0, + .debug_level = 0, + .debug_mask = 0, .ant_sel = 0, }; @@ -386,7 +385,8 @@ MODULE_DESCRIPTION("Realtek 8723BE 802.11n PCI wireless"); MODULE_FIRMWARE("rtlwifi/rtl8723befw.bin"); module_param_named(swenc, rtl8723be_mod_params.sw_crypto, bool, 0444); -module_param_named(debug, rtl8723be_mod_params.debug, int, 0444); +module_param_named(debug_level, rtl8723be_mod_params.debug_level, int, 0644); +module_param_named(debug_mask, rtl8723be_mod_params.debug_mask, ullong, 0644); module_param_named(ips, rtl8723be_mod_params.inactiveps, bool, 0444); module_param_named(swlps, rtl8723be_mod_params.swctrl_lps, bool, 0444); module_param_named(fwlps, rtl8723be_mod_params.fwctrl_lps, bool, 0444); @@ -399,7 +399,8 @@ MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 0)\n"); -MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)"); MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n"); MODULE_PARM_DESC(ant_sel, "Set to 1 or 2 to force antenna number (default 0)\n"); diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.c index 8e0d038df701..ac573d69f6d6 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.c @@ -26,6 +26,7 @@ #include "../wifi.h" #include "../pci.h" #include "../base.h" +#include "../efuse.h" #include "fw_common.h" #include <linux/module.h> @@ -53,65 +54,6 @@ void rtl8723_enable_fw_download(struct ieee80211_hw *hw, bool enable) } EXPORT_SYMBOL_GPL(rtl8723_enable_fw_download); -void rtl8723_fw_block_write(struct ieee80211_hw *hw, - const u8 *buffer, u32 size) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 blocksize = sizeof(u32); - u8 *bufferptr = (u8 *)buffer; - u32 *pu4byteptr = (u32 *)buffer; - u32 i, offset, blockcount, remainsize; - - blockcount = size / blocksize; - remainsize = size % blocksize; - - for (i = 0; i < blockcount; i++) { - offset = i * blocksize; - rtl_write_dword(rtlpriv, (FW_8192C_START_ADDRESS + offset), - *(pu4byteptr + i)); - } - if (remainsize) { - offset = blockcount * blocksize; - bufferptr += offset; - for (i = 0; i < remainsize; i++) { - rtl_write_byte(rtlpriv, - (FW_8192C_START_ADDRESS + offset + i), - *(bufferptr + i)); - } - } -} -EXPORT_SYMBOL_GPL(rtl8723_fw_block_write); - -void rtl8723_fw_page_write(struct ieee80211_hw *hw, - u32 page, const u8 *buffer, u32 size) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 value8; - u8 u8page = (u8) (page & 0x07); - - value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page; - - rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8); - rtl8723_fw_block_write(hw, buffer, size); -} -EXPORT_SYMBOL_GPL(rtl8723_fw_page_write); - -void rtl8723_fill_dummy(u8 *pfwbuf, u32 *pfwlen) -{ - u32 fwlen = *pfwlen; - u8 remain = (u8) (fwlen % 4); - - remain = (remain == 0) ? 0 : (4 - remain); - - while (remain > 0) { - pfwbuf[fwlen] = 0; - fwlen++; - remain--; - } - *pfwlen = fwlen; -} -EXPORT_SYMBOL(rtl8723_fill_dummy); - void rtl8723_write_fw(struct ieee80211_hw *hw, enum version_8723e version, u8 *buffer, u32 size, u8 max_page) @@ -123,7 +65,7 @@ void rtl8723_write_fw(struct ieee80211_hw *hw, RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size); - rtl8723_fill_dummy(bufferptr, &size); + rtl_fill_dummy(bufferptr, &size); page_nums = size / FW_8192C_PAGE_SIZE; remain_size = size % FW_8192C_PAGE_SIZE; @@ -134,15 +76,14 @@ void rtl8723_write_fw(struct ieee80211_hw *hw, } for (page = 0; page < page_nums; page++) { offset = page * FW_8192C_PAGE_SIZE; - rtl8723_fw_page_write(hw, page, (bufferptr + offset), - FW_8192C_PAGE_SIZE); + rtl_fw_page_write(hw, page, (bufferptr + offset), + FW_8192C_PAGE_SIZE); } if (remain_size) { offset = page_nums * FW_8192C_PAGE_SIZE; page = page_nums; - rtl8723_fw_page_write(hw, page, (bufferptr + offset), - remain_size); + rtl_fw_page_write(hw, page, (bufferptr + offset), remain_size); } RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW write done.\n"); } diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.h b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.h index 8ea372d1626e..77c25a976233 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.h +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723com/fw_common.h @@ -28,7 +28,6 @@ #define REG_SYS_FUNC_EN 0x0002 #define REG_MCUFWDL 0x0080 -#define FW_8192C_START_ADDRESS 0x1000 #define FW_8192C_PAGE_SIZE 4096 #define FW_8723A_POLLING_TIMEOUT_COUNT 1000 #define FW_8723B_POLLING_TIMEOUT_COUNT 6000 @@ -84,10 +83,6 @@ enum rtl8723be_cmd { void rtl8723ae_firmware_selfreset(struct ieee80211_hw *hw); void rtl8723be_firmware_selfreset(struct ieee80211_hw *hw); void rtl8723_enable_fw_download(struct ieee80211_hw *hw, bool enable); -void rtl8723_fw_block_write(struct ieee80211_hw *hw, - const u8 *buffer, u32 size); -void rtl8723_fw_page_write(struct ieee80211_hw *hw, - u32 page, const u8 *buffer, u32 size); void rtl8723_write_fw(struct ieee80211_hw *hw, enum version_8723e version, u8 *buffer, u32 size, u8 max_page); @@ -95,6 +90,5 @@ int rtl8723_fw_free_to_go(struct ieee80211_hw *hw, bool is_8723be, int count); int rtl8723_download_fw(struct ieee80211_hw *hw, bool is_8723be, int count); bool rtl8723_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb); -void rtl8723_fill_dummy(u8 *pfwbuf, u32 *pfwlen); #endif diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c index 94e97dce5457..328c64d465ba 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/fw.c @@ -27,6 +27,7 @@ #include "../pci.h" #include "../base.h" #include "../core.h" +#include "../efuse.h" #include "reg.h" #include "def.h" #include "fw.h" @@ -51,63 +52,6 @@ static void _rtl8821ae_enable_fw_download(struct ieee80211_hw *hw, bool enable) } } -static void _rtl8821ae_fw_block_write(struct ieee80211_hw *hw, - const u8 *buffer, u32 size) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 blocksize = sizeof(u32); - u8 *bufferptr = (u8 *)buffer; - u32 *pu4byteptr = (u32 *)buffer; - u32 i, offset, blockcount, remainsize; - - blockcount = size / blocksize; - remainsize = size % blocksize; - - for (i = 0; i < blockcount; i++) { - offset = i * blocksize; - rtl_write_dword(rtlpriv, (FW_8821AE_START_ADDRESS + offset), - *(pu4byteptr + i)); - } - - if (remainsize) { - offset = blockcount * blocksize; - bufferptr += offset; - for (i = 0; i < remainsize; i++) { - rtl_write_byte(rtlpriv, (FW_8821AE_START_ADDRESS + - offset + i), *(bufferptr + i)); - } - } -} - -static void _rtl8821ae_fw_page_write(struct ieee80211_hw *hw, - u32 page, const u8 *buffer, u32 size) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u8 value8; - u8 u8page = (u8)(page & 0x07); - - value8 = (rtl_read_byte(rtlpriv, REG_MCUFWDL + 2) & 0xF8) | u8page; - - rtl_write_byte(rtlpriv, (REG_MCUFWDL + 2), value8); - _rtl8821ae_fw_block_write(hw, buffer, size); -} - -static void _rtl8821ae_fill_dummy(u8 *pfwbuf, u32 *pfwlen) -{ - u32 fwlen = *pfwlen; - u8 remain = (u8)(fwlen % 4); - - remain = (remain == 0) ? 0 : (4 - remain); - - while (remain > 0) { - pfwbuf[fwlen] = 0; - fwlen++; - remain--; - } - - *pfwlen = fwlen; -} - static void _rtl8821ae_write_fw(struct ieee80211_hw *hw, enum version_8821ae version, u8 *buffer, u32 size) @@ -119,7 +63,7 @@ static void _rtl8821ae_write_fw(struct ieee80211_hw *hw, RT_TRACE(rtlpriv, COMP_FW, DBG_LOUD, "FW size is %d bytes,\n", size); - _rtl8821ae_fill_dummy(bufferptr, &size); + rtl_fill_dummy(bufferptr, &size); pagenums = size / FW_8821AE_PAGE_SIZE; remainsize = size % FW_8821AE_PAGE_SIZE; @@ -129,15 +73,14 @@ static void _rtl8821ae_write_fw(struct ieee80211_hw *hw, for (page = 0; page < pagenums; page++) { offset = page * FW_8821AE_PAGE_SIZE; - _rtl8821ae_fw_page_write(hw, page, (bufferptr + offset), - FW_8821AE_PAGE_SIZE); + rtl_fw_page_write(hw, page, (bufferptr + offset), + FW_8821AE_PAGE_SIZE); } if (remainsize) { offset = pagenums * FW_8821AE_PAGE_SIZE; page = pagenums; - _rtl8821ae_fw_page_write(hw, page, (bufferptr + offset), - remainsize); + rtl_fw_page_write(hw, page, (bufferptr + offset), remainsize); } } diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c index 220de5f89dbc..cd2a53b7e053 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/sw.c @@ -160,8 +160,6 @@ int rtl8821ae_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->psc.wo_wlan_mode = WAKE_ON_MAGIC_PACKET | WAKE_ON_PATTERN_MATCH; - /* for debug level */ - rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug; /* for LPS & IPS */ rtlpriv->psc.inactiveps = rtlpriv->cfg->mod_params->inactiveps; rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; @@ -309,7 +307,8 @@ static struct rtl_mod_params rtl8821ae_mod_params = { .fwctrl_lps = true, .msi_support = true, .int_clear = true, - .debug = 0, + .debug_level = 0, + .debug_mask = 0, .disable_watchdog = 0, }; @@ -430,7 +429,8 @@ MODULE_DESCRIPTION("Realtek 8821ae 802.11ac PCI wireless"); MODULE_FIRMWARE("rtlwifi/rtl8821aefw.bin"); module_param_named(swenc, rtl8821ae_mod_params.sw_crypto, bool, 0444); -module_param_named(debug, rtl8821ae_mod_params.debug, int, 0444); +module_param_named(debug_level, rtl8821ae_mod_params.debug_level, int, 0644); +module_param_named(debug_mask, rtl8821ae_mod_params.debug_mask, ullong, 0644); module_param_named(ips, rtl8821ae_mod_params.inactiveps, bool, 0444); module_param_named(swlps, rtl8821ae_mod_params.swctrl_lps, bool, 0444); module_param_named(fwlps, rtl8821ae_mod_params.fwctrl_lps, bool, 0444); @@ -443,7 +443,8 @@ MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 1)\n"); -MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_level, "Set debug level (0-5) (default 0)"); +MODULE_PARM_DESC(debug_mask, "Set debug mask (default 0)"); MODULE_PARM_DESC(disable_watchdog, "Set to 1 to disable the watchdog (default 0)\n"); MODULE_PARM_DESC(int_clear, "Set to 0 to disable interrupt clear before set (default 1)\n"); diff --git a/drivers/net/wireless/realtek/rtlwifi/usb.c b/drivers/net/wireless/realtek/rtlwifi/usb.c index b2b62ef8b07d..44bdb2bdeeb1 100644 --- a/drivers/net/wireless/realtek/rtlwifi/usb.c +++ b/drivers/net/wireless/realtek/rtlwifi/usb.c @@ -818,12 +818,30 @@ static void rtl_usb_stop(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); + struct urb *urb; /* should after adapter start and interrupt enable. */ set_hal_stop(rtlhal); cancel_work_sync(&rtlpriv->works.fill_h2c_cmd); /* Enable software */ SET_USB_STOP(rtlusb); + + /* free pre-allocated URBs from rtl_usb_start() */ + usb_kill_anchored_urbs(&rtlusb->rx_submitted); + + tasklet_kill(&rtlusb->rx_work_tasklet); + cancel_work_sync(&rtlpriv->works.lps_change_work); + + flush_workqueue(rtlpriv->works.rtl_wq); + + skb_queue_purge(&rtlusb->rx_queue); + + while ((urb = usb_get_from_anchor(&rtlusb->rx_cleanup_urbs))) { + usb_free_coherent(urb->dev, urb->transfer_buffer_length, + urb->transfer_buffer, urb->transfer_dma); + usb_free_urb(urb); + } + rtlpriv->cfg->ops->hw_disable(hw); } @@ -1073,7 +1091,6 @@ int rtl_usb_probe(struct usb_interface *intf, rtlpriv->rtlhal.interface = INTF_USB; rtlpriv->cfg = rtl_hal_cfg; rtlpriv->intf_ops = &rtl_usb_ops; - rtl_dbgp_flag_init(hw); /* Init IO handler */ _rtl_usb_io_handler_init(&udev->dev, hw); rtlpriv->cfg->ops->read_chip_version(hw); diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h index dafe486f8448..310fa90200b2 100644 --- a/drivers/net/wireless/realtek/rtlwifi/wifi.h +++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h @@ -2221,11 +2221,13 @@ struct rtl_intf_ops { }; struct rtl_mod_params { + /* default: 0,0 */ + u64 debug_mask; /* default: 0 = using hardware encryption */ bool sw_crypto; /* default: 0 = DBG_EMERG (0)*/ - int debug; + int debug_level; /* default: 1 = using no linked power save */ bool inactiveps; @@ -2345,16 +2347,6 @@ struct rtl_works { struct work_struct fill_h2c_cmd; }; -struct rtl_debug { - u32 dbgp_type[DBGP_TYPE_MAX]; - int global_debuglevel; - u64 global_debugcomponents; - - /* add for proc debug */ - struct proc_dir_entry *proc_dir; - char proc_name[20]; -}; - #define MIMO_PS_STATIC 0 #define MIMO_PS_DYNAMIC 1 #define MIMO_PS_NOLIMIT 3 @@ -2583,7 +2575,6 @@ struct rtl_priv { /* sta entry list for ap adhoc or mesh */ struct list_head entry_list; - struct rtl_debug dbg; int max_fw_size; /* @@ -2713,23 +2704,14 @@ enum bt_radio_shared { (le32_to_cpu(_val)) /* Read data from memory */ -#define READEF1BYTE(_ptr) \ +#define READEF1BYTE(_ptr) \ EF1BYTE(*((u8 *)(_ptr))) /* Read le16 data from memory and convert to host ordering */ -#define READEF2BYTE(_ptr) \ +#define READEF2BYTE(_ptr) \ EF2BYTE(*(_ptr)) -#define READEF4BYTE(_ptr) \ +#define READEF4BYTE(_ptr) \ EF4BYTE(*(_ptr)) -/* Write data to memory */ -#define WRITEEF1BYTE(_ptr, _val) \ - (*((u8 *)(_ptr))) = EF1BYTE(_val) -/* Write le16 data to memory in host ordering */ -#define WRITEEF2BYTE(_ptr, _val) \ - (*((u16 *)(_ptr))) = EF2BYTE(_val) -#define WRITEEF4BYTE(_ptr, _val) \ - (*((u32 *)(_ptr))) = EF2BYTE(_val) - /* Create a bit mask * Examples: * BIT_LEN_MASK_32(0) => 0x00000000 @@ -2810,14 +2792,14 @@ value to host byte ordering.*/ * Set subfield of little-endian 4-byte value to specified value. */ #define SET_BITS_TO_LE_4BYTE(__pstart, __bitoffset, __bitlen, __val) \ - *((u32 *)(__pstart)) = \ - ( \ + *((__le32 *)(__pstart)) = \ + cpu_to_le32( \ LE_BITS_CLEARED_TO_4BYTE(__pstart, __bitoffset, __bitlen) | \ ((((u32)__val) & BIT_LEN_MASK_32(__bitlen)) << (__bitoffset)) \ ); #define SET_BITS_TO_LE_2BYTE(__pstart, __bitoffset, __bitlen, __val) \ - *((u16 *)(__pstart)) = \ - ( \ + *((__le16 *)(__pstart)) = \ + cpu_to_le16( \ LE_BITS_CLEARED_TO_2BYTE(__pstart, __bitoffset, __bitlen) | \ ((((u16)__val) & BIT_LEN_MASK_16(__bitlen)) << (__bitoffset)) \ ); diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c index 47fe7f96a242..287023ef4a78 100644 --- a/drivers/net/wireless/ti/wlcore/sdio.c +++ b/drivers/net/wireless/ti/wlcore/sdio.c @@ -81,13 +81,6 @@ static int __must_check wl12xx_sdio_raw_read(struct device *child, int addr, sdio_claim_host(func); - if (unlikely(dump)) { - printk(KERN_DEBUG "wlcore_sdio: READ from 0x%04x\n", addr); - print_hex_dump(KERN_DEBUG, "wlcore_sdio: READ ", - DUMP_PREFIX_OFFSET, 16, 1, - buf, len, false); - } - if (unlikely(addr == HW_ACCESS_ELP_CTRL_REG)) { ((u8 *)buf)[0] = sdio_f0_readb(func, addr, &ret); dev_dbg(child->parent, "sdio read 52 addr 0x%x, byte 0x%02x\n", @@ -107,6 +100,13 @@ static int __must_check wl12xx_sdio_raw_read(struct device *child, int addr, if (WARN_ON(ret)) dev_err(child->parent, "sdio read failed (%d)\n", ret); + if (unlikely(dump)) { + printk(KERN_DEBUG "wlcore_sdio: READ from 0x%04x\n", addr); + print_hex_dump(KERN_DEBUG, "wlcore_sdio: READ ", + DUMP_PREFIX_OFFSET, 16, 1, + buf, len, false); + } + return ret; } |