From 5b112d3d098c97b867cc580f590395cd1e72f18c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 1 Feb 2013 01:49:58 +0100 Subject: cfg80211: pass wiphy to cfg80211_ref_bss/put_bss This prepares for using the spinlock instead of krefs which is needed in the next patch to track the refs of combined BSSes correctly. Acked-by: Bing Zhao [mwifiex] Signed-off-by: Johannes Berg --- drivers/net/wireless/mwifiex/cfg80211.c | 2 +- drivers/net/wireless/mwifiex/scan.c | 2 +- drivers/net/wireless/mwifiex/sta_ioctl.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net/wireless/mwifiex') diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 3a004b85b99..81c84a29308 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1430,7 +1430,7 @@ static int mwifiex_cfg80211_inform_ibss_bss(struct mwifiex_private *priv) bss = cfg80211_inform_bss(priv->wdev->wiphy, chan, bss_info.bssid, 0, WLAN_CAPABILITY_IBSS, 0, ie_buf, ie_len, 0, GFP_KERNEL); - cfg80211_put_bss(bss); + cfg80211_put_bss(priv->wdev->wiphy, bss); memcpy(priv->cfg_bssid, bss_info.bssid, ETH_ALEN); return 0; diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 9189a32b784..23249248752 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -1746,7 +1746,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, .mac_address, ETH_ALEN)) mwifiex_update_curr_bss_params(priv, bss); - cfg80211_put_bss(bss); + cfg80211_put_bss(priv->wdev->wiphy, bss); } } else { dev_dbg(adapter->dev, "missing BSS channel IE\n"); diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index f542bb8ccbc..ee85b41a4df 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -324,7 +324,7 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, } if (bss) - cfg80211_put_bss(bss); + cfg80211_put_bss(priv->adapter->wiphy, bss); } else { /* Adhoc mode */ /* If the requested SSID matches current SSID, return */ @@ -354,7 +354,7 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, " list. Joining...\n"); ret = mwifiex_adhoc_join(priv, bss_desc); if (bss) - cfg80211_put_bss(bss); + cfg80211_put_bss(priv->adapter->wiphy, bss); } else { dev_dbg(adapter->dev, "info: Network not found in " "the list, creating adhoc with ssid = %s\n", -- cgit v1.2.3-70-g09d2 From 83c7aa1a1475ae1c42640ab6e4559016142efc67 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Feb 2013 16:51:29 +0100 Subject: cfg80211: remove scan ies NULL check There's no way scan BSS IEs can be NULL as even if the allocation fails the frame is discarded. Remove some code checking for this and document that it is always non-NULL. Signed-off-by: Johannes Berg --- drivers/net/wireless/mwifiex/sta_ioctl.c | 5 ----- include/net/cfg80211.h | 8 ++++---- net/wireless/scan.c | 11 +++-------- 3 files changed, 7 insertions(+), 17 deletions(-) (limited to 'drivers/net/wireless/mwifiex') diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index ee85b41a4df..8866a2b69c9 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -162,11 +162,6 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, rcu_read_lock(); ies = rcu_dereference(bss->ies); - if (WARN_ON(!ies)) { - /* should never happen */ - rcu_read_unlock(); - return -EINVAL; - } beacon_ie = kmemdup(ies->data, ies->len, GFP_ATOMIC); beacon_ie_len = ies->len; rcu_read_unlock(); diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 04a702d1f2a..fb766314b3a 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1287,10 +1287,10 @@ struct cfg80211_bss_ies { * @tsf: timestamp of last received update * @beacon_interval: the beacon interval as from the frame * @capability: the capability field in host byte order - * @ies: the information elements (Note that there - * is no guarantee that these are well-formed!); this is a pointer to - * either the beacon_ies or proberesp_ies depending on whether Probe - * Response frame has been received + * @ies: the information elements (Note that there is no guarantee that these + * are well-formed!); this is a pointer to either the beacon_ies or + * proberesp_ies depending on whether Probe Response frame has been + * received. It is always non-%NULL. * @beacon_ies: the information elements from the last Beacon frame * (implementation note: if @hidden_beacon_bss is set this struct doesn't * own the beacon_ies, but they're just pointers to the ones from the diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 5e0983d6042..02a238329c8 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -1293,15 +1293,10 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info, rcu_read_lock(); ies = rcu_dereference(bss->pub.ies); - if (ies) { - rem = ies->len; - ie = ies->data; - } else { - rem = 0; - ie = NULL; - } + rem = ies->len; + ie = ies->data; - while (ies && rem >= 2) { + while (rem >= 2) { /* invalid data */ if (ie[1] > rem - 2) break; -- cgit v1.2.3-70-g09d2 From 8cef2c9df88fdd13f518e6607de9d664b31f26cc Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 5 Feb 2013 16:54:31 +0100 Subject: cfg80211: move TSF into IEs While technically the TSF isn't an IE, it can be necessary to distinguish between the TSF from a beacon and a probe response, in particular in order to know the next DTIM TBTT, as not all APs are spec compliant wrt. TSF==0 being a DTIM TBTT and thus the DTIM count needs to be taken into account as well. To allow this, move the TSF into the IE struct so it can be known whence it came. Signed-off-by: Johannes Berg --- drivers/net/wireless/mwifiex/sta_ioctl.c | 2 +- include/net/cfg80211.h | 5 ++--- net/mac80211/ibss.c | 14 ++++++++++---- net/mac80211/mlme.c | 6 +++++- net/wireless/nl80211.c | 27 ++++++++++++++++----------- net/wireless/scan.c | 7 +++---- 6 files changed, 37 insertions(+), 24 deletions(-) (limited to 'drivers/net/wireless/mwifiex') diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 8866a2b69c9..0d018460daf 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -164,6 +164,7 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, ies = rcu_dereference(bss->ies); beacon_ie = kmemdup(ies->data, ies->len, GFP_ATOMIC); beacon_ie_len = ies->len; + bss_desc->timestamp = ies->tsf; rcu_read_unlock(); if (!beacon_ie) { @@ -179,7 +180,6 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv, bss_desc->cap_info_bitmap = bss->capability; bss_desc->bss_band = bss_priv->band; bss_desc->fw_tsf = bss_priv->fw_tsf; - bss_desc->timestamp = bss->tsf; if (bss_desc->cap_info_bitmap & WLAN_CAPABILITY_PRIVACY) { dev_dbg(priv->adapter->dev, "info: InterpretIE: AP WEP enabled\n"); bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP; diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index fb766314b3a..77686ca2894 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1266,11 +1266,13 @@ enum cfg80211_signal_type { /** * struct cfg80211_bss_ie_data - BSS entry IE data + * @tsf: TSF contained in the frame that carried these IEs * @rcu_head: internal use, for freeing * @len: length of the IEs * @data: IE data */ struct cfg80211_bss_ies { + u64 tsf; struct rcu_head rcu_head; int len; u8 data[]; @@ -1284,7 +1286,6 @@ struct cfg80211_bss_ies { * * @channel: channel this BSS is on * @bssid: BSSID of the BSS - * @tsf: timestamp of last received update * @beacon_interval: the beacon interval as from the frame * @capability: the capability field in host byte order * @ies: the information elements (Note that there is no guarantee that these @@ -1304,8 +1305,6 @@ struct cfg80211_bss_ies { * @priv: private area for driver use, has at least wiphy->bss_priv_size bytes */ struct cfg80211_bss { - u64 tsf; - struct ieee80211_channel *channel; const struct cfg80211_bss_ies __rcu *ies; diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 71c55cc0f7b..055fa9436e9 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c @@ -242,6 +242,8 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, u32 basic_rates; int i, j; u16 beacon_int = cbss->beacon_interval; + const struct cfg80211_bss_ies *ies; + u64 tsf; lockdep_assert_held(&sdata->u.ibss.mtx); @@ -265,13 +267,17 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, } } + rcu_read_lock(); + ies = rcu_dereference(cbss->ies); + tsf = ies->tsf; + rcu_read_unlock(); + __ieee80211_sta_join_ibss(sdata, cbss->bssid, beacon_int, cbss->channel, basic_rates, cbss->capability, - cbss->tsf, - false); + tsf, false); } static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, @@ -535,8 +541,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, cbss = container_of((void *)bss, struct cfg80211_bss, priv); - /* was just updated in ieee80211_bss_info_update */ - beacon_timestamp = cbss->tsf; + /* same for beacon and probe response */ + beacon_timestamp = le64_to_cpu(mgmt->u.beacon.timestamp); /* check if we need to merge IBSS */ diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 40ce00c6d4c..51eca5a0cda 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -3667,6 +3667,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, bool have_higher_than_11mbit; int min_rate = INT_MAX, min_rate_index = -1; struct ieee80211_supported_band *sband; + const struct cfg80211_bss_ies *ies; sband = local->hw.wiphy->bands[cbss->channel->band]; @@ -3710,7 +3711,10 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, /* set timing information */ sdata->vif.bss_conf.beacon_int = cbss->beacon_interval; - sdata->vif.bss_conf.sync_tsf = cbss->tsf; + rcu_read_lock(); + ies = rcu_dereference(cbss->ies); + sdata->vif.bss_conf.sync_tsf = ies->tsf; + rcu_read_unlock(); sdata->vif.bss_conf.sync_device_ts = bss->device_ts; /* tell driver about BSSID, basic rates and timing */ diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 807d448e702..93bc63eae07 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -4997,6 +4997,7 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, const struct cfg80211_bss_ies *ies; void *hdr; struct nlattr *bss; + bool tsf = false; ASSERT_WDEV_LOCK(wdev); @@ -5020,22 +5021,24 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, rcu_read_lock(); ies = rcu_dereference(res->ies); - if (ies && ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS, - ies->len, ies->data)) { - rcu_read_unlock(); - goto nla_put_failure; + if (ies) { + if (nla_put_u64(msg, NL80211_BSS_TSF, ies->tsf)) + goto fail_unlock_rcu; + tsf = true; + if (ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS, + ies->len, ies->data)) + goto fail_unlock_rcu; } ies = rcu_dereference(res->beacon_ies); - if (ies && ies->len && nla_put(msg, NL80211_BSS_BEACON_IES, - ies->len, ies->data)) { - rcu_read_unlock(); - goto nla_put_failure; + if (ies) { + if (!tsf && nla_put_u64(msg, NL80211_BSS_TSF, ies->tsf)) + goto fail_unlock_rcu; + if (ies->len && nla_put(msg, NL80211_BSS_BEACON_IES, + ies->len, ies->data)) + goto fail_unlock_rcu; } rcu_read_unlock(); - if (res->tsf && - nla_put_u64(msg, NL80211_BSS_TSF, res->tsf)) - goto nla_put_failure; if (res->beacon_interval && nla_put_u16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval)) goto nla_put_failure; @@ -5080,6 +5083,8 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, return genlmsg_end(msg, hdr); + fail_unlock_rcu: + rcu_read_unlock(); nla_put_failure: genlmsg_cancel(msg, hdr); return -EMSGSIZE; diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 02a238329c8..b7a16798498 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -695,7 +695,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev, if (found) { found->pub.beacon_interval = tmp->pub.beacon_interval; - found->pub.tsf = tmp->pub.tsf; found->pub.signal = tmp->pub.signal; found->pub.capability = tmp->pub.capability; found->ts = tmp->ts; @@ -880,7 +879,6 @@ cfg80211_inform_bss(struct wiphy *wiphy, memcpy(tmp.pub.bssid, bssid, ETH_ALEN); tmp.pub.channel = channel; tmp.pub.signal = signal; - tmp.pub.tsf = tsf; tmp.pub.beacon_interval = beacon_interval; tmp.pub.capability = capability; /* @@ -895,6 +893,7 @@ cfg80211_inform_bss(struct wiphy *wiphy, if (!ies) return NULL; ies->len = ielen; + ies->tsf = tsf; memcpy(ies->data, ie, ielen); rcu_assign_pointer(tmp.pub.beacon_ies, ies); @@ -951,6 +950,7 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, if (!ies) return NULL; ies->len = ielen; + ies->tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp); memcpy(ies->data, mgmt->u.probe_resp.variable, ielen); if (ieee80211_is_probe_resp(mgmt->frame_control)) @@ -962,7 +962,6 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, memcpy(tmp.pub.bssid, mgmt->bssid, ETH_ALEN); tmp.pub.channel = channel; tmp.pub.signal = signal; - tmp.pub.tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp); tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int); tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info); @@ -1409,7 +1408,7 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info, if (buf) { memset(&iwe, 0, sizeof(iwe)); iwe.cmd = IWEVCUSTOM; - sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->pub.tsf)); + sprintf(buf, "tsf=%016llx", (unsigned long long)(ies->tsf)); iwe.u.data.length = strlen(buf); current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, buf); -- cgit v1.2.3-70-g09d2 From dd04e6acd828d51255fbb2d9b7b0e5b85df04f0b Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Fri, 8 Feb 2013 18:18:06 -0800 Subject: mwifiex: store card specific data in PCI device table entry This patch adds support for storing PCIe device specific data into driver_data structure of pci_device_id. When a device with known device_id is probed, we use this driver_data to populate card specific structres in driver. This enables to remove device specific defines for scratch registers, firmware name, FW download block size, etc. from source code. This will make addition of support for new chipsets a lot easier. Signed-off-by: Avinash Patil Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/pcie.c | 211 +++++++++++++++++++++--------------- drivers/net/wireless/mwifiex/pcie.h | 113 ++++++++++++++----- 2 files changed, 206 insertions(+), 118 deletions(-) (limited to 'drivers/net/wireless/mwifiex') diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index df88e65595c..29c539b9424 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c @@ -94,6 +94,13 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev, card->dev = pdev; + if (ent->driver_data) { + struct mwifiex_pcie_device *data = (void *)ent->driver_data; + card->pcie.firmware = data->firmware; + card->pcie.reg = data->reg; + card->pcie.blksz_fw_dl = data->blksz_fw_dl; + } + if (mwifiex_add_card(card, &add_remove_card_sem, &pcie_ops, MWIFIEX_PCIE)) { pr_err("%s failed\n", __func__); @@ -237,6 +244,7 @@ static DEFINE_PCI_DEVICE_TABLE(mwifiex_ids) = { { PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P, PCI_ANY_ID, PCI_ANY_ID, 0, 0, + .driver_data = (unsigned long) &mwifiex_pcie8766, }, {}, }; @@ -369,6 +377,7 @@ static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter) static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; int i; /* @@ -377,7 +386,7 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) * starts at zero with rollover bit set */ card->txbd_wrptr = 0; - card->txbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND; + card->txbd_rdptr |= reg->tx_rollover_ind; /* allocate shared memory for the BD ring and divide the same in to several descriptors */ @@ -417,6 +426,7 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; struct sk_buff *skb; int i; @@ -440,7 +450,7 @@ static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter) card->txbd_ring_pbase); card->txbd_ring_size = 0; card->txbd_wrptr = 0; - card->txbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND; + card->txbd_rdptr = 0 | reg->tx_rollover_ind; card->txbd_ring_vbase = NULL; card->txbd_ring_pbase = 0; @@ -453,6 +463,7 @@ static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter) static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; struct sk_buff *skb; int i; dma_addr_t buf_pa; @@ -463,7 +474,7 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) * starts at zero with rollover bit set */ card->rxbd_wrptr = 0; - card->rxbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND; + card->rxbd_rdptr = reg->rx_rollover_ind; card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * MWIFIEX_MAX_TXRX_BD; @@ -526,6 +537,7 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; struct sk_buff *skb; int i; @@ -550,7 +562,7 @@ static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter) card->rxbd_ring_pbase); card->rxbd_ring_size = 0; card->rxbd_wrptr = 0; - card->rxbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND; + card->rxbd_rdptr = 0 | reg->rx_rollover_ind; card->rxbd_ring_vbase = NULL; card->rxbd_ring_pbase = 0; @@ -563,6 +575,7 @@ static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter) static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; struct sk_buff *skb; int i; dma_addr_t buf_pa; @@ -573,7 +586,7 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) * starts at zero with rollover bit set */ card->evtbd_wrptr = 0; - card->evtbd_rdptr |= MWIFIEX_BD_FLAG_ROLLOVER_IND; + card->evtbd_rdptr = reg->evt_rollover_ind; card->evtbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * MWIFIEX_MAX_EVT_BD; @@ -636,6 +649,7 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; struct sk_buff *skb; int i; @@ -658,7 +672,7 @@ static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter) card->evtbd_ring_vbase, card->evtbd_ring_pbase); card->evtbd_wrptr = 0; - card->evtbd_rdptr = 0 | MWIFIEX_BD_FLAG_ROLLOVER_IND; + card->evtbd_rdptr = 0 | reg->evt_rollover_ind; card->evtbd_ring_size = 0; card->evtbd_ring_vbase = NULL; card->evtbd_ring_pbase = 0; @@ -771,12 +785,13 @@ static int mwifiex_pcie_delete_sleep_cookie_buf(struct mwifiex_adapter *adapter) static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; u32 rdptr; /* Read the TX ring read pointer set by firmware */ - if (mwifiex_read_reg(adapter, REG_TXBD_RDPTR, &rdptr)) { + if (mwifiex_read_reg(adapter, reg->tx_rdptr, &rdptr)) { dev_err(adapter->dev, - "Flush TXBD: failed to read REG_TXBD_RDPTR\n"); + "Flush TXBD: failed to read reg->tx_rdptr\n"); return -1; } @@ -805,14 +820,15 @@ static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter) dma_addr_t buf_pa; u32 wrdoneidx, rdptr, unmap_count = 0; struct pcie_service_card *card = adapter->card; + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; if (!mwifiex_pcie_ok_to_access_hw(adapter)) mwifiex_pm_wakeup_card(adapter); /* Read the TX ring read pointer set by firmware */ - if (mwifiex_read_reg(adapter, REG_TXBD_RDPTR, &rdptr)) { + if (mwifiex_read_reg(adapter, reg->tx_rdptr, &rdptr)) { dev_err(adapter->dev, - "SEND COMP: failed to read REG_TXBD_RDPTR\n"); + "SEND COMP: failed to read reg->tx_rdptr\n"); return -1; } @@ -820,11 +836,11 @@ static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter) card->txbd_rdptr, rdptr); /* free from previous txbd_rdptr to current txbd_rdptr */ - while (((card->txbd_rdptr & MWIFIEX_TXBD_MASK) != - (rdptr & MWIFIEX_TXBD_MASK)) || - ((card->txbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) != - (rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) { - wrdoneidx = card->txbd_rdptr & MWIFIEX_TXBD_MASK; + while (((card->txbd_rdptr & reg->tx_mask) != + (rdptr & reg->tx_mask)) || + ((card->txbd_rdptr & reg->tx_rollover_ind) != + (rdptr & reg->tx_rollover_ind))) { + wrdoneidx = card->txbd_rdptr & reg->tx_mask; skb = card->tx_buf_list[wrdoneidx]; if (skb) { @@ -850,20 +866,20 @@ static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter) card->txbd_ring[wrdoneidx]->flags = 0; card->txbd_rdptr++; - if ((card->txbd_rdptr & MWIFIEX_TXBD_MASK) == num_tx_buffs) + if ((card->txbd_rdptr & reg->tx_mask) == num_tx_buffs) card->txbd_rdptr = ((card->txbd_rdptr & - MWIFIEX_BD_FLAG_ROLLOVER_IND) ^ - MWIFIEX_BD_FLAG_ROLLOVER_IND); + reg->tx_rollover_ind) ^ + reg->tx_rollover_ind); } if (unmap_count) adapter->data_sent = false; if (card->txbd_flush) { - if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) == - (card->txbd_rdptr & MWIFIEX_TXBD_MASK)) && - ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) != - (card->txbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) + if (((card->txbd_wrptr & reg->tx_mask) == + (card->txbd_rdptr & reg->tx_mask)) && + ((card->txbd_wrptr & reg->tx_rollover_ind) != + (card->txbd_rdptr & reg->tx_rollover_ind))) card->txbd_flush = 0; else mwifiex_clean_pcie_ring_buf(adapter); @@ -883,6 +899,7 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb, struct mwifiex_tx_param *tx_param) { struct pcie_service_card *card = adapter->card; + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; u32 wrindx; int ret; dma_addr_t buf_pa; @@ -913,7 +930,7 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb, PCI_DMA_TODEVICE)) return -1; - wrindx = card->txbd_wrptr & MWIFIEX_TXBD_MASK; + wrindx = card->txbd_wrptr & reg->tx_mask; MWIFIEX_SKB_PACB(skb, &buf_pa); card->tx_buf_list[wrindx] = skb; card->txbd_ring[wrindx]->paddr = buf_pa; @@ -921,17 +938,17 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb, card->txbd_ring[wrindx]->flags = MWIFIEX_BD_FLAG_FIRST_DESC | MWIFIEX_BD_FLAG_LAST_DESC; - if ((++card->txbd_wrptr & MWIFIEX_TXBD_MASK) == + if ((++card->txbd_wrptr & reg->tx_mask) == MWIFIEX_MAX_TXRX_BD) card->txbd_wrptr = ((card->txbd_wrptr & - MWIFIEX_BD_FLAG_ROLLOVER_IND) ^ - MWIFIEX_BD_FLAG_ROLLOVER_IND); + reg->tx_rollover_ind) ^ + reg->tx_rollover_ind); - /* Write the TX ring write pointer in to REG_TXBD_WRPTR */ - if (mwifiex_write_reg(adapter, REG_TXBD_WRPTR, + /* Write the TX ring write pointer in to reg->tx_wrptr */ + if (mwifiex_write_reg(adapter, reg->tx_wrptr, card->txbd_wrptr)) { dev_err(adapter->dev, - "SEND DATA: failed to write REG_TXBD_WRPTR\n"); + "SEND DATA: failed to write reg->tx_wrptr\n"); ret = -1; goto done_unmap; } @@ -984,6 +1001,7 @@ done_unmap: static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; u32 wrptr, rd_index; dma_addr_t buf_pa; int ret = 0; @@ -993,23 +1011,23 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) mwifiex_pm_wakeup_card(adapter); /* Read the RX ring Write pointer set by firmware */ - if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) { + if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) { dev_err(adapter->dev, - "RECV DATA: failed to read REG_TXBD_RDPTR\n"); + "RECV DATA: failed to read reg->rx_wrptr\n"); ret = -1; goto done; } card->rxbd_wrptr = wrptr; - while (((wrptr & MWIFIEX_RXBD_MASK) != - (card->rxbd_rdptr & MWIFIEX_RXBD_MASK)) || - ((wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) == - (card->rxbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) { + while (((wrptr & reg->rx_mask) != + (card->rxbd_rdptr & reg->rx_mask)) || + ((wrptr & reg->rx_rollover_ind) == + (card->rxbd_rdptr & reg->rx_rollover_ind))) { struct sk_buff *skb_data; u16 rx_len; __le16 pkt_len; - rd_index = card->rxbd_rdptr & MWIFIEX_RXBD_MASK; + rd_index = card->rxbd_rdptr & reg->rx_mask; skb_data = card->rx_buf_list[rd_index]; MWIFIEX_SKB_PACB(skb_data, &buf_pa); @@ -1051,28 +1069,28 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) card->rxbd_ring[rd_index]->len = skb_tmp->len; card->rxbd_ring[rd_index]->flags = 0; - if ((++card->rxbd_rdptr & MWIFIEX_RXBD_MASK) == + if ((++card->rxbd_rdptr & reg->rx_mask) == MWIFIEX_MAX_TXRX_BD) { card->rxbd_rdptr = ((card->rxbd_rdptr & - MWIFIEX_BD_FLAG_ROLLOVER_IND) ^ - MWIFIEX_BD_FLAG_ROLLOVER_IND); + reg->rx_rollover_ind) ^ + reg->rx_rollover_ind); } dev_dbg(adapter->dev, "info: RECV DATA: \n", card->rxbd_rdptr, wrptr); - /* Write the RX ring read pointer in to REG_RXBD_RDPTR */ - if (mwifiex_write_reg(adapter, REG_RXBD_RDPTR, + /* Write the RX ring read pointer in to reg->rx_rdptr */ + if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr)) { dev_err(adapter->dev, - "RECV DATA: failed to write REG_RXBD_RDPTR\n"); + "RECV DATA: failed to write reg->rx_rdptr\n"); ret = -1; goto done; } /* Read the RX ring Write pointer set by firmware */ - if (mwifiex_read_reg(adapter, REG_RXBD_WRPTR, &wrptr)) { + if (mwifiex_read_reg(adapter, reg->rx_wrptr, &wrptr)) { dev_err(adapter->dev, - "RECV DATA: failed to read REG_TXBD_RDPTR\n"); + "RECV DATA: failed to read reg->rx_wrptr\n"); ret = -1; goto done; } @@ -1093,6 +1111,7 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) { dma_addr_t buf_pa; struct pcie_service_card *card = adapter->card; + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; if (!(skb->data && skb->len)) { dev_err(adapter->dev, @@ -1106,9 +1125,10 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) MWIFIEX_SKB_PACB(skb, &buf_pa); - /* Write the lower 32bits of the physical address to scratch - * register 0 */ - if (mwifiex_write_reg(adapter, PCIE_SCRATCH_0_REG, (u32)buf_pa)) { + /* Write the lower 32bits of the physical address to low command + * address scratch register + */ + if (mwifiex_write_reg(adapter, reg->cmd_addr_lo, (u32)buf_pa)) { dev_err(adapter->dev, "%s: failed to write download command to boot code.\n", __func__); @@ -1117,9 +1137,10 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) return -1; } - /* Write the upper 32bits of the physical address to scratch - * register 1 */ - if (mwifiex_write_reg(adapter, PCIE_SCRATCH_1_REG, + /* Write the upper 32bits of the physical address to high command + * address scratch register + */ + if (mwifiex_write_reg(adapter, reg->cmd_addr_hi, (u32)((u64)buf_pa >> 32))) { dev_err(adapter->dev, "%s: failed to write download command to boot code.\n", @@ -1129,10 +1150,10 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) return -1; } - /* Write the command length to scratch register 2 */ - if (mwifiex_write_reg(adapter, PCIE_SCRATCH_2_REG, skb->len)) { + /* Write the command length to cmd_size scratch register */ + if (mwifiex_write_reg(adapter, reg->cmd_size, skb->len)) { dev_err(adapter->dev, - "%s: failed to write command len to scratch reg 2\n", + "%s: failed to write command len to cmd_size scratch reg\n", __func__); pci_unmap_single(card->dev, buf_pa, MWIFIEX_UPLD_SIZE, PCI_DMA_TODEVICE); @@ -1158,11 +1179,12 @@ mwifiex_pcie_send_boot_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; - /* Write the RX ring read pointer in to REG_RXBD_RDPTR */ - if (mwifiex_write_reg(adapter, REG_RXBD_RDPTR, card->rxbd_rdptr | 0)) { + /* Write the RX ring read pointer in to reg->rx_rdptr */ + if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr)) { dev_err(adapter->dev, - "RECV DATA: failed to write REG_RXBD_RDPTR\n"); + "RECV DATA: failed to write reg->rx_rdptr\n"); return -1; } return 0; @@ -1174,6 +1196,7 @@ static int mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) { struct pcie_service_card *card = adapter->card; + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; int ret = 0; dma_addr_t cmd_buf_pa, cmdrsp_buf_pa; u8 *payload = (u8 *)skb->data; @@ -1206,7 +1229,7 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) /* To send a command, the driver will: 1. Write the 64bit physical address of the data buffer to - SCRATCH1 + SCRATCH0 + cmd response address low + cmd response address high 2. Ring the door bell (i.e. set the door bell interrupt) In response to door bell interrupt, the firmware will perform @@ -1218,7 +1241,7 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) MWIFIEX_SKB_PACB(card->cmdrsp_buf, &cmdrsp_buf_pa); /* Write the lower 32bits of the cmdrsp buffer physical address */ - if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO, + if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo, (u32)cmdrsp_buf_pa)) { dev_err(adapter->dev, "Failed to write download cmd to boot code.\n"); @@ -1227,7 +1250,7 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) } /* Write the upper 32bits of the cmdrsp buffer physical address */ - if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI, + if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi, (u32)((u64)cmdrsp_buf_pa >> 32))) { dev_err(adapter->dev, "Failed to write download cmd to boot code.\n"); @@ -1237,15 +1260,16 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) } MWIFIEX_SKB_PACB(card->cmd_buf, &cmd_buf_pa); - /* Write the lower 32bits of the physical address to REG_CMD_ADDR_LO */ - if (mwifiex_write_reg(adapter, REG_CMD_ADDR_LO, (u32)cmd_buf_pa)) { + /* Write the lower 32bits of the physical address to reg->cmd_addr_lo */ + if (mwifiex_write_reg(adapter, reg->cmd_addr_lo, + (u32)cmd_buf_pa)) { dev_err(adapter->dev, "Failed to write download cmd to boot code.\n"); ret = -1; goto done; } - /* Write the upper 32bits of the physical address to REG_CMD_ADDR_HI */ - if (mwifiex_write_reg(adapter, REG_CMD_ADDR_HI, + /* Write the upper 32bits of the physical address to reg->cmd_addr_hi */ + if (mwifiex_write_reg(adapter, reg->cmd_addr_hi, (u32)((u64)cmd_buf_pa >> 32))) { dev_err(adapter->dev, "Failed to write download cmd to boot code.\n"); @@ -1253,10 +1277,11 @@ mwifiex_pcie_send_cmd(struct mwifiex_adapter *adapter, struct sk_buff *skb) goto done; } - /* Write the command length to REG_CMD_SIZE */ - if (mwifiex_write_reg(adapter, REG_CMD_SIZE, card->cmd_buf->len)) { + /* Write the command length to reg->cmd_size */ + if (mwifiex_write_reg(adapter, reg->cmd_size, + card->cmd_buf->len)) { dev_err(adapter->dev, - "Failed to write cmd len to REG_CMD_SIZE\n"); + "Failed to write cmd len to reg->cmd_size\n"); ret = -1; goto done; } @@ -1283,6 +1308,7 @@ done: static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; struct sk_buff *skb = card->cmdrsp_buf; int count = 0; u16 rx_len; @@ -1328,14 +1354,14 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) /* Clear the cmd-rsp buffer address in scratch registers. This will prevent firmware from writing to the same response buffer again. */ - if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_LO, 0)) { + if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_lo, 0)) { dev_err(adapter->dev, "cmd_done: failed to clear cmd_rsp_addr_lo\n"); return -1; } /* Write the upper 32bits of the cmdrsp buffer physical address */ - if (mwifiex_write_reg(adapter, REG_CMDRSP_ADDR_HI, 0)) { + if (mwifiex_write_reg(adapter, reg->cmdrsp_addr_hi, 0)) { dev_err(adapter->dev, "cmd_done: failed to clear cmd_rsp_addr_hi\n"); return -1; @@ -1380,6 +1406,7 @@ static int mwifiex_pcie_cmdrsp_complete(struct mwifiex_adapter *adapter, static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK; u32 wrptr, event; dma_addr_t buf_pa; @@ -1399,9 +1426,9 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter) } /* Read the event ring write pointer set by firmware */ - if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) { + if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) { dev_err(adapter->dev, - "EventReady: failed to read REG_EVTBD_WRPTR\n"); + "EventReady: failed to read reg->evt_wrptr\n"); return -1; } @@ -1409,8 +1436,8 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter) card->evtbd_rdptr, wrptr); if (((wrptr & MWIFIEX_EVTBD_MASK) != (card->evtbd_rdptr & MWIFIEX_EVTBD_MASK)) || - ((wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) == - (card->evtbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) { + ((wrptr & reg->evt_rollover_ind) == + (card->evtbd_rdptr & reg->evt_rollover_ind))) { struct sk_buff *skb_cmd; __le16 data_len = 0; u16 evt_len; @@ -1462,6 +1489,7 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, struct sk_buff *skb) { struct pcie_service_card *card = adapter->card; + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; int ret = 0; u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK; u32 wrptr; @@ -1477,9 +1505,9 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, } /* Read the event ring write pointer set by firmware */ - if (mwifiex_read_reg(adapter, REG_EVTBD_WRPTR, &wrptr)) { + if (mwifiex_read_reg(adapter, reg->evt_wrptr, &wrptr)) { dev_err(adapter->dev, - "event_complete: failed to read REG_EVTBD_WRPTR\n"); + "event_complete: failed to read reg->evt_wrptr\n"); return -1; } @@ -1504,17 +1532,18 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, if ((++card->evtbd_rdptr & MWIFIEX_EVTBD_MASK) == MWIFIEX_MAX_EVT_BD) { card->evtbd_rdptr = ((card->evtbd_rdptr & - MWIFIEX_BD_FLAG_ROLLOVER_IND) ^ - MWIFIEX_BD_FLAG_ROLLOVER_IND); + reg->evt_rollover_ind) ^ + reg->evt_rollover_ind); } dev_dbg(adapter->dev, "info: Updated ", card->evtbd_rdptr, wrptr); - /* Write the event ring read pointer in to REG_EVTBD_RDPTR */ - if (mwifiex_write_reg(adapter, REG_EVTBD_RDPTR, card->evtbd_rdptr)) { + /* Write the event ring read pointer in to reg->evt_rdptr */ + if (mwifiex_write_reg(adapter, reg->evt_rdptr, + card->evtbd_rdptr)) { dev_err(adapter->dev, - "event_complete: failed to read REG_EVTBD_RDPTR\n"); + "event_complete: failed to read reg->evt_rdptr\n"); return -1; } @@ -1543,6 +1572,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, u32 block_retry_cnt = 0; dma_addr_t buf_pa; struct pcie_service_card *card = adapter->card; + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; if (!firmware || !firmware_len) { dev_err(adapter->dev, @@ -1574,7 +1604,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, break; for (tries = 0; tries < MAX_POLL_TRIES; tries++) { - ret = mwifiex_read_reg(adapter, PCIE_SCRATCH_2_REG, + ret = mwifiex_read_reg(adapter, reg->cmd_size, &len); if (ret) { dev_warn(adapter->dev, @@ -1620,16 +1650,15 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter, dev_dbg(adapter->dev, "."); - tx_blocks = (txlen + - MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD - 1) / - MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD; + tx_blocks = (txlen + card->pcie.blksz_fw_dl - 1) / + card->pcie.blksz_fw_dl; /* Copy payload to buffer */ memmove(skb->data, &firmware[offset], txlen); } skb_put(skb, MWIFIEX_UPLD_SIZE - skb->len); - skb_trim(skb, tx_blocks * MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD); + skb_trim(skb, tx_blocks * card->pcie.blksz_fw_dl); /* Send the boot command to device */ if (mwifiex_pcie_send_boot_cmd(adapter, skb)) { @@ -1682,6 +1711,8 @@ mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num) { int ret = 0; u32 firmware_stat, winner_status; + struct pcie_service_card *card = adapter->card; + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; u32 tries; /* Mask spurios interrupts */ @@ -1692,7 +1723,8 @@ mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num) } dev_dbg(adapter->dev, "Setting driver ready signature\n"); - if (mwifiex_write_reg(adapter, REG_DRV_READY, FIRMWARE_READY_PCIE)) { + if (mwifiex_write_reg(adapter, reg->drv_rdy, + FIRMWARE_READY_PCIE)) { dev_err(adapter->dev, "Failed to write driver ready signature\n"); return -1; @@ -1700,7 +1732,7 @@ mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num) /* Wait for firmware initialization event */ for (tries = 0; tries < poll_num; tries++) { - if (mwifiex_read_reg(adapter, PCIE_SCRATCH_3_REG, + if (mwifiex_read_reg(adapter, reg->fw_status, &firmware_stat)) ret = -1; else @@ -1717,7 +1749,7 @@ mwifiex_check_fw_status(struct mwifiex_adapter *adapter, u32 poll_num) } if (ret) { - if (mwifiex_read_reg(adapter, PCIE_SCRATCH_3_REG, + if (mwifiex_read_reg(adapter, reg->fw_status, &winner_status)) ret = -1; else if (!winner_status) { @@ -2061,10 +2093,11 @@ static void mwifiex_pcie_cleanup(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; if (user_rmmod) { dev_dbg(adapter->dev, "Clearing driver ready signature\n"); - if (mwifiex_write_reg(adapter, REG_DRV_READY, 0x00000000)) + if (mwifiex_write_reg(adapter, reg->drv_rdy, 0x00000000)) dev_err(adapter->dev, "Failed to write driver not-ready signature\n"); } @@ -2102,7 +2135,7 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) } adapter->dev = &pdev->dev; - strcpy(adapter->fw_name, PCIE8766_DEFAULT_FW_NAME); + strcpy(adapter->fw_name, card->pcie.firmware); return 0; } diff --git a/drivers/net/wireless/mwifiex/pcie.h b/drivers/net/wireless/mwifiex/pcie.h index 37eeb2ca6b2..7ef660ec058 100644 --- a/drivers/net/wireless/mwifiex/pcie.h +++ b/drivers/net/wireless/mwifiex/pcie.h @@ -75,27 +75,6 @@ #define MWIFIEX_BD_FLAG_ROLLOVER_IND BIT(7) #define MWIFIEX_BD_FLAG_FIRST_DESC BIT(0) #define MWIFIEX_BD_FLAG_LAST_DESC BIT(1) -#define REG_CMD_ADDR_LO PCIE_SCRATCH_0_REG -#define REG_CMD_ADDR_HI PCIE_SCRATCH_1_REG -#define REG_CMD_SIZE PCIE_SCRATCH_2_REG - -#define REG_CMDRSP_ADDR_LO PCIE_SCRATCH_4_REG -#define REG_CMDRSP_ADDR_HI PCIE_SCRATCH_5_REG - -/* TX buffer description read pointer */ -#define REG_TXBD_RDPTR PCIE_SCRATCH_6_REG -/* TX buffer description write pointer */ -#define REG_TXBD_WRPTR PCIE_SCRATCH_7_REG -/* RX buffer description read pointer */ -#define REG_RXBD_RDPTR PCIE_SCRATCH_8_REG -/* RX buffer description write pointer */ -#define REG_RXBD_WRPTR PCIE_SCRATCH_9_REG -/* Event buffer description read pointer */ -#define REG_EVTBD_RDPTR PCIE_SCRATCH_10_REG -/* Event buffer description write pointer */ -#define REG_EVTBD_WRPTR PCIE_SCRATCH_11_REG -/* Driver ready signature write pointer */ -#define REG_DRV_READY PCIE_SCRATCH_12_REG /* Max retry number of command write */ #define MAX_WRITE_IOMEM_RETRY 2 @@ -104,6 +83,78 @@ /* FW awake cookie after FW ready */ #define FW_AWAKE_COOKIE (0xAA55AA55) +struct mwifiex_pcie_card_reg { + u16 cmd_addr_lo; + u16 cmd_addr_hi; + u16 fw_status; + u16 cmd_size; + u16 cmdrsp_addr_lo; + u16 cmdrsp_addr_hi; + u16 tx_rdptr; + u16 tx_wrptr; + u16 rx_rdptr; + u16 rx_wrptr; + u16 evt_rdptr; + u16 evt_wrptr; + u16 drv_rdy; + u16 tx_start_ptr; + u32 tx_mask; + u32 tx_wrap_mask; + u32 rx_mask; + u32 rx_wrap_mask; + u32 tx_rollover_ind; + u32 rx_rollover_ind; + u32 evt_rollover_ind; + u8 ring_flag_sop; + u8 ring_flag_eop; + u8 ring_flag_xs_sop; + u8 ring_flag_xs_eop; + u32 ring_tx_start_ptr; + u8 pfu_enabled; +}; + +static const struct mwifiex_pcie_card_reg mwifiex_reg_8766 = { + .cmd_addr_lo = PCIE_SCRATCH_0_REG, + .cmd_addr_hi = PCIE_SCRATCH_1_REG, + .cmd_size = PCIE_SCRATCH_2_REG, + .fw_status = PCIE_SCRATCH_3_REG, + .cmdrsp_addr_lo = PCIE_SCRATCH_4_REG, + .cmdrsp_addr_hi = PCIE_SCRATCH_5_REG, + .tx_rdptr = PCIE_SCRATCH_6_REG, + .tx_wrptr = PCIE_SCRATCH_7_REG, + .rx_rdptr = PCIE_SCRATCH_8_REG, + .rx_wrptr = PCIE_SCRATCH_9_REG, + .evt_rdptr = PCIE_SCRATCH_10_REG, + .evt_wrptr = PCIE_SCRATCH_11_REG, + .drv_rdy = PCIE_SCRATCH_12_REG, + .tx_start_ptr = 0, + .tx_mask = MWIFIEX_TXBD_MASK, + .tx_wrap_mask = 0, + .rx_mask = MWIFIEX_RXBD_MASK, + .rx_wrap_mask = 0, + .tx_rollover_ind = MWIFIEX_BD_FLAG_ROLLOVER_IND, + .rx_rollover_ind = MWIFIEX_BD_FLAG_ROLLOVER_IND, + .evt_rollover_ind = MWIFIEX_BD_FLAG_ROLLOVER_IND, + .ring_flag_sop = 0, + .ring_flag_eop = 0, + .ring_flag_xs_sop = 0, + .ring_flag_xs_eop = 0, + .ring_tx_start_ptr = 0, + .pfu_enabled = 0, +}; + +struct mwifiex_pcie_device { + const char *firmware; + const struct mwifiex_pcie_card_reg *reg; + u16 blksz_fw_dl; +}; + +static const struct mwifiex_pcie_device mwifiex_pcie8766 = { + .firmware = PCIE8766_DEFAULT_FW_NAME, + .reg = &mwifiex_reg_8766, + .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD, +}; + struct mwifiex_pcie_buf_desc { u64 paddr; u16 len; @@ -113,6 +164,7 @@ struct mwifiex_pcie_buf_desc { struct pcie_service_card { struct pci_dev *dev; struct mwifiex_adapter *adapter; + struct mwifiex_pcie_device pcie; u8 txbd_flush; u32 txbd_wrptr; @@ -150,10 +202,11 @@ struct pcie_service_card { static inline int mwifiex_pcie_txbd_empty(struct pcie_service_card *card, u32 rdptr) { - if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) == - (rdptr & MWIFIEX_TXBD_MASK)) && - ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) != - (rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; + + if (((card->txbd_wrptr & reg->tx_mask) == (rdptr & reg->tx_mask)) && + ((card->txbd_wrptr & reg->tx_rollover_ind) != + (rdptr & reg->tx_rollover_ind))) return 1; return 0; @@ -162,10 +215,12 @@ mwifiex_pcie_txbd_empty(struct pcie_service_card *card, u32 rdptr) static inline int mwifiex_pcie_txbd_not_full(struct pcie_service_card *card) { - if (((card->txbd_wrptr & MWIFIEX_TXBD_MASK) != - (card->txbd_rdptr & MWIFIEX_TXBD_MASK)) || - ((card->txbd_wrptr & MWIFIEX_BD_FLAG_ROLLOVER_IND) != - (card->txbd_rdptr & MWIFIEX_BD_FLAG_ROLLOVER_IND))) + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; + + if (((card->txbd_wrptr & reg->tx_mask) != + (card->txbd_rdptr & reg->tx_mask)) || + ((card->txbd_wrptr & reg->tx_rollover_ind) != + (card->txbd_rdptr & reg->tx_rollover_ind))) return 1; return 0; -- cgit v1.2.3-70-g09d2 From 0732484b47b57ef90bb08408d60fddbad0262d82 Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Fri, 8 Feb 2013 18:18:07 -0800 Subject: mwifiex: separate ring initialization and ring creation routines This patch separates PCIe ring initialization from ring creation routines. This modularizes ring creation(TXBD, RXBD and event rings) functions. Readability has been improved while moving the code around. Signed-off-by: Avinash Patil Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/pcie.c | 327 +++++++++++++++++++++--------------- 1 file changed, 194 insertions(+), 133 deletions(-) (limited to 'drivers/net/wireless/mwifiex') diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 29c539b9424..06aae55485e 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c @@ -372,13 +372,199 @@ static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter) } /* - * This function creates buffer descriptor ring for TX + * This function initializes TX buffer ring descriptors + */ +static int mwifiex_init_txq_ring(struct mwifiex_adapter *adapter) +{ + struct pcie_service_card *card = adapter->card; + struct mwifiex_pcie_buf_desc *desc; + int i; + + for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { + card->tx_buf_list[i] = NULL; + card->txbd_ring[i] = (void *)(card->txbd_ring_vbase + + (sizeof(*desc) * i)); + desc = card->txbd_ring[i]; + memset(desc, 0, sizeof(*desc)); + } + + return 0; +} + +/* This function initializes RX buffer ring descriptors. Each SKB is allocated + * here and after mapping PCI memory, its physical address is assigned to + * PCIE Rx buffer descriptor's physical address. + */ +static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter) +{ + struct pcie_service_card *card = adapter->card; + struct sk_buff *skb; + struct mwifiex_pcie_buf_desc *desc; + dma_addr_t buf_pa; + int i; + + for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { + /* Allocate skb here so that firmware can DMA data from it */ + skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); + if (!skb) { + dev_err(adapter->dev, + "Unable to allocate skb for RX ring.\n"); + kfree(card->rxbd_ring_vbase); + return -ENOMEM; + } + + if (mwifiex_map_pci_memory(adapter, skb, + MWIFIEX_RX_DATA_BUF_SIZE, + PCI_DMA_FROMDEVICE)) + return -1; + + MWIFIEX_SKB_PACB(skb, &buf_pa); + + dev_dbg(adapter->dev, + "info: RX ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n", + skb, skb->len, skb->data, (u32)buf_pa, + (u32)((u64)buf_pa >> 32)); + + card->rx_buf_list[i] = skb; + card->rxbd_ring[i] = (void *)(card->rxbd_ring_vbase + + (sizeof(*desc) * i)); + desc = card->rxbd_ring[i]; + desc->paddr = buf_pa; + desc->len = (u16)skb->len; + desc->flags = 0; + } + + return 0; +} + +/* This function initializes event buffer ring descriptors. Each SKB is + * allocated here and after mapping PCI memory, its physical address is assigned + * to PCIE Rx buffer descriptor's physical address + */ +static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter) +{ + struct pcie_service_card *card = adapter->card; + struct mwifiex_pcie_buf_desc *desc; + struct sk_buff *skb; + dma_addr_t buf_pa; + int i; + + for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) { + /* Allocate skb here so that firmware can DMA data from it */ + skb = dev_alloc_skb(MAX_EVENT_SIZE); + if (!skb) { + dev_err(adapter->dev, + "Unable to allocate skb for EVENT buf.\n"); + kfree(card->evtbd_ring_vbase); + return -ENOMEM; + } + skb_put(skb, MAX_EVENT_SIZE); + + if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE, + PCI_DMA_FROMDEVICE)) + return -1; + + MWIFIEX_SKB_PACB(skb, &buf_pa); + + dev_dbg(adapter->dev, + "info: EVT ring: skb=%p len=%d data=%p buf_pa=%#x:%x\n", + skb, skb->len, skb->data, (u32)buf_pa, + (u32)((u64)buf_pa >> 32)); + + card->evt_buf_list[i] = skb; + card->evtbd_ring[i] = (void *)(card->evtbd_ring_vbase + + (sizeof(*desc) * i)); + + desc = card->evtbd_ring[i]; + desc->paddr = buf_pa; + desc->len = (u16)skb->len; + desc->flags = 0; + } + + return 0; +} + +/* This function cleans up TX buffer rings. If any of the buffer list has valid + * SKB address, associated SKB is freed. + */ +static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter) +{ + struct pcie_service_card *card = adapter->card; + struct sk_buff *skb; + struct mwifiex_pcie_buf_desc *desc; + int i; + + for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { + desc = card->txbd_ring[i]; + if (card->tx_buf_list[i]) { + skb = card->tx_buf_list[i]; + pci_unmap_single(card->dev, desc->paddr, skb->len, + PCI_DMA_TODEVICE); + dev_kfree_skb_any(skb); + } + card->tx_buf_list[i] = NULL; + memset(desc, 0, sizeof(*desc)); + } + + return; +} + +/* This function cleans up RX buffer rings. If any of the buffer list has valid + * SKB address, associated SKB is freed. + */ +static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter) +{ + struct pcie_service_card *card = adapter->card; + struct mwifiex_pcie_buf_desc *desc; + struct sk_buff *skb; + int i; + + for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { + desc = card->rxbd_ring[i]; + if (card->rx_buf_list[i]) { + skb = card->rx_buf_list[i]; + pci_unmap_single(card->dev, desc->paddr, + MWIFIEX_RX_DATA_BUF_SIZE, + PCI_DMA_FROMDEVICE); + dev_kfree_skb_any(skb); + } + memset(desc, 0, sizeof(*desc)); + } + + return; +} + +/* This function cleans up event buffer rings. If any of the buffer list has + * valid SKB address, associated SKB is freed. + */ +static void mwifiex_cleanup_evt_ring(struct mwifiex_adapter *adapter) +{ + struct pcie_service_card *card = adapter->card; + struct mwifiex_pcie_buf_desc *desc; + struct sk_buff *skb; + int i; + + for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) { + desc = card->evtbd_ring[i]; + if (card->evt_buf_list[i]) { + skb = card->evt_buf_list[i]; + pci_unmap_single(card->dev, desc->paddr, MAX_EVENT_SIZE, + PCI_DMA_FROMDEVICE); + dev_kfree_skb_any(skb); + } + card->evt_buf_list[i] = NULL; + memset(desc, 0, sizeof(*desc)); + } + + return; +} + +/* This function creates buffer descriptor ring for TX */ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; - int i; /* * driver maintaines the write pointer and firmware maintaines the read @@ -408,41 +594,15 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) card->txbd_ring_vbase, (unsigned int)card->txbd_ring_pbase, (u32)((u64)card->txbd_ring_pbase >> 32), card->txbd_ring_size); - for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { - card->txbd_ring[i] = (struct mwifiex_pcie_buf_desc *) - (card->txbd_ring_vbase + - (sizeof(struct mwifiex_pcie_buf_desc) - * i)); - - card->tx_buf_list[i] = NULL; - card->txbd_ring[i]->paddr = 0; - card->txbd_ring[i]->len = 0; - card->txbd_ring[i]->flags = 0; - } - - return 0; + return mwifiex_init_txq_ring(adapter); } static int mwifiex_pcie_delete_txbd_ring(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; - struct sk_buff *skb; - int i; - for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { - if (card->tx_buf_list[i]) { - skb = card->tx_buf_list[i]; - pci_unmap_single(card->dev, card->txbd_ring[i]->paddr, - skb->len, PCI_DMA_TODEVICE); - dev_kfree_skb_any(skb); - } - card->tx_buf_list[i] = NULL; - card->txbd_ring[i]->paddr = 0; - card->txbd_ring[i]->len = 0; - card->txbd_ring[i]->flags = 0; - card->txbd_ring[i] = NULL; - } + mwifiex_cleanup_txq_ring(adapter); if (card->txbd_ring_vbase) pci_free_consistent(card->dev, card->txbd_ring_size, @@ -464,9 +624,6 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; - struct sk_buff *skb; - int i; - dma_addr_t buf_pa; /* * driver maintaines the read pointer and firmware maintaines the write @@ -496,39 +653,7 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) (u32)((u64)card->rxbd_ring_pbase >> 32), card->rxbd_ring_size); - for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { - card->rxbd_ring[i] = (struct mwifiex_pcie_buf_desc *) - (card->rxbd_ring_vbase + - (sizeof(struct mwifiex_pcie_buf_desc) - * i)); - - /* Allocate skb here so that firmware can DMA data from it */ - skb = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); - if (!skb) { - dev_err(adapter->dev, - "Unable to allocate skb for RX ring.\n"); - kfree(card->rxbd_ring_vbase); - return -ENOMEM; - } - if (mwifiex_map_pci_memory(adapter, skb, - MWIFIEX_RX_DATA_BUF_SIZE, - PCI_DMA_FROMDEVICE)) - return -1; - - MWIFIEX_SKB_PACB(skb, &buf_pa); - - dev_dbg(adapter->dev, "info: RX ring: add new skb base: %p, " - "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n", - skb, skb->data, (u32)buf_pa, (u32)((u64)buf_pa >> 32), - skb->len); - - card->rx_buf_list[i] = skb; - card->rxbd_ring[i]->paddr = buf_pa; - card->rxbd_ring[i]->len = (u16)skb->len; - card->rxbd_ring[i]->flags = 0; - } - - return 0; + return mwifiex_init_rxq_ring(adapter); } /* @@ -538,23 +663,8 @@ static int mwifiex_pcie_delete_rxbd_ring(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; - struct sk_buff *skb; - int i; - for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { - if (card->rx_buf_list[i]) { - skb = card->rx_buf_list[i]; - pci_unmap_single(card->dev, card->rxbd_ring[i]->paddr , - MWIFIEX_RX_DATA_BUF_SIZE, - PCI_DMA_FROMDEVICE); - dev_kfree_skb_any(skb); - } - card->rx_buf_list[i] = NULL; - card->rxbd_ring[i]->paddr = 0; - card->rxbd_ring[i]->len = 0; - card->rxbd_ring[i]->flags = 0; - card->rxbd_ring[i] = NULL; - } + mwifiex_cleanup_rxq_ring(adapter); if (card->rxbd_ring_vbase) pci_free_consistent(card->dev, card->rxbd_ring_size, @@ -576,9 +686,6 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; - struct sk_buff *skb; - int i; - dma_addr_t buf_pa; /* * driver maintaines the read pointer and firmware maintaines the write @@ -608,39 +715,7 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) (u32)((u64)card->evtbd_ring_pbase >> 32), card->evtbd_ring_size); - for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) { - card->evtbd_ring[i] = (struct mwifiex_pcie_buf_desc *) - (card->evtbd_ring_vbase + - (sizeof(struct mwifiex_pcie_buf_desc) - * i)); - - /* Allocate skb here so that firmware can DMA data from it */ - skb = dev_alloc_skb(MAX_EVENT_SIZE); - if (!skb) { - dev_err(adapter->dev, - "Unable to allocate skb for EVENT buf.\n"); - kfree(card->evtbd_ring_vbase); - return -ENOMEM; - } - skb_put(skb, MAX_EVENT_SIZE); - - if (mwifiex_map_pci_memory(adapter, skb, MAX_EVENT_SIZE, - PCI_DMA_FROMDEVICE)) - return -1; - - MWIFIEX_SKB_PACB(skb, &buf_pa); - dev_dbg(adapter->dev, "info: Evt ring: add new skb. base: %p, " - "buf_base: %p, buf_pbase: %#x:%x, buf_len: %#x\n", - skb, skb->data, (u32)buf_pa, (u32)((u64)buf_pa >> 32), - skb->len); - - card->evt_buf_list[i] = skb; - card->evtbd_ring[i]->paddr = buf_pa; - card->evtbd_ring[i]->len = (u16)skb->len; - card->evtbd_ring[i]->flags = 0; - } - - return 0; + return mwifiex_pcie_init_evt_ring(adapter); } /* @@ -650,22 +725,8 @@ static int mwifiex_pcie_delete_evtbd_ring(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; - struct sk_buff *skb; - int i; - for (i = 0; i < MWIFIEX_MAX_EVT_BD; i++) { - if (card->evt_buf_list[i]) { - skb = card->evt_buf_list[i]; - pci_unmap_single(card->dev, card->evtbd_ring[i]->paddr, - MAX_EVENT_SIZE, PCI_DMA_FROMDEVICE); - dev_kfree_skb_any(skb); - } - card->evt_buf_list[i] = NULL; - card->evtbd_ring[i]->paddr = 0; - card->evtbd_ring[i]->len = 0; - card->evtbd_ring[i]->flags = 0; - card->evtbd_ring[i] = NULL; - } + mwifiex_cleanup_evt_ring(adapter); if (card->evtbd_ring_vbase) pci_free_consistent(card->dev, card->evtbd_ring_size, -- cgit v1.2.3-70-g09d2 From e05dc3e93c136ecd329ed2d57d4eb2e82f530304 Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Fri, 8 Feb 2013 18:18:08 -0800 Subject: mwifiex: define generic data type for PCIe ring buffers This patch defines PCIe ring buffer array pointer as void instead of mwifiex_pcie_buf_desc. This will enable us to use same pointers for ring operations instead of new structures if buffer descriptor structure changes. Also split out event buffer descriptor structure from struct mwifiex_pcie_buf_desc. For PCIe8766 TX/RX buffer descriptor is same as evevt buffer descriptor. Newer chips could use different TX/RX buffer descriptor while event descriptor remains the same. Signed-off-by: Avinash Patil Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/pcie.c | 49 ++++++++++++++++++++----------------- drivers/net/wireless/mwifiex/pcie.h | 12 ++++++--- 2 files changed, 35 insertions(+), 26 deletions(-) (limited to 'drivers/net/wireless/mwifiex') diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 06aae55485e..6c15969efd5 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c @@ -444,7 +444,7 @@ static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter) static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; - struct mwifiex_pcie_buf_desc *desc; + struct mwifiex_evt_buf_desc *desc; struct sk_buff *skb; dma_addr_t buf_pa; int i; @@ -474,7 +474,6 @@ static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter) card->evt_buf_list[i] = skb; card->evtbd_ring[i] = (void *)(card->evtbd_ring_vbase + (sizeof(*desc) * i)); - desc = card->evtbd_ring[i]; desc->paddr = buf_pa; desc->len = (u16)skb->len; @@ -540,7 +539,7 @@ static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter) static void mwifiex_cleanup_evt_ring(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; - struct mwifiex_pcie_buf_desc *desc; + struct mwifiex_evt_buf_desc *desc; struct sk_buff *skb; int i; @@ -695,7 +694,7 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) card->evtbd_wrptr = 0; card->evtbd_rdptr = reg->evt_rollover_ind; - card->evtbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * + card->evtbd_ring_size = sizeof(struct mwifiex_evt_buf_desc) * MWIFIEX_MAX_EVT_BD; dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n", card->evtbd_ring_size); @@ -880,6 +879,7 @@ static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter) struct sk_buff *skb; dma_addr_t buf_pa; u32 wrdoneidx, rdptr, unmap_count = 0; + struct mwifiex_pcie_buf_desc *desc; struct pcie_service_card *card = adapter->card; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; @@ -922,9 +922,8 @@ static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter) } card->tx_buf_list[wrdoneidx] = NULL; - card->txbd_ring[wrdoneidx]->paddr = 0; - card->txbd_ring[wrdoneidx]->len = 0; - card->txbd_ring[wrdoneidx]->flags = 0; + desc = card->txbd_ring[wrdoneidx]; + memset(desc, 0, sizeof(*desc)); card->txbd_rdptr++; if ((card->txbd_rdptr & reg->tx_mask) == num_tx_buffs) @@ -964,6 +963,7 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb, u32 wrindx; int ret; dma_addr_t buf_pa; + struct mwifiex_pcie_buf_desc *desc; __le16 *tmp; if (!(skb->data && skb->len)) { @@ -994,10 +994,11 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb, wrindx = card->txbd_wrptr & reg->tx_mask; MWIFIEX_SKB_PACB(skb, &buf_pa); card->tx_buf_list[wrindx] = skb; - card->txbd_ring[wrindx]->paddr = buf_pa; - card->txbd_ring[wrindx]->len = (u16)skb->len; - card->txbd_ring[wrindx]->flags = MWIFIEX_BD_FLAG_FIRST_DESC | - MWIFIEX_BD_FLAG_LAST_DESC; + desc = card->txbd_ring[wrindx]; + desc->paddr = buf_pa; + desc->len = (u16)skb->len; + desc->flags = MWIFIEX_BD_FLAG_FIRST_DESC | + MWIFIEX_BD_FLAG_LAST_DESC; if ((++card->txbd_wrptr & reg->tx_mask) == MWIFIEX_MAX_TXRX_BD) @@ -1049,9 +1050,7 @@ done_unmap: MWIFIEX_SKB_PACB(skb, &buf_pa); pci_unmap_single(card->dev, buf_pa, skb->len, PCI_DMA_TODEVICE); card->tx_buf_list[wrindx] = NULL; - card->txbd_ring[wrindx]->paddr = 0; - card->txbd_ring[wrindx]->len = 0; - card->txbd_ring[wrindx]->flags = 0; + memset(desc, 0, sizeof(*desc)); return ret; } @@ -1067,6 +1066,7 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) dma_addr_t buf_pa; int ret = 0; struct sk_buff *skb_tmp = NULL; + struct mwifiex_pcie_buf_desc *desc; if (!mwifiex_pcie_ok_to_access_hw(adapter)) mwifiex_pm_wakeup_card(adapter); @@ -1126,9 +1126,10 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n", skb_tmp, rd_index); card->rx_buf_list[rd_index] = skb_tmp; - card->rxbd_ring[rd_index]->paddr = buf_pa; - card->rxbd_ring[rd_index]->len = skb_tmp->len; - card->rxbd_ring[rd_index]->flags = 0; + desc = card->rxbd_ring[rd_index]; + desc->paddr = buf_pa; + desc->len = skb_tmp->len; + desc->flags = 0; if ((++card->rxbd_rdptr & reg->rx_mask) == MWIFIEX_MAX_TXRX_BD) { @@ -1471,6 +1472,7 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter) u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK; u32 wrptr, event; dma_addr_t buf_pa; + struct mwifiex_evt_buf_desc *desc; if (!mwifiex_pcie_ok_to_access_hw(adapter)) mwifiex_pm_wakeup_card(adapter); @@ -1512,9 +1514,8 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter) /* Take the pointer and set it to event pointer in adapter and will return back after event handling callback */ card->evt_buf_list[rdptr] = NULL; - card->evtbd_ring[rdptr]->paddr = 0; - card->evtbd_ring[rdptr]->len = 0; - card->evtbd_ring[rdptr]->flags = 0; + desc = card->evtbd_ring[rdptr]; + memset(desc, 0, sizeof(*desc)); event = *(u32 *) &skb_cmd->data[INTF_HEADER_LEN]; adapter->event_cause = event; @@ -1555,6 +1556,7 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, u32 rdptr = card->evtbd_rdptr & MWIFIEX_EVTBD_MASK; u32 wrptr; dma_addr_t buf_pa; + struct mwifiex_evt_buf_desc *desc; if (!skb) return 0; @@ -1581,9 +1583,10 @@ static int mwifiex_pcie_event_complete(struct mwifiex_adapter *adapter, MWIFIEX_SKB_PACB(skb, &buf_pa); card->evt_buf_list[rdptr] = skb; MWIFIEX_SKB_PACB(skb, &buf_pa); - card->evtbd_ring[rdptr]->paddr = buf_pa; - card->evtbd_ring[rdptr]->len = (u16)skb->len; - card->evtbd_ring[rdptr]->flags = 0; + desc = card->evtbd_ring[rdptr]; + desc->paddr = buf_pa; + desc->len = (u16)skb->len; + desc->flags = 0; skb = NULL; } else { dev_dbg(adapter->dev, diff --git a/drivers/net/wireless/mwifiex/pcie.h b/drivers/net/wireless/mwifiex/pcie.h index 7ef660ec058..7ebdc74f2bb 100644 --- a/drivers/net/wireless/mwifiex/pcie.h +++ b/drivers/net/wireless/mwifiex/pcie.h @@ -155,6 +155,12 @@ static const struct mwifiex_pcie_device mwifiex_pcie8766 = { .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD, }; +struct mwifiex_evt_buf_desc { + u64 paddr; + u16 len; + u16 flags; +} __packed; + struct mwifiex_pcie_buf_desc { u64 paddr; u16 len; @@ -172,7 +178,7 @@ struct pcie_service_card { u32 txbd_ring_size; u8 *txbd_ring_vbase; dma_addr_t txbd_ring_pbase; - struct mwifiex_pcie_buf_desc *txbd_ring[MWIFIEX_MAX_TXRX_BD]; + void *txbd_ring[MWIFIEX_MAX_TXRX_BD]; struct sk_buff *tx_buf_list[MWIFIEX_MAX_TXRX_BD]; u32 rxbd_wrptr; @@ -180,7 +186,7 @@ struct pcie_service_card { u32 rxbd_ring_size; u8 *rxbd_ring_vbase; dma_addr_t rxbd_ring_pbase; - struct mwifiex_pcie_buf_desc *rxbd_ring[MWIFIEX_MAX_TXRX_BD]; + void *rxbd_ring[MWIFIEX_MAX_TXRX_BD]; struct sk_buff *rx_buf_list[MWIFIEX_MAX_TXRX_BD]; u32 evtbd_wrptr; @@ -188,7 +194,7 @@ struct pcie_service_card { u32 evtbd_ring_size; u8 *evtbd_ring_vbase; dma_addr_t evtbd_ring_pbase; - struct mwifiex_pcie_buf_desc *evtbd_ring[MWIFIEX_MAX_EVT_BD]; + void *evtbd_ring[MWIFIEX_MAX_EVT_BD]; struct sk_buff *evt_buf_list[MWIFIEX_MAX_EVT_BD]; struct sk_buff *cmd_buf; -- cgit v1.2.3-70-g09d2 From ca8f21127883f8c1ea48b9ce8f93ead2175142a7 Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Fri, 8 Feb 2013 18:18:09 -0800 Subject: mwifiex: add PCIe8897 support This patch adds PCIe8897 support to mwifiex. In PCIe8897 PFU (pre-fetch unit) is enabled by default. This patch adds support to accommodate this feaure as well. Signed-off-by: Avinash Patil Signed-off-by: Yogesh Ashok Powar Signed-off-by: Nishant Sarmukadam Signed-off-by: Bing Zhao Signed-off-by: Frank Huang Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/Kconfig | 4 +- drivers/net/wireless/mwifiex/pcie.c | 242 ++++++++++++++++++++++++++--------- drivers/net/wireless/mwifiex/pcie.h | 99 ++++++++++++-- 3 files changed, 275 insertions(+), 70 deletions(-) (limited to 'drivers/net/wireless/mwifiex') diff --git a/drivers/net/wireless/mwifiex/Kconfig b/drivers/net/wireless/mwifiex/Kconfig index b2e27723f80..4f614aad9de 100644 --- a/drivers/net/wireless/mwifiex/Kconfig +++ b/drivers/net/wireless/mwifiex/Kconfig @@ -20,12 +20,12 @@ config MWIFIEX_SDIO mwifiex_sdio. config MWIFIEX_PCIE - tristate "Marvell WiFi-Ex Driver for PCIE 8766" + tristate "Marvell WiFi-Ex Driver for PCIE 8766/8897" depends on MWIFIEX && PCI select FW_LOADER ---help--- This adds support for wireless adapters based on Marvell - 8766 chipset with PCIe interface. + 8766/8897 chipsets with PCIe interface. If you choose to build it as a module, it will be called mwifiex_pcie. diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 6c15969efd5..3b9be7c185c 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c @@ -237,15 +237,17 @@ static int mwifiex_pcie_resume(struct pci_dev *pdev) return 0; } -#define PCIE_VENDOR_ID_MARVELL (0x11ab) -#define PCIE_DEVICE_ID_MARVELL_88W8766P (0x2b30) - static DEFINE_PCI_DEVICE_TABLE(mwifiex_ids) = { { PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8766P, PCI_ANY_ID, PCI_ANY_ID, 0, 0, .driver_data = (unsigned long) &mwifiex_pcie8766, }, + { + PCIE_VENDOR_ID_MARVELL, PCIE_DEVICE_ID_MARVELL_88W8897, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + .driver_data = (unsigned long) &mwifiex_pcie8897, + }, {}, }; @@ -377,15 +379,24 @@ static int mwifiex_pcie_enable_host_int(struct mwifiex_adapter *adapter) static int mwifiex_init_txq_ring(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; struct mwifiex_pcie_buf_desc *desc; + struct mwifiex_pfu_buf_desc *desc2; int i; for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { card->tx_buf_list[i] = NULL; - card->txbd_ring[i] = (void *)(card->txbd_ring_vbase + - (sizeof(*desc) * i)); - desc = card->txbd_ring[i]; - memset(desc, 0, sizeof(*desc)); + if (reg->pfu_enabled) { + card->txbd_ring[i] = (void *)card->txbd_ring_vbase + + (sizeof(*desc2) * i); + desc2 = card->txbd_ring[i]; + memset(desc2, 0, sizeof(*desc2)); + } else { + card->txbd_ring[i] = (void *)card->txbd_ring_vbase + + (sizeof(*desc) * i); + desc = card->txbd_ring[i]; + memset(desc, 0, sizeof(*desc)); + } } return 0; @@ -398,8 +409,10 @@ static int mwifiex_init_txq_ring(struct mwifiex_adapter *adapter) static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; struct sk_buff *skb; struct mwifiex_pcie_buf_desc *desc; + struct mwifiex_pfu_buf_desc *desc2; dma_addr_t buf_pa; int i; @@ -426,12 +439,23 @@ static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter) (u32)((u64)buf_pa >> 32)); card->rx_buf_list[i] = skb; - card->rxbd_ring[i] = (void *)(card->rxbd_ring_vbase + - (sizeof(*desc) * i)); - desc = card->rxbd_ring[i]; - desc->paddr = buf_pa; - desc->len = (u16)skb->len; - desc->flags = 0; + if (reg->pfu_enabled) { + card->rxbd_ring[i] = (void *)card->rxbd_ring_vbase + + (sizeof(*desc2) * i); + desc2 = card->rxbd_ring[i]; + desc2->paddr = buf_pa; + desc2->len = (u16)skb->len; + desc2->frag_len = (u16)skb->len; + desc2->flags = reg->ring_flag_eop | reg->ring_flag_sop; + desc2->offset = 0; + } else { + card->rxbd_ring[i] = (void *)(card->rxbd_ring_vbase + + (sizeof(*desc) * i)); + desc = card->rxbd_ring[i]; + desc->paddr = buf_pa; + desc->len = (u16)skb->len; + desc->flags = 0; + } } return 0; @@ -489,20 +513,33 @@ static int mwifiex_pcie_init_evt_ring(struct mwifiex_adapter *adapter) static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; struct sk_buff *skb; struct mwifiex_pcie_buf_desc *desc; + struct mwifiex_pfu_buf_desc *desc2; int i; for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { - desc = card->txbd_ring[i]; - if (card->tx_buf_list[i]) { - skb = card->tx_buf_list[i]; - pci_unmap_single(card->dev, desc->paddr, skb->len, - PCI_DMA_TODEVICE); - dev_kfree_skb_any(skb); + if (reg->pfu_enabled) { + desc2 = card->txbd_ring[i]; + if (card->tx_buf_list[i]) { + skb = card->tx_buf_list[i]; + pci_unmap_single(card->dev, desc2->paddr, + skb->len, PCI_DMA_TODEVICE); + dev_kfree_skb_any(skb); + } + memset(desc2, 0, sizeof(*desc2)); + } else { + desc = card->txbd_ring[i]; + if (card->tx_buf_list[i]) { + skb = card->tx_buf_list[i]; + pci_unmap_single(card->dev, desc->paddr, + skb->len, PCI_DMA_TODEVICE); + dev_kfree_skb_any(skb); + } + memset(desc, 0, sizeof(*desc)); } card->tx_buf_list[i] = NULL; - memset(desc, 0, sizeof(*desc)); } return; @@ -514,20 +551,33 @@ static void mwifiex_cleanup_txq_ring(struct mwifiex_adapter *adapter) static void mwifiex_cleanup_rxq_ring(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; struct mwifiex_pcie_buf_desc *desc; + struct mwifiex_pfu_buf_desc *desc2; struct sk_buff *skb; int i; for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { - desc = card->rxbd_ring[i]; - if (card->rx_buf_list[i]) { - skb = card->rx_buf_list[i]; - pci_unmap_single(card->dev, desc->paddr, - MWIFIEX_RX_DATA_BUF_SIZE, - PCI_DMA_FROMDEVICE); - dev_kfree_skb_any(skb); + if (reg->pfu_enabled) { + desc2 = card->rxbd_ring[i]; + if (card->rx_buf_list[i]) { + skb = card->rx_buf_list[i]; + pci_unmap_single(card->dev, desc2->paddr, + skb->len, PCI_DMA_TODEVICE); + dev_kfree_skb_any(skb); + } + memset(desc2, 0, sizeof(*desc2)); + } else { + desc = card->rxbd_ring[i]; + if (card->rx_buf_list[i]) { + skb = card->rx_buf_list[i]; + pci_unmap_single(card->dev, desc->paddr, + skb->len, PCI_DMA_TODEVICE); + dev_kfree_skb_any(skb); + } + memset(desc, 0, sizeof(*desc)); } - memset(desc, 0, sizeof(*desc)); + card->rx_buf_list[i] = NULL; } return; @@ -571,12 +621,21 @@ static int mwifiex_pcie_create_txbd_ring(struct mwifiex_adapter *adapter) * starts at zero with rollover bit set */ card->txbd_wrptr = 0; - card->txbd_rdptr |= reg->tx_rollover_ind; + + if (reg->pfu_enabled) + card->txbd_rdptr = 0; + else + card->txbd_rdptr |= reg->tx_rollover_ind; /* allocate shared memory for the BD ring and divide the same in to several descriptors */ - card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * - MWIFIEX_MAX_TXRX_BD; + if (reg->pfu_enabled) + card->txbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) * + MWIFIEX_MAX_TXRX_BD; + else + card->txbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * + MWIFIEX_MAX_TXRX_BD; + dev_dbg(adapter->dev, "info: txbd_ring: Allocating %d bytes\n", card->txbd_ring_size); card->txbd_ring_vbase = pci_alloc_consistent(card->dev, @@ -632,8 +691,13 @@ static int mwifiex_pcie_create_rxbd_ring(struct mwifiex_adapter *adapter) card->rxbd_wrptr = 0; card->rxbd_rdptr = reg->rx_rollover_ind; - card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * - MWIFIEX_MAX_TXRX_BD; + if (reg->pfu_enabled) + card->rxbd_ring_size = sizeof(struct mwifiex_pfu_buf_desc) * + MWIFIEX_MAX_TXRX_BD; + else + card->rxbd_ring_size = sizeof(struct mwifiex_pcie_buf_desc) * + MWIFIEX_MAX_TXRX_BD; + dev_dbg(adapter->dev, "info: rxbd_ring: Allocating %d bytes\n", card->rxbd_ring_size); card->rxbd_ring_vbase = pci_alloc_consistent(card->dev, @@ -695,7 +759,8 @@ static int mwifiex_pcie_create_evtbd_ring(struct mwifiex_adapter *adapter) card->evtbd_rdptr = reg->evt_rollover_ind; card->evtbd_ring_size = sizeof(struct mwifiex_evt_buf_desc) * - MWIFIEX_MAX_EVT_BD; + MWIFIEX_MAX_EVT_BD; + dev_dbg(adapter->dev, "info: evtbd_ring: Allocating %d bytes\n", card->evtbd_ring_size); card->evtbd_ring_vbase = pci_alloc_consistent(card->dev, @@ -875,11 +940,11 @@ static int mwifiex_clean_pcie_ring_buf(struct mwifiex_adapter *adapter) */ static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter) { - const u32 num_tx_buffs = MWIFIEX_MAX_TXRX_BD; struct sk_buff *skb; dma_addr_t buf_pa; - u32 wrdoneidx, rdptr, unmap_count = 0; + u32 wrdoneidx, rdptr, num_tx_buffs, unmap_count = 0; struct mwifiex_pcie_buf_desc *desc; + struct mwifiex_pfu_buf_desc *desc2; struct pcie_service_card *card = adapter->card; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; @@ -896,12 +961,14 @@ static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter) dev_dbg(adapter->dev, "SEND COMP: rdptr_prev=0x%x, rdptr=0x%x\n", card->txbd_rdptr, rdptr); + num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr; /* free from previous txbd_rdptr to current txbd_rdptr */ while (((card->txbd_rdptr & reg->tx_mask) != (rdptr & reg->tx_mask)) || ((card->txbd_rdptr & reg->tx_rollover_ind) != (rdptr & reg->tx_rollover_ind))) { - wrdoneidx = card->txbd_rdptr & reg->tx_mask; + wrdoneidx = (card->txbd_rdptr & reg->tx_mask) >> + reg->tx_start_ptr; skb = card->tx_buf_list[wrdoneidx]; if (skb) { @@ -922,9 +989,23 @@ static int mwifiex_pcie_send_data_complete(struct mwifiex_adapter *adapter) } card->tx_buf_list[wrdoneidx] = NULL; - desc = card->txbd_ring[wrdoneidx]; - memset(desc, 0, sizeof(*desc)); - card->txbd_rdptr++; + + if (reg->pfu_enabled) { + desc2 = (void *)card->txbd_ring[wrdoneidx]; + memset(desc2, 0, sizeof(*desc2)); + } else { + desc = card->txbd_ring[wrdoneidx]; + memset(desc, 0, sizeof(*desc)); + } + switch (card->dev->device) { + case PCIE_DEVICE_ID_MARVELL_88W8766P: + card->txbd_rdptr++; + break; + case PCIE_DEVICE_ID_MARVELL_88W8897: + card->txbd_rdptr += reg->ring_tx_start_ptr; + break; + } + if ((card->txbd_rdptr & reg->tx_mask) == num_tx_buffs) card->txbd_rdptr = ((card->txbd_rdptr & @@ -960,10 +1041,11 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb, { struct pcie_service_card *card = adapter->card; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; - u32 wrindx; + u32 wrindx, num_tx_buffs, rx_val; int ret; dma_addr_t buf_pa; struct mwifiex_pcie_buf_desc *desc; + struct mwifiex_pfu_buf_desc *desc2; __le16 *tmp; if (!(skb->data && skb->len)) { @@ -975,6 +1057,7 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb, if (!mwifiex_pcie_ok_to_access_hw(adapter)) mwifiex_pm_wakeup_card(adapter); + num_tx_buffs = MWIFIEX_MAX_TXRX_BD << reg->tx_start_ptr; dev_dbg(adapter->dev, "info: SEND DATA: \n", card->txbd_rdptr, card->txbd_wrptr); if (mwifiex_pcie_txbd_not_full(card)) { @@ -991,24 +1074,44 @@ mwifiex_pcie_send_data(struct mwifiex_adapter *adapter, struct sk_buff *skb, PCI_DMA_TODEVICE)) return -1; - wrindx = card->txbd_wrptr & reg->tx_mask; + wrindx = (card->txbd_wrptr & reg->tx_mask) >> reg->tx_start_ptr; MWIFIEX_SKB_PACB(skb, &buf_pa); card->tx_buf_list[wrindx] = skb; - desc = card->txbd_ring[wrindx]; - desc->paddr = buf_pa; - desc->len = (u16)skb->len; - desc->flags = MWIFIEX_BD_FLAG_FIRST_DESC | - MWIFIEX_BD_FLAG_LAST_DESC; - if ((++card->txbd_wrptr & reg->tx_mask) == - MWIFIEX_MAX_TXRX_BD) + if (reg->pfu_enabled) { + desc2 = (void *)card->txbd_ring[wrindx]; + desc2->paddr = buf_pa; + desc2->len = (u16)skb->len; + desc2->frag_len = (u16)skb->len; + desc2->offset = 0; + desc2->flags = MWIFIEX_BD_FLAG_FIRST_DESC | + MWIFIEX_BD_FLAG_LAST_DESC; + } else { + desc = card->txbd_ring[wrindx]; + desc->paddr = buf_pa; + desc->len = (u16)skb->len; + desc->flags = MWIFIEX_BD_FLAG_FIRST_DESC | + MWIFIEX_BD_FLAG_LAST_DESC; + } + + switch (card->dev->device) { + case PCIE_DEVICE_ID_MARVELL_88W8766P: + card->txbd_wrptr++; + break; + case PCIE_DEVICE_ID_MARVELL_88W8897: + card->txbd_wrptr += reg->ring_tx_start_ptr; + break; + } + + if ((card->txbd_wrptr & reg->tx_mask) == num_tx_buffs) card->txbd_wrptr = ((card->txbd_wrptr & reg->tx_rollover_ind) ^ reg->tx_rollover_ind); + rx_val = card->rxbd_rdptr & reg->rx_wrap_mask; /* Write the TX ring write pointer in to reg->tx_wrptr */ if (mwifiex_write_reg(adapter, reg->tx_wrptr, - card->txbd_wrptr)) { + card->txbd_wrptr | rx_val)) { dev_err(adapter->dev, "SEND DATA: failed to write reg->tx_wrptr\n"); ret = -1; @@ -1050,7 +1153,11 @@ done_unmap: MWIFIEX_SKB_PACB(skb, &buf_pa); pci_unmap_single(card->dev, buf_pa, skb->len, PCI_DMA_TODEVICE); card->tx_buf_list[wrindx] = NULL; - memset(desc, 0, sizeof(*desc)); + if (reg->pfu_enabled) + memset(desc2, 0, sizeof(*desc2)); + else + memset(desc, 0, sizeof(*desc)); + return ret; } @@ -1062,11 +1169,12 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; - u32 wrptr, rd_index; + u32 wrptr, rd_index, tx_val; dma_addr_t buf_pa; int ret = 0; struct sk_buff *skb_tmp = NULL; struct mwifiex_pcie_buf_desc *desc; + struct mwifiex_pfu_buf_desc *desc2; if (!mwifiex_pcie_ok_to_access_hw(adapter)) mwifiex_pm_wakeup_card(adapter); @@ -1126,10 +1234,20 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) "RECV DATA: Attach new sk_buff %p at rxbd_rdidx=%d\n", skb_tmp, rd_index); card->rx_buf_list[rd_index] = skb_tmp; - desc = card->rxbd_ring[rd_index]; - desc->paddr = buf_pa; - desc->len = skb_tmp->len; - desc->flags = 0; + + if (reg->pfu_enabled) { + desc2 = (void *)card->rxbd_ring[rd_index]; + desc2->paddr = buf_pa; + desc2->len = skb_tmp->len; + desc2->frag_len = skb_tmp->len; + desc2->offset = 0; + desc2->flags = reg->ring_flag_sop | reg->ring_flag_eop; + } else { + desc = card->rxbd_ring[rd_index]; + desc->paddr = buf_pa; + desc->len = skb_tmp->len; + desc->flags = 0; + } if ((++card->rxbd_rdptr & reg->rx_mask) == MWIFIEX_MAX_TXRX_BD) { @@ -1140,9 +1258,10 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter) dev_dbg(adapter->dev, "info: RECV DATA: \n", card->rxbd_rdptr, wrptr); + tx_val = card->txbd_wrptr & reg->tx_wrap_mask; /* Write the RX ring read pointer in to reg->rx_rdptr */ if (mwifiex_write_reg(adapter, reg->rx_rdptr, - card->rxbd_rdptr)) { + card->rxbd_rdptr | tx_val)) { dev_err(adapter->dev, "RECV DATA: failed to write reg->rx_rdptr\n"); ret = -1; @@ -1242,9 +1361,11 @@ static int mwifiex_pcie_init_fw_port(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; + int tx_wrap = card->txbd_wrptr & reg->tx_wrap_mask; /* Write the RX ring read pointer in to reg->rx_rdptr */ - if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr)) { + if (mwifiex_write_reg(adapter, reg->rx_rdptr, card->rxbd_rdptr | + tx_wrap)) { dev_err(adapter->dev, "RECV DATA: failed to write reg->rx_rdptr\n"); return -1; @@ -2259,7 +2380,7 @@ static int mwifiex_pcie_init_module(void) { int ret; - pr_debug("Marvell 8766 PCIe Driver\n"); + pr_debug("Marvell PCIe Driver\n"); sema_init(&add_remove_card_sem, 1); @@ -2302,4 +2423,5 @@ MODULE_AUTHOR("Marvell International Ltd."); MODULE_DESCRIPTION("Marvell WiFi-Ex PCI-Express Driver version " PCIE_VERSION); MODULE_VERSION(PCIE_VERSION); MODULE_LICENSE("GPL v2"); -MODULE_FIRMWARE("mrvl/pcie8766_uapsta.bin"); +MODULE_FIRMWARE(PCIE8766_DEFAULT_FW_NAME); +MODULE_FIRMWARE(PCIE8897_DEFAULT_FW_NAME); diff --git a/drivers/net/wireless/mwifiex/pcie.h b/drivers/net/wireless/mwifiex/pcie.h index 7ebdc74f2bb..608061578b3 100644 --- a/drivers/net/wireless/mwifiex/pcie.h +++ b/drivers/net/wireless/mwifiex/pcie.h @@ -29,6 +29,11 @@ #include "main.h" #define PCIE8766_DEFAULT_FW_NAME "mrvl/pcie8766_uapsta.bin" +#define PCIE8897_DEFAULT_FW_NAME "mrvl/pcie8897_uapsta.bin" + +#define PCIE_VENDOR_ID_MARVELL (0x11ab) +#define PCIE_DEVICE_ID_MARVELL_88W8766P (0x2b30) +#define PCIE_DEVICE_ID_MARVELL_88W8897 (0x2b38) /* Constants for Buffer Descriptor (BD) rings */ #define MWIFIEX_MAX_TXRX_BD 0x20 @@ -57,6 +62,8 @@ #define PCIE_SCRATCH_10_REG 0xCE8 #define PCIE_SCRATCH_11_REG 0xCEC #define PCIE_SCRATCH_12_REG 0xCF0 +#define PCIE_RD_DATA_PTR_Q0_Q1 0xC08C +#define PCIE_WR_DATA_PTR_Q0_Q1 0xC05C #define CPU_INTR_DNLD_RDY BIT(0) #define CPU_INTR_DOOR_BELL BIT(1) @@ -75,6 +82,14 @@ #define MWIFIEX_BD_FLAG_ROLLOVER_IND BIT(7) #define MWIFIEX_BD_FLAG_FIRST_DESC BIT(0) #define MWIFIEX_BD_FLAG_LAST_DESC BIT(1) +#define MWIFIEX_BD_FLAG_SOP BIT(0) +#define MWIFIEX_BD_FLAG_EOP BIT(1) +#define MWIFIEX_BD_FLAG_XS_SOP BIT(2) +#define MWIFIEX_BD_FLAG_XS_EOP BIT(3) +#define MWIFIEX_BD_FLAG_EVT_ROLLOVER_IND BIT(7) +#define MWIFIEX_BD_FLAG_RX_ROLLOVER_IND BIT(10) +#define MWIFIEX_BD_FLAG_TX_START_PTR BIT(16) +#define MWIFIEX_BD_FLAG_TX_ROLLOVER_IND BIT(26) /* Max retry number of command write */ #define MAX_WRITE_IOMEM_RETRY 2 @@ -143,6 +158,36 @@ static const struct mwifiex_pcie_card_reg mwifiex_reg_8766 = { .pfu_enabled = 0, }; +static const struct mwifiex_pcie_card_reg mwifiex_reg_8897 = { + .cmd_addr_lo = PCIE_SCRATCH_0_REG, + .cmd_addr_hi = PCIE_SCRATCH_1_REG, + .cmd_size = PCIE_SCRATCH_2_REG, + .fw_status = PCIE_SCRATCH_3_REG, + .cmdrsp_addr_lo = PCIE_SCRATCH_4_REG, + .cmdrsp_addr_hi = PCIE_SCRATCH_5_REG, + .tx_rdptr = PCIE_RD_DATA_PTR_Q0_Q1, + .tx_wrptr = PCIE_WR_DATA_PTR_Q0_Q1, + .rx_rdptr = PCIE_WR_DATA_PTR_Q0_Q1, + .rx_wrptr = PCIE_RD_DATA_PTR_Q0_Q1, + .evt_rdptr = PCIE_SCRATCH_10_REG, + .evt_wrptr = PCIE_SCRATCH_11_REG, + .drv_rdy = PCIE_SCRATCH_12_REG, + .tx_start_ptr = 16, + .tx_mask = 0x03FF0000, + .tx_wrap_mask = 0x07FF0000, + .rx_mask = 0x000003FF, + .rx_wrap_mask = 0x000007FF, + .tx_rollover_ind = MWIFIEX_BD_FLAG_TX_ROLLOVER_IND, + .rx_rollover_ind = MWIFIEX_BD_FLAG_RX_ROLLOVER_IND, + .evt_rollover_ind = MWIFIEX_BD_FLAG_EVT_ROLLOVER_IND, + .ring_flag_sop = MWIFIEX_BD_FLAG_SOP, + .ring_flag_eop = MWIFIEX_BD_FLAG_EOP, + .ring_flag_xs_sop = MWIFIEX_BD_FLAG_XS_SOP, + .ring_flag_xs_eop = MWIFIEX_BD_FLAG_XS_EOP, + .ring_tx_start_ptr = MWIFIEX_BD_FLAG_TX_START_PTR, + .pfu_enabled = 1, +}; + struct mwifiex_pcie_device { const char *firmware; const struct mwifiex_pcie_card_reg *reg; @@ -155,6 +200,12 @@ static const struct mwifiex_pcie_device mwifiex_pcie8766 = { .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD, }; +static const struct mwifiex_pcie_device mwifiex_pcie8897 = { + .firmware = PCIE8897_DEFAULT_FW_NAME, + .reg = &mwifiex_reg_8897, + .blksz_fw_dl = MWIFIEX_PCIE_BLOCK_SIZE_FW_DNLD, +}; + struct mwifiex_evt_buf_desc { u64 paddr; u16 len; @@ -167,6 +218,15 @@ struct mwifiex_pcie_buf_desc { u16 flags; } __packed; +struct mwifiex_pfu_buf_desc { + u16 flags; + u16 offset; + u16 frag_len; + u16 len; + u64 paddr; + u32 reserved; +} __packed; + struct pcie_service_card { struct pci_dev *dev; struct mwifiex_adapter *adapter; @@ -210,10 +270,22 @@ mwifiex_pcie_txbd_empty(struct pcie_service_card *card, u32 rdptr) { const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; - if (((card->txbd_wrptr & reg->tx_mask) == (rdptr & reg->tx_mask)) && - ((card->txbd_wrptr & reg->tx_rollover_ind) != + switch (card->dev->device) { + case PCIE_DEVICE_ID_MARVELL_88W8766P: + if (((card->txbd_wrptr & reg->tx_mask) == + (rdptr & reg->tx_mask)) && + ((card->txbd_wrptr & reg->tx_rollover_ind) != + (rdptr & reg->tx_rollover_ind))) + return 1; + break; + case PCIE_DEVICE_ID_MARVELL_88W8897: + if (((card->txbd_wrptr & reg->tx_mask) == + (rdptr & reg->tx_mask)) && + ((card->txbd_wrptr & reg->tx_rollover_ind) == (rdptr & reg->tx_rollover_ind))) - return 1; + return 1; + break; + } return 0; } @@ -223,11 +295,22 @@ mwifiex_pcie_txbd_not_full(struct pcie_service_card *card) { const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; - if (((card->txbd_wrptr & reg->tx_mask) != - (card->txbd_rdptr & reg->tx_mask)) || - ((card->txbd_wrptr & reg->tx_rollover_ind) != - (card->txbd_rdptr & reg->tx_rollover_ind))) - return 1; + switch (card->dev->device) { + case PCIE_DEVICE_ID_MARVELL_88W8766P: + if (((card->txbd_wrptr & reg->tx_mask) != + (card->txbd_rdptr & reg->tx_mask)) || + ((card->txbd_wrptr & reg->tx_rollover_ind) != + (card->txbd_rdptr & reg->tx_rollover_ind))) + return 1; + break; + case PCIE_DEVICE_ID_MARVELL_88W8897: + if (((card->txbd_wrptr & reg->tx_mask) != + (card->txbd_rdptr & reg->tx_mask)) || + ((card->txbd_wrptr & reg->tx_rollover_ind) == + (card->txbd_rdptr & reg->tx_rollover_ind))) + return 1; + break; + } return 0; } -- cgit v1.2.3-70-g09d2 From 52301a815e81cdcbcf971ba28df0376dc7f3961c Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Tue, 12 Feb 2013 14:38:32 -0800 Subject: mwifiex: device specific sleep cookie handling for PCIe This patch adds support for handling of PCIe sleep cookie depending upon device properties. Some PCIe devices need sleep cookie probing before accessing HW while some others don't. A new sleep_cookie variable is defined as part of mwifiex_pcie_card_reg strcture and set/reset as per device capability. Sleep cookie is allocated/accessed/freed only when flag sleep_cookie for this particular device is enabled. Signed-off-by: Avinash Patil Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/pcie.c | 30 ++++++++++++++++++++++-------- drivers/net/wireless/mwifiex/pcie.h | 3 +++ 2 files changed, 25 insertions(+), 8 deletions(-) (limited to 'drivers/net/wireless/mwifiex') diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 3b9be7c185c..492655c048d 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c @@ -62,6 +62,10 @@ static bool mwifiex_pcie_ok_to_access_hw(struct mwifiex_adapter *adapter) { u32 *cookie_addr; struct pcie_service_card *card = adapter->card; + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; + + if (!reg->sleep_cookie) + return true; if (card->sleep_cookie_vbase) { cookie_addr = (u32 *)card->sleep_cookie_vbase; @@ -299,8 +303,10 @@ static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data) static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter) { int i = 0; + struct pcie_service_card *card = adapter->card; + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; - while (mwifiex_pcie_ok_to_access_hw(adapter)) { + while (reg->sleep_cookie && mwifiex_pcie_ok_to_access_hw(adapter)) { i++; usleep_range(10, 20); /* 50ms max wait */ @@ -1513,8 +1519,8 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter) if (adapter->ps_state == PS_STATE_SLEEP_CFM) { mwifiex_process_sleep_confirm_resp(adapter, skb->data, skb->len); - while (mwifiex_pcie_ok_to_access_hw(adapter) && - (count++ < 10)) + while (reg->sleep_cookie && (count++ < 10) && + mwifiex_pcie_ok_to_access_hw(adapter)) usleep_range(50, 60); } else { dev_err(adapter->dev, @@ -2172,6 +2178,7 @@ static int mwifiex_pcie_init(struct mwifiex_adapter *adapter) struct pcie_service_card *card = adapter->card; int ret; struct pci_dev *pdev = card->dev; + const struct mwifiex_pcie_card_reg *reg = card->pcie.reg; pci_set_drvdata(pdev, card); @@ -2234,10 +2241,13 @@ static int mwifiex_pcie_init(struct mwifiex_adapter *adapter) ret = mwifiex_pcie_alloc_cmdrsp_buf(adapter); if (ret) goto err_alloc_cmdbuf; - ret = mwifiex_pcie_alloc_sleep_cookie_buf(adapter); - if (ret) - goto err_alloc_cookie; - + if (reg->sleep_cookie) { + ret = mwifiex_pcie_alloc_sleep_cookie_buf(adapter); + if (ret) + goto err_alloc_cookie; + } else { + card->sleep_cookie_vbase = NULL; + } return ret; err_alloc_cookie: @@ -2334,12 +2344,16 @@ static int mwifiex_register_dev(struct mwifiex_adapter *adapter) static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter) { struct pcie_service_card *card = adapter->card; + const struct mwifiex_pcie_card_reg *reg; if (card) { dev_dbg(adapter->dev, "%s(): calling free_irq()\n", __func__); free_irq(card->dev->irq, card->dev); - mwifiex_pcie_delete_sleep_cookie_buf(adapter); + reg = card->pcie.reg; + if (reg->sleep_cookie) + mwifiex_pcie_delete_sleep_cookie_buf(adapter); + mwifiex_pcie_delete_cmdrsp_buf(adapter); mwifiex_pcie_delete_evtbd_ring(adapter); mwifiex_pcie_delete_rxbd_ring(adapter); diff --git a/drivers/net/wireless/mwifiex/pcie.h b/drivers/net/wireless/mwifiex/pcie.h index 608061578b3..d322ab8604e 100644 --- a/drivers/net/wireless/mwifiex/pcie.h +++ b/drivers/net/wireless/mwifiex/pcie.h @@ -126,6 +126,7 @@ struct mwifiex_pcie_card_reg { u8 ring_flag_xs_eop; u32 ring_tx_start_ptr; u8 pfu_enabled; + u8 sleep_cookie; }; static const struct mwifiex_pcie_card_reg mwifiex_reg_8766 = { @@ -156,6 +157,7 @@ static const struct mwifiex_pcie_card_reg mwifiex_reg_8766 = { .ring_flag_xs_eop = 0, .ring_tx_start_ptr = 0, .pfu_enabled = 0, + .sleep_cookie = 1, }; static const struct mwifiex_pcie_card_reg mwifiex_reg_8897 = { @@ -186,6 +188,7 @@ static const struct mwifiex_pcie_card_reg mwifiex_reg_8897 = { .ring_flag_xs_eop = MWIFIEX_BD_FLAG_XS_EOP, .ring_tx_start_ptr = MWIFIEX_BD_FLAG_TX_START_PTR, .pfu_enabled = 1, + .sleep_cookie = 0, }; struct mwifiex_pcie_device { -- cgit v1.2.3-70-g09d2